/*---------------------------------------------------------------------------------*/ /* $RCSfile: testEntr.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" #include "testEntr.h" #include "testEntrColumns.h" /* Globals */ extern DBT_HostVar hv[]; extern DBT_Indicator *indic[]; int totalRowsProcessed = 0; int arraySize = 1; int columnsCount = 3; int showResult = 0; int from = 0; int count = 0; int debugLevel = 0; char *req = NULL; const char *login = ""; const char *pwd = ""; const char *server = ""; DBT_Connection conn; DBT_Statement st; DBT_Result res; /** * Main. */ int main(int argc, char **argv) { int i; DBT_Status rc; TOOLT_Counter *counter = NULL; /* Parse arguments */ parseArgs(argc, argv); req = createSelectRequest(columnsCount); 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 */ rc = DB_Connect(&conn, login, pwd, server); if (DB_ERROR(rc)) { printf("Error: Could not connect (%s)\n", DB_Error_Message_Get()); return 1; } say("\n==== SELECT ===================================================\n"); /* Init data that are going to be selected then 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: %s)\n", rc, DB_Error_Message_Get()); 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: %s)\n", rc, DB_Error_Message_Get()); return 1; } /* Associate nth hostvar to nth column (note: first column index is 1) */ say("Define output vars\n"); for (i=0; i < columnsCount; ++i) { rc = DB_Statement_DefineVar(&st, arraySize, i+1, &hv[i]); if (DB_ERROR(rc)) { printf("Error: Could not define vars (%s)\n", DB_Error_Message_Get()); return 1; } } say("Executing Statement (from row %d, count=%d)...\n", from, count); TOOL_Counter_Start(counter, 0); /* Note: 'count' is not relevant here: the number of rows fetched will be equal to the size of the array of defined values (set by DB_Statement_DefineVars). IMPORTANT: However, if some hostvars are bound to placeholders (:1, :2, etc.) in a SELECT statement with DB_Statement_BindVars(), 'count' must be equal to 1 ! No array allowed. */ rc = DB_Statement_Execute(&st, from, count, &res); TOOL_Counter_Stop(counter, 0); /* Display results of SELECT request */ if (rc == DBS_OK || rc == DBS_END_OF_DATA) { say("Result = %s; %d rows processed in %ld ms\n", ERROR_TO_STRING(rc), res.rowsProcessed, TOOL_Counter_Get(counter, 0)); if (showResult) displayValues(res.rowsProcessed); } else { say("Error: %s", DB_Error_Message_Get()); say("%d rows processed (error at iteration %d)\n", res.rowsProcessed, res.errorIteration); } /* If you want to execute another SELECT request, you should cancel the current cursor (to destroy pre-fetch rows) with: */ if (DB_Statement_Fetch_Terminate(&st) != DBS_OK) say("Error: Could not cancel pre-fetch cursor\n"); say("\n\n==== INSERT ===================================================\n"); free(req); req = createInsertRequest(columnsCount); /* Note that although we use the same statement as for SELECT, we could use a new one. */ 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: %s)\n", rc, DB_Error_Message_Get()); return 1; } /* Associate nth hostvar to nth placeholder (note: first placeholder index is 1) */ say("Bind Vars\n"); for (i=0; i < columnsCount; ++i) { rc = DB_Statement_BindVar(&st, arraySize, i+1, &hv[i]); 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("Executing Statement (array size: %d; starting from row %d, %d by %d)...\n", arraySize, from, count, count); TOOL_Counter_Start(counter, 0); while (from < arraySize) { if (from + count > arraySize) count = arraySize - from; rc = DB_Statement_Execute(&st, from, count, &res); totalRowsProcessed += res.rowsProcessed; if (DB_ERROR(rc)) break; from += count; } 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", totalRowsProcessed, res.errorIteration); } else { say("OK, %d rows processed in %ld ms\n", totalRowsProcessed, TOOL_Counter_Get(counter, 0)); } /* End transaction */ say("Committing Transaction\n\n"); DB_Transaction_Commit(&conn); DB_Statement_Close(&st); /* End of work */ 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[1024]; 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], "--from")) { if (++i >= argc) { usage(argv); exit(1); } from = atoi(argv[i]); } else if (! strcasecmp(argv[i], "--count")) { if (++i >= argc) { usage(argv); exit(1); } count = atoi(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], "--col")) { if (++i >= argc) { usage(argv); exit(1); } columnsCount = atoi(argv[i]); } else if (! strcasecmp(argv[i], "--show")) { showResult = 1; } else if (! strcasecmp(argv[i], "--size")) { if (++i >= argc) { usage(argv); exit(1); } arraySize = atoi(argv[i]); } 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) { char *b = basename(argv[0]); printf(USAGE, b, b, b); } /** * 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; }