⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jnicli.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#define _JNI_IMPLEMENTATION_ 1#include <jni.h>#include "fastdb.h"#include "localcli.h"static cli_var_type const cliTypeMap[] = {    cli_oid,     cli_bool,   // TP_BOOL    cli_int2,   // TP_CHAR    cli_int1,   // TP_INT1    cli_int2,   // TP_INT2    cli_int4,   // TP_INT4    cli_int8,   // TP_INT8    cli_real4,  // TP_REAL4    cli_real8,  // TP_REAL8    cli_asciiz, // TP_STRING    cli_int8,   // TP_DATE     cli_array_of_bool, // TP_BOOL_ARRAY    cli_array_of_int2, // TP_CHAR_ARRAY    cli_array_of_int1, // TP_INT1_ARRAY    cli_array_of_int2, // TP_INT2_ARRAY    cli_array_of_int4, // TP_INT4_ARRAY    cli_array_of_int8, // TP_INT8_ARRAY    cli_array_of_real4, // TP_REAL4_ARRAY    cli_array_of_real8, // TP_REAL8_ARRAY    cli_array_of_string, // TP_STRING_ARRAY};inline char const* getStringBody(JNIEnv* env, jstring str) {    return env->GetStringUTFChars(str, 0);}inline void releaseStringBody(JNIEnv* env, jstring str, char const* body) {    env->ReleaseStringUTFChars(str, body);}inline int getStringLength(JNIEnv* env, jstring str) {    return env->GetStringUTFLength(str);}inline jstring newString(JNIEnv* env, char const* body) {    return env->NewStringUTF(body);}class ClassDescriptor {  public:    int nColumns;    cli_field_descriptor* columns;    char*                 names;    ~ClassDescriptor() {         delete[] columns;        delete[] names;    }};const size_t VARYING_BLOCK_SIZE = 1024;struct VaryingBlock {     VaryingBlock* next;    char          data[1];};class ObjectBuffer {    dbSmallBuffer fixedPart;    VaryingBlock* varyingPart;    size_t fixedPos;    size_t varyingPos;  public:    void* base() {        return fixedPart.base();    }    ObjectBuffer() {         fixedPos = 0;        varyingPos = 0;        varyingPart = NULL;    }    ~ObjectBuffer() {         VaryingBlock *curr, *next;        for (curr = varyingPart; curr != NULL; curr = next) {             next = curr->next;            dbFree(curr);        }    }    void* appendFixed(size_t size) {         return appendFixed(size, size);    }    void* appendFixed(size_t size, size_t alignment) {         fixedPos = DOALIGN(fixedPos, alignment);        fixedPart.put(fixedPos + size);        void* ptr = fixedPart.base() + fixedPos;        fixedPos += size;        return ptr;    }    void* appendVarying(size_t nElems, size_t elemSize) {         varyingPos = DOALIGN(varyingPos, elemSize);        size_t size = nElems*elemSize;        void* ptr;        if (varyingPart != NULL && varyingPos + size <= VARYING_BLOCK_SIZE) {             ptr = &varyingPart->data[varyingPos];            varyingPos += size;        } else {            VaryingBlock* blk = (VaryingBlock*)                dbMalloc(sizeof(VaryingBlock*) + (size < VARYING_BLOCK_SIZE ? VARYING_BLOCK_SIZE : size));            blk->next = varyingPart;            varyingPart = blk;            ptr = varyingPart->data;            varyingPos = size;        }        return ptr;    }};class JniResultSet {  public:    byte*  record;    size_t pos;    dbAnyCursor cursor;    bool   first;    JniResultSet(dbTableDescriptor* desc)     : record(new byte[desc->size()]), pos(0), cursor(*desc, dbCursorViewOnly, record), first(true)    {        memset(record, 0, desc->size());        cursor.reset();    }    int size() {         return cursor.getNumberOfRecords();    }    oid_t next() {        pos = 0;        if (first) {             if (cursor.isEmpty()) {                 delete this;                return 0;            }            first = false;        } else if (!cursor.gotoNext()) {            delete this;            return 0;        }        cursor.fetch();        return cursor.currId;    }    jbyte nextByte() {         return (jbyte)record[pos++];    }    jshort nextShort() {         pos = DOALIGN(pos, sizeof(jshort));        jshort val = *(jshort*)(record + pos);        pos += sizeof(jshort);        return val;    }    jint nextInt() {         pos = DOALIGN(pos, sizeof(jint));        jint val = *(jint*)(record + pos);        pos += sizeof(jint);        return val;    }    jlong nextLong() {         pos = DOALIGN(pos, sizeof(jlong));        jlong val = *(jlong*)(record + pos);        pos += sizeof(jlong);        return val;    }    jstring nextString(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(char*));        jstring val = newString(env, *(char**)(record + pos));        pos += sizeof(char*);        return val;    }           jbooleanArray nextBoolArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jbooleanArray val = env->NewBooleanArray(arr->size);        env->SetBooleanArrayRegion(val, 0, arr->size, (jboolean*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jcharArray nextCharArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jcharArray val = env->NewCharArray(arr->size);        env->SetCharArrayRegion(val, 0, arr->size, (jchar*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jbyteArray nextByteArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jbyteArray val = env->NewByteArray(arr->size);        env->SetByteArrayRegion(val, 0, arr->size, (jbyte*)arr->data);        pos += sizeof(cli_array_t);        return val;    }           jshortArray nextShortArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jshortArray val = env->NewShortArray(arr->size);        env->SetShortArrayRegion(val, 0, arr->size, (jshort*)arr->data);        pos += sizeof(cli_array_t);        return val;    }           jintArray nextIntArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jintArray val = env->NewIntArray(arr->size);        env->SetIntArrayRegion(val, 0, arr->size, (jint*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jlongArray nextLongArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jlongArray val = env->NewLongArray(arr->size);        env->SetLongArrayRegion(val, 0, arr->size, (jlong*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jfloatArray nextFloatArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jfloatArray val = env->NewFloatArray(arr->size);        env->SetFloatArrayRegion(val, 0, arr->size, (jfloat*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jdoubleArray nextDoubleArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        jdoubleArray val = env->NewDoubleArray(arr->size);        env->SetDoubleArrayRegion(val, 0, arr->size, (jdouble*)arr->data);        pos += sizeof(cli_array_t);        return val;    }    jobjectArray nextStringArray(JNIEnv* env) {         pos = DOALIGN(pos, sizeof(void*));        cli_array_t* arr = (cli_array_t*)(record + pos);        int size = (int)arr->size;        jobjectArray val = env->NewObjectArray(size, env->FindClass("java/lang/String"), NULL);        char** spp = (char**)arr->data;        for (int i = 0; i < size; i++) {            env->SetObjectArrayElement(val, i, newString(env, spp[i]));        }        pos += sizeof(cli_array_t);        return val;    }    ~JniResultSet() {         delete[] record;    }};class JniDatabase : public dbDatabase {  private:    oid_t   tableId;    oid_t   nextTableId;    JNIEnv* env;  public:    JniDatabase(JNIEnv* env, dbAccessType type, size_t poolSize)     : dbDatabase(type, poolSize)    {        this->env = env;    }    virtual void handleError(dbErrorClass error, char const* msg, int arg = 0) {        jclass cls = env->FindClass("jnicli/CliException");        if (cls != NULL) {             env->ThrowNew(cls, msg);                }    }    void open(char const* databaseName, char const* databasePath, int transactionCommitDelay)    {        if (!dbDatabase::open(databaseName, databasePath, transactionCommitDelay)) {            handleError(dbDatabase::DatabaseOpenError, "Failed to open database");            return;        }        dbTable* table = (dbTable*)getRow(dbMetaTableId);        dbTableDescriptor* metatable = new dbTableDescriptor(table);        linkTable(metatable, dbMetaTableId);        oid_t tid = table->firstRow;        nextTableId = tid;        while (tid != 0) {            table = (dbTable*)getRow(tid);            dbTableDescriptor* desc = new dbTableDescriptor(table);            linkTable(desc, tid);            desc->setFlags();            tid = table->next;        }    }      jstring nextTable() {        tableId = nextTableId;        if (tableId == 0) {             if (!completeDescriptorsInitialization()) {                close();                handleError(dbDatabase::DatabaseOpenError, "Referenced table not found");            }            return NULL;        }        dbTable* table = (dbTable*)getRow(tableId);        jstring name = newString(env, (char*)((byte*)table + table->name.offs));        nextTableId = table->next;        return name;    }    dbTableDescriptor* createTable(char const* name, ClassDescriptor* clsDesc) {        beginTransaction(dbExclusiveLock);        dbTableDescriptor* tableDesc = NULL;        int rc = dbCLI::create_table(this, name, clsDesc->nColumns, clsDesc->columns);        if (rc == cli_unsupported_type) {            handleError(dbDatabase::DatabaseOpenError, "Unsupported table field type");            return NULL;        }        return findTableByName(name);    }            dbTableDescriptor* updateTable(char const* name, ClassDescriptor* clsDesc) {        beginTransaction(dbExclusiveLock);        int rc = dbCLI::alter_table(this, name, clsDesc->nColumns, clsDesc->columns);        if (rc == cli_unsupported_type) {            handleError(dbDatabase::DatabaseOpenError, "Unsupported table field type");            return NULL;        }        return findTableByName(name);    }    oid_t insert(dbTableDescriptor* desc, ObjectBuffer* buf) {         dbAnyReference ref;        char** ptr = (char**)buf->base();        insertRecord(desc, &ref, buf->base());        return ref.getOid();    }                JniResultSet* select(dbTableDescriptor* desc, char const* query) {         JniResultSet* rs = new JniResultSet(desc);                rs->cursor.select(query, dbCursorViewOnly, NULL);        return rs;    }                void update(oid_t oid, dbTableDescriptor* desc, ObjectBuffer* buf) {        dbDatabase::update(oid, desc, buf->base());    }    int remove(dbTableDescriptor* desc, char const* query) {         JniResultSet rs(desc);                int result = rs.cursor.select(query, dbCursorForUpdate, NULL);        rs.cursor.removeAllSelected();        return result;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -