📄 subsql.cpp
字号:
dbExprNodeAllocator::instance.reset();
ctx->catched = false;
dbFree(record);
}
break;
case tkn_select:
if (!opened) {
error("Database not opened");
continue;
}
outputOid = true;
count = false;
if ((tkn = scan()) == tkn_all) {
outputOid = false;
tkn = scan();
} else if (tkn == tkn_count) {
if (!expect("'('", tkn_lpar)
|| !expect("'*'", tkn_all)
|| !expect("')'", tkn_rpar))
{
continue;
}
count = true;
tkn = scan();
}
columns = NULL;
if (tkn != tkn_from) {
while (true) {
if (tkn != tkn_ident) {
error("Field name or 'from' expected");
}
dbFieldDescriptor* column = new dbFieldDescriptor(name);
if (columns != NULL) {
column->next = columns;
column->prev = columns->prev;
column->prev->next = column;
columns->prev = column;
} else {
columns = column;
column->prev = column->next = column;
}
tkn = scan();
if (tkn != tkn_comma) {
break;
}
tkn = scan();
}
}
if (tkn != tkn_from) {
deleteColumns(columns);
error("FROM expected");
continue;
}
dotIsPartOfIdentifier = true;
if (scan() != tkn_ident) {
deleteColumns(columns);
error("Table name expected");
continue;
}
if ((desc = findTable(name)) != NULL) {
dbAnyCursor cursor(*desc, dbCursorViewOnly, NULL);
query.pos = pos;
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.compileError()) {
deleteColumns(columns);
dbExprNodeAllocator::instance.reset();
ctx->catched = false;
break;
}
} else {
deleteColumns(columns);
ctx->catched = false;
break;
}
if (count) {
printf("%d records selected\n",
cursor.getNumberOfRecords());
} else {
if (cursor.gotoFirst()) {
dbFieldDescriptor* columnList;
if (columns != NULL) {
columnList = columns;
dbFieldDescriptor* cc = columns;
do {
dbFieldDescriptor* next = cc->next;
dbFieldDescriptor* fd = desc->columns;
do {
if (cc->name == fd->name) {
*cc = *fd;
cc->next = next;
goto Found;
}
} while ((fd = fd->next) != desc->columns);
char buf[256];
sprintf(buf, "Column '%s' is not found\n", cc->name);
error(buf);
Found:
printf("%s ", fd->name);
cc = next;
} while (cc != columns);
} else {
columnList = desc->columns;
dbFieldDescriptor* fd = columnList;
do {
printf("%s ", fd->name);
} while ((fd = fd->next) != columnList);
}
if (outputOid) {
printf("\n#%lx: (", (unsigned long)cursor.currId);
} else {
printf("\n(");
}
dumpRecord((byte*)getRow(cursor.currId), columnList);
printf(")");
while (cursor.gotoNext()) {
if (outputOid) {
printf(",\n#%lx: (", (unsigned long)cursor.currId);
} else {
printf(",\n(");
}
dumpRecord((byte*)getRow(cursor.currId), columnList);
printf(")");
}
printf("\n\t%d records selected\n",
cursor.getNumberOfRecords());
} else {
fprintf(stderr, "No records selected\n");
}
}
#ifdef THROW_EXCEPTION_ON_ERROR
} catch(dbException const&) {}
#else
} else {
if (query.mutexLocked) {
query.mutexLocked = false;
query.mutex.unlock();
}
}
#endif
deleteColumns(columns);
ctx->catched = false;
} else {
error("No such table in database");
}
break;
case tkn_open:
if (expect("database name", tkn_sconst)) {
char* databaseName = new char[strlen(buf)+1];
strcpy(databaseName, buf);
char* fileName = NULL;
if ((tkn = scan()) == tkn_sconst) {
fileName = buf;
} else if (tkn != tkn_semi) {
delete[] databaseName;
error("database file name expected");
continue;
}
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;
loadMetaTable();
existedTables = tables;
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:
dotIsPartOfIdentifier = true;
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -