📄 database.cpp
字号:
sattr.ivalue = (*(db_int8(*)(dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0)); return; case dbvmFuncArg2Real: sattr.fvalue = (*(real8(*)(dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0)); return; case dbvmFuncArg2Str: copyString(iattr, sattr, (*(char*(*)(dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0))); return; case dbvmFuncArgArg2Bool: sattr.bvalue = (*(bool(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1)); return; case dbvmFuncArgArg2Int: sattr.ivalue = (*(db_int8(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1)); return; case dbvmFuncArgArg2Real: sattr.fvalue = (*(real8(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1)); return; case dbvmFuncArgArg2Str: copyString(iattr, sattr, (*(char*(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1))); return; case dbvmFuncArgArgArg2Bool: sattr.bvalue = (*(bool(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1), dbUserFunctionArgument(expr, iattr, sattr, 2)); return; case dbvmFuncArgArgArg2Int: sattr.ivalue = (*(db_int8(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1), dbUserFunctionArgument(expr, iattr, sattr, 2)); return; case dbvmFuncArgArgArg2Real: sattr.fvalue = (*(real8(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1), dbUserFunctionArgument(expr, iattr, sattr, 2)); return; case dbvmFuncArgArgArg2Str: copyString(iattr, sattr, (*(char*(*)(dbUserFunctionArgument const&, dbUserFunctionArgument const&, dbUserFunctionArgument const&))expr->func.fptr) (dbUserFunctionArgument(expr, iattr, sattr, 0), dbUserFunctionArgument(expr, iattr, sattr, 1), dbUserFunctionArgument(expr, iattr, sattr, 2))); return; case dbvmFuncInt2Bool: execute(expr->func.arg[0], iattr, sattr); sattr.bvalue = (*(bool(*)(db_int8))expr->func.fptr)(sattr.ivalue); return; case dbvmFuncReal2Bool: execute(expr->func.arg[0], iattr, sattr); sattr.bvalue = (*(bool(*)(real8))expr->func.fptr)(sattr.fvalue); return; case dbvmFuncStr2Bool: execute(expr->func.arg[0], iattr, sattr); sattr.bvalue = (*(bool(*)(char const*))expr->func.fptr)(sattr.array.base); return; case dbvmFuncInt2Int: execute(expr->func.arg[0], iattr, sattr); sattr.ivalue = (*(db_int8(*)(db_int8))expr->func.fptr)(sattr.ivalue); return; case dbvmFuncReal2Int: execute(expr->func.arg[0], iattr, sattr); sattr.ivalue = (*(db_int8(*)(real8))expr->func.fptr)(sattr.fvalue); return; case dbvmFuncStr2Int: execute(expr->func.arg[0], iattr, sattr); sattr.ivalue = (*(db_int8(*)(char const*))expr->func.fptr)(sattr.array.base); return; case dbvmFuncInt2Real: execute(expr->func.arg[0], iattr, sattr); sattr.fvalue = (*(real8(*)(db_int8))expr->func.fptr)(sattr.ivalue); return; case dbvmFuncReal2Real: execute(expr->func.arg[0], iattr, sattr); sattr.fvalue = (*(real8(*)(real8))expr->func.fptr)(sattr.fvalue); return; case dbvmFuncStr2Real: execute(expr->func.arg[0], iattr, sattr); sattr.fvalue = (*(real8(*)(char const*))expr->func.fptr)(sattr.array.base); return; case dbvmFuncInt2Str: execute(expr->func.arg[0], iattr, sattr); copyString(iattr, sattr, (*(char*(*)(db_int8))expr->func.fptr)(sattr.ivalue)); return; case dbvmFuncReal2Str: execute(expr->func.arg[0], iattr, sattr); copyString(iattr, sattr, (*(char*(*)(real8))expr->func.fptr)(sattr.fvalue)); return; case dbvmFuncStr2Str: execute(expr->func.arg[0], iattr, sattr); copyString(iattr, sattr, (*(char*(*)(char const*))expr->func.fptr)(sattr.array.base)); return; case dbvmInArrayBool: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfBool(sattr, sattr2); return; case dbvmInArrayInt1: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfInt1(sattr, sattr2); return; case dbvmInArrayInt2: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfInt2(sattr, sattr2); return; case dbvmInArrayInt4: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfInt4(sattr, sattr2); return; case dbvmInArrayInt8: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfInt8(sattr, sattr2); return; case dbvmInArrayReal4: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfReal4(sattr, sattr2); return; case dbvmInArrayReal8: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfReal8(sattr, sattr2); return; case dbvmInArrayString: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfString(sattr, sattr2); return; case dbvmInArrayReference: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchArrayOfReference(sattr, sattr2); return; case dbvmInString: execute(expr->operand[0], iattr, sattr); execute(expr->operand[1], iattr, sattr2); searchInString(sattr, sattr2); return; default: assert(false); }}void dbDatabase::handleError(dbErrorClass error, char const* msg, int arg){ if (errorHandler != NULL) { (*errorHandler)(error, msg, arg); }#ifdef THROW_EXCEPTION_ON_ERROR if (error != NoError) { if (error == DatabaseOpenError) { fprintf(stderr, "%s\n", msg); } else { throw dbException(error, msg, arg); } }#else char buf[256]; switch (error) { case QueryError: fprintf(stderr, "%s in position %d\n", msg, arg); return; case ArithmeticError: fprintf(stderr, "%s\n", msg); break; case IndexOutOfRangeError: fprintf(stderr, "Index %d is out of range\n", arg); break; case DatabaseOpenError: fprintf(stderr, "%s\n", msg); return; case FileError: fprintf(stderr, "%s: %s\n", msg, dbFile::errorText(arg, buf, sizeof(buf))); break; case OutOfMemoryError: fprintf(stderr,"Not enough memory: failed to allocate %d bytes\n",arg); break; case NullReferenceError: fprintf(stderr, "Null object reference is accessed\n"); break; case Deadlock: fprintf(stderr, "Deadlock is caused by upgrading shared locks to exclusive"); break; case LockRevoked: fprintf(stderr, "Lock is revoked by some other client"); break; case InconsistentInverseReference: fprintf(stderr, "%s\n", msg); return; case DatabaseReadOnly: fprintf(stderr, "Attempt to modify readonly database"); break; default: return; } abort();#endif}void dbDatabase::initializeMetaTable(){ static struct { char const* name; int type; int size; int offs; } metaTableFields[] = { { "name", dbField::tpString, sizeof(dbVarying), offsetof(dbTable, name)}, { "fields", dbField::tpArray, sizeof(dbVarying), offsetof(dbTable, fields)}, { "fields[]", dbField::tpStructure, sizeof(dbField), 0}, { "fields[].name", dbField::tpString, sizeof(dbVarying), offsetof(dbField, name)}, { "fields[].tableName",dbField::tpString,sizeof(dbVarying), offsetof(dbField, tableName)}, { "fields[].inverse", dbField::tpString, sizeof(dbVarying), offsetof(dbField, inverse)}, { "fields[].type", dbField::tpInt4, 4, offsetof(dbField, type)}, { "fields[].offset", dbField::tpInt4, 4, offsetof(dbField, offset)}, { "fields[].size", dbField::tpInt4, 4, offsetof(dbField, size)}, { "fields[].hashTable", dbField::tpReference, sizeof(oid_t), offsetof(dbField, hashTable)}, { "fields[].tTree", dbField::tpReference, sizeof(oid_t), offsetof(dbField, tTree)}, { "fixedSize", dbField::tpInt4, 4, offsetof(dbTable, fixedSize)}, { "nRows", dbField::tpInt4, 4, offsetof(dbTable, nRows)}, { "nColumns", dbField::tpInt4, 4, offsetof(dbTable, nColumns)}, { "firstRow", dbField::tpReference, sizeof(oid_t), offsetof(dbTable, firstRow)}, { "lastRow", dbField::tpReference, sizeof(oid_t), offsetof(dbTable, lastRow)} #ifdef AUTOINCREMENT_SUPPORT ,{ "count", dbField::tpInt4, 4, offsetof(dbTable, count)} #endif }; unsigned i; size_t varyingSize = strlen(dbMetaTableName)+1; for (i = 0; i < itemsof(metaTableFields); i++) { varyingSize += strlen(metaTableFields[i].name) + 3; } offs_t metaTableOffs = allocate(sizeof(dbTable) + sizeof(dbField)*itemsof(metaTableFields) + varyingSize); index[0][dbMetaTableId] = metaTableOffs; dbTable* table = (dbTable*)(baseAddr + metaTableOffs); table->size = sizeof(dbTable) + sizeof(dbField)*itemsof(metaTableFields) + varyingSize; table->next = table->prev = 0; int offs = sizeof(dbTable) + sizeof(dbField)*itemsof(metaTableFields); table->name.offs = offs; table->name.size = strlen(dbMetaTableName)+1; strcpy((char*)table + offs, dbMetaTableName); offs += table->name.size; table->fields.offs = sizeof(dbTable); table->fields.size = itemsof(metaTableFields); table->fixedSize = sizeof(dbTable); table->nRows = 0; table->nColumns = 5; table->firstRow = 0; table->lastRow = 0;#ifdef AUTOINCREMENT_SUPPORT table->count = 0;#endif dbField* field = (dbField*)((char*)table + table->fields.offs); offs -= sizeof(dbTable); for (i = 0; i < itemsof(metaTableFields); i++) { field->name.offs = offs; field->name.size = strlen(metaTableFields[i].name) + 1; strcpy((char*)field + offs, metaTableFields[i].name); offs += field->name.size; field->tableName.offs = offs; field->tableName.size = 1; *((char*)field + offs++) = '\0'; field->inverse.offs = offs; field->inverse.size = 1; *((char*)field + offs++) = '\0'; field->type = metaTableFields[i].type; field->size = metaTableFields[i].size; field->offset = metaTableFields[i].offs; field->hashTable = 0; field->tTree = 0; field += 1; offs -= sizeof(dbField); }}bool dbDatabase::open(char const* dbName, char const* fiName, time_t waitLockTimeoutMsec, time_t commitDelaySec){ dbWaitLockTimeout = waitLockTimeoutMsec; delete[] databaseName; delete[] fileName; commitDelay = 0; commitTimeout = 0; commitTimerStarted = 0; backupFileName = NULL; backupPeriod = 0; opened = false; stopDelayedCommitThread = false; databaseNameLen = strlen(dbName); char* name = new char[databaseNameLen+16]; sprintf(name, "%s.in", dbName); databaseName = name; if (fiName == NULL) { fileName = new char[databaseNameLen + 5]; sprintf(fileName, "%s.fdb", dbName); } else { fileName = new char[strlen(fiName)+1]; strcpy(fileName, fiName); } dbInitializationMutex::initializationStatus status; status = initMutex.initialize(name); if (status == dbInitializationMutex::InitializationError) { handleError(DatabaseOpenError, "Failed to start database initialization"); return false; } sprintf(name, "%s.dm", dbName); if (!shm.open(name)) { handleError(DatabaseOpenError, "Failed to open database monitor"); return false; } monitor = shm.get(); sprintf(name, "%s.ws", dbName); if (!writeSem.open(name)) { handleError(DatabaseOpenError, "Failed to initialize database writers semaphore"); return false; } sprintf(name, "%s.rs", dbName); if (!readSem.open(name)) { handleError(DatabaseOpenError, "Failed to initialize database readers semaphore"); return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -