| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * PROGRAM: Object oriented API samples.
- * MODULE: 02.update.cpp
- * DESCRIPTION: Run once prepared statement with parameters
- * a few times, committing transaction after each run.
- * Learns how to prepare statement, manually define parameters
- * for it, execute that statement with different parameters
- * and perform non-default error processing.
- *
- * Example for the following interfaces:
- * IAttachment - database attachment
- * ITransaction - transaction
- * IStatement - SQL statement execution
- * IMessageMetadata - describe input and output data format
- * IMetadataBuilder - tool to modify/create metadata
- * IStatus - return state holder
- *
- * Note that all updates are rolled back in this version. (see *** later)
- *
- * The contents of this file are subject to the Interbase 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.Inprise.com/IPL.html
- *
- * Software distributed under the License is distributed on an
- * "AS IS" basis, 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 Inprise Corporation
- * and its predecessors. Portions created by Inprise Corporation are
- * Copyright (C) Inprise Corporation.
- *
- * All Rights Reserved.
- * Contributor(s): ______________________________________.
- * Alex Peshkov, 2013
- */
- #include "ifaceExamples.h"
- static IMaster* master = fb_get_master_interface();
- int get_input(char*, double*);
- static const char* Dept_data[] =
- {"622", "100", "116", "900", 0};
- static double Percent_data[] =
- {0.05, 1.00, 0.075, 0.10, 0};
- int Input_ptr = 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();
- // declare pointers to required interfaces
- IAttachment* att = NULL;
- ITransaction* tra = NULL;
- // Interface executes prepared SQL statement
- IStatement* stmt = NULL;
- // Interfaces provides access to format of data in messages
- IMessageMetadata* meta = NULL;
- // Interface makes it possible to change format of data or define it yourself
- IMetadataBuilder* builder = NULL;
- const char* updstr =
- "UPDATE department SET budget = ? * budget + budget WHERE dept_no = ?";
- try
- {
- // attach employee db
- att = prov->attachDatabase(&status, "employee", 0, NULL);
- // start transaction
- tra = att->startTransaction(&status, 0, NULL);
- // prepare statement
- stmt = att->prepare(&status, tra, 0, updstr, SAMPLES_DIALECT, 0);
- // build metadata
- // IMaster creates empty new metadata in builder
- builder = master->getMetadataBuilder(&status, 2);
- // set required info on fields
- builder->setType(&status, 0, SQL_DOUBLE + 1);
- builder->setType(&status, 1, SQL_TEXT + 1);
- builder->setLength(&status, 1, 3);
- // IMetadata should be ready
- meta = builder->getMetadata(&status);
- // no need in builder any more
- builder->release();
- builder = NULL;
- // allocate buffer on stack
- char buffer[256];
- unsigned len = meta->getMessageLength(&status);
- if (len > sizeof(buffer))
- {
- throw "Input message length too big - can't continue";
- }
- // locations of parameters in input message
- char* dept_no = &buffer[meta->getOffset(&status, 1)];
- double* percent_inc = (double*) &buffer[meta->getOffset(&status, 0)];
- // null IDs (set to NOT NULL)
- short* flag = (short*)&buffer[meta->getNullOffset(&status, 0)];
- *flag = 0;
- flag = (short*) &buffer[meta->getNullOffset(&status, 1)];
- *flag = 0;
- // Get the next department-percent increase input pair.
- while (get_input(dept_no, percent_inc))
- {
- printf("\nIncreasing budget for department: %s by %5.2lf percent.\n",
- dept_no, *percent_inc);
- // Update the budget.
- try
- {
- stmt->execute(&status, tra, meta, buffer, NULL, NULL);
- }
- catch (const FbException& error)
- {
- // Handle exception raised during statement execution
- if (error.getStatus()->getErrors()[1] == isc_not_valid)
- {
- // Don't save the update, if the new budget exceeds the limit.
- printf("\tExceeded budget limit -- not updated.\n");
- tra->rollbackRetaining(&status);
- continue;
- }
- // Another error - use default handler
- throw;
- }
- // Save each department's update independently.
- // *** Change to commitRetaining() to see changes
- // *** tra->commitRetaining(&status);
- tra->rollbackRetaining(&status);
- }
- // close interfaces
- 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 (builder)
- builder->release();
- if (meta)
- meta->release();
- if (stmt)
- stmt->release();
- if (tra)
- tra->release();
- if (att)
- att->release();
- prov->release();
- status.dispose();
- return rc;
- }
- /*
- * Get the department and percent parameters for an example to run.
- */
- int get_input (char *dept_no, double *percent)
- {
- if (Dept_data[Input_ptr] == 0)
- return 0;
- strcpy(dept_no, Dept_data[Input_ptr]);
- if ((*percent = Percent_data[Input_ptr++]) == 0)
- return 0;
- return 1;
- }
|