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; // Status wrapper ThrowStatusWrapper status(master->getStatus()); // Declare pointers to required interfaces IProvider* prov = master->getDispatcher(); IUtil* utl = master->getUtilInterface(); IService* svc = NULL; IXpbBuilder *spb1 = NULL; IXpbBuilder *spb2 = NULL; try { printf("** Attaching to service manager...\n"); // Prepare SPB to attach to service manager spb1 = utl->getXpbBuilder(&status, IXpbBuilder::SPB_ATTACH, NULL, 0); spb1->insertString(&status, isc_spb_user_name, "sysdba"); spb1->insertString(&status, isc_spb_password, "masterkey"); // In case when your program is expected to be used on a server // with multiple security database it's very good idea to specify // DB expected to be used by services (you anyway need separate // services connectons for databases with different user list location). spb1->insertString(&status, isc_spb_expected_db, "employee"); // Attach to service manager svc = prov->attachServiceManager(&status, "service_mgr", spb1->getBufferLength(&status), spb1->getBuffer(&status)); printf("** Demo of querying information about server version...\n"); // In the simplest case sendItems parameter may be NULL // Building receiveItems is mostly trivial const unsigned char receiveItems[] = {isc_info_svc_server_version}; // Output buffer unsigned char results[1024]; // Query server version svc->query(&status, 0, NULL, sizeof(receiveItems), receiveItems, sizeof(results), results); printInfo(results, sizeof(results)); printf("** Demo of running utility using service manager...\n"); // Build service start SPB spb2 = utl->getXpbBuilder(&status, IXpbBuilder::SPB_START, NULL, 0); spb2->insertTag(&status, isc_action_svc_db_stats); spb2->insertString(&status, isc_spb_dbname, "employee"); spb2->insertInt(&status, isc_spb_options, isc_spb_sts_encryption); // Start service svc->start(&status, spb2->getBufferLength(&status), spb2->getBuffer(&status)); // Prepare receiveItems block const unsigned char receiveItems2[] = {isc_info_svc_line}; // Query service output do { svc->query(&status, 0, NULL, sizeof(receiveItems2), receiveItems2, sizeof(results), results); } while (printInfo(results, sizeof(results))); printf("** Detaching from service manager...\n"); // Detach from service manager svc->detach(&status); svc = NULL; printf("** Done.\n"); } 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 (svc) svc->release(); // generic cleanup prov->release(); status.dispose(); if (spb1) spb1->dispose(); if (spb2) spb2->dispose(); return rc; }