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

📄 subsql.cpp

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

⌨️ 快捷键说明

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