libdatabase/utils/testSelect.c
2006-02-28 23:28:21 +00:00

273 lines
8.8 KiB
C
Raw Blame History

/*---------------------------------------------------------------------------------*/
/* $RCSfile: testSelect.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 <string.h>
#include <bdm.h>
#include <database.h>
int main(int argc, char **argv);
int parseArgs(int argc, char **argv, char **login, char **pwd, char **base, char **sql, int *tp);
int sqlAnalyse(const char *sql);
int execQuery(DBT_Connection *conn, const char *sql, int tp);
int main(int argc, char **argv) {
DBT_Connection conn;
DBT_Status rco;
char *login = NULL;
char *pwd = NULL;
char *base = NULL;
char *sql = NULL;
int tp = 1;
int rc = 1;
if (parseArgs(argc, argv, &login, &pwd, &base, &sql, &tp)) {
BDM_Trace(0, "testSelect", "main", "Usage : %s options\n\n\
Les options sont :\n\
-sql ou --sql-query <requete SQL> : requ<71>te <20> ex<65>cuter\n\
-ps ou --packet-size <taille paquets> : nombre de lignes par fetch (1 par d<>faut)\n\
-db ou --db-connection <user/pwd@base> : param<61>tres de connexion <20> Oracle\n\
--debug<n> : niveau de trace", basename(argv[0]));
return rc;
}
/* connexion Oracle */
DB_Library_Open(0);
memset(&conn, 0, sizeof(conn));
while (1) {
rco = DB_Connect(&conn, login, pwd, base);
if (DB_ERROR(rco)) break;
while (1) {
if (execQuery(&conn, sql, tp)) break;
if (1) break;
}
DB_Disconnect(&conn);
rc = 0;
if (1) break;
}
DB_Library_Close();
return rc;
}
int parseArgs(int argc, char **argv, char **login, char **pwd, char **base, char **sql, int *tp) {
int i = 1;
while (i < argc) {
if (!strcmp(argv[i], "-sql") || !strcmp(argv[i], "--sql-query")) {
if (++i == argc) {
BDM_Trace(0, "testSelect", "parseArgs", "Param<EFBFBD>tre attendu apr<70>s %s", argv[i - 1]);
return 1;
}
if (*sql) BDM_Trace(1, "testSelect", "parseArgs", "Une seule requ<71>te SQL attendue : seule la derni<6E>re est prise en compte");
*sql = argv[i++];
} else if (!strcmp(argv[i], "-ps") || !strcmp(argv[i], "--packet-size")) {
if (++i == argc) {
BDM_Trace(0, "testSelect", "parseArgs", "Param<EFBFBD>tre attendu apr<70>s %s", argv[i - 1]);
return 1;
}
if (atoi(argv[i]) < 1) {
BDM_Trace(0, "testSelect", "parseArgs", "Le nombre de lignes par fetch doit <20>tre > 0");
return 1;
}
*tp = atoi(argv[i++]);
} else if (!strcmp(argv[i], "-db") || !strcmp(argv[i], "--db-connection")) {
char *start, *end;
if (++i == argc) {
BDM_Trace(0, "testSelect", "parseArgs", "Param<EFBFBD>tre attendu apr<70>s %s", argv[i - 1]);
return 1;
}
start = argv[i++];
end = start;
while (*end && *end != '/') ++end;
if (!*end) return 1;
*end = '\0';
*login = start;
start = ++end;
while (*end && *end != '@') ++end;
*pwd = start;
if (*end == '@') {
*end = '\0';
*base = end + 1;
}
} else if (!strncmp(argv[i], "--debug", 7)) {
int level;
level = atoi(argv[i++] + 7);
if (level < 0) {
BDM_Trace(0, "testSelect", "parseArgs", "Le niveau de trace doit <20>tre fix<69> par --debug<n> : --debug2, --debug5, etc");
return 1;
}
BDM_Trace_SetLevel(level, "testSelect");
} else {
BDM_Trace(0, "testSelect", "parseArgs", "Option %s non reconnue", argv[i]);
return 1;
}
}
if (!*sql) {
BDM_Trace(0, "testSelect", "parseArgs", "Option -sql obligatoire");
return 1;
}
if (!*login) {
BDM_Trace(0, "testSelect", "parseArgs", "Option -db obligatoire");
return 1;
}
return 0;
}
int sqlAnalyse(const char *sql) {
int colCount = 0;
int par = 0;
const char *ptr;
const char *sep = "() \t\n\r";
BDM_Trace(3, "testSelect", "sqlAnalyse", "Analyse de \"%s\"", sql);
/* ptr : d<>but de la 1<>re colonne */
ptr = sql;
while (*ptr && strchr(sep, *ptr) == NULL) ++ptr;
while (*ptr) {
if (*ptr == '(') {
++par;
++ptr;
continue;
}
if (*ptr == ')') {
if (!par) {
BDM_Trace(0, "testSelect", "sqlAnalyse", ") rencontr<74> sans ( : %s", ptr);
return 0;
}
--par;
++ptr;
continue;
}
if (*ptr == ',' && !par) {
++colCount;
++ptr;
continue;
}
if (strchr(sep, *ptr)) {
char tmp[6];
int i;
strncpy(tmp, ptr + 1, 5);
tmp[5] = '\0';
for (i = 0; i < 5; ++i)
if (tmp[i] >= 'A' && tmp[i] <= 'Z') tmp[i] += 'a' - 'A';
if (!strcmp(tmp, "from ")) {
++colCount;
break;
}
++ptr;
continue;
}
++ptr;
}
if (!*ptr) {
BDM_Trace(0, "testSelect", "sqlAnalyse", "FROM non trouv<75> dans la requ<71>te");
return 0;
}
if (!colCount) {
BDM_Trace(0, "testSelect", "sqlAnalyse", "Aucune colonne n'a <20>t<EFBFBD> identifi<66>e");
return 0;
}
BDM_Trace(2, "testSelect", "sqlAnalyse", "La requ<71>te devrait retourner %d colonnes", colCount);
return colCount;
}
int execQuery(DBT_Connection *conn, const char *sql, int tp) {
int colCount = sqlAnalyse(sql);
int idx;
DBT_HostVar *hv = NULL;
char *data = NULL;
const int max = 100 + 1;
DBT_Indicator *inull = NULL;
DBT_Status rc = DBS_OK;
DBT_Statement st;
DBT_Result res;
/* nombre de colonnes */
if (colCount == 0) return 1;
while (1) {
BDM_Trace(3, "testSelect", "execQuery", "Pr<EFBFBD>paration des variables pour %d colonnes x %d lignes", colCount, tp);
/* HostVar */
hv = (DBT_HostVar *)malloc(sizeof(DBT_HostVar) * colCount);
memset(hv, 0, sizeof(DBT_HostVar) * colCount);
/* data */
data = (char *)malloc((size_t)tp * max * colCount);
/* inull */
inull = (DBT_Indicator *)malloc(sizeof(DBT_Indicator) * colCount * tp);
for (idx = 0; !DB_ERROR(rc) && idx < colCount; ++idx)
rc = DB_HostVar_Setup(&hv[idx], DBD_STRING, max, data + tp * max * idx, &inull[tp * idx]);
if (DB_ERROR(rc)) break;
rc = DB_Statement_Init(conn, &st);
if (DB_ERROR(rc)) break;
rc = DB_Statement_Prepare(&st, sql);
if (DB_ERROR(rc)) break;
for (idx = 0; !DB_ERROR(rc) && idx < colCount; ++idx)
rc = DB_Statement_DefineVar(&st, tp, idx + 1, &hv[idx]);
if (DB_ERROR(rc)) break;
BDM_Trace(3, "testSelect", "execQuery", "Variables initialis<69>es");
rc = DB_Statement_ExecuteSelect(&st, &res);
while (rc == DBS_OK) {
int nl;
BDM_Trace(3, "testSelect", "execQuery", "Lecture de %d enregistrements", res.rowsProcessed);
for (nl = 0; nl < res.rowsProcessed; ++nl) {
for (idx = 0; idx < colCount; ++idx)
printf("%s%s", idx ? ";" : "", inull[idx * tp + nl] ? "" : data + max * (idx * tp + nl));
printf("\n");
}
if (st.isEOF) break;
rc = DB_Statement_Fetch(&st, &res);
}
DB_Statement_Close(&st);
if (1) break;
}
free(inull);
free(data);
free(hv);
if (DB_ERROR(rc)) return 1;
return 0;
}