static cell AMX_NATIVE_CALL SQL_NextResultSet(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs) { MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!"); return 0; } if (rs->NextResultSet()) { return 1; } else { qInfo->info.rs = NULL; return 0; } }
static cell AMX_NATIVE_CALL SQL_ReadResult(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs || rs->IsDone()) { MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!"); return 0; } IResultRow *row = rs->GetRow(); unsigned int col = static_cast<unsigned int>(params[2]); if (col >= rs->FieldCount()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col); return 0; } cell numparams = params[0] / sizeof(cell); switch (numparams) { case 4: { const char *str = row->GetString(col); if (!str) str = ""; cell *len = MF_GetAmxAddr(amx, params[4]); MF_SetAmxString(amx, params[3], str, (int)*len); break; } case 3: { REAL num = row->GetFloat(col); cell *addr = MF_GetAmxAddr(amx, params[3]); *addr = amx_ftoc(num); break; } case 2: { int num = row->GetInt(col); return num; break; } default: { MF_LogError(amx, AMX_ERR_NATIVE, "Bad number of arguments passed."); break; } } return 1; }
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs) { MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!"); return 0; } int len; char *namewa = MF_GetAmxString(amx, params[2], 0, &len); unsigned int columnId; if (!rs->FieldNameToNum(namewa, &columnId)) { return -1; } return columnId; }
static cell_t SQL_FieldNumToName(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } unsigned int field = params[2]; const char *fldname; if ((fldname = rs->FieldNumToName(field)) == NULL) { return pContext->ThrowNativeError("Invalid field index %d", field); } pContext->StringToLocalUTF8(params[3], params[4], fldname, NULL); return 1; }
static cell_t SQL_FetchSize(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } IResultRow *row = rs->CurrentRow(); if (!row) { return pContext->ThrowNativeError("Current result set has no fetched rows"); } if ((unsigned)params[2] >= rs->GetFieldCount()) { return pContext->ThrowNativeError("Invalid field index %d", params[2]); } return row->GetDataSize(params[2]); }
static cell AMX_NATIVE_CALL SQL_IsNull(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs || rs->IsDone()) { MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!"); return 0; } unsigned int col = static_cast<unsigned int>(params[2]); if (col >= rs->FieldCount()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col); return 0; } IResultRow *rr = rs->GetRow(); return rr->IsNull(col) ? 1 : 0; }
static cell AMX_NATIVE_CALL SQL_FieldNumToName(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs) { MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!"); return 0; } unsigned int col = static_cast<unsigned int>(params[2]); const char *namewa = rs->FieldNumToName(col); if (!namewa) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col); return 0; } MF_SetAmxString(amx, params[3], namewa, params[4]); return 1; }
void CookieManager::ClientConnectCallback(int serial, IQuery *data) { int client; /* Check validity of client */ if ((client = playerhelpers->GetClientFromSerial(serial)) == 0) { return; } statsPending[client] = false; IResultSet *results; /* Check validity of results */ if (data == NULL || (results = data->GetResultSet()) == NULL) { return; } CookieData *pData; IResultRow *row; unsigned int timestamp; CookieAccess access; while (results->MoreRows() && ((row = results->FetchRow()) != NULL)) { const char *name = ""; row->GetString(0, &name, NULL); const char *value = ""; row->GetString(1, &value, NULL); pData = new CookieData(value); pData->changed = false; pData->timestamp = (row->GetInt(4, (int *)×tamp) == DBVal_Data) ? timestamp : 0; Cookie *parent = FindCookie(name); if (parent == NULL) { const char *desc = ""; row->GetString(2, &desc, NULL); access = CookieAccess_Public; row->GetInt(3, (int *)&access); parent = CreateCookie(name, desc, access); } pData->parent = parent; parent->data[client] = pData; clientData[client].append(pData); } statsLoaded[client] = true; cookieDataLoadedForward->PushCell(client); cookieDataLoadedForward->Execute(NULL); }
//native dbi_field(Result:_result, _fieldnum, {Float,_}:... ); static cell AMX_NATIVE_CALL dbi_field(AMX *amx, cell *params) { oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult); if (!oldrs) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]); return 0; } IResultSet *rs = oldrs->info.rs; if (rs->IsDone()) { return 0; } IResultRow *rr = rs->GetRow(); unsigned int num = (unsigned int)params[2] - 1; if (num >= rs->FieldCount()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column %d", params[2]); return 0; } cell stype = params[0] / sizeof(cell); const char *data = rr->GetString(num); if (!data) data = ""; switch (stype) { case 2: { return atoi(data); break; } case 3: { cell *destaddr = MF_GetAmxAddr(amx, params[3]); REAL fdata = atof(data); *destaddr = amx_ftoc(fdata); return 1; break; } case 4: { return MF_SetAmxString(amx, params[3], data, params[4]); break; } } /** never reach here */ return 0; }
static cell_t SQL_FetchRow(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } return (rs->FetchRow() != NULL) ? true : false; }
static cell_t SQL_GetFieldCount(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return 0; } return rs->GetFieldCount(); }
void CookieManager::SelectIdCallback(Cookie *pCookie, IQuery *data) { IResultSet *results; if (data == NULL || (results = data->GetResultSet()) == NULL) { return; } IResultRow *row = results->FetchRow(); if (row == NULL) { return; } row->GetInt(0, &pCookie->dbid); }
static cell AMX_NATIVE_CALL SQL_NumResults(AMX *amx, cell *params) { AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); if (!qInfo) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); return 0; } IResultSet *rs = qInfo->info.rs; if (!rs) { return 0; } return rs->RowCount(); }
static cell_t SQL_FetchString(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } IResultRow *row = rs->CurrentRow(); if (!row) { return pContext->ThrowNativeError("Current result set has no fetched rows"); } const char *str; size_t length; DBResult res = row->GetString(params[2], &str, &length); if (res == DBVal_Error) { return pContext->ThrowNativeError("Error fetching data from field %d", params[2]); } else if (res == DBVal_TypeMismatch) { return pContext->ThrowNativeError("Could not fetch data in field %d as a string", params[2]); } pContext->StringToLocalUTF8(params[3], params[4], str, &length); cell_t *addr; pContext->LocalToPhysAddr(params[5], &addr); *addr = (cell_t)res; return (cell_t)length; }
static cell_t SQL_FetchInt(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } IResultRow *row = rs->CurrentRow(); if (!row) { return pContext->ThrowNativeError("Current result set has no fetched rows"); } int iv; DBResult res = row->GetInt(params[2], &iv); if (res == DBVal_Error) { return pContext->ThrowNativeError("Error fetching data from field %d", params[2]); } else if (res == DBVal_TypeMismatch) { return pContext->ThrowNativeError("Could not fetch data in field %d as an integer", params[2]); } cell_t *addr; pContext->LocalToPhysAddr(params[3], &addr); *addr = (cell_t)res; return iv; }
static cell_t SQL_FieldNameToNum(IPluginContext *pContext, const cell_t *params) { IQuery *query; HandleError err; if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None) { return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err); } IResultSet *rs = query->GetResultSet(); if (!rs) { return pContext->ThrowNativeError("No current result set"); } char *field; pContext->LocalToString(params[2], &field); cell_t *num; pContext->LocalToPhysAddr(params[3], &num); return rs->FieldNameToNum(field, (unsigned int *)num) ? 1 : 0; }
Result<void> set_primary_key_from_results(AnyRef record, const IRecordType* record_type, const IResultSet& results) { // Set the primary key of the record. auto pk = record_type->abstract_primary_key(); if (pk) { auto id_as_string = results.get(0, pk->column()); if (id_as_string) { PrimaryKey pk_value; std::stringstream ss { *id_as_string }; ss >> pk_value.id; pk->set(record, pk_value); return Nothing; } else { return make_error<PersistError>("Backend did not return an ID for the primary key (meaning INSERT probably failed)."); } }
int main() { int rc = 0; setenv("ISC_USER", "sysdba", 0); setenv("ISC_PASSWORD", "masterkey", 0); ThrowStatusWrapper status(master->getStatus()); IProvider* prov = master->getDispatcher(); IAttachment* att = NULL; ITransaction* tra = NULL; IResultSet* rs = NULL; const char* dbName = "employee"; try { att = prov->attachDatabase(&status, dbName, 0, NULL); tra = att->startTransaction(&status, 0, NULL); // Comment some tables att->execute(&status, tra, 0, "comment on table employee is 'Employees'", SAMPLES_DIALECT, NULL, NULL, NULL, NULL); att->execute(&status, tra, 0, "comment on table customer is 'Customers'", SAMPLES_DIALECT, NULL, NULL, NULL, NULL); att->execute(&status, tra, 0, "comment on table country is 'Countries and national currencies'", SAMPLES_DIALECT, NULL, NULL, NULL, NULL); tra->commitRetaining(&status); // Print tables list FB_MESSAGE(Input, ThrowStatusWrapper, (FB_INTEGER, systemFlag) ) input(&status, master); FB_MESSAGE(Output, ThrowStatusWrapper, (FB_SMALLINT, relationId) (FB_VARCHAR(31), relationName) (FB_VARCHAR(100), description) ) output(&status, master); input.clear(); input->systemFlag = 0; rs = att->openCursor(&status, tra, 0, "select rdb$relation_id, rdb$relation_name, rdb$description" " from rdb$relations" " where rdb$system_flag = ?" " order by rdb$relation_id", SAMPLES_DIALECT, input.getMetadata(), input.getData(), output.getMetadata(), NULL, 0); printf(" ID Name/comment\n"); while (rs->fetchNext(&status, output.getData()) == IStatus::RESULT_OK) { unsigned lRelName = output->relationNameNull ? 0 : output->relationName.length; unsigned lDesc = output->descriptionNull ? 0 : output->description.length; printf("%4d %*.*s%c%*.*s\n", output->relationId, lRelName, lRelName, output->relationName.str, lDesc ? '/' : ' ', lDesc, lDesc, output->description.str); } rs->close(&status); rs = NULL; tra->commit(&status); tra = NULL; att->detach(&status); att = NULL; } catch (const FbException& error) { // handle error rc = 1; char buf[256]; master->getUtilInterface()->formatStatus(buf, sizeof(buf), error.getStatus()); fprintf(stderr, "%s\n", buf); } // release interfaces after error caught if (rs) rs->release(); if (tra) tra->release(); if (att) att->release(); // generic cleanup prov->release(); status.dispose(); }
//native dbi_result(Result:_result, _field[], {Float,_}:... ); static cell AMX_NATIVE_CALL dbi_result(AMX *amx, cell *params) { oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult); if (!oldrs) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]); return 0; } IResultSet *rs = oldrs->info.rs; if (rs->IsDone()) { return 0; } IResultRow *rr = rs->GetRow(); unsigned int num; bool found = false; unsigned int fields = rs->FieldCount(); int len; char *field = MF_GetAmxString(amx, params[2], 0, &len); for (unsigned int i=0; i<fields; i++) { if (strcmp(field, rs->FieldNumToName(i)) == 0) { num = i; found = true; break; } } if (!found) { MF_LogError(amx, AMX_ERR_NATIVE, "Unknown column \"%s\"", field); return 0; } cell stype = params[0] / sizeof(cell); const char *data = rr->GetString(num); if (!data) data = ""; switch (stype) { case 2: { return atoi(data); break; } case 3: { cell *destaddr = MF_GetAmxAddr(amx, params[3]); REAL fdata = atof(data); *destaddr = amx_ftoc(fdata); return 1; break; } case 4: { return MF_SetAmxString(amx, params[3], data, params[4]); break; } } /** never reach here */ return 0; }
int main() { int rc = 0; // set default password if none specified in environment setenv("ISC_USER", "sysdba", 0); setenv("ISC_PASSWORD", "masterkey", 0); // status vector and main dispatcher ThrowStatusWrapper status(master->getStatus()); IProvider* prov = master->getDispatcher(); IUtil* utl = master->getUtilInterface(); // declare pointers to required interfaces IAttachment* att = NULL; ITransaction* tra = NULL; IStatement* stmt = NULL; IMessageMetadata* meta = NULL; IMetadataBuilder* builder = NULL; IXpbBuilder* tpb = NULL; // Interface provides access to data returned by SELECT statement IResultSet* curs = NULL; try { // attach employee db att = prov->attachDatabase(&status, "employee", 0, NULL); // start read only transaction tpb = utl->getXpbBuilder(&status, IXpbBuilder::TPB, NULL, 0); tpb->insertTag(&status, isc_tpb_read_committed); tpb->insertTag(&status, isc_tpb_no_rec_version); tpb->insertTag(&status, isc_tpb_wait); tpb->insertTag(&status, isc_tpb_read); tra = att->startTransaction(&status, tpb->getBufferLength(&status), tpb->getBuffer(&status)); // prepare statement stmt = att->prepare(&status, tra, 0, "select last_name, first_name, phone_ext from phone_list " "where location = 'Monterey' order by last_name, first_name", SAMPLES_DIALECT, IStatement::PREPARE_PREFETCH_METADATA); // get list of columns meta = stmt->getOutputMetadata(&status); builder = meta->getBuilder(&status); unsigned cols = meta->getCount(&status); // struct to cache received metadata struct MyField { const char* name; unsigned length, offset; }; MyField* fields = new MyField[cols]; memset(fields, 0, sizeof(MyField) * cols); // parse columns list & coerce datatype(s) for (unsigned j = 0; j < cols; ++j) { unsigned t = meta->getType(&status, j); if (t == SQL_VARYING || t == SQL_TEXT) { builder->setType(&status, j, SQL_TEXT); fields[j].name = meta->getField(&status, j); } } // release automatically created metadata // metadata is not database object, therefore no specific call to close it meta->release(); // get metadata with coerced datatypes meta = builder->getMetadata(&status); // builder not needed any more builder->release(); builder = NULL; // now we may also get offsets info for (unsigned j = 0; j < cols; ++j) { if (fields[j].name) { fields[j].length = meta->getLength(&status, j); fields[j].offset = meta->getOffset(&status, j); } } // open cursor curs = stmt->openCursor(&status, tra, NULL, NULL, meta, 0); // allocate output buffer unsigned l = meta->getMessageLength(&status); unsigned char* buffer = new unsigned char[l]; // fetch records from cursor and print them for (int line = 0; curs->fetchNext(&status, buffer) == IStatus::RESULT_OK; ++line) { if (line % 10 == 0) { printf("\n"); for (unsigned j = 0; j < cols; ++j) { if (fields[j].name) { printf("%-*.*s ", fields[j].length, fields[j].length, fields[j].name); } } printf("\n"); } for (unsigned j = 0; j < cols; ++j) { if (fields[j].name) { printf("%*.*s ", fields[j].length, fields[j].length, buffer + fields[j].offset); } } printf("\n"); } printf("\n"); // close interfaces curs->close(&status); curs = NULL; stmt->free(&status); stmt = NULL; meta->release(); meta = NULL; tra->commit(&status); tra = NULL; att->detach(&status); att = NULL; } catch (const FbException& error) { // handle error rc = 1; char buf[256]; master->getUtilInterface()->formatStatus(buf, sizeof(buf), error.getStatus()); fprintf(stderr, "%s\n", buf); } // release interfaces after error caught if (meta) meta->release(); if (builder) builder->release(); if (curs) curs->release(); if (stmt) stmt->release(); if (tra) tra->release(); if (att) att->release(); if (tpb) tpb->dispose(); prov->release(); status.dispose(); return rc; }
int main() { int rc = 0; // set default password if none specified in environment setenv("ISC_USER", "sysdba", 0); setenv("ISC_PASSWORD", "masterkey", 0); // declare pointers to required interfaces IStatus* st = NULL; IProvider* prov = NULL; IAttachment* att = NULL; ITransaction* tra = NULL; IStatement* stmt = NULL; IResultSet* curs = NULL; IMessageMetadata* meta = NULL; IMetadataBuilder* builder = NULL; try { // status vector and main dispatcher st = master->getStatus(); prov = master->getDispatcher(); // attach employee db att = prov->attachDatabase(st, "localhost:employee", 0, NULL); check(st, "attachDatabase"); // start default transaction tra = att->startTransaction(st, 0, NULL); check(st, "startTransaction"); // prepare statement stmt = att->prepare(st, tra, 0, "select * from country", 3, IStatement::PREPARE_PREFETCH_METADATA); check(st, "prepare"); // get list of columns meta = stmt->getOutputMetadata(st); check(st, "getOutputMetadata"); builder = meta->getBuilder(st); check(st, "getBuilder"); unsigned cols = meta->getCount(st); check(st, "getCount"); // struct to cache received metadata struct MyField { const char* name; unsigned length, offset; }; MyField* fields = new MyField[cols]; memset(fields, 0, sizeof(MyField) * cols); // parse columns list & coerce datatype(s) for (unsigned j = 0; j < cols; ++j) { unsigned t = meta->getType(st, j); check(st, "getType"); if (t == SQL_VARYING || t == SQL_TEXT) { builder->setType(st, j, SQL_TEXT); check(st, "setType"); fields[j].name = meta->getField(st, j); check(st, "getField"); } } meta->release(); meta = builder->getMetadata(st); check(st, "getMetadata"); // now we may also get offsets info for (unsigned j = 0; j < cols; ++j) { if (fields[j].name) { fields[j].length = meta->getLength(st, j); check(st, "getLength"); fields[j].offset = meta->getOffset(st, j); check(st, "getOffset"); } } builder->release(); builder = NULL; // open cursor curs = stmt->openCursor(st, tra, NULL, NULL, meta); check(st, "openCursor"); // allocate output buffer unsigned l = meta->getMessageLength(st); check(st, "getMessageLength"); unsigned char* buffer = new unsigned char[l]; // fetch records from cursor and print them while (curs->fetch(st, buffer)) { for (unsigned j = 0; j < cols; ++j) { if (fields[j].name) { printf("%s: %*.*s\n", fields[j].name, fields[j].length, fields[j].length, buffer + fields[j].offset); } } printf("\n"); } check(st, "fetch"); // close interfaces curs->close(st); check(st, "close"); curs = NULL; stmt->free(st); check(st, "free"); stmt = NULL; meta->release(); meta = NULL; tra->commit(st); check(st, "commit"); tra = NULL; att->detach(st); check(st, "detach"); att = NULL; } catch(const char* text) { // handle error rc = 1; fprintf(stderr, "%s:\n", text); if (st) isc_print_status(st->get()); } // release interfaces after error caught if (meta) meta->release(); if (builder) builder->release(); if (curs) curs->release(); if (stmt) stmt->release(); if (tra) tra->release(); if (att) att->release(); if (prov) prov->release(); if (st) st->dispose(); return rc; }
void CookieManager::ClientConnectCallback(int serial, IQuery *data) { int client; IResultSet *results; /* Check validity of client */ if ((client = playerhelpers->GetClientFromSerial(serial)) == 0) { return; } /* Check validity of results */ if (data == NULL || (results = data->GetResultSet()) == NULL) { return; } IResultRow *row; do { if ((row = results->FetchRow()) == NULL) { break; } const char *name; row->GetString(0, &name, NULL); const char *value; row->GetString(1, &value, NULL); CookieData *pData = new CookieData(value); pData->changed = false; Cookie *parent = FindCookie(name); if (parent == NULL) { const char *desc; row->GetString(2, &desc, NULL); CookieAccess access = CookieAccess_Public; row->GetInt(3, (int *)&access); parent = CreateCookie(name, desc, access); cookieTrie.insert(name, parent); cookieList.push_back(parent); } pData->parent = parent; parent->data[client] = pData; clientData[client].push_back(pData); } while (results->MoreRows()); statsLoaded[client] = true; cookieDataLoadedForward->PushCell(client); cookieDataLoadedForward->Execute(NULL); }