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

📄 subsql.cpp

📁 俄罗斯牛人KK的作品,著名的ORDBMS,这里上传最新的3.39版本源代码.希望了解对象关系数据库的同好,请不要错过.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                error("Array components can not be indexed");
                return NULL;
            }
        } else { 
            return NULL;
        }
        while ((tkn = scan()) != tkn_semi) { 
            if (tkn != tkn_dot) { 
                error("'.' expected");
                return NULL;
            }   
            if (expect("field name", tkn_ident)) { 
                if ((fd = fd->find(name)) == NULL) { 
                    error("No such field in the table");
                    return NULL;
                } else if (fd->type == dbField::tpArray) {      
                    error("Array components can not be indexed");
                    return NULL;
                }       
            } else { 
                return NULL;
            }
        }
        if (fd->type == dbField::tpStructure) { 
            error("Structures can not be indexed");
            return NULL;
        } 
        return fd;
    }
    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.compileError()) { 
                            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;
                }

⌨️ 快捷键说明

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