337 lines
10 KiB
C
337 lines
10 KiB
C
|
/*---------------------------------------------------------------------------------*/
|
||
|
/* $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 <stdio.h>
|
||
|
#include <libgen.h>
|
||
|
|
||
|
#include <tool.h>
|
||
|
#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;
|
||
|
}
|