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

📄 subsql.cpp

📁 用于嵌入式环境的数据库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                return -1;
            }
            offs += strlen(node->sval) + 1;
        } 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;
            }
        } 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;
    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::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);

    int nRows = ((dbTable*)getRow(desc->tableId))->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) { 
        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;
    }
    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) { 

⌨️ 快捷键说明

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