localcli.cpp
来自「FastDb是高效的内存数据库系统」· C++ 代码 · 共 3,024 行 · 第 1/5 页
CPP
3,024 行
int cli_get_first(int statement)
{
return dbCLI::instance.get_first(statement);
}
int dbCLI::get_first(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
if (!stmt->cursor.gotoFirst())
{
return cli_not_found;
}
return fetch_columns(stmt);
}
int cli_get_last(int statement)
{
return dbCLI::instance.get_last(statement);
}
int dbCLI::get_last(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
if (!stmt->cursor.gotoLast())
{
return cli_not_found;
}
return fetch_columns(stmt);
}
int cli_get_next(int statement)
{
return dbCLI::instance.get_next(statement);
}
int dbCLI::get_next(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
if (!((stmt->first_fetch && stmt->cursor.gotoFirst()) ||
(!stmt->first_fetch && stmt->cursor.gotoNext())))
{
return cli_not_found;
}
return fetch_columns(stmt);
}
int cli_get_prev(int statement)
{
return dbCLI::instance.get_prev(statement);
}
int dbCLI::get_prev(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
if (!((stmt->first_fetch && stmt->cursor.gotoLast()) ||
(!stmt->first_fetch && stmt->cursor.gotoPrev())))
{
return cli_not_found;
}
return fetch_columns(stmt);
}
int cli_skip(int statement, int n)
{
return dbCLI::instance.skip(statement, n);
}
int dbCLI::skip(int statement, int n)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
if ((n > 0 && !((stmt->first_fetch && stmt->cursor.gotoFirst() && stmt->cursor.skip(n-1)
|| (!stmt->first_fetch && stmt->cursor.skip(n)))))
|| (n < 0 && !((stmt->first_fetch && stmt->cursor.gotoLast() && stmt->cursor.skip(n+1)
|| (!stmt->first_fetch && stmt->cursor.skip(n))))))
{
return cli_not_found;
}
return fetch_columns(stmt);
}
int cli_seek(int statement, cli_oid_t oid)
{
return dbCLI::instance.seek(statement, oid);
}
int dbCLI::seek(int statement, cli_oid_t oid)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
if (!stmt->prepared)
{
return cli_not_fetched;
}
int pos = stmt->cursor.seek(oid);
if (pos < 0)
{
return cli_not_found;
}
int rc = fetch_columns(stmt);
if (rc == cli_ok)
{
return pos;
}
else
{
return rc;
}
}
cli_oid_t cli_get_oid(int statement)
{
return dbCLI::instance.get_current_oid(statement);
}
cli_oid_t dbCLI::get_current_oid(int statement)
{
statement_desc* s = statements.get(statement);
if (s == NULL)
{
return cli_bad_descriptor;
}
return s->cursor.currId;
}
int cli_free(int statement)
{
return dbCLI::instance.free_statement(statement);
}
int dbCLI::free_statement(int statement)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL)
{
return cli_bad_descriptor;
}
return free_statement(stmt);
}
int dbCLI::free_statement(statement_desc* stmt)
{
{
dbCriticalSection cs(stmt->session->mutex);
statement_desc *sp, **spp = &stmt->session->stmts;
while ((sp = *spp) != stmt)
{
if (sp == NULL)
{
return cli_bad_descriptor;
}
spp = &sp->next;
}
*spp = stmt->next;
}
column_binding *cb, *next_cb;
for (cb = stmt->columns; cb != NULL; cb = next_cb)
{
next_cb = cb->next;
delete[] cb->name;
column_allocator.free(cb);
}
parameter_binding *pb, *next_pb;
for (pb = stmt->params; pb != NULL; pb = next_pb)
{
next_pb = pb->next;
delete[] pb->name;
parameter_allocator.free(pb);
}
statements.free(stmt);
return cli_ok;
}
int cli_commit(int session)
{
return dbCLI::instance.commit(session);
}
int dbCLI::commit(int session)
{
session_desc* s = sessions.get(session);
if (s == NULL)
{
return cli_bad_descriptor;
}
while (s->dropped_tables != NULL)
{
dbTableDescriptor* next = s->dropped_tables->nextDbTable;
delete s->dropped_tables;
s->dropped_tables = next;
}
s->db->commit();
s->existed_tables = s->db->tables;
return cli_ok;
}
int cli_precommit(int session)
{
return dbCLI::instance.precommit(session);
}
int dbCLI::precommit(int session)
{
session_desc* s = sessions.get(session);
if (s == NULL)
{
return cli_bad_descriptor;
}
s->db->precommit();
return cli_ok;
}
int cli_abort(int session)
{
return dbCLI::instance.abort(session);
}
int dbCLI::abort(int session)
{
session_desc* s = sessions.get(session);
if (s == NULL)
{
return cli_bad_descriptor;
}
dbDatabase* db = s->db;
while (s->dropped_tables != NULL)
{
dbTableDescriptor* next = s->dropped_tables->nextDbTable;
db->linkTable(s->dropped_tables, s->dropped_tables->tableId);
s->dropped_tables = next;
}
s->db->rollback();
while (db->tables != s->existed_tables)
{
dbTableDescriptor* table = db->tables;
db->unlinkTable(table);
delete table;
}
return cli_ok;
}
int cli_remove(int statement)
{
return dbCLI::instance.remove(statement);
}
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;
fp->size= fd->appSize;
fp->offs= fd->appOffs;
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_INDETIFIER_LENGTH 256
int sql_scanner::get
()
{
char buf[MAX_QUERY_INDETIFIER_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_INDETIFIER_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 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::create_table(dbDatabase* db, char const* tableName, int nColumns,
cli_field_descriptor* columns)
{
int i;
db->modified = true;
if (db->findTableByName(tableName) != NULL)
{
return cli_table_already_exists;
}
int nFields = nColumns;
int varyingLength = strlen(tableName) + 1;
for (i = 0; i < nColumns; 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)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?