📄 subsql.cpp
字号:
if (opened) {
close();
while (droppedTables != NULL) {
dbTableDescriptor* next = droppedTables->nextDbTable;
delete droppedTables;
droppedTables = next;
}
opened = false;
dbTableDescriptor::cleanup();
}
time_t transactionCommitDelay = 0;
char* delay = getenv("FASTDB_COMMIT_DELAY");
if (delay != NULL) {
transactionCommitDelay = atoi(delay);
}
if (!open(databaseName, fileName, INFINITE, transactionCommitDelay)) {
fprintf(stderr, "Database not opened\n");
} else {
opened = true;
dbTable* table = (dbTable*)getRow(dbMetaTableId);
dbTableDescriptor* desc = new dbTableDescriptor(table);
linkTable(desc, dbMetaTableId);
oid_t tableId = table->firstRow;
while (tableId != 0) {
table = (dbTable*)getRow(tableId);
for (desc = tables; desc != NULL && desc->tableId != tableId; desc = desc->nextDbTable);
if (desc == NULL) {
dbTableDescriptor* desc = new dbTableDescriptor(table);
linkTable(desc, tableId);
desc->setFlags();
}
tableId = table->next;
}
existedTables = tables;
if (!completeDescriptorsInitialization()) {
error("Reference to undefined table");
}
char* backupName = getenv("FASTDB_BACKUP_NAME");
if (backupName != NULL) {
char* backupPeriod = getenv("FASTDB_BACKUP_PERIOD");
time_t period = 60*60*24; // one day
if (backupPeriod != NULL) {
period = atoi(backupPeriod);
}
printf("Schedule backup to file %s each %u seconds\n",
backupName, (unsigned)period);
scheduleBackup(backupName, period);
}
}
delete[] databaseName;
}
break;
case tkn_drop:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (monitor->users != 1) {
error("Can not perform operation with active appliations");
continue;
}
switch (scan()) {
case tkn_table:
if (expect("table name", tkn_ident)) {
desc = findTable(name);
if (desc == NULL) {
error("No such table in database");
} else {
dropTable(desc);
if (desc == existedTables) {
existedTables = desc->nextDbTable;
}
unlinkTable(desc);
desc->nextDbTable = droppedTables;
droppedTables = desc;
}
}
break;
case tkn_hash:
fd = readFieldName();
if (fd != NULL) {
if (fd->hashTable == 0) {
error("This field is not hashed");
} else {
dropHashTable(fd);
}
}
break;
case tkn_index:
fd = readFieldName();
if (fd != NULL) {
if (fd->tTree == 0) {
error("There is no index for this field");
} else {
dropIndex(fd);
}
}
break;
default:
error("Expecting 'table', 'hash' or 'index' keyword");
continue;
}
break;
case tkn_backup:
if (!opened) {
error("Database not opened");
continue;
}
compactify = false;
if ((tkn = scan()) == tkn_compactify) {
compactify = true;
tkn = scan();
}
if (tkn != tkn_sconst) {
error("Backup file name expected");
} else {
if (!backup(buf, compactify)) {
printf("Backup failed\n");
} else {
while (droppedTables != NULL) {
dbTableDescriptor* next = droppedTables->nextDbTable;
delete droppedTables;
droppedTables = next;
}
commit();
existedTables = tables;
}
}
continue;
case tkn_create:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (monitor->users != 1) {
error("Can not perform operation with active appliations\n");
continue;
}
switch (scan()) {
case tkn_hash:
if (!expect("on", tkn_on)) {
continue;
}
fd = readFieldName();
if (fd != NULL) {
if (fd->hashTable != 0) {
error("This field is already hashed");
} else {
createHashTable(fd);
}
}
break;
case tkn_index:
if (!expect("on", tkn_on)) {
continue;
}
fd = readFieldName();
if (fd != NULL) {
if (fd->tTree != 0) {
error("Index already exists");
} else {
createIndex(fd);
}
}
break;
case tkn_table:
updateTable(true);
break;
default:
error("Expecting 'table', 'hash' or 'index' keyword");
continue;
}
break;
case tkn_alter:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (monitor->users != 1) {
error("Can not perform operation with active appliations\n");
continue;
}
switch (scan()) {
case tkn_table:
updateTable(false);
break;
default:
error("Expecting 'table' keyword");
continue;
}
break;
case tkn_insert:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (expect("into", tkn_into) && expect("table name", tkn_ident)) {
if ((desc = findTable(name)) == NULL) {
error("No such table in database");
continue;
}
if (!expect("values", tkn_values)) {
continue;
}
beginTransaction(dbExclusiveLock);
modified = true;
while (expect("(", tkn_lpar)) {
dbList* list = NULL;
int n = readValues(&list);
if (n <= 0 || !insertRecord(list, desc)) {
if (n == 0) {
error("Empty fields list");
}
tkn = tkn_semi; // just avoid extra error messages
} else {
tkn = scan();
}
while (list != NULL) {
dbList* tail = list->next;
delete list;
list = tail;
}
if (tkn == tkn_semi) {
break;
} else if (tkn != tkn_comma) {
error("';' or ',' expected");
}
}
}
break;
case tkn_delete:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (expect("FROM", tkn_from) && expect("table name", tkn_ident)) {
if ((desc = findTable(name)) == NULL) {
error("No such table in database");
continue;
}
dbAnyCursor cursor(*desc, dbCursorForUpdate, NULL);
dbDatabaseThreadContext* ctx = threadContext.get();
ctx->interactive = true;
ctx->catched = true;
#ifdef THROW_EXCEPTION_ON_ERROR
try {
#else
if (setjmp(ctx->unwind) == 0) {
#endif
if (readCondition()) {
query = (char const*)buf;
cursor.reset();
select(&cursor, query);
if (!query.compiled()) {
dbExprNodeAllocator::instance.reset();
ctx->catched = false;
continue;
}
} else {
ctx->catched = false;
continue;
}
int n_deleted = cursor.getNumberOfRecords();
cursor.removeAllSelected();
printf("\n\t%d records deleted\n", n_deleted);
#ifdef THROW_EXCEPTION_ON_ERROR
} catch(dbException const&) {}
#else
} else {
if (query.mutexLocked) {
query.mutexLocked = false;
query.mutex.unlock();
}
}
#endif
ctx->catched = false;
}
break;
case tkn_commit:
if (!opened) {
error("Database not opened");
} else {
while (droppedTables != NULL) {
dbTableDescriptor* next = droppedTables->nextDbTable;
delete droppedTables;
droppedTables = next;
}
commit();
existedTables = tables;
}
continue;
case tkn_rollback:
if (!opened) {
error("Database not opened");
} else {
while (droppedTables != NULL) {
dbTableDescriptor* next = droppedTables->nextDbTable;
linkTable(droppedTables, droppedTables->tableId);
droppedTables = next;
}
rollback();
while (tables != existedTables) {
dbTableDescriptor* table = tables;
unlinkTable(table);
delete table;
}
}
continue;
case tkn_show:
if (!opened) {
error("Database not opened");
} else {
printf("FastDB version : %d.%02d\n"
"Database version : %d.%02d\n"
"Database file size: %lu Kb\n"
"Object index size : %lu handles\n"
"Used part of index: %lu handles\n"
"Number of users : %d\n"
"Number of readers : %d\n"
"Number of writers : %d\n"
"Number of blocked readers : %d\n"
"Number of blocked writers : %d\n",
FASTDB_MAJOR_VERSION, FASTDB_MINOR_VERSION,
header->majorVersion, header->minorVersion,
(unsigned long)(header->size/1024),
(unsigned long)header->root[1-header->curr].indexSize,
(unsigned long)header->root[1-header->curr].indexUsed,
monitor->users,
monitor->nReaders,
monitor->nWriters,
monitor->nWaitReaders,
monitor->nWaitWriters + monitor->waitForUpgrade);
printf("\nTABLES:\n");
printf("OID FixedSize Fields Columns TableName\n");
printf("---------------------------------------------------------\n");
for (dbTableDescriptor* desc=tables; desc != NULL; desc=desc->nextDbTable)
{
printf("0x%06x %8d %8d %8d %s\n",
desc->tableId, desc->fixedSize,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -