libdatabase/utils/testUpdateArray.c

339 lines
9.4 KiB
C
Raw Normal View History

2006-03-01 00:28:21 +01:00
/*---------------------------------------------------------------------------------*/
/* $RCSfile: testUpdateArray.c,v $ */
/*---------------------------------------------------------------------------------*/
/* $Revision: 1.1 $ */
/* $Name: $ */
/* $Date: 2006/02/28 23:28:21 $ */
/* $Author: agibert $ */
/*---------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/* This file is part of LibDataBase */
/* */
/* LibDataBase is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU Lesser General Public Licence as published by */
/* the Free Software Foundation; either version 2.1 of the License, or */
/* (at your option) any later version. */
/* */
/* LibDataBase is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with LibDataBase; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*---------------------------------------------------------------------------------*/
#include <stdio.h>
#include <libgen.h>
#include <tool.h>
#include "../lib/database.h"
/* Globals */
const char *USAGE = "Usage: %s --db <Database spec> [--req <delete SQL request>]\n\
Executes an UPDATE request using an array as comparison values. The request is:\n\
\"update dummy set c1=:1 where c3=:2\".\n\
The table 'dummy' should have the following format:\n\
\"CREATE TABLE dummy (c1 NUMBER(35) primary key, c2 VARCHAR2(16), c3 NUMBER(10))\".\n\
Try with the following data:\n\
1 ABC 100\n\
2 ABC 101\n\
3 ABC 102\n\
4 ABC 103\n\
5 ABC 104\n\
\n\
Command line arguments:\n\
--req Another SQL request, if you whish - Be careful that there are only 2 placeholders (:1 and :2).\n\
--db Database on which to operate. Format: \"login/pwd@server\"\n";
extern int strcasecmp(const char *, const char *);
extern char *strdup(const char *);
void parseArgs(int argc, char **argv);
void usage(char **argv);
void say (const char *format, ...);
void splitDBSpec(char *spec, const char **login, const char **pwd, const char **server);
int setupHostVars(void);
void setupData(int n);
int debugLevel = 0;
int arraySize = 3;
int baseIndex = 0;
char *req = NULL;
const char *login = "";
const char *pwd = "";
const char *server = "";
DBT_Connection conn;
DBT_Statement st;
DBT_Result res;
DBT_HostVar hv1;
DBT_HostVar hv2;
DBT_HostVar hv3;
int *dynInt1 = NULL;
int *dynInt2 = NULL;
int *dynInt3 = NULL;
DBT_Indicator *dynIndic1 = NULL;
DBT_Indicator *dynIndic2 = NULL;
DBT_Indicator *dynIndic3 = NULL;
/**
* Main.
*/
int main(int argc, char **argv) {
DBT_Status rc;
TOOLT_Counter *counter = NULL;
/* Parse arguments */
parseArgs(argc, argv);
if (req == NULL) {
/*req = strdup("update dummy set c1=:1 where c3=:2");*/
req = strdup("update dummy set c1=:1 where :2 = 0 and c3=:3");
}
counter = TOOL_Counter_Alloc(1);
rc = DB_Library_Open(DBD_DEBUG | DBD_ERRMSG);
if (DB_ERROR(rc)) {
printf("Error: Could not open library (%s)\n", DB_Error_Message_Get());
return 1;
}
/* Connect to Database */
say("Connecting to %s/%s@%s...\n", login, pwd, server);
rc = DB_Connect(&conn, login, pwd, server);
if (DB_ERROR(rc)) {
printf("Error: Could not connect (%s)\n", DB_Error_Message_Get());
return 1;
}
/* Init data that are going to be inserted */
say("Setup data and HostVars\n");
setupData(arraySize);
if (setupHostVars() == FALSE)
return 1;
/* Init statement */
rc = DB_Statement_Init(&conn, &st);
if (DB_ERROR(rc)) {
printf("Error: Could not init statement (err %d)\n", rc);
return 1;
}
say("Preparing statement for query: '%s'\n", req);
rc = DB_Statement_Prepare(&st, req);
if (DB_ERROR(rc)) {
printf("Error: Could not prepare statement (err %d)\n", rc);
return 1;
}
say("Bind Vars\n");
rc = DB_Statement_BindVars(&st, arraySize, &hv1, &hv2, &hv3, NULL);
if (DB_ERROR(rc)) {
printf("Error: Could not bind vars (%s)\n", DB_Error_Message_Get());
return 1;
}
/* Start transaction */
say("Start Transaction\n");
DB_Transaction_Start(&conn);
say("\nExecuting Statement...\n");
TOOL_Counter_Start(counter, 0);
rc = DB_Statement_Execute(&st, 0, 3, &res);
TOOL_Counter_Stop(counter, 0);
if (DB_ERROR(rc)) {
say("Error: %s", DB_Error_Message_Get());
say("%d rows processed (error at iteration %d)\n", res.rowsProcessed, res.errorIteration);
}
else {
say("OK, %d rows processed in %ld ms\n", res.rowsProcessed, TOOL_Counter_Get(counter, 0));
}
/*DB_Transaction_Rollback(&conn);*/
say("\nCommitting Transaction\n");
DB_Transaction_Commit(&conn);
if (req)
free(req);
TOOL_Counter_Free(counter);
DB_Disconnect(&conn);
DB_Library_Close();
say("End.\n");
return 0;
}
/**
* Affichage sur la sortie standard.
*/
void say(const char *format, ...) {
char buffer[512];
va_list v;
va_start(v, format);
vsnprintf(buffer, sizeof(buffer), format, v);
fprintf (stdout, "%s", buffer);
va_end(v);
}
/**
* Arguments.
*/
void parseArgs(int argc, char **argv) {
int i = 0;
for (i = 1; i < argc; ++i) {
if (! strcasecmp(argv[i], "--debuglevel")) {
if (++i >= argc) {
usage(argv);
exit(1);
}
debugLevel = atoi(argv[i]);
DB_Debug_Level_Set(debugLevel);
}
else if (! strcasecmp(argv[i], "--req")) {
if (++i >= argc) {
usage(argv);
exit(1);
}
req = strdup(argv[i]);
}
else if (! strcasecmp(argv[i], "--db")) {
if (++i >= argc) {
usage(argv);
exit(1);
}
splitDBSpec(argv[i], &login, &pwd, &server);
}
else if (! strcasecmp(argv[i], "--help") || ! strcasecmp(argv[i], "-h") || ! strcasecmp(argv[i], "-?")) {
usage(argv);
exit(1);
}
else {
usage(argv);
exit(1);
}
}
}
/**
* Usage.
*/
void usage(char **argv) {
printf(USAGE, basename(argv[0]));
}
/**
* Splits a database specification in the format "login/password@server" into its
* basic components 'login', 'password' and 'server'.
* Note that the initial 'spec' string may be altered.
*/
void splitDBSpec(char *spec, const char **login_, const char **pwd_, const char **server_) {
char *p = NULL;
*login_ = spec;
p = strchr(spec, '/');
if (p == NULL)
return;
*p = 0;
*pwd_ = ++p;
p = strchr(p, '@');
if (p == NULL)
return;
*p = 0;
*server_ = ++p;
}
/**
* Initializes host variables.
* Associates an 'hostvar' with a type, size, array of values and array of indicators.
*/
int setupHostVars(void) {
if (DB_HostVar_Setup(&hv1, DBD_INTEGER, 0, dynInt1, dynIndic1) != DBS_OK ||
DB_HostVar_Setup(&hv2, DBD_INTEGER, 0, dynInt2, dynIndic2) != DBS_OK ||
DB_HostVar_Setup(&hv3, DBD_INTEGER, 0, dynInt3, dynIndic3) != DBS_OK) {
say("Error: %s\n", DB_Error_Message_Get());
return FALSE;
}
return TRUE;
}
/**
* Setup arrays of values and indicators.
* (IN) n: Rows count to allocate for each array.
*/
void setupData(int n) {
int i;
dynInt1 = malloc(n * sizeof(int));
dynInt2 = malloc(n * sizeof(int));
dynInt3 = malloc(n * sizeof(int));
dynIndic1 = malloc(n * sizeof(int));
dynIndic2 = malloc(n * sizeof(int));
dynIndic3 = malloc(n * sizeof(int));
/* Zeroe indicators */
for (i = 0; i < n; i++) {
dynIndic1[i] = 0;
dynIndic2[i] = 0;
dynIndic3[i] = 0;
}
/* These are the places to update : set c1=2001 where c3=101, etc. */
/*
dynInt1[0] = 2001;
dynInt3[0] = 101;
dynInt1[1] = 2002;
dynInt3[1] = 102;
dynInt1[2] = 2003;
dynInt3[2] = 103;
*/
dynInt1[0] = 91;
dynInt2[0] = 1;
dynInt3[0] = 101;
dynInt1[1] = 92;
dynInt2[1] = 0;
dynInt3[1] = 101;
dynInt1[2] = 93;
dynInt2[2] = 0;
dynInt3[2] = 103;
}