delphimvcframework/unittests/general/Several/bin32/firebird/examples/api/api13.c

197 lines
5.6 KiB
C

/*
* Program type: API Interface
*
* Description:
* This program performs a multi-database transaction
* with a two-phase commit. A 'currency' field is updated
* in database 1 for table country, and corresponding
* 'from_currency' or 'to_currency' fields are updated in
* database 2 for table cross_rate. The transaction is
* committed only if all instances of the string are
* changed successfully in both databases.
* 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): ______________________________________.
*/
#include <stdlib.h>
#include <string.h>
#include <ibase.h>
#include <stdio.h>
#include "example.h"
#define BUFLEN 512
#define CURRENLEN 10
char *sel_str1 =
"SELECT currency FROM country WHERE country = 'Canada'";
int main (int argc, char** argv)
{
char *country = "Canada"; /* passed as a parameter */
char *new_name = "CdnDollar"; /* passed as a parameter */
char orig_name[CURRENLEN + 1];
char buf[BUFLEN + 1];
isc_db_handle db1 = NULL, /* handle for database 1 */
db2 = NULL; /* handle for database 2 */
isc_tr_handle trans1 = NULL; /* transaction handle */
ISC_STATUS_ARRAY status;
XSQLDA * sel_sqlda;
isc_stmt_handle stmt = NULL;
long stat1, stat2, stat3;
char empdb[128], empdb2[128];
if (argc > 1)
strcpy(empdb, argv[1]);
else
strcpy(empdb, "employee.fdb");
if (argc > 2)
strcpy(empdb2, argv[2]);
else
strcpy(empdb2, "employe2.fdb");
/* Open database 1. */
printf("Attaching to database %s\n", empdb);
if (isc_attach_database(status, 0, empdb, &db1, 0, NULL))
{
ERREXIT(status, 1)
}
/* Open database 2. */
printf ("Attaching to database %s\n", empdb2);
if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
{
ERREXIT(status, 1)
}
/* Start a two-database transaction. */
if (isc_start_transaction(status, &trans1, 2, &db1, 0, NULL, &db2, 0, NULL))
{
ERREXIT(status, 1)
}
/*
* Get the string, which is to be globally changed.
*/
sprintf(buf, "SELECT currency FROM country WHERE country = '%s'", country);
sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
sel_sqlda->sqln = 1;
sel_sqlda->version = 1;
if (isc_dsql_allocate_statement(status, &db1, &stmt))
{
ERREXIT(status, 1)
}
if (isc_dsql_prepare(status, &trans1, &stmt, 0, sel_str1, 1, sel_sqlda))
{
ERREXIT(status, 1)
}
sel_sqlda->sqlvar[0].sqldata = orig_name;
sel_sqlda->sqlvar[0].sqltype = SQL_TEXT;
sel_sqlda->sqlvar[0].sqllen = CURRENLEN;
if (isc_dsql_execute(status, &trans1, &stmt, 1, NULL))
{
ERREXIT(status, 1)
}
if (isc_dsql_fetch(status, &stmt, 1, sel_sqlda))
{
ERREXIT(status, 1)
}
orig_name[CURRENLEN] = '\0';
printf("Modifying currency string: %s\n", orig_name);
/*
* Change the string in database 1.
*/
sprintf(buf, "UPDATE country SET currency = '%s' WHERE country = 'Canada'",
new_name);
stat1 = 0L;
if (isc_dsql_execute_immediate(status, &db1, &trans1, 0, buf, 1, NULL))
{
isc_print_status(status);
stat1 = isc_sqlcode(status);
}
/*
* Change all corresponding occurences of the string in database 2.
*/
sprintf(buf, "UPDATE cross_rate SET from_currency = '%s' WHERE \
from_currency = '%s'", new_name, orig_name);
stat2 = 0L;
if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
{
isc_print_status(status);
stat2 = isc_sqlcode(status);
}
sprintf(buf, "UPDATE cross_rate SET to_currency = '%s' WHERE \
to_currency = '%s'", new_name, orig_name);
stat3 = 0L;
if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
{
isc_print_status(status);
stat3 = isc_sqlcode(status);
}
if (isc_dsql_free_statement(status, &stmt, DSQL_close))
isc_print_status(status);
/*
* If all statements executed successfully, commit the transaction.
* Otherwise, undo all work.
*/
if (!stat1 && !stat2 && !stat3)
{
if (isc_commit_transaction (status, &trans1))
isc_print_status(status);
printf("Changes committed.\n");
}
else
{
printf("update1: %d\n", stat1);
printf("update2: %d\n", stat2);
printf("update3: %d\n", stat3);
if (isc_rollback_transaction(status, &trans1))
isc_print_status(status);
printf("Changes undone.\n");
}
/* Close database 1. */
if (isc_detach_database(status, &db1))
isc_print_status(status);
/* Close database 2. */
if (isc_detach_database(status, &db2))
isc_print_status(status);
free(sel_sqlda);
return 0;
}