/*---------------------------------------------------------------------------------*/ /* $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 #include #include #include #include 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 : requête à exécuter\n\ -ps ou --packet-size : nombre de lignes par fetch (1 par défaut)\n\ -db ou --db-connection : paramètres de connexion à Oracle\n\ --debug : 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ètre attendu après %s", argv[i - 1]); return 1; } if (*sql) BDM_Trace(1, "testSelect", "parseArgs", "Une seule requête SQL attendue : seule la derniè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ètre attendu après %s", argv[i - 1]); return 1; } if (atoi(argv[i]) < 1) { BDM_Trace(0, "testSelect", "parseArgs", "Le nombre de lignes par fetch doit ê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ètre attendu aprè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 être fixé par --debug : --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é 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é dans la requête"); return 0; } if (!colCount) { BDM_Trace(0, "testSelect", "sqlAnalyse", "Aucune colonne n'a été identifiée"); return 0; } BDM_Trace(2, "testSelect", "sqlAnalyse", "La requê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é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é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; }