📄 localcli.cpp
字号:
}
int dbCLI::remove(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL || !stmt->prepared) {
return cli_bad_descriptor;
}
if (!stmt->for_update) {
return cli_not_update_mode;
}
if (stmt->cursor.isEmpty()) {
return cli_not_found;
}
stmt->cursor.removeAllSelected();
return cli_ok;
}
int cli_describe(int session, char const* table, cli_field_descriptor** fields)
{
return dbCLI::instance.describe(session, table, fields);
}
int dbCLI::describe(int session, char const* table, cli_field_descriptor** fields)
{
session_desc* s = sessions.get(session);
if (s == NULL) {
return cli_bad_descriptor;
}
dbDatabase* db = s->db;
dbTableDescriptor* desc = db->findTableByName(table);
if (desc == NULL) {
return cli_table_not_found;
} else {
int nColumns = desc->nColumns;
cli_field_descriptor* fp =
(cli_field_descriptor*)malloc(nColumns*sizeof(cli_field_descriptor));
dbFieldDescriptor* fd = desc->columns;
*fields = fp;
for (int i = 0; i < nColumns; i++, fp++) {
fp->type = (cli_var_type)map_type(fd);
fp->name = fd->name;
fp->refTableName = (fd->type == dbField::tpArray) ? fd->components->refTableName : fd->refTableName;
fp->inverseRefFieldName = fd->inverseRefName;
fp->flags = 0;
if (fd->tTree != 0) {
fp->flags |= cli_indexed;
}
if (fd->hashTable != 0) {
fp->flags |= cli_hashed;
}
fd = fd->next;
}
return nColumns;
}
}
int cli_show_tables(int session, cli_table_descriptor** tables)
{
return dbCLI::instance.show_tables(session, tables);
}
int dbCLI::show_tables(int session, cli_table_descriptor** tables)
{
session_desc* s = sessions.get(session);
if (s == NULL) {
return cli_bad_descriptor;
}
dbTableDescriptor* desc;
int nTables = 0;
for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {
if (strcmp(desc->name, "Metatable")) {
nTables += 1;
}
}
if (nTables != 0) {
cli_table_descriptor* td = (cli_table_descriptor*)malloc(nTables*sizeof(cli_table_descriptor));
*tables = td;
for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {
if (strcmp(desc->name, "Metatable")) {
td->name = desc->name;
td += 1;
}
}
} else {
*tables = NULL;
}
return nTables;
}
#define MAX_QUERY_IDENTIFIER_LENGTH 256
int sql_scanner::get()
{
char buf[MAX_QUERY_IDENTIFIER_LENGTH];
int i = 0, ch;
do {
ch = *p++;
if (ch == '\0') {
return tkn_eof;
}
} while (ch > 0 && ch <= 32);
if (ch == '*') {
return tkn_all;
} else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-') {
int const_type = tkn_iconst;
while (true) {
ch = *p++;
if (ch == '.' || ch == 'e' || ch == 'E') {
const_type = tkn_fconst;
} else if (!((ch >= '0' && ch <= '9') || ch == '+' || ch == '-')) {
break;
}
}
return const_type;
} else if (isalnum(ch) || ch == '$' || ch == '_') {
do {
buf[i++] = ch;
if (i == MAX_QUERY_IDENTIFIER_LENGTH) {
// Identifier too long
return tkn_error;
}
ch = *p++;
} while (ch != EOF && (isalnum(ch) || ch == '$' || ch == '_'));
p -= 1;
buf[i] = '\0';
ident = buf;
return dbSymbolTable::add(ident, tkn_ident);
} else {
// Invalid symbol
return tkn_error;
}
}
int cli_create_table(int session, char const* tableName, int nColumns,
cli_field_descriptor* columns)
{
return dbCLI::instance.create_table(session, tableName, nColumns, columns);
}
int cli_alter_table(int session, char const* tableName, int nColumns,
cli_field_descriptor* columns)
{
return dbCLI::instance.alter_table(session, tableName, nColumns, columns);
}
int dbCLI::create_table(int session, char const* tableName, int nColumns,
cli_field_descriptor* columns)
{
session_desc* s = sessions.get(session);
if (s == NULL) {
return cli_bad_descriptor;
}
s->db->beginTransaction(dbDatabase::dbExclusiveLock);
if (s->existed_tables == NULL) {
s->existed_tables = s->db->tables;
}
return create_table(s->db, tableName, nColumns, columns);
}
int dbCLI::alter_table(int session, char const* tableName, int nColumns,
cli_field_descriptor* columns)
{
session_desc* s = sessions.get(session);
if (s == NULL) {
return cli_bad_descriptor;
}
s->db->beginTransaction(dbDatabase::dbExclusiveLock);
return alter_table(s->db, tableName, nColumns, columns);
}
int dbCLI::calculate_varying_length(char const* tableName, int& nFields, cli_field_descriptor* columns)
{
int varyingLength = strlen(tableName) + 1;
for (int i = 0, n = nFields; i < n; i++) {
int type = columns[i].type;
varyingLength += strlen(columns[i].name) + 3;
if (type == cli_oid || type == cli_array_of_oid) {
varyingLength += strlen(columns[i].refTableName);
if (columns[i].inverseRefFieldName != NULL) {
varyingLength += strlen(columns[i].inverseRefFieldName);
}
}
switch (type) {
case cli_oid:
case cli_bool:
case cli_int1:
case cli_int2:
case cli_int4:
case cli_autoincrement:
case cli_int8:
case cli_real4:
case cli_real8:
case cli_asciiz:
case cli_pasciiz:
break;
case cli_array_of_oid:
case cli_array_of_bool:
case cli_array_of_int1:
case cli_array_of_int2:
case cli_array_of_int4:
case cli_array_of_int8:
case cli_array_of_real4:
case cli_array_of_real8:
case cli_array_of_string:
varyingLength += strlen(columns[i].name) + 2 + 3;
nFields += 1;
break;
case cli_unknown:
return cli_unsupported_type;
}
}
return varyingLength;
}
dbTableDescriptor* dbCLI::create_table_descriptor(dbDatabase* db,
oid_t oid,
dbTable* table,
char const* tableName,
int nFields,
int nColumns,
cli_field_descriptor* columns)
{
int offs = sizeof(dbTable) + sizeof(dbField)*nFields;
table->name.offs = offs;
table->name.size = strlen(tableName)+1;
strcpy((char*)table + offs, tableName);
offs += table->name.size;
size_t size = sizeof(dbRecord);
table->fields.offs = sizeof(dbTable);
int fieldOffs = table->fields.offs;
dbField* field = (dbField*)((char*)table + fieldOffs);
offs -= sizeof(dbTable);
for (int i = 0; i < nColumns; i++, fieldOffs += sizeof(dbField), field++, offs -= sizeof(dbField)) {
field->name.offs = offs;
field->name.size = strlen(columns[i].name) + 1;
strcpy((char*)field + offs, columns[i].name);
offs += field->name.size;
field->tableName.offs = offs;
int type = columns[i].type;
if (type == cli_oid || type == cli_array_of_oid) {
if (type == cli_oid) {
field->tableName.size = strlen(columns[i].refTableName) + 1;
strcpy((char*)field + offs, columns[i].refTableName);
offs += field->tableName.size;
} else {
field->tableName.size = 1;
*((char*)field + offs) = '\0';
offs += 1;
}
field->inverse.offs = offs;
if (columns[i].inverseRefFieldName != NULL) {
field->inverse.size = strlen(columns[i].inverseRefFieldName) + 1;
strcpy((char*)field + offs, columns[i].inverseRefFieldName);
offs += field->inverse.size;
} else {
field->inverse.size = 1;
*((char*)field + offs) = '\0';
offs += 1;
}
} else {
field->tableName.size = 1;
*((char*)field + offs) = '\0';
offs += 1;
field->inverse.size = 1;
field->inverse.offs = offs;
*((char*)field + offs) = '\0';
offs += 1;
}
field->tTree = field->hashTable = 0;
switch (type) {
case cli_oid:
field->type = dbField::tpReference;
field->size = sizeof(oid_t);
break;
case cli_bool:
field->type = dbField::tpBool;
field->size = sizeof(bool);
break;
case cli_int1:
field->type = dbField::tpInt1;
field->size = sizeof(int1);
break;
case cli_int2:
field->type = dbField::tpInt2;
field->size = sizeof(int2);
break;
case cli_int4:
case cli_autoincrement:
field->type = dbField::tpInt4;
field->size = sizeof(int4);
break;
case cli_int8:
field->type = dbField::tpInt8;
field->size = sizeof(db_int8);
break;
case cli_real4:
field->type = dbField::tpReal4;
field->size = sizeof(real4);
break;
case cli_real8:
field->type = dbField::tpReal8;
field->size = sizeof(real8);
break;
case cli_asciiz:
case cli_pasciiz:
field->type = dbField::tpString;
field->size = sizeof(dbVarying);
field->offset = DOALIGN(size, sizeof(int4));
size = field->offset + sizeof(dbVarying);
if (db != NULL && (columns[i].flags & cli_hashed)) {
oid_t hashOid = dbHashTable::allocate(db);
table = (dbTable*)db->getRow(oid);
field = (dbField*)((char*)table + fieldOffs);
field->hashTable = hashOid;
} else {
field->hashTable = 0;
}
if (db != NULL && (columns[i].flags & cli_indexed)) {
oid_t treeOid = dbTtree::allocate(db);
table = (dbTable*)db->getRow(oid);
field = (dbField*)((char*)table + fieldOffs);
field->tTree = treeOid;
} else {
field->tTree = 0;
}
continue;
case cli_array_of_oid:
case cli_array_of_bool:
case cli_array_of_int1:
case cli_array_of_int2:
case cli_array_of_int4:
case cli_array_of_int8:
case cli_array_of_real4:
case cli_array_of_real8:
case cli_array_of_string:
field->type = dbField::tpArray;
field->size = sizeof(dbVarying);
field->offset = DOALIGN(size, sizeof(int4));
size = field->offset + sizeof(dbVarying);
field->hashTable = field->tTree = 0;
field += 1;
fieldOffs += sizeof(dbField);
offs -= sizeof(dbField);
field->name.offs = offs;
field->name.size = strlen(columns[i].name) + 3;
sprintf((char*)field + offs, "%s[]", columns[i].name);
offs += field->name.size;
field->tableName.offs = offs;
if (type == cli_array_of_oid) {
field->tableName.size = strlen(columns[i].refTableName) + 1;
strcpy((char*)field + offs, columns[i].refTableName);
offs += field->tableName.size;
} else {
field->tableName.size = 1;
*((char*)field + offs) = '\0';
offs += 1;
}
field->inverse.offs = offs;
field->inverse.size = 1;
*((char*)field + offs) = '\0';
offs += 1;
field->offset = 0;
field->hashTable = field->tTree = 0;
switch (type) {
case cli_array_of_oid:
field->type = dbField::tpReference;
field->size = sizeof(oid_t);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -