📄 subsql.cpp
字号:
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;}bool dbSubSql::parse() { dbTableDescriptor* desc; dbFieldDescriptor* fd; int tkn; bool count, outputOid, compactify; 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; } 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); 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; } if (autocommit || !modified) { commit(); // release locks } dbExprNodeAllocator::instance.reset(); ctx->catched = false; dbFree(record); } continue; 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(); } if (tkn != tkn_from) { error("'from' keyword expected"); continue; } if (scan() != tkn_ident) { error("Table name expected"); continue; } if ((desc = findTable(name)) != NULL) { dbAnyCursor cursor(*desc, dbCursorViewOnly, NULL); query.pos = pos; dbDatabaseThreadContext* ctx = threadContext.get(); ctx->interactive = true; ctx->catched = true;#ifdef THROW_EXCEPTION_ON_ERROR try {#else if (setjmp(ctx->unwind) == 0) {#endif if (readCondition()) { query = (char const*)buf; cursor.reset(); select(&cursor, query); if (!query.compiled()) { dbExprNodeAllocator::instance.reset(); ctx->catched = false; continue; } } else { ctx->catched = false; continue; } if (count) { printf("%d records selected\n", cursor.getNumberOfRecords()); } else { if (cursor.gotoFirst()) { dbFieldDescriptor* fd = desc->columns; do { printf("%s ", fd->name); } while ((fd = fd->next) != desc->columns); if (outputOid) { printf("\n#%x: (", cursor.currId); } else { printf("\n("); } dumpRecord((byte*)getRow(cursor.currId), cursor.table->columns); printf(")"); while (cursor.gotoNext()) { if (outputOid) { printf(",\n#%x: (", cursor.currId); } else { printf(",\n("); } dumpRecord((byte*)getRow(cursor.currId), cursor.table->columns); printf(")"); } printf("\n\t%d records selected\n", cursor.getNumberOfRecords()); } else { fprintf(stderr, "No records selected\n"); } }#ifdef THROW_EXCEPTION_ON_ERROR } catch(dbException const&) {}#else } else { if (query.mutexLocked) { query.mutexLocked = false; query.mutex.unlock(); } }#endif ctx->catched = false; if (!modified || autocommit) { commit(); // release locks } } else { error("No such table in database"); } continue; case tkn_open: if (expect("database name", tkn_sconst)) { char* databaseName = new char[strlen(buf)+1]; strcpy(databaseName, buf); char* fileName = NULL; if ((tkn = scan()) == tkn_sconst) { fileName = buf; } else if (tkn != tkn_semi) { delete[] databaseName; error("database file name expected"); continue; } if (opened) { close(); while (droppedTables != NULL) { dbTableDescriptor* next = droppedTables->nextDbTable; delete droppedTables; droppedTables = next; } opened = false; dbTableDescriptor::cleanup(); } time_t transactionCommitDelay = 0; char* delay = getenv("FASTDB_COMMIT_DELAY"); if (delay != NULL) { transactionCommitDelay = atoi(delay); } if (!open(databaseName, fileName, INFINITE, transactionCommitDelay)) { fprintf(stderr, "Database not opened\n"); } else { opened = true; dbTable* table = (dbTable*)getRow(dbMetaTableId); dbTableDescriptor* desc = new dbTableDescriptor(table); linkTable(desc, dbMetaTableId); oid_t tableId = table->firstRow; while (tableId != 0) { table = (dbTable*)getRow(tableId); for (desc = tables; desc != NULL && desc->tableId != tableId; desc = desc->nextDbTable); if (desc == NULL) { dbTableDescriptor* desc = new dbTableDescriptor(table); linkTable(desc, tableId); desc->setFlags(); } tableId = table->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -