📄 subsql.cpp
字号:
return false; } char* name = this->name; int varyingLength = strlen(name)+1; static const struct { int size; int alignment; } typeDesc[] = { { sizeof(bool), sizeof(bool) }, { sizeof(int1), sizeof(int1) }, { sizeof(int2), sizeof(int2) }, { sizeof(int4), sizeof(int4) }, { sizeof(db_int8), sizeof(db_int8) }, { sizeof(real4), sizeof(real4) }, { sizeof(real8), sizeof(real8) }, { sizeof(dbVarying), 4 }, { sizeof(oid_t), sizeof(oid_t) }, { sizeof(dbVarying), 4 }, {0}, // tpMethodBool, {0}, // tpMethodInt1, {0}, // tpMethodInt2, {0}, // tpMethodInt4, {0}, // tpMethodInt8, {0}, // tpMethodReal4, {0}, // tpMethodReal8, {0}, // tpMethodString, {0}, // tpMethodReference, {0}, // tpStructure, {0}, // tpRawBinary, {0}, // tpStdString, { sizeof(rectangle), sizeof(coord_t) }, // tpRectangle, {0} // tpUnknown }; const int maxFields = 256; tableField fields[maxFields]; int nFields = 0; int nColumns = 0; tkn = tkn_comma; while (tkn == tkn_comma) { if (nFields+1 == maxFields) { error("Too many fields"); break; } if (!expect("field name", tkn_ident)) { break; } int nameLen = strlen(buf)+1; fields[nFields].name = new char[nameLen]; strcpy(fields[nFields].name, buf); varyingLength += nameLen + 2; char* refTableName; char* inverseRefName; int type = parseType(refTableName, inverseRefName); fields[nFields++].type = type; if (type == dbField::tpUnknown) { break; } nColumns += 1; if (type == dbField::tpArray) { if (nFields+1 == maxFields) { error("Too many fields"); break; } fields[nFields].name = new char[nameLen+2]; sprintf(fields[nFields].name, "%s[]", fields[nFields-1].name); varyingLength += nameLen+2+2; type = parseType(refTableName, inverseRefName); if (type == dbField::tpUnknown) { break; } if (type == dbField::tpArray) { error("Arrays of arrays are not supported by CLI"); break; } if (type == dbField::tpReference) { fields[nFields].refTableName = refTableName; varyingLength += strlen(refTableName); if (inverseRefName != NULL) { fields[nFields-1].inverseRefName = inverseRefName; varyingLength += strlen(inverseRefName); } } fields[nFields++].type = type; } else if (type == dbField::tpReference) { fields[nFields-1].refTableName = refTableName; varyingLength += strlen(refTableName); if (inverseRefName != NULL) { fields[nFields-1].inverseRefName = inverseRefName; varyingLength += strlen(inverseRefName); } } tkn = scan(); } if (tkn == tkn_rpar) { beginTransaction(dbExclusiveLock); dbTableDescriptor* oldDesc = findTable(name); if (oldDesc != NULL) { if (create) { error("Table already exists"); return false; } } else { if (!create) { error("Table not found"); return false; } } dbTable* table; oid_t oid; if (create) { modified = true; oid = allocateRow(dbMetaTableId, sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength); table = (dbTable*)getRow(oid); } else { oid = oldDesc->tableId; table = (dbTable*)new char[sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength]; } int offs = sizeof(dbTable) + sizeof(dbField)*nFields; table->name.offs = offs; table->name.size = strlen(name)+1; strcpy((char*)table + offs, name); offs += table->name.size; size_t size = sizeof(dbRecord); table->fields.offs = sizeof(dbTable); dbField* field = (dbField*)((char*)table + table->fields.offs); offs -= sizeof(dbTable); bool arrayComponent = false; for (int i = 0; i < nFields; i++) { field->name.offs = offs; field->name.size = strlen(fields[i].name) + 1; strcpy((char*)field + offs, fields[i].name); offs += field->name.size; field->tableName.offs = offs; if (fields[i].refTableName) { field->tableName.size = strlen(fields[i].refTableName) + 1; strcpy((char*)field + offs, fields[i].refTableName); offs += field->tableName.size; } else { field->tableName.size = 1; *((char*)field + offs++) = '\0'; } field->inverse.offs = offs; if (fields[i].inverseRefName) { field->inverse.size = strlen(fields[i].inverseRefName) + 1; strcpy((char*)field + offs, fields[i].inverseRefName); offs += field->inverse.size; } else { field->inverse.size = 1; *((char*)field + offs++) = '\0'; } field->flags = 0; field->type = fields[i].type; field->size = typeDesc[fields[i].type].size; if (!arrayComponent) { size = DOALIGN(size, typeDesc[fields[i].type].alignment); field->offset = size; size += field->size; } else { field->offset = 0; } field->hashTable = 0; field->tTree = 0; arrayComponent = field->type == dbField::tpArray; field += 1; offs -= sizeof(dbField); } table->fields.size = nFields; table->fixedSize = size; table->nRows = 0; table->nColumns = nColumns; table->firstRow = 0; table->lastRow = 0; if (create) { linkTable(new dbTableDescriptor(table), oid); } else { dbTableDescriptor* newDesc = new dbTableDescriptor(table); delete[] (char*)table; dbTable* oldTable = (dbTable*)getRow(oid); if (!newDesc->equal(oldTable)) { bool saveConfirmDeleteColumns = confirmDeleteColumns; confirmDeleteColumns = true; modified = true; schemeVersion += 1; unlinkTable(oldDesc); if (oldTable->nRows == 0) { updateTableDescriptor(newDesc, oid); } else { reformatTable(oid, newDesc); } delete oldDesc; confirmDeleteColumns = saveConfirmDeleteColumns; } } if (!completeDescriptorsInitialization()) { warning("Reference to undefined table"); } } return tkn == tkn_rpar;}int dbSubSql::parseType(char*& refTableName, char*& inverseFieldName){ switch (scan()) { case tkn_bool: return dbField::tpBool; case tkn_int1: return dbField::tpInt1; case tkn_int2: return dbField::tpInt2; case tkn_int4: return dbField::tpInt4; case tkn_int8: return dbField::tpInt8; case tkn_real4: return dbField::tpReal4; case tkn_real8: return dbField::tpReal8; case tkn_array: return expect("of", tkn_of) ? dbField::tpArray : dbField::tpUnknown; case tkn_string: return dbField::tpString; case tkn_reference: if (expect("to", tkn_to) && expect("referenced table name", tkn_ident)) { refTableName = new char[strlen(buf)+1]; strcpy(refTableName, buf); int tkn = scan(); if (tkn == tkn_inverse) { if (!expect("inverse reference field name", tkn_ident)) { return dbField::tpUnknown; } inverseFieldName = new char[strlen(buf)+1]; strcpy(inverseFieldName, buf); } else { inverseFieldName = NULL; ungetToken = tkn; } return dbField::tpReference; } else { return dbField::tpUnknown; } case tkn_rectangle: return dbField::tpRectangle; default: error("Field type expected"); } return dbField::tpUnknown;}int dbSubSql::readExpression(){ int i, ch; for (i = 0; (ch = get()) != ';' && ch != ',' && ch != EOF; i++) { if (i+1 >= buflen) { char* newbuf = new char[buflen*2]; memcpy(newbuf, buf, buflen); delete[] buf; buf = newbuf; buflen *= 2; } buf[i] = ch; } buf[i] = '\0'; return ch;}bool dbSubSql::readCondition(){ int i, ch; for (i = 0; (ch = get()) != ';' && ch != EOF; i++) { if (i+1 >= buflen) { char* newbuf = new char[buflen*2]; memcpy(newbuf, buf, buflen); delete[] buf; buf = newbuf; buflen *= 2; } buf[i] = ch; } buf[i] = '\0'; if (ch != ';') { error("unexpected end of input"); return false; } return true;}void dbSubSql::dumpRecord(byte* base, dbFieldDescriptor* first){ int i, n; byte* elem; dbFieldDescriptor* fd = first; do { if (fd != first) { printf(", "); } switch (fd->type) { case dbField::tpBool: printf("%s", *(bool*)(base + fd->dbsOffs) ? "true" : "false"); continue; case dbField::tpInt1: printf("%d", *(int1*)(base + fd->dbsOffs)); continue; case dbField::tpInt2: printf("%d", *(int2*)(base + fd->dbsOffs)); continue; case dbField::tpInt4: printf("%d", *(int4*)(base + fd->dbsOffs)); continue; case dbField::tpInt8: printf(INT8_FORMAT, *(db_int8*)(base + fd->dbsOffs)); continue; case dbField::tpReal4: printf("%f", *(real4*)(base + fd->dbsOffs)); continue; case dbField::tpReal8: printf("%f", *(real8*)(base + fd->dbsOffs)); continue; case dbField::tpString: printf("'%s'", (char*)base+((dbVarying*)(base+fd->dbsOffs))->offs); continue; case dbField::tpReference: printf("#%lx", (unsigned long)*(oid_t*)(base + fd->dbsOffs)); continue; case dbField::tpRectangle: { int i, sep = '('; rectangle& r = *(rectangle*)(base + fd->dbsOffs); for (i = 0; i < rectangle::dim*2; i++) { printf("%c%f", sep, (double)r.boundary[i]); sep = ','; } printf(")"); } continue; case dbField::tpRawBinary: n = fd->dbsSize; elem = base + fd->dbsOffs; printf("("); for (i = 0; i < n; i++) { if (i != 0) { printf(", "); } printf("%02x", *elem++); } printf(")"); continue; case dbField::tpArray: n = ((dbVarying*)(base + fd->dbsOffs))->size; elem = base + ((dbVarying*)(base + fd->dbsOffs))->offs; printf("("); for (i = 0; i < n; i++) { if (i != 0) { printf(", "); } dumpRecord(elem, fd->components); 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -