📄 subsql.cpp
字号:
return NULL;}bool dbSubSql::updateFields(dbAnyCursor* cursor, dbUpdateElement* elems){ char buf[64], *src; dbInheritedAttribute iattr; dbSynthesizedAttribute sattr; iattr.db = this; iattr.oid = cursor->currId; iattr.table = (dbTable*)getRow(cursor->table->tableId); iattr.record = (byte*)getRow(cursor->currId); iattr.paramBase = (size_t)cursor->paramBase; do { dbExprNode* expr = elems->value; dbFieldDescriptor* fd = elems->field; execute(expr, iattr, sattr); byte* dst = cursor->record + fd->appOffs; switch (fd->type) { case dbField::tpBool: switch (expr->type) { case tpInteger: *(bool*)dst = sattr.ivalue != 0; continue; case tpBoolean: *(bool*)dst = sattr.bvalue; continue; case tpReal: *(bool*)dst = sattr.fvalue != 0; continue; case tpString: *(bool*)dst = *sattr.base == 'T' || *sattr.base == 't' || *sattr.base == '1'; continue; } break; case dbField::tpInt1: switch (expr->type) { case tpInteger: *(int1*)dst = (int1)sattr.ivalue; continue; case tpBoolean: *(int1*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int1*)dst = (int1)sattr.fvalue; continue; case tpString: *(int1*)dst = (int1)atoi((char*)sattr.base); continue; } break; case dbField::tpInt2: switch (expr->type) { case tpInteger: *(int2*)dst = (int2)sattr.ivalue; continue; case tpBoolean: *(int2*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int2*)dst = (int2)sattr.fvalue; continue; case tpString: *(int2*)dst = (int2)atoi((char*)sattr.base); continue; } break; case dbField::tpInt4: switch (expr->type) { case tpInteger: *(int4*)dst = (int4)sattr.ivalue; continue; case tpBoolean: *(int4*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int4*)dst = (int4)sattr.fvalue; continue; case tpString: *(int4*)dst = (int1)atoi((char*)sattr.base); continue; } break; case dbField::tpInt8: switch (expr->type) { case tpInteger: *(db_int8*)dst = sattr.ivalue; continue; case tpBoolean: *(db_int8*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(db_int8*)dst = (db_int8)sattr.fvalue; continue; case tpString: *(db_int8*)dst = (db_int8)atoi((char*)sattr.base); continue; } break; case dbField::tpReal4: switch (expr->type) { case tpInteger: *(real4*)dst = (real4)sattr.ivalue; continue; case tpBoolean: *(real4*)dst = (real4)(sattr.bvalue ? 1 : 0); continue; case tpReal: *(real4*)dst = (real4)sattr.fvalue; continue; case tpString: *(real4*)dst = (real4)atof((char*)sattr.base); continue; } break; case dbField::tpReal8: switch (expr->type) { case tpInteger: *(real8*)dst = (real8)sattr.ivalue; continue; case tpBoolean: *(real8*)dst = sattr.bvalue ? 1.0 : 0.0; continue; case tpReal: *(real8*)dst = sattr.fvalue; continue; case tpString: *(real8*)dst = atof((char*)sattr.base); continue; } break; case dbField::tpString: src = buf; switch (expr->type) { case tpInteger: sprintf(buf, INT8_FORMAT, sattr.ivalue); break; case tpBoolean: strcpy(buf, sattr.bvalue ? "t" : "f"); break; case tpReal: sprintf(buf, "%f", sattr.fvalue); break; case tpString: src = (char*)sattr.base; break; } *(char**)dst = new char[strlen(src)+1]; strcpy(*(char**)dst, src); elems->strValue = *(char**)dst; continue; case dbField::tpReference: if (expr->type == tpInteger) { *(oid_t*)dst = sattr.oid; continue; } } assert(false); } while ((elems = elems->next) != NULL); return true;}void dbSubSql::deleteColumns(dbFieldDescriptor* columns){ if (columns != NULL) { dbFieldDescriptor *next, *fd = columns; do { next = fd->next; fd->type = dbField::tpUnknown; fd->longName = NULL; delete fd; fd = next; } while (next != columns); } }void dbSubSql::profile(){ printf("TABLES:\n"); printf(" Fixed Fields Columns Rows Total Aligned TableName\n"); printf("----------------------------------------------------------------\n"); beginTransaction(dbSharedLock); for (dbTableDescriptor* desc=tables; desc != NULL; desc=desc->nextDbTable) { dbRecord* rec; dbTable* table = (dbTable*)getRow(desc->tableId); size_t totalSize = 0; size_t totalAlignedSize = 0; for (oid_t oid = table->firstRow; oid != 0; oid = rec->next) { rec = getRow(oid); totalSize += rec->size; totalAlignedSize += DOALIGN(rec->size, dbAllocationQuantum); } printf("%8ld %8ld %8ld %8ld %8ld %8ld %s\n", (long)desc->fixedSize,(long)desc->nFields, (long)desc->nColumns, (long)table->nRows, (long)totalSize, (long)totalAlignedSize, desc->name); }} bool dbSubSql::parse() { dbTableDescriptor* desc; dbFieldDescriptor* fd; int tkn; bool count, outputOid, compactify; dbFieldDescriptor* columns; line = 1; pos = 0; while (true) { if (in == stdin) { printf(prompt); tkn = scan(); pos += strlen(prompt); } else { tkn = scan(); } switch (tkn) { case tkn_update: if (!opened) { error("Database not opened"); continue; } if (accessType == dbReadOnly) { error("Operation is not possible in read-only mode"); continue; } dotIsPartOfIdentifier = true; if (expect("table name", tkn_ident)) { if ((desc = findTable(name)) == NULL) { error("No such table in database"); continue; } if (!expect("set", tkn_set)) { continue; } dbDatabaseThreadContext* ctx = threadContext.get(); byte *record = dbMalloc(desc->appSize); memset(record, 0, desc->appSize); ctx->interactive = true; ctx->catched = true; dbUpdateElement* elems = NULL; if (!expect("field name", tkn_ident)) { goto updateCleanup; } #ifdef THROW_EXCEPTION_ON_ERROR try {#else if (setjmp(ctx->unwind) == 0) {#endif char* condition = NULL; int startPos = pos; while (true) { dbUpdateElement* elem = new dbUpdateElement; dbFieldDescriptor* fd = desc->findSymbol(name); if (fd == NULL) { error("No such field in the table"); goto updateCleanup; } if (fd->type > dbField::tpReference) { error("Field can not be updated"); goto updateCleanup; } elem->field = fd; elem->next = elems; elems = elem; if (!expect("=", tkn_eq)) { goto updateCleanup; } startPos = pos; int ch = readExpression(); if (ch == EOF) { error("unexpected end of input"); goto updateCleanup; } condition = strstr(buf, "where"); if (condition != NULL) { *condition = '\0'; } dbExprNode* expr = ctx->compiler.compileExpression(desc, buf, startPos); if (expr == NULL) { goto updateCleanup; } if (expr->type > tpString) { error("Invalid expression type"); goto updateCleanup; } elem->value = expr; if (condition == NULL && ch == ',') { if (!expect("field name", tkn_ident)) { goto updateCleanup; } } else { break; } } dbAnyCursor cursor(*desc, dbCursorForUpdate, record); cursor.reset(); if (condition != NULL) { query.pos = startPos + (condition - buf) + 5; query = (char const*)(condition + 5); select(&cursor, query); if (!query.compiled()) { goto updateCleanup; } } else { select(&cursor); } if (cursor.gotoFirst()) { do { cursor.fetch(); if (!updateFields(&cursor, elems)) { goto updateCleanup; } cursor.update(); } while (cursor.gotoNext()); } printf("\n\t%d records updated\n", cursor.getNumberOfRecords());#ifdef THROW_EXCEPTION_ON_ERROR } catch(dbException const&) {}#else } else { if (query.mutexLocked) { query.mutexLocked = false; query.mutex.unlock(); } }#endif updateCleanup: query.reset(); while (elems != NULL) { dbUpdateElement* elem = elems; elems = elems->next; delete elem; } dbExprNodeAllocator::instance.reset(); ctx->catched = false; dbFree(record); } break; case tkn_select: if (!opened) { error("Database not opened"); continue; } outputOid = true; count = false; if ((tkn = scan()) == tkn_all) { outputOid = false; tkn = scan(); } else if (tkn == tkn_count) { if (!expect("'('", tkn_lpar) || !expect("'*'", tkn_all) || !expect("')'", tkn_rpar)) { continue; } count = true; tkn = scan(); } columns = NULL; if (tkn != tkn_from) { while (true) { if (tkn != tkn_ident) { error("Field name or 'from' expected"); } dbFieldDescriptor* column = new dbFieldDescriptor(name); if (columns != NULL) { column->next = columns; column->prev = columns->prev; column->prev->next = column; columns->prev = column;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -