?? subsql.cpp
字號:
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->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;
}
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);
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);
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("#%x", *(oid_t*)(base + fd->dbsOffs));
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:
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::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)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -