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

📄 subsql.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -