📄 subsql.cpp
字号:
case tpInteger:
*(int2*)dst = (int2)sattr.ivalue;
continue;
case tpBoolean:
*(int2*)dst = sattr.bvalue ? 1 : 0;
continue;
case tpReal:
*(int2*)dst = (int2)sattr.fvalue;
continue;
case tpString:
*(int2*)dst = (int2)atoi((char*)sattr.base);
continue;
}
break;
case dbField::tpInt4:
switch (expr->type) {
case tpInteger:
*(int4*)dst = (int4)sattr.ivalue;
continue;
case tpBoolean:
*(int4*)dst = sattr.bvalue ? 1 : 0;
continue;
case tpReal:
*(int4*)dst = (int4)sattr.fvalue;
continue;
case tpString:
*(int4*)dst = (int1)atoi((char*)sattr.base);
continue;
}
break;
case dbField::tpInt8:
switch (expr->type) {
case tpInteger:
*(db_int8*)dst = sattr.ivalue;
continue;
case tpBoolean:
*(db_int8*)dst = sattr.bvalue ? 1 : 0;
continue;
case tpReal:
*(db_int8*)dst = (db_int8)sattr.fvalue;
continue;
case tpString:
*(db_int8*)dst = (db_int8)atoi((char*)sattr.base);
continue;
}
break;
case dbField::tpReal4:
switch (expr->type) {
case tpInteger:
*(real4*)dst = (real4)sattr.ivalue;
continue;
case tpBoolean:
*(real4*)dst = (real4)(sattr.bvalue ? 1 : 0);
continue;
case tpReal:
*(real4*)dst = (real4)sattr.fvalue;
continue;
case tpString:
*(real4*)dst = (real4)atof((char*)sattr.base);
continue;
}
break;
case dbField::tpReal8:
switch (expr->type) {
case tpInteger:
*(real8*)dst = (real8)sattr.ivalue;
continue;
case tpBoolean:
*(real8*)dst = sattr.bvalue ? 1.0 : 0.0;
continue;
case tpReal:
*(real8*)dst = sattr.fvalue;
continue;
case tpString:
*(real8*)dst = atof((char*)sattr.base);
continue;
}
break;
case dbField::tpString:
src = buf;
switch (expr->type) {
case tpInteger:
sprintf(buf, INT8_FORMAT, sattr.ivalue);
break;
case tpBoolean:
strcpy(buf, sattr.bvalue ? "t" : "f");
break;
case tpReal:
sprintf(buf, "%f", sattr.fvalue);
break;
case tpString:
src = (char*)sattr.base;
break;
}
*(char**)dst = new char[strlen(src)+1];
strcpy(*(char**)dst, src);
elems->strValue = *(char**)dst;
continue;
case dbField::tpReference:
if (expr->type == tpInteger) {
*(oid_t*)dst = sattr.oid;
continue;
}
}
assert(false);
} while ((elems = elems->next) != NULL);
return true;
}
bool dbSubSql::parse()
{
dbTableDescriptor* desc;
dbFieldDescriptor* fd;
int tkn;
bool count, outputOid, compactify;
line = 1;
pos = 0;
while (true) {
if (in == stdin) {
printf(prompt);
tkn = scan();
pos += strlen(prompt);
} else {
tkn = scan();
}
switch (tkn) {
case tkn_update:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
if (expect("table name", tkn_ident)) {
if ((desc = findTable(name)) == NULL) {
error("No such table in database");
continue;
}
if (!expect("set", tkn_set)) {
continue;
}
dbDatabaseThreadContext* ctx = threadContext.get();
byte *record = dbMalloc(desc->appSize);
ctx->interactive = true;
ctx->catched = true;
dbUpdateElement* elems = NULL;
if (!expect("field name", tkn_ident)) {
goto updateCleanup;
}
#ifdef THROW_EXCEPTION_ON_ERROR
try {
#else
if (setjmp(ctx->unwind) == 0) {
#endif
char* condition = NULL;
int startPos = pos;
while (true) {
dbUpdateElement* elem = new dbUpdateElement;
dbFieldDescriptor* fd = desc->findSymbol(name);
if (fd == NULL) {
error("No such field in the table");
goto updateCleanup;
}
if (fd->type > dbField::tpReference) {
error("Field can not be updated");
goto updateCleanup;
}
elem->field = fd;
elem->next = elems;
elems = elem;
if (!expect("=", tkn_eq)) {
goto updateCleanup;
}
startPos = pos;
int ch = readExpression();
if (ch == EOF) {
error("unexpected end of input");
goto updateCleanup;
}
condition = strstr(buf, "where");
if (condition != NULL) {
*condition = '\0';
}
dbExprNode* expr = ctx->compiler.compileExpression(desc, buf, startPos);
if (expr == NULL) {
goto updateCleanup;
}
if (expr->type > tpString) {
error("Invalid expression type");
goto updateCleanup;
}
elem->value = expr;
if (condition == NULL && ch == ',') {
if (!expect("field name", tkn_ident)) {
goto updateCleanup;
}
} else {
break;
}
}
dbAnyCursor cursor(*desc, dbCursorForUpdate, record);
cursor.reset();
if (condition != NULL) {
query.pos = startPos + (condition - buf) + 5;
query = (char const*)(condition + 5);
select(&cursor, query);
if (!query.compiled()) {
goto updateCleanup;
}
} else {
select(&cursor);
}
if (cursor.gotoFirst()) {
do {
cursor.fetch();
if (!updateFields(&cursor, elems)) {
goto updateCleanup;
}
cursor.update();
} while (cursor.gotoNext());
}
printf("\n\t%d records updated\n", cursor.getNumberOfRecords());
#ifdef THROW_EXCEPTION_ON_ERROR
} catch(dbException const&) {}
#else
} else {
if (query.mutexLocked) {
query.mutexLocked = false;
query.mutex.unlock();
}
}
#endif
updateCleanup:
query.reset();
while (elems != NULL) {
dbUpdateElement* elem = elems;
elems = elems->next;
delete elem;
}
if (autocommit || !modified) {
commit(); // release locks
}
dbExprNodeAllocator::instance.reset();
ctx->catched = false;
dbFree(record);
}
continue;
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();
}
if (tkn != tkn_from) {
error("'from' keyword expected");
continue;
}
if (scan() != tkn_ident) {
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.compiled()) {
dbExprNodeAllocator::instance.reset();
ctx->catched = false;
continue;
}
} else {
ctx->catched = false;
continue;
}
if (count) {
printf("%d records selected\n",
cursor.getNumberOfRecords());
} else {
if (cursor.gotoFirst()) {
dbFieldDescriptor* fd = desc->columns;
do {
printf("%s ", fd->name);
} while ((fd = fd->next) != desc->columns);
if (outputOid) {
printf("\n#%x: (", cursor.currId);
} else {
printf("\n(");
}
dumpRecord((byte*)getRow(cursor.currId),
cursor.table->columns);
printf(")");
while (cursor.gotoNext()) {
if (outputOid) {
printf(",\n#%x: (", cursor.currId);
} else {
printf(",\n(");
}
dumpRecord((byte*)getRow(cursor.currId),
cursor.table->columns);
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
ctx->catched = false;
if (!modified || autocommit) {
commit(); // release locks
}
} else {
error("No such table in database");
}
continue;
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -