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

📄 subsql.cpp

📁 俄罗斯牛人KK的作品,著名的ORDBMS,这里上传最新的3.39版本源代码.希望了解对象关系数据库的同好,请不要错过.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                elem += fd->components->dbsSize;
            }
            printf(")");
            continue;
          case dbField::tpStructure:
            if (dateFormat != NULL 
                && fd->components->next == fd->components 
                && strcmp(fd->components->name, "stamp") == 0) 
            { 
                char buf[64];
                printf(((dbDateTime*)(base + fd->components->dbsOffs))->asString(buf, sizeof buf, dateFormat));
                continue;
            }
            printf("(");
            dumpRecord(base, fd->components);
            printf(")");
        }
    } while ((fd = fd->next) != first);
}

int dbSubSql::calculateRecordSize(dbList* node, int offs, 
                                  dbFieldDescriptor* first)
{
    dbFieldDescriptor* fd = first;
    do { 
        if (node == NULL) { 
            return -1;
        }
        if (fd->type == dbField::tpArray) { 
            if (node->type != dbList::nTuple) { 
                return -1;
            }
            int nElems = node->aggregate.nComponents;
            offs = DOALIGN(offs, fd->components->alignment) 
                 + nElems*fd->components->dbsSize;
            if (fd->attr & dbFieldDescriptor::HasArrayComponents) {
                dbList* component = node->aggregate.components;
                while (--nElems >= 0) { 
                    int d = calculateRecordSize(component,offs,fd->components);
                    if (d < 0) return d;
                    offs = d;
                    component = component->next;
                }
            } 
        } else if (fd->type == dbField::tpString) { 
            if (node->type != dbList::nString) { 
                return -1;
            }
            offs += strlen(node->sval) + 1;
        } else if (fd->type == dbField::tpRectangle) {
            if (node->type != dbList::nTuple) { 
                return -1;
            }
            int nCoords = node->aggregate.nComponents;
            if (nCoords != rectangle::dim*2) {
                return -1;
            }
            dbList* component = node->aggregate.components;
            while (--nCoords >= 0) {
                if (component->type != dbList::nInteger && component->type != dbList::nReal) {
                    return -1;
                }
                component = component->next;
            }
        } else if (fd->type == dbField::tpRawBinary) { 
            if (node->type != dbList::nTuple) { 
                return -1;
            }
            int nElems = node->aggregate.nComponents;
            dbList* component = node->aggregate.components;
            if (size_t(nElems) > fd->dbsSize) { 
                return -1;
            }
            while (--nElems >= 0) { 
                if (component->type != dbList::nInteger
                    || (component->ival & ~0xFF) != 0) 
                { 
                    return -1;
                }
                component = component->next;
            }
#ifdef AUTOINCREMENT_SUPPORT
        } else if (node->type == dbList::nAutoinc) {        
            if (fd->type != dbField::tpInt4) {
                return -1;
            }
#endif
        } else { 
            if (!((node->type == dbList::nBool && fd->type == dbField::tpBool)
                  || (node->type == dbList::nInteger 
                      && (fd->type == dbField::tpInt1
                          || fd->type == dbField::tpInt2
                          || fd->type == dbField::tpInt4
                          || fd->type == dbField::tpInt8
                          || fd->type == dbField::tpReference))
                  || (node->type == dbList::nReal 
                      && (fd->type == dbField::tpReal4
                          || fd->type == dbField::tpReal8))
                  || (node->type == dbList::nTuple 
                      && fd->type == dbField::tpStructure)))
            {
                return -1;
            }
            if (fd->attr & dbFieldDescriptor::HasArrayComponents) {
                int d = calculateRecordSize(node->aggregate.components,
                                            offs, fd->components);
                if (d < 0) return d;
                offs = d;
            }
        }
        node = node->next;
    } while ((fd = fd->next) != first);
    return offs;    
}

bool dbSubSql::isValidOid(oid_t oid) 
{
    return oid == 0 || 
        (oid < currIndexSize && (currIndex[oid] & (dbFreeHandleMarker|dbInternalObjectMarker)) == 0);
}

int dbSubSql::initializeRecordFields(dbList* node, byte* dst, int offs, 
                                     dbFieldDescriptor* first)
{
    dbFieldDescriptor* fd = first;
    dbList* component;
    byte* elem;
    coord_t* coord;
    int len, elemOffs, elemSize;

    do { 
        if (node->type == dbList::nString && fd->type != dbField::tpString) { 
            char* s = node->sval;
            long  ival;
            switch (fd->type) {
              case dbField::tpBool:
                *(bool*)(dst+fd->dbsOffs) = *s == '1' || *s == 't' || *s == 'T';
                break;
              case dbField::tpInt1:
                if (sscanf(s, "%ld", &ival) != 1) { 
                    return -1;
                }
                *(int1*)(dst+fd->dbsOffs) = (int1)ival;
              case dbField::tpInt2:
                if (sscanf(s, "%ld", &ival) != 1) { 
                    return -1;
                }
                *(int2*)(dst+fd->dbsOffs) = (int2)ival;
              case dbField::tpInt4:
                if (sscanf(s, "%ld", &ival) != 1) { 
                    return -1;
                }
                *(int4*)(dst+fd->dbsOffs) = (int4)ival;
              case dbField::tpInt8:
                if (sscanf(s, "%ld", &ival) != 1) { 
                    return -1;
                }
                *(db_int8*)(dst+fd->dbsOffs) = ival;
                break;
              case dbField::tpReal4:
                if (sscanf(s, "%f", (real4*)(dst+fd->dbsOffs)) != 1) { 
                    return -1;
                }
                break;
              case dbField::tpReal8:
                if (sscanf(s, "%lf", (real8*)(dst+fd->dbsOffs)) != 1) { 
                    return -1;
                }
                break;
            }
#ifdef AUTOINCREMENT_SUPPORT
        } else if (node->type == dbList::nAutoinc) {        
            if (fd->type == dbField::tpInt4) {
                *(int4*)(dst+fd->dbsOffs) = fd->defTable->autoincrementCount;
            } else { 
                return -1;
            }
#endif
        } else { 
            switch (fd->type) { 
              case dbField::tpBool:
                *(bool*)(dst+fd->dbsOffs) = node->bval;
                break;
              case dbField::tpInt1:
                *(int1*)(dst+fd->dbsOffs) = (int1)node->ival;
                break;
              case dbField::tpInt2:
                *(int2*)(dst+fd->dbsOffs) = (int2)node->ival;
                break;
              case dbField::tpInt4:
                *(int4*)(dst+fd->dbsOffs) = (int4)node->ival;
                break;
              case dbField::tpInt8:
                *(db_int8*)(dst+fd->dbsOffs) = node->ival;
                break;
              case dbField::tpReal4:
                *(real4*)(dst+fd->dbsOffs) = (real4)node->fval;
                break;
              case dbField::tpReal8:
                *(real8*)(dst+fd->dbsOffs) = node->fval;
                break;
              case dbField::tpReference:
                if (isValidOid((oid_t)node->ival)) {                
                    *(oid_t*)(dst+fd->dbsOffs) = (oid_t)node->ival;
                } else { 
                    return -1;
                }
                break;
              case dbField::tpString:
                ((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
                len = strlen(node->sval) + 1;
                ((dbVarying*)(dst+fd->dbsOffs))->size = len;
                memcpy(dst + offs, node->sval, len);
                offs += len;
                break;
              case dbField::tpRawBinary:
                len = node->aggregate.nComponents;
                component = node->aggregate.components;
                elem = dst + fd->dbsOffs;
                while (--len >= 0) { 
                    *elem++ = (byte)component->ival;
                    component = component->next;
                }
                break;
              case dbField::tpRectangle:
                len = node->aggregate.nComponents;
                component = node->aggregate.components;
                coord = (coord_t*)(dst + fd->dbsOffs);
                assert(len == rectangle::dim*2);                    
                while (--len >= 0) {
                    *coord++ = (component->type == dbList::nInteger) 
                        ? (coord_t)component->ival : (coord_t)component->fval;
                    component = component->next;
                }
                break;
              case dbField::tpArray:
                len = node->aggregate.nComponents;
                elem = (byte*)DOALIGN(long(dst) + offs, fd->components->alignment);
                offs = elem - dst;
                ((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
                ((dbVarying*)(dst+fd->dbsOffs))->size = len;
                elemSize = fd->components->dbsSize;  
                elemOffs = len*elemSize;
                offs += elemOffs;
                component = node->aggregate.components;
                while (--len >= 0) { 
                    elemOffs = initializeRecordFields(component, elem, elemOffs, 
                                                      fd->components);
                    elemOffs -= elemSize;
                    elem += elemSize;
                    component = component->next;
                }
                offs += elemOffs;
                break;
              case dbField::tpStructure:
                offs = initializeRecordFields(node->aggregate.components, 
                                              dst, offs, fd->components);
            }
        }
        node = node->next;
    } while ((fd = fd->next) != first);

    return offs;
}


bool dbSubSql::insertRecord(dbList* list, dbTableDescriptor* desc)
{
    int size = calculateRecordSize(list, desc->fixedSize, desc->columns);
    if (size < 0) { 
        error("Incompatible types in insert statement");
        return false;
    }
    oid_t oid = allocateRow(desc->tableId, size);
    byte* dst = (byte*)getRow(oid);    
    initializeRecordFields(list, dst, desc->fixedSize, desc->columns);

    dbTable* table = (dbTable*)getRow(desc->tableId);
#ifdef AUTOINCREMENT_SUPPORT
    desc->autoincrementCount = table->count;
#endif
    int nRows = table->nRows;
    dbFieldDescriptor* fd;
    for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField){
        dbHashTable::insert(this, fd->hashTable, oid, fd->type, fd->dbsSize, fd->dbsOffs, 
                            nRows);
    }
    for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField) { 
        if (fd->type == dbField::tpRectangle) { 
            dbRtree::insert(this, fd->tTree, oid, fd->dbsOffs);
        } else { 
            dbTtree::insert(this, fd->tTree, oid, fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs);
        }
    }    
    return true;
}

int dbSubSql::readValues(dbList** chain)
{
    int i, n = 0;
    int tkn;
    dbList* node;

    while (true) { 
        switch (scan()) { 
          case tkn_lpar:
            node = new dbList(dbList::nTuple);
            node->aggregate.components = NULL;
            i = readValues(&node->aggregate.components);
            if (i < 0) { 
                return -1;
            }
            node->aggregate.nComponents = i;
            break;
          case tkn_rpar:
            return -n; // valid only in case of empty list
          case tkn_iconst:
            node = new dbList(dbList::nInteger);
            node->ival = ival;
            break;
          case tkn_true:
            node = new dbList(dbList::nBool);
            node->bval = true;
            break;
          case tkn_false:
            node = new dbList(dbList::nBool);
            node->bval = false;
            break;          
          case tkn_fconst:
            node = new dbList(dbList::nReal);
            node->fval = fval;
            break;
          case tkn_sconst:
            node = new dbList(dbList::nString);
            node->sval = new char[strlen(buf)+1];
            strcpy(node->sval, buf);
            break;
          case tkn_autoincrement:
            node =  new dbList(dbList::nAutoinc);
            break;
          case tkn_error:
            return -1;
          default:
            error("Syntax error in insert list");
            return -1;
        }
        *chain = node;
        chain = &node->next;
        n += 1;
        if ((tkn = scan()) == tkn_rpar) { 
            return n;
        }
        if (tkn != tkn_comma) {   
            error("',' expected");
            return -1;
        }
    }
}


dbFieldDescriptor* dbSubSql::readFieldName()
{
    int tkn;

    if (expect("table name", tkn_ident)) { 
        dbTableDescriptor* desc;
        dbFieldDescriptor* fd;
        if ((desc = findTable(name)) == NULL) { 
            error("No such table in database");
            return NULL;
        }       
        if (expect(".", tkn_dot) && expect("field name", tkn_ident)) { 
            if ((fd = desc->findSymbol(name)) == NULL) { 
                error("No such field in the table");
                return NULL;
            } else if (fd->type == dbField::tpArray) {  

⌨️ 快捷键说明

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