/*---------------------------------------------------------------------------------*/ /* $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 #include #include #include "../lib/database.h" /* Globals */ const char *USAGE = "Usage: %s --db [--req ]\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; }