From 5d6030db2e46cc82f5b81ddbb556821dbbfe9ac7 Mon Sep 17 00:00:00 2001 From: Dimitry Sibiryakov Date: Thu, 2 Jun 2016 12:43:14 +0200 Subject: [PATCH] Make example 01 built on Windows. Add example of backup (#33) --- examples/interfaces/01.create.cpp | 9 +- examples/interfaces/10.backup.cpp | 175 ++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 examples/interfaces/10.backup.cpp diff --git a/examples/interfaces/01.create.cpp b/examples/interfaces/01.create.cpp index 0d46327d67..a53383d86e 100644 --- a/examples/interfaces/01.create.cpp +++ b/examples/interfaces/01.create.cpp @@ -47,10 +47,6 @@ 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 is used to return wide error description to user // IProvider is needed to start to work with database (or service) @@ -77,6 +73,8 @@ int main() // create DPB - use non-default page size 4Kb dpb = utl->getXpbBuilder(&status, IXpbBuilder::DPB, NULL, 0); dpb->insertInt(&status, isc_dpb_page_size, 4 * 1024); + dpb->insertString(&status, isc_dpb_user_name, "sysdba"); + dpb->insertString(&status, isc_dpb_password, "masterkey"); // create empty database att = prov->createDatabase(&status, "fbtests.fdb", dpb->getBufferLength(&status), @@ -88,7 +86,8 @@ int main() att = NULL; // attach it once again - att = prov->attachDatabase(&status, "fbtests.fdb", 0, NULL); + att = prov->attachDatabase(&status, "fbtests.fdb", + dpb->getBufferLength(&status), dpb->getBuffer(&status)); printf("Re-attached database fbtests.fdb\n"); // start transaction diff --git a/examples/interfaces/10.backup.cpp b/examples/interfaces/10.backup.cpp new file mode 100644 index 0000000000..978d33a50b --- /dev/null +++ b/examples/interfaces/10.backup.cpp @@ -0,0 +1,175 @@ +/* + * PROGRAM: Object oriented API samples. + * MODULE: 10.backup.cpp + * DESCRIPTION: A sample of making backup of database using service maanger. + * + * Example for the following interfaces: + * IService - interface to work with service maanger. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alexander Peshkoff + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2016 Alexander Peshkoff + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + */ + +#include "ifaceExamples.h" + +static IMaster* master = fb_get_master_interface(); + +// print information, returned by isc_svc_query() call + +bool printLine(const unsigned char*& p) +{ + const ISC_USHORT length = (ISC_USHORT) isc_vax_integer((char*)p, sizeof(ISC_USHORT)); + p += sizeof(ISC_USHORT); + if (length > 0) + printf("%*.*s\n", length, length, p); + p += length; + return length > 0; +} + +bool printInfo(const unsigned char* p, size_t pSize) +{ + bool ret = false; + bool ignoreTruncation = false; + const unsigned char* const end = p + pSize; + + while (p < end && *p != isc_info_end) + { + switch (*p++) + { + case isc_info_svc_line: + ret = printLine(p); + break; + + case isc_info_truncated: + if (!ignoreTruncation) + { + printf("\n<<< truncated >>>\n"); + } + fflush(stdout); + ret = true; + break; + + case isc_info_svc_timeout: + case isc_info_data_not_ready: + ret = true; + break; + + default: + printf("Unknown item 0x%x in received buffer\n", p[-1]); + } + } + + fflush(stdout); + return ret; +} + + +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.fdb"); + + // Attach to service manager + svc = prov->attachServiceManager(&status, "service_mgr", spb1->getBufferLength(&status), + spb1->getBuffer(&status)); + + // 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]; + + printf("** Demo of making backup using service manager...\n"); + + // Build service start SPB + spb2 = utl->getXpbBuilder(&status, IXpbBuilder::SPB_START, NULL, 0); + spb2->insertTag(&status, isc_action_svc_backup); + spb2->insertString(&status, isc_spb_dbname, "employee.fdb"); + spb2->insertString(&status, isc_spb_bkp_file, "employee.fbk"); + spb2->insertInt(&status, isc_spb_options, isc_spb_bkp_no_garbage_collect); + + // 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; +}