📄 localcli.cpp
字号:
int var_type,
void* var_ptr,
cli_column_set set,
cli_column_get get)
{
return cli_array_column_ex(statement, column_name, var_type, var_ptr,
(cli_column_set_ex)set, (cli_column_get_ex)get, NULL);
}
int cli_array_column_ex(int statement,
char const* column_name,
int var_type,
void* var_ptr,
cli_column_set_ex set,
cli_column_get_ex get,
void* user_data)
{
return dbCLI::instance.bind_array_column(statement, column_name, var_type, var_ptr, set, get, user_data);
}
int dbCLI::bind_array_column(int statement,
char const* column_name,
int var_type,
void* var_ptr,
cli_column_set_ex set,
cli_column_get_ex get,
void* user_data)
{
statement_desc* s = statements.get(statement);
if (s == NULL) {
return cli_bad_descriptor;
}
if (var_type < cli_asciiz || var_type > cli_array_of_string) {
return cli_unsupported_type;
}
s->prepared = false;
column_binding* cb = column_allocator.allocate();
cb->name = new char[strlen(column_name) + 1];
cb->next = s->columns;
s->columns = cb;
s->n_columns += 1;
strcpy(cb->name, column_name);
cb->var_type = var_type;
cb->var_len = NULL;
cb->var_ptr = var_ptr;
cb->set_fnc = set;
cb->get_fnc = get;
cb->user_data = user_data;
return cli_ok;
}
int dbCLI::match_columns(char const* table_name, statement_desc* stmt)
{
stmt->table = stmt->session->db->findTable(table_name);
if (stmt->table == NULL) {
return cli_table_not_found;
}
for (column_binding* cb = stmt->columns; cb != NULL; cb = cb->next) {
cb->field = stmt->table->find(cb->name);
if (cb->field == NULL) {
return cli_column_not_found;
}
}
return cli_ok;
}
int cli_fetch(int statement, int for_update)
{
return dbCLI::instance.fetch(statement, for_update);
}
int dbCLI::fetch(int statement, int for_update)
{
statement_desc* stmt = statements.get(statement);
if (stmt == NULL) {
return cli_bad_descriptor;
}
stmt->for_update = for_update;
stmt->oid = 0;
stmt->first_fetch = true;
if (!stmt->prepared) {
int tkn;
sql_scanner scanner(stmt->sql.base());
if (scanner.get() != tkn_select) {
return cli_bad_statement;
}
if ((tkn = scanner.get()) == tkn_all) {
tkn = scanner.get();
}
if (tkn == tkn_from && scanner.get() == tkn_ident) {
int rc = match_columns(scanner.identifier(), stmt);
if (rc != cli_ok) {
return rc;
}
} else {
return cli_bad_statement;
}
char* p = scanner.current_position(), *q = p;
parameter_binding* pb = stmt->params;
stmt->query.reset();
while (*p != '\0') {
if (*p == '\'') {
do {
do {
p += 1;
} while (*p != '\0' && *p != '\'');
if (*p == '\0') {
return cli_bad_statement;
}
} while (*++p == '\'');
} else if (*p == '%') {
if (p != q) {
*p = '\0';
stmt->query.append(dbQueryElement::qExpression, q);
}
if (pb->var_ptr == NULL) {
return cli_unbound_parameter;
}
switch(pb->var_type) {
case cli_oid:
stmt->query.append(dbQueryElement::qVarReference, pb->var_ptr);
break;
case cli_bool:
stmt->query.append(dbQueryElement::qVarBool, pb->var_ptr);
break;
case cli_int1:
stmt->query.append(dbQueryElement::qVarInt1, pb->var_ptr);
break;
case cli_int2:
stmt->query.append(dbQueryElement::qVarInt2, pb->var_ptr);
break;
case cli_int4:
stmt->query.append(dbQueryElement::qVarInt4, pb->var_ptr);
break;
case cli_int8:
stmt->query.append(dbQueryElement::qVarInt8, pb->var_ptr);
break;
case cli_datetime:
stmt->query.append(sizeof(cli_time_t) == 4
? dbQueryElement::qVarInt4 : dbQueryElement::qVarInt8,
pb->var_ptr);
break;
case cli_real4:
stmt->query.append(dbQueryElement::qVarReal4, pb->var_ptr);
break;
case cli_real8:
stmt->query.append(dbQueryElement::qVarReal8, pb->var_ptr);
break;
case cli_asciiz:
stmt->query.append(dbQueryElement::qVarString, pb->var_ptr);
break;
case cli_pasciiz:
stmt->query.append(dbQueryElement::qVarStringPtr, pb->var_ptr);
break;
case cli_array_of_oid:
stmt->query.append(dbQueryElement::qVarArrayOfRefPtr, pb->var_ptr);
break;
case cli_array_of_int4:
stmt->query.append(dbQueryElement::qVarArrayOfInt4Ptr, pb->var_ptr);
break;
case cli_array_of_int8:
stmt->query.append(dbQueryElement::qVarArrayOfInt8Ptr, pb->var_ptr);
break;
case cli_rectangle:
stmt->query.append(dbQueryElement::qVarRectangle, pb->var_ptr);
break;
default:
return cli_unsupported_type;
}
while (isalnum((unsigned char)*++p) || *p == '_');
q = p;
pb = pb->next;
} else {
p += 1;
}
}
if (p != q) {
stmt->query.append(dbQueryElement::qExpression, q);
}
stmt->prepared = true;
}
stmt->cursor.setTable(stmt->table);
stmt->cursor.reset();
#ifdef THROW_EXCEPTION_ON_ERROR
try {
#endif
return stmt->cursor.select(stmt->query, for_update ? dbCursorForUpdate : dbCursorViewOnly);
#ifdef THROW_EXCEPTION_ON_ERROR
} catch (dbException const& x) {
return (x.getErrCode() == dbDatabase::QueryError)
? cli_bad_statement : cli_runtime_error;
}
#endif
}
int dbCLI::fetch_columns(statement_desc* stmt)
{
stmt->first_fetch = false;
if (stmt->cursor.isEmpty()) {
return cli_not_found;
}
stmt->updated = false;
if (stmt->record_struct != NULL) {
stmt->cursor.fetch();
return cli_ok;
}
char* data = (char*)stmt->session->db->getRow(stmt->cursor.currId);
for (column_binding* cb = stmt->columns; cb != NULL; cb = cb->next) {
dbFieldDescriptor* fd = cb->field;
char* src = data + fd->dbsOffs;
char* dst = (char*)cb->var_ptr;
// Allow fetching of structures with one component
if (fd->type == dbField::tpStructure && fd->components->next == NULL) {
fd = fd->components;
}
switch (fd->type) {
case dbField::tpBool:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(bool*)src;
continue;
case cli_int1:
*(cli_int1_t*)dst = *(bool*)src ? 1 : 0;
continue;
case cli_int2:
*(cli_int2_t*)dst = *(bool*)src ? 1 : 0;
continue;
case cli_int4:
*(cli_int4_t*)dst = *(bool*)src ? 1 : 0;
continue;
case cli_int8:
*(db_int8*)dst = *(bool*)src ? 1 : 0;
continue;
case cli_datetime:
*(cli_time_t*)dst = *(bool*)src ? 1 : 0;
continue;
case cli_real4:
*(cli_real4_t*)dst = (cli_real4_t)(*(bool*)src ? 1 : 0);
continue;
case cli_real8:
*(cli_real8_t*)dst = *(bool*)src ? 1 : 0;
continue;
}
break;
case dbField::tpInt1:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(int1*)src != 0;
continue;
case cli_int1:
*(cli_int1_t*)dst = *(int1*)src;
continue;
case cli_int2:
*(cli_int2_t*)dst = *(int1*)src;
continue;
case cli_int4:
*(cli_int4_t*)dst = *(int1*)src;
continue;
case cli_int8:
*(db_int8*)dst = *(int1*)src;
continue;
case cli_datetime:
*(cli_time_t*)dst = *(int1*)src;
continue;
case cli_real4:
*(cli_real4_t*)dst = *(int1*)src;
continue;
case cli_real8:
*(cli_real8_t*)dst = *(int1*)src;
continue;
}
break;
case dbField::tpInt2:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(int2*)src != 0;
continue;
case cli_int1:
*(cli_int1_t*)dst = (int1)*(int2*)src;
continue;
case cli_int2:
*(cli_int2_t*)dst = *(int2*)src;
continue;
case cli_int4:
*(cli_int4_t*)dst = *(int2*)src;
continue;
case cli_int8:
*(db_int8*)dst = *(int2*)src;
continue;
case cli_datetime:
*(cli_time_t*)dst = *(int2*)src;
continue;
case cli_real4:
*(cli_real4_t*)dst = *(int2*)src;
continue;
case cli_real8:
*(cli_real8_t*)dst = *(int2*)src;
continue;
}
break;
case dbField::tpInt4:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(int4*)src != 0;
continue;
case cli_int1:
*(cli_int1_t*)dst = (cli_int1_t)*(int4*)src;
continue;
case cli_int2:
*(cli_int2_t*)dst = (cli_int2_t)*(int4*)src;
continue;
case cli_int4:
case cli_autoincrement:
*(cli_int4_t*)dst = *(int4*)src;
continue;
case cli_int8:
*(db_int8*)dst = *(int4*)src;
continue;
case cli_datetime:
*(cli_time_t*)dst = *(int4*)src;
continue;
case cli_real4:
*(cli_real4_t*)dst = (cli_real4_t)*(int4*)src;
continue;
case cli_real8:
*(cli_real8_t*)dst = *(int4*)src;
continue;
}
break;
case dbField::tpInt8:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(db_int8*)src != 0;
continue;
case cli_int1:
*(cli_int1_t*)dst = (cli_int1_t)*(db_int8*)src;
continue;
case cli_int2:
*(cli_int2_t*)dst = (cli_int2_t)*(db_int8*)src;
continue;
case cli_int4:
*(cli_int4_t*)dst = (cli_int4_t)*(db_int8*)src;
continue;
case cli_int8:
*(db_int8*)dst = *(db_int8*)src;
continue;
case cli_datetime:
*(cli_time_t*)dst = (cli_time_t)*(db_int8*)src;
continue;
case cli_real4:
*(cli_real4_t*)dst = (cli_real4_t)*(db_int8*)src;
continue;
case cli_real8:
*(cli_real8_t*)dst = (cli_real8_t)*(db_int8*)src;
continue;
}
break;
case dbField::tpReal4:
switch (cb->var_type) {
case cli_bool:
*(cli_bool_t*)dst = *(real4*)src != 0;
continue;
case cli_int1:
*(cli_int1_t*)dst = (cli_int1_t)*(real4*)src;
continue;
case cli_int2:
*(cli_int2_t*)dst = (cli_int2_t)*(real4*)src;
continue;
case cli_int4:
*(cli_int4_t*)dst = (cli_int4_t)*(real4*)src;
continue;
case cli_int8:
*(db_int8*)dst = (db_int8)*(real4*)src;
continue;
case cli_datetime:
*(cli_time_t*)dst = (cli_time_t)*(real4*)src;
continue;
case cli_real4:
*(cli_real4_t*)dst = *(real4*)src;
continue;
case cli_real8:
*(cli_real8_t*)dst = *(real4*)src;
continue;
}
break;
case dbField::tpReal8:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -