Revert DB module API changes for branch 2.0, first stage - added/removed files.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Fri, 8 Jan 2010 11:47:22 +0000 (11:47 +0000)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Fri, 8 Jan 2010 11:47:22 +0000 (11:47 +0000)
org.glite.lbjp-common.db/interface/db-int.h [deleted file]
org.glite.lbjp-common.db/src/db-mysql.c [deleted file]
org.glite.lbjp-common.db/src/db-pg.c [deleted file]
org.glite.lbjp-common.db/src/db.c [deleted file]

diff --git a/org.glite.lbjp-common.db/interface/db-int.h b/org.glite.lbjp-common.db/interface/db-int.h
deleted file mode 100644 (file)
index 7a86c84..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifdef WIN32
-#define asprintf(STR, FMT...) trio_asprintf((STR), ##FMT)
-#define vasprintf(STR, FMT, VARGS) trio_asprintf((STR), (FMT), (VARGS))
-#define strcasestr(H,N) strstr((H), (N))
-#endif
-
-#define dprintf(CTX, FMT...) if ((CTX)->caps & GLITE_LBU_DB_CAP_ERRORS) fprintf(stderr, ##FMT)
-
-struct glite_lbu_DBContext_s {
-       int backend;
-       struct {
-               int code;
-               char *desc;
-       } err;
-       int caps;
-};
-typedef struct glite_lbu_DBContext_s glite_lbu_DBContext_t;
-
-struct glite_lbu_Statement_s {
-       glite_lbu_DBContext ctx;
-};
-typedef struct glite_lbu_Statement_s glite_lbu_Statement_t;
-
-
-
-typedef struct {
-       int backend;
-
-       int (*initContext)(glite_lbu_DBContext *ctx);
-       void (*freeContext)(glite_lbu_DBContext ctx);
-       int (*connect)(glite_lbu_DBContext ctx, const char *cs);
-       void (*close)(glite_lbu_DBContext ctx);
-       int (*queryCaps)(glite_lbu_DBContext ctx);
-       void (*setCaps)(glite_lbu_DBContext ctx, int caps);
-
-       int (*transaction)(glite_lbu_DBContext ctx);
-       int (*commit)(glite_lbu_DBContext ctx);
-       int (*rollback)(glite_lbu_DBContext ctx);
-
-       int (*fetchRow)(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
-       void (*freeStmt)(glite_lbu_Statement *stmt);
-
-       int (*queryIndices)(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names);
-       int (*execSQL)(glite_lbu_DBContext ctx, const char *cmd, glite_lbu_Statement *stmt);
-       int (*queryColumns)(glite_lbu_Statement stmt_gen, char **cols);
-
-       int (*prepareStmt)(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt);
-       int (*execPreparedStmt_v)(glite_lbu_Statement stmt, int n, va_list ap);
-       long int (*lastid)(glite_lbu_Statement stmt);
-
-       void (*timeToDB)(time_t, char **str);
-       void (*timestampToDB)(double t, char **str);
-       time_t (*DBToTime)(const char *str);
-       double (*DBToTimestamp)(const char *str);
-} glite_lbu_DBBackend_t;
-
-int glite_lbu_DBSetError(glite_lbu_DBContext ctx, int code, const char *func, int line, const char *desc, ...);
-
-void glite_lbu_TimeToStrGeneric(time_t t, char **str, const char *amp);
-void glite_lbu_TimestampToStrGeneric(double t, char **str, const char *amp);
diff --git a/org.glite.lbjp-common.db/src/db-mysql.c b/org.glite.lbjp-common.db/src/db-mysql.c
deleted file mode 100644 (file)
index 60468d7..0000000
+++ /dev/null
@@ -1,1121 +0,0 @@
-#include <sys/types.h>
-#ifdef LBS_DB_PROFILE
-#include <sys/time.h>
-#endif
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <dlfcn.h>
-#include <pthread.h>
-#ifdef HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-#ifndef STDCALL
-#define STDCALL __stdcall
-#endif
-#else
-#define STDCALL
-#endif
-
-#include <mysql.h>
-#include <mysqld_error.h>
-#include <mysql_version.h>
-#include <errmsg.h>
-
-#include "glite/lbu/trio.h"
-#include "db.h"
-#include "db-int.h"
-
-
-#define GLITE_LBU_MYSQL_INDEX_VERSION 40001
-#define GLITE_LBU_MYSQL_PREPARED_VERSION 40102
-#define BUF_INSERT_ROW_ALLOC_BLOCK     1000
-#ifndef GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH
-#define GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH 256
-#endif
-
-#define CLR_ERR(CTX) glite_lbu_DBClearError((glite_lbu_DBContext)(CTX))
-#define ERR(CTX, CODE, ARGS...) glite_lbu_DBSetError((glite_lbu_DBContext)((CTX)), (CODE), __FUNCTION__, __LINE__, ##ARGS)
-#define STATUS(CTX) glite_lbu_DBError((glite_lbu_DBContext)((CTX)), NULL, NULL)
-#define MY_ERR(CTX) myerr((CTX), __FUNCTION__, __LINE__)
-#define MY_ERRSTMT(STMT) myerrstmt((STMT), __FUNCTION__, __LINE__)
-#define MY_ISOKSTMT(STMT, RETRY) myisokstmt((STMT), __FUNCTION__, __LINE__, (RETRY))
-
-#define USE_TRANS(CTX) ((CTX->generic.caps & GLITE_LBU_DB_CAP_TRANSACTIONS) != 0)
-#define LOAD(SYM, SYM2) if ((*(void **)(&mysql_module.SYM) = dlsym(mysql_module.lib, SYM2)) == NULL) { \
-       err = ERR(ctx, ENOENT, "can't load symbol '%s' from mysql library (%s)", SYM2, dlerror()); \
-       break; \
-}
-
-
-
-struct glite_lbu_DBContextMysql_s {
-       struct glite_lbu_DBContext_s generic;
-       int in_transaction;     /* this flag is set whenever we are in DB transaction */
-       MYSQL *mysql;
-};
-typedef struct glite_lbu_DBContextMysql_s *glite_lbu_DBContextMysql;
-
-
-struct glite_lbu_StatementMysql_s {
-       glite_lbu_Statement_t generic;
-
-       /* for simple commands */
-       MYSQL_RES           *result;
-
-       /* for prepared commands */
-       MYSQL_STMT          *stmt;
-       unsigned long        nrfields;
-       char                *sql;
-};
-typedef struct glite_lbu_StatementMysql_s *glite_lbu_StatementMysql;
-
-
-/*
- * mapping glite DB types to mysql types
- */
-int glite_type_to_mysql[] = {
-       MYSQL_TYPE_NULL,
-       MYSQL_TYPE_TINY,
-       MYSQL_TYPE_LONG,
-       MYSQL_TYPE_TINY_BLOB,
-       MYSQL_TYPE_TINY_BLOB,
-       MYSQL_TYPE_BLOB,
-       MYSQL_TYPE_BLOB,
-       MYSQL_TYPE_MEDIUM_BLOB,
-       MYSQL_TYPE_MEDIUM_BLOB,
-       MYSQL_TYPE_LONG_BLOB,
-       MYSQL_TYPE_LONG_BLOB,
-       MYSQL_TYPE_VAR_STRING,
-       MYSQL_TYPE_STRING,
-       MYSQL_TYPE_DATE,
-       MYSQL_TYPE_TIME,
-       MYSQL_TYPE_DATETIME,
-       MYSQL_TYPE_TIMESTAMP,
-};
-
-
-typedef struct {
-       void *lib;
-       pthread_mutex_t lock;
-
-       void * STDCALL(*mysql_init)(void *);
-       unsigned long STDCALL(*mysql_get_client_version)(void);
-       int STDCALL(*mysql_options)(MYSQL *mysql, enum mysql_option option, const char *arg);
-       unsigned int STDCALL(*mysql_errno)(MYSQL *mysql);
-       const char *STDCALL(*mysql_error)(MYSQL *mysql);
-       unsigned int STDCALL(*mysql_stmt_errno)(MYSQL_STMT *stmt);
-       const char *STDCALL(*mysql_stmt_error)(MYSQL_STMT *stmt);
-       MYSQL * STDCALL(*mysql_real_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag);
-       void STDCALL(*mysql_close)(MYSQL *mysql);
-       int STDCALL(*mysql_query)(MYSQL *mysql, const char *stmt_str);
-       MYSQL_RES *STDCALL(*mysql_store_result)(MYSQL *mysql);
-       void STDCALL(*mysql_free_result)(MYSQL_RES *result);
-       my_ulonglong STDCALL(*mysql_affected_rows)(MYSQL *mysql);
-       my_bool STDCALL(*mysql_stmt_close)(MYSQL_STMT *);
-       unsigned int STDCALL(*mysql_num_fields)(MYSQL_RES *result);
-       unsigned long *STDCALL(*mysql_fetch_lengths)(MYSQL_RES *result);
-       my_bool STDCALL(*mysql_stmt_bind_result)(MYSQL_STMT *stmt, MYSQL_BIND *bind);
-       int STDCALL(*mysql_stmt_prepare)(MYSQL_STMT *stmt, const char *stmt_str, unsigned long length);
-       int STDCALL(*mysql_stmt_store_result)(MYSQL_STMT *stmt);
-       MYSQL_ROW STDCALL(*mysql_fetch_row)(MYSQL_RES *result);
-       MYSQL_FIELD *STDCALL(*mysql_fetch_field)(MYSQL_RES *result);
-       const char *STDCALL(*mysql_get_server_info)(MYSQL *mysql);
-       MYSQL_STMT *STDCALL(*mysql_stmt_init)(MYSQL *mysql);
-       my_bool STDCALL(*mysql_stmt_bind_param)(MYSQL_STMT *stmt, MYSQL_BIND *bind);
-       int STDCALL(*mysql_stmt_execute)(MYSQL_STMT *stmt);
-       int STDCALL(*mysql_stmt_fetch)(MYSQL_STMT *stmt);
-       my_ulonglong STDCALL(*mysql_stmt_insert_id)(MYSQL_STMT *stmt);
-       my_ulonglong STDCALL(*mysql_stmt_affected_rows)(MYSQL_STMT *stmt);
-       MYSQL_RES *STDCALL(*mysql_stmt_result_metadata)(MYSQL_STMT *stmt);
-       int STDCALL(*mysql_stmt_fetch_column)(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned int column, unsigned long offset);
-} mysql_module_t;
-
-
-/* backend module declaration */
-int glite_lbu_InitDBContextMysql(glite_lbu_DBContext *ctx_gen);
-void glite_lbu_FreeDBContextMysql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_DBConnectMysql(glite_lbu_DBContext ctx_gen, const char *cs);
-void glite_lbu_DBCloseMysql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_DBQueryCapsMysql(glite_lbu_DBContext ctx_gen);
-void glite_lbu_DBSetCapsMysql(glite_lbu_DBContext commmon_ctx, int caps);
-int glite_lbu_TransactionMysql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_CommitMysql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_RollbackMysql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_FetchRowMysql(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
-void glite_lbu_FreeStmtMysql(glite_lbu_Statement *stmt);
-int glite_lbu_QueryIndicesMysql(glite_lbu_DBContext ctx_gen, const char *table, char ***key_names, char ****column_names);
-int glite_lbu_ExecSQLMysql(glite_lbu_DBContext ctx_gen, const char *cmd, glite_lbu_Statement *stmt);
-int glite_lbu_QueryColumnsMysql(glite_lbu_Statement stmt_gen, char **cols);
-int glite_lbu_PrepareStmtMysql(glite_lbu_DBContext ctx_gen, const char *sql, glite_lbu_Statement *stmt_gen);
-int glite_lbu_ExecPreparedStmtMysql_v(glite_lbu_Statement stmt_gen, int n, va_list ap);
-long int glite_lbu_LastidMysql(glite_lbu_Statement stmt_gen);
-
-glite_lbu_DBBackend_t mysql_backend = {
-       backend: GLITE_LBU_DB_BACKEND_MYSQL,
-
-       initContext: glite_lbu_InitDBContextMysql,
-       freeContext: glite_lbu_FreeDBContextMysql,
-       connect: glite_lbu_DBConnectMysql,
-       close: glite_lbu_DBCloseMysql,
-       queryCaps: glite_lbu_DBQueryCapsMysql,
-       setCaps: glite_lbu_DBSetCapsMysql,
-       transaction: glite_lbu_TransactionMysql,
-       commit: glite_lbu_CommitMysql,
-       rollback: glite_lbu_RollbackMysql,
-       fetchRow: glite_lbu_FetchRowMysql,
-       freeStmt: glite_lbu_FreeStmtMysql,
-       queryIndices: glite_lbu_QueryIndicesMysql,
-       execSQL: glite_lbu_ExecSQLMysql,
-       queryColumns: glite_lbu_QueryColumnsMysql,
-
-       timeToDB: glite_lbu_TimeToStr,
-       timestampToDB: glite_lbu_TimestampToStr,
-       DBToTime: glite_lbu_StrToTime,
-       DBToTimestamp: glite_lbu_StrToTimestamp,
-
-       prepareStmt: glite_lbu_PrepareStmtMysql,
-       execPreparedStmt_v: glite_lbu_ExecPreparedStmtMysql_v,
-       lastid: glite_lbu_LastidMysql,
-};
-
-static mysql_module_t mysql_module = {
-       lib: NULL,
-       lock: PTHREAD_MUTEX_INITIALIZER,
-};
-
-
-static int myerr(glite_lbu_DBContextMysql ctx, const char *source, int line);
-static int myerrstmt(glite_lbu_StatementMysql stmt, const char *source, int line);
-static int myisokstmt(glite_lbu_StatementMysql stmt, const char *source, int line, int *retry);
-static int db_connect(glite_lbu_DBContextMysql ctx, const char *cs, MYSQL **mysql);
-static void db_close(MYSQL *mysql);
-static int transaction_test(glite_lbu_DBContext ctx, int *caps);
-static int FetchRowSimple(glite_lbu_DBContextMysql ctx, MYSQL_RES *result, unsigned long *lengths, char **results);
-static int FetchRowPrepared(glite_lbu_DBContextMysql ctx, glite_lbu_StatementMysql stmt, unsigned int n, unsigned long *lengths, char **results);
-static void set_time(MYSQL_TIME *mtime, const double time);
-static void glite_lbu_DBCleanup(void);
-static void glite_lbu_FreeStmt_int(glite_lbu_StatementMysql stmt);
-
-
-/* ---- common ---- */
-
-
-
-int glite_lbu_InitDBContextMysql(glite_lbu_DBContext *ctx_gen) {
-       glite_lbu_DBContextMysql ctx;
-       int err = 0;
-       int ver_u;
-
-       ctx = calloc(1, sizeof *ctx);
-       if (!ctx) return ENOMEM;
-       *ctx_gen = (glite_lbu_DBContext)ctx;
-
-       /* dynamic load the client library */
-       pthread_mutex_lock(&mysql_module.lock);
-       if (!mysql_module.lib) {
-               mysql_module.lib = dlopen(MYSQL_SONAME, RTLD_LAZY | RTLD_LOCAL);
-               if (!mysql_module.lib) return ERR(ctx, ENOENT, "dlopen(): " MYSQL_SONAME ": %s", dlerror());
-               do {
-                       LOAD(mysql_init, "mysql_init");
-                       LOAD(mysql_get_client_version, "mysql_get_client_version");
-                       LOAD(mysql_options, "mysql_options");
-                       LOAD(mysql_errno, "mysql_errno");
-                       LOAD(mysql_error, "mysql_error");
-                       LOAD(mysql_stmt_errno, "mysql_stmt_errno");
-                       LOAD(mysql_stmt_error, "mysql_stmt_error");
-                       LOAD(mysql_real_connect, "mysql_real_connect");
-                       LOAD(mysql_close, "mysql_close");
-                       LOAD(mysql_query, "mysql_query");
-                       LOAD(mysql_store_result, "mysql_store_result");
-                       LOAD(mysql_free_result, "mysql_free_result");
-                       LOAD(mysql_affected_rows, "mysql_affected_rows");
-                       LOAD(mysql_stmt_close, "mysql_stmt_close");
-                       LOAD(mysql_num_fields, "mysql_num_fields");
-                       LOAD(mysql_fetch_lengths, "mysql_fetch_lengths");
-                       LOAD(mysql_stmt_bind_result, "mysql_stmt_bind_result");
-                       LOAD(mysql_stmt_prepare, "mysql_stmt_prepare");
-                       LOAD(mysql_stmt_store_result, "mysql_stmt_store_result");
-                       LOAD(mysql_fetch_row, "mysql_fetch_row");
-                       LOAD(mysql_fetch_field, "mysql_fetch_field");
-                       LOAD(mysql_get_server_info, "mysql_get_server_info");
-                       LOAD(mysql_stmt_init, "mysql_stmt_init");
-                       LOAD(mysql_stmt_bind_param, "mysql_stmt_bind_param");
-                       LOAD(mysql_stmt_execute, "mysql_stmt_execute");
-                       LOAD(mysql_stmt_fetch, "mysql_stmt_fetch");
-                       LOAD(mysql_stmt_insert_id, "mysql_stmt_insert_id");
-                       LOAD(mysql_stmt_affected_rows, "mysql_stmt_affected_rows");
-                       LOAD(mysql_stmt_result_metadata, "mysql_stmt_result_metadata");
-                       LOAD(mysql_stmt_fetch_column, "mysql_stmt_fetch_column");
-
-                       // check the runtime version
-                       ver_u = mysql_module.mysql_get_client_version();
-                       if (ver_u != MYSQL_VERSION_ID) {
-                               fprintf(stderr,"Warning: MySQL library version mismatch (compiled '%d', runtime '%d')", MYSQL_VERSION_ID, ver_u);
-#ifdef SYSLOG_H
-                               syslog(LOG_WARNING,"MySQL library version mismatch (compiled '%d', runtime '%d')", MYSQL_VERSION_ID, ver_u);
-#endif
-                       }
-
-                       pthread_mutex_unlock(&mysql_module.lock);
-                       atexit(glite_lbu_DBCleanup);
-               } while(0);
-
-               if (err) {
-                       dlclose(mysql_module.lib);
-                       mysql_module.lib = NULL;
-                       pthread_mutex_unlock(&mysql_module.lock);
-                       return err;
-               }
-       } else pthread_mutex_unlock(&mysql_module.lock);
-
-       return 0;
-}
-
-
-void glite_lbu_FreeDBContextMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       if (ctx) {
-               assert(ctx->mysql == NULL);
-               free(ctx);
-       }
-}
-
-
-int glite_lbu_DBConnectMysql(glite_lbu_DBContext ctx_gen, const char *cs) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       if (db_connect(ctx, cs, &ctx->mysql) != 0 ||
-           glite_lbu_ExecSQLMysql(ctx_gen, "SET AUTOCOMMIT=1", NULL) < 0 ||
-           glite_lbu_ExecSQLMysql(ctx_gen, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ", NULL) < 0)
-               return STATUS(ctx);
-       else
-               return 0;
-}
-
-
-void glite_lbu_DBCloseMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       db_close(ctx->mysql);
-       ctx->mysql = NULL;
-       CLR_ERR(ctx);
-}
-
-
-int glite_lbu_DBQueryCapsMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-       MYSQL   *m = ctx->mysql;
-       int     major,minor,sub,version,caps;
-       const char *ver_s;
-
-       caps = 0;
-
-       ver_s = mysql_module.mysql_get_server_info(m);
-       if (!ver_s || 3 != sscanf(ver_s,"%d.%d.%d",&major,&minor,&sub))
-               return ERR(ctx, EINVAL, "problem retreiving MySQL version");
-       version = 10000*major + 100*minor + sub;
-
-       if (version >= GLITE_LBU_MYSQL_INDEX_VERSION) caps |= GLITE_LBU_DB_CAP_INDEX;
-       if (version >= GLITE_LBU_MYSQL_PREPARED_VERSION) caps |= GLITE_LBU_DB_CAP_PREPARED;
-
-       CLR_ERR(ctx);
-       transaction_test(ctx_gen, &caps);
-
-       if (STATUS(ctx) == 0) return caps;
-       else return -1;
-}
-
-
-void glite_lbu_DBSetCapsMysql(glite_lbu_DBContext ctx_gen, int caps) {
-       ctx_gen->caps = caps;
-}
-
-
-int glite_lbu_TransactionMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       CLR_ERR(ctx);
-       if (USE_TRANS(ctx)) {
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "SET AUTOCOMMIT=0", NULL) < 0) goto err;
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "BEGIN", NULL) < 0) goto err;
-               ctx->in_transaction = 1;
-       }
-err:
-       return STATUS(ctx);
-}
-
-
-int glite_lbu_CommitMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       CLR_ERR(ctx);
-       if (USE_TRANS(ctx)) {
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "COMMIT", NULL) < 0) goto err;
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "SET AUTOCOMMIT=1", NULL) < 0) goto err;
-               ctx->in_transaction = 0;
-       }
-err:
-       return STATUS(ctx);
-}
-
-
-int glite_lbu_RollbackMysql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-
-       CLR_ERR(ctx);
-       if (USE_TRANS(ctx)) { 
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "ROLLBACK", NULL) < 0) goto err;
-               if (glite_lbu_ExecSQLMysql(ctx_gen, "SET AUTOCOMMIT=1", NULL) < 0) goto err;
-               ctx->in_transaction = 0;
-       }
-err:
-       return STATUS(ctx);
-}
-
-
-int glite_lbu_FetchRowMysql(glite_lbu_Statement stmt_gen, unsigned int n, unsigned long *lengths, char **results) {
-       glite_lbu_StatementMysql stmt = (glite_lbu_StatementMysql)stmt_gen;
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)stmt->generic.ctx;
-
-       memset(results, 0, n * sizeof(*results));
-       if (stmt->result) return FetchRowSimple(ctx, stmt->result, lengths, results);
-       else return FetchRowPrepared(ctx, stmt, n, lengths, results);
-}
-
-
-static void glite_lbu_FreeStmt_int(glite_lbu_StatementMysql stmt) {
-       if (stmt) {
-               if (stmt->result) mysql_module.mysql_free_result(stmt->result);
-               if (stmt->stmt) mysql_module.mysql_stmt_close(stmt->stmt);
-               free(stmt->sql);
-       }
-}
-
-
-void glite_lbu_FreeStmtMysql(glite_lbu_Statement *stmt_gen) {
-       glite_lbu_StatementMysql *stmt = (glite_lbu_StatementMysql*)stmt_gen;
-
-       glite_lbu_FreeStmt_int(*stmt);
-       free(*stmt);
-       *stmt = NULL;
-}
-
-
-int glite_lbu_QueryIndicesMysql(glite_lbu_DBContext ctx_gen, const char *table, char ***key_names, char ****column_names) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-       glite_lbu_Statement stmt;
-
-       size_t  i,j,ret;
-
-/* XXX: "show index from" columns. Matches at least MySQL 4.0.11 */
-       char    *sql, *showcol[12];
-       int     Key_name,Seq_in_index,Column_name,Sub_part;
-
-       char    **keys = NULL;
-       size_t  *cols = NULL;
-       char    **col_names = NULL;
-
-       size_t  nkeys = 0;
-
-       char    ***idx = NULL;
-
-       Key_name = Seq_in_index = Column_name = Sub_part = -1;
-
-       asprintf(&sql, "show index from %s", table);
-       if (glite_lbu_ExecSQLMysql(ctx_gen,sql,&stmt)<0) {
-               free(sql);
-               return STATUS(ctx);
-       }
-       free(sql);
-
-       while ((ret = glite_lbu_FetchRowMysql(stmt,sizeof(showcol)/sizeof(showcol[0]),NULL,showcol)) > 0) {
-               assert(ret <= (int)(sizeof showcol/sizeof showcol[0]));
-
-               if (!col_names) {
-                       col_names = malloc(ret * sizeof col_names[0]);
-                       glite_lbu_QueryColumnsMysql(stmt,col_names);
-                       for (i=0; i<ret; i++) 
-                               if (!strcasecmp(col_names[i],"Key_name")) Key_name = i;
-                               else if (!strcasecmp(col_names[i],"Seq_in_index")) Seq_in_index = i;
-                               else if (!strcasecmp(col_names[i],"Column_name")) Column_name = i;
-                               else if (!strcasecmp(col_names[i],"Sub_part")) Sub_part = i;
-
-                       assert(Key_name >= 0 && Seq_in_index >= 0 && 
-                                       Column_name >= 0 && Sub_part >= 0);
-
-               }
-
-               for (i=0; i<nkeys && strcasecmp(showcol[Key_name],keys[i]); i++);
-
-               if (i == nkeys) {
-                       keys = realloc(keys,(i+2) * sizeof keys[0]);
-                       keys[i] = strdup(showcol[Key_name]);
-//printf("** KEY [%d] %s\n", i, keys[i]);
-                       keys[i+1] = NULL;
-                       cols = realloc(cols,(i+1) * sizeof cols[0]); 
-                       cols[i] = 0;
-                       idx = realloc(idx,(i+2) * sizeof idx[0]);
-                       idx[i] = idx[i+1] = NULL;
-                       nkeys++;
-               }
-
-               j = atoi(showcol[Seq_in_index])-1;
-               if (cols[i] <= j) {
-                       cols[i] = j+1;
-                       idx[i] = realloc(idx[i],(j+2)*sizeof idx[i][0]);
-                       memset(&idx[i][j+1],0,sizeof idx[i][0]);
-               }
-               idx[i][j] = strdup(showcol[Column_name]);
-//printf("****** [%d, %d] %s\n", i, j, idx[i][j]);
-//FIXME: needed?idx[i][j].value.i = atoi(showcol[Sub_part]);
-               for (i = 0; i<ret; i++) free(showcol[i]);
-       }
-
-       glite_lbu_FreeStmtMysql(&stmt);
-       free(cols);
-       free(col_names);
-
-       if (ret == 0) CLR_ERR(ctx);
-       else {
-               free(keys);
-               keys = NULL;
-               for (i = 0; idx[i]; i++) {
-                       for (j = 0; idx[i][j]; j++) free(idx[i][j]);
-                       free(idx[i]);
-               }
-               free(idx);
-               idx = NULL;
-       }
-
-       if (key_names) *key_names = keys;
-       else {
-               for (i = 0; keys[i]; i++) free(keys[i]);
-               free(keys);
-       }
-       *column_names = idx;
-
-       return STATUS(ctx);
-}
-
-
-/* ---- simple ---- */
-
-int glite_lbu_ExecSQLMysql(glite_lbu_DBContext ctx_gen, const char *cmd, glite_lbu_Statement *stmt_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-       glite_lbu_StatementMysql stmt;
-       int     merr;
-       int     retry_nr = 0;
-       int     do_reconnect = 0;
-#ifdef LBS_DB_PROFILE
-       struct timeval  start,end;
-       int     pid;
-
-       static struct timeval sum = {
-               tv_sec: 0,
-               tv_usec: 0
-       };
-#endif
-
-       CLR_ERR(ctx);
-
-       if (stmt_gen) *stmt_gen = NULL;
-       stmt = NULL;
-
-#ifdef LBS_DB_PROFILE
-       gettimeofday(&start,NULL);
-#endif
-
-       while (retry_nr == 0 || do_reconnect) {
-               do_reconnect = 0;
-               if (mysql_module.mysql_query(ctx->mysql, cmd)) {
-                       /* error occured */
-                       switch (merr = mysql_module.mysql_errno(ctx->mysql)) {
-                               case 0:
-                                       break;
-                               case ER_DUP_ENTRY: 
-                                       ERR(ctx, EEXIST, mysql_module.mysql_error(ctx->mysql));
-                                       return -1;
-                                       break;
-                               case CR_SERVER_LOST:
-                               case CR_SERVER_GONE_ERROR:
-                                       if (ctx->in_transaction) {
-                                               ERR(ctx, ERESTART, mysql_module.mysql_error(ctx->mysql));
-                                               return -1;
-                                       }
-                                       else if (retry_nr <= 0) 
-                                               do_reconnect = 1;
-                                       break;
-                               case ER_LOCK_DEADLOCK:
-                                       ERR(ctx, EDEADLOCK, mysql_module.mysql_error(ctx->mysql));
-                                       return -1;
-                                       break;  
-                               default:
-                                       MY_ERR(ctx);
-                                       return -1;
-                                       break;
-                       }
-               }
-               retry_nr++;
-       }
-
-       if (stmt_gen) {
-               stmt = calloc(1, sizeof(*stmt));
-               if (!stmt) {
-                       ERR(ctx, ENOMEM, NULL);
-                       return -1;
-               }
-               stmt->generic.ctx = ctx_gen;
-               stmt->result = mysql_module.mysql_store_result(ctx->mysql);
-               if (!stmt->result) {
-                       if (mysql_module.mysql_errno(ctx->mysql)) {
-                               MY_ERR(ctx);
-                               free(stmt);
-                               return -1;
-                       }
-               }
-               *stmt_gen = (glite_lbu_Statement)stmt;
-       } else {
-               MYSQL_RES       *r = mysql_module.mysql_store_result(ctx->mysql);
-               mysql_module.mysql_free_result(r);
-       }
-#ifdef LBS_DB_PROFILE
-       pid = getpid();
-       gettimeofday(&end,NULL);
-       end.tv_usec -= start.tv_usec;
-       end.tv_sec -= start.tv_sec;
-       if (end.tv_usec < 0) { end.tv_sec--; end.tv_usec += 1000000; }
-
-       sum.tv_usec += end.tv_usec;
-       sum.tv_sec += end.tv_sec + sum.tv_usec / 1000000;
-       sum.tv_usec -= 1000000 * (sum.tv_usec / 1000000);
-       fprintf(stderr,"[%d] %s\n[%d] %3ld.%06ld (sum: %3ld.%06ld)\n",pid,cmd,pid,end.tv_sec,end.tv_usec,sum.tv_sec,sum.tv_usec);
-#endif
-
-       return mysql_module.mysql_affected_rows(ctx->mysql);
-}
-
-
-int glite_lbu_QueryColumnsMysql(glite_lbu_Statement stmt_gen, char **cols)
-{
-       glite_lbu_StatementMysql stmt = (glite_lbu_StatementMysql)stmt_gen;
-       int     i = 0;
-       MYSQL_FIELD     *f;
-
-       CLR_ERR(stmt->generic.ctx);
-       if (!stmt->result) return ERR(stmt->generic.ctx, ENOTSUP, "QueryColumns implemented only for simple API");
-       while ((f = mysql_module.mysql_fetch_field(stmt->result))) cols[i++] = f->name;
-       return i == 0;
-}
-
-
-/* ---- prepared --- */
-
-int glite_lbu_PrepareStmtMysql(glite_lbu_DBContext ctx_gen, const char *sql, glite_lbu_Statement *stmt_gen) {
-       glite_lbu_DBContextMysql ctx = (glite_lbu_DBContextMysql)ctx_gen;
-       glite_lbu_StatementMysql stmt;
-       int ret, retry;
-       MYSQL_RES *meta;
-
-       // init
-       stmt = calloc(1, sizeof(*stmt));
-       stmt->generic.ctx = ctx_gen;
-       *stmt_gen = NULL;
-
-       // create the SQL command
-       if ((stmt->stmt = mysql_module.mysql_stmt_init(ctx->mysql)) == NULL)
-               return STATUS(ctx);
-
-       // prepare the SQL command
-       retry = 1;
-       do {
-               mysql_module.mysql_stmt_prepare(stmt->stmt, sql, strlen(sql));
-               ret = MY_ISOKSTMT(stmt, &retry);
-       } while (ret == 0);
-       if (ret == -1) goto failed;
-
-       // number of fields (0 for no results)
-       if ((meta = mysql_module.mysql_stmt_result_metadata(stmt->stmt)) != NULL) {
-               stmt->nrfields = mysql_module.mysql_num_fields(meta);
-               mysql_module.mysql_free_result(meta);
-       } else
-               stmt->nrfields = 0;
-
-       // remember the command
-       stmt->sql = strdup(sql);
-
-       *stmt_gen = (glite_lbu_Statement)stmt;
-       return CLR_ERR(ctx);
-
-failed:
-       glite_lbu_FreeStmt_int(stmt);
-       free(stmt);
-       return STATUS(ctx);
-}
-
-
-int glite_lbu_ExecPreparedStmtMysql_v(glite_lbu_Statement stmt_gen, int n, va_list ap) {
-       glite_lbu_StatementMysql stmt = (glite_lbu_StatementMysql)stmt_gen;
-       int i, prepare_retry;
-       glite_lbu_DBType type;
-       char *pchar;
-       int *pint;
-       long int *plint;
-       MYSQL_TIME *ptime;
-       int ret, retry;
-       MYSQL_BIND *binds = NULL;
-       void **data = NULL;
-       unsigned long *lens;
-       glite_lbu_Statement newstmt;
-
-       // gather parameters
-       if (n) {
-               binds = calloc(n, sizeof(MYSQL_BIND));
-               data = calloc(n, sizeof(void *));
-               lens = calloc(n, sizeof(unsigned long *));
-       }
-       for (i = 0; i < n; i++) {
-               type = va_arg(ap, glite_lbu_DBType);
-               switch (type) {
-               case GLITE_LBU_DB_TYPE_TINYINT:
-                       pchar = binds[i].buffer = data[i] = malloc(sizeof(char));
-                       *pchar = va_arg(ap, int);
-                       break;
-
-               case GLITE_LBU_DB_TYPE_INT:
-                       plint = binds[i].buffer = data[i] = malloc(sizeof(long int));
-                       *plint = va_arg(ap, long int);
-                       break;
-
-               case GLITE_LBU_DB_TYPE_BOOLEAN:
-                       pint = binds[i].buffer = data[i] = malloc(sizeof(int));
-                       *pint = va_arg(ap, int) ? 1 : 0;
-                       break;
-
-               case GLITE_LBU_DB_TYPE_TINYBLOB:
-               case GLITE_LBU_DB_TYPE_TINYTEXT:
-               case GLITE_LBU_DB_TYPE_BLOB:
-               case GLITE_LBU_DB_TYPE_TEXT:
-               case GLITE_LBU_DB_TYPE_MEDIUMBLOB:
-               case GLITE_LBU_DB_TYPE_MEDIUMTEXT:
-               case GLITE_LBU_DB_TYPE_LONGBLOB:
-               case GLITE_LBU_DB_TYPE_LONGTEXT:
-                       binds[i].buffer = va_arg(ap, void *);
-                       binds[i].length = &lens[i];
-                       lens[i] = va_arg(ap, unsigned long);
-                       break;
-
-               case GLITE_LBU_DB_TYPE_VARCHAR:
-               case GLITE_LBU_DB_TYPE_CHAR:
-                       binds[i].buffer = va_arg(ap, char *);
-                       binds[i].length = &lens[i];
-                       lens[i] = binds[i].buffer ? strlen((char *)binds[i].buffer) : 0;
-                       break;
-
-               case GLITE_LBU_DB_TYPE_DATE:
-               case GLITE_LBU_DB_TYPE_TIME:
-               case GLITE_LBU_DB_TYPE_DATETIME:
-                       ptime = binds[i].buffer = data[i] = malloc(sizeof(MYSQL_TIME));
-                       set_time(ptime, va_arg(ap, time_t));
-                       break;
-
-               case GLITE_LBU_DB_TYPE_TIMESTAMP:
-                       ptime = binds[i].buffer = data[i] = malloc(sizeof(MYSQL_TIME));
-                       set_time(ptime, va_arg(ap, double));
-                       break;
-
-               case GLITE_LBU_DB_TYPE_NULL:
-                       break;
-
-               default:
-                       assert("unimplemented parameter assign" == NULL);
-                       break;
-               }
-               binds[i].buffer_type = glite_type_to_mysql[type];
-       }
-
-       prepare_retry = 2;
-       do {
-               // bind parameters
-               if (n) {
-                       if (mysql_module.mysql_stmt_bind_param(stmt->stmt, binds) != 0) {
-                               MY_ERRSTMT(stmt);
-                               ret = -1;
-                               goto statement_failed;
-                       }
-               }
-
-               // run
-               retry = 1;
-               do {
-                       mysql_module.mysql_stmt_execute(stmt->stmt);
-                       ret = MY_ISOKSTMT(stmt, &retry);
-               } while (ret == 0);
-       statement_failed:
-               if (ret == -1) {
-                       if (mysql_module.mysql_stmt_errno(stmt->stmt) == ER_UNKNOWN_STMT_HANDLER) {
-                               // expired the prepared command ==> restore it
-                               if (glite_lbu_PrepareStmtMysql(stmt->generic.ctx, stmt->sql, &newstmt) == -1) goto failed;
-                               glite_lbu_FreeStmt_int(stmt);
-                               memcpy(stmt, newstmt, sizeof(struct glite_lbu_StatementMysql_s));
-                               prepare_retry--;
-                               ret = 0;
-                       } else goto failed;
-               }
-       } while (ret == 0 && prepare_retry > 0);
-
-       // result
-       retry = 1;
-       do {
-               mysql_module.mysql_stmt_store_result(stmt->stmt);
-               ret = MY_ISOKSTMT(stmt, &retry);
-       } while (ret == 0);
-       if (ret == -1) goto failed;
-
-       // free params
-       if (n) {
-               for (i = 0; i < n; i++) free(data[i]);
-               free(data);
-               free(binds);
-               free(lens);
-       }
-       CLR_ERR(stmt->generic.ctx);
-       return mysql_module.mysql_stmt_affected_rows(stmt->stmt);
-
-failed:
-       for (i = 0; i < n; i++) free(data[i]);
-       free(data);
-       free(binds);
-       free(lens);
-       return -1;
-}
-
-
-long int glite_lbu_LastidMysql(glite_lbu_Statement stmt_gen) {
-       glite_lbu_StatementMysql stmt = (glite_lbu_StatementMysql)stmt_gen;
-       my_ulonglong i;
-
-       CLR_ERR(stmt_gen->ctx);
-       i = mysql_module.mysql_stmt_insert_id(stmt->stmt);
-       assert(i < ((unsigned long int)-1) >> 1);
-       return (long int)i;
-}
-
-
-/*
- * helping function: find oud mysql error and sets on the context
- */
-static int myerr(glite_lbu_DBContextMysql ctx, const char *source, int line) {
-       return glite_lbu_DBSetError(&ctx->generic, EIO, source, line, mysql_module.mysql_error(ctx->mysql));
-}
-
-
-/*
- * helping function: find oud mysql stmt error and sets on the context
- */
-static int myerrstmt(glite_lbu_StatementMysql stmt, const char *source, int line) {    
-       return glite_lbu_DBSetError(stmt->generic.ctx, EIO, source, line, mysql_module.mysql_stmt_error(stmt->stmt));
-}
-
-
-/*
- * helping function: error handle
- *
- * \return -1 failed
- * \return  0 retry
- * \return  1 OK
- */
-static int myisokstmt(glite_lbu_StatementMysql stmt, const char *source, int line, int *retry) {
-       switch (mysql_module.mysql_stmt_errno(stmt->stmt)) {
-               case 0:
-                       return 1;
-                       break;
-               case ER_DUP_ENTRY:
-                       glite_lbu_DBSetError(stmt->generic.ctx, EEXIST, source, line, mysql_module.mysql_stmt_error(stmt->stmt));
-                       return -1;
-                       break;
-               case CR_SERVER_LOST:
-               case CR_SERVER_GONE_ERROR:
-                       if (*retry > 0) {
-                               (*retry)--;
-                               return 0;
-                       } else {
-                               myerrstmt(stmt, source, line);
-                               return -1;
-                       }
-                       break;
-               default:
-                       myerrstmt(stmt, source, line);
-                       return -1;
-                       break;
-       }
-}
-
-
-/*
- * mysql connect
- */
-static int db_connect(glite_lbu_DBContextMysql ctx, const char *cs, MYSQL **mysql) {
-       char    *buf = NULL;
-       char    *host,*user,*pw,*db; 
-       char    *slash,*at,*colon;
-       int      ret;
-#if MYSQL_VERSION_ID >= 50013
-       my_bool reconnect = 1;
-#endif
-
-       // needed for SQL result parameters
-       assert(sizeof(int) >= sizeof(my_bool));
-
-       if (!cs) return ERR(ctx, EINVAL, "connect string not specified");
-       
-       if (!(*mysql = mysql_module.mysql_init(NULL))) return ERR(ctx, ENOMEM, NULL);
-
-       mysql_module.mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my");
-#if MYSQL_VERSION_ID >= 50013
-       /* XXX: may result in weird behaviour in the middle of transaction */
-       mysql_module.mysql_options(*mysql, MYSQL_OPT_RECONNECT, &reconnect);
-#endif
-
-       host = user = pw = db = NULL;
-
-       buf = strdup(cs);
-       slash = strchr(buf,'/');
-       at = strrchr(buf,'@');
-       colon = strrchr(buf,':');
-
-       if (!slash || !at || !colon) {
-               free(buf);
-               db_close(*mysql);
-               *mysql = NULL;
-               return ERR(ctx, EINVAL, "Invalid DB connect string");
-       }
-
-       *slash = *at = *colon = 0;
-       host = at+1;
-       user = buf;
-       pw = slash+1;
-       db = colon+1;
-
-       /* ljocha: CLIENT_FOUND_ROWS added to make authorization check
-        * working in update_notif(). 
-        * Hope it does not break anything else */ 
-       if (!mysql_module.mysql_real_connect(*mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) {
-               ret = MY_ERR(ctx);
-               db_close(*mysql);
-               *mysql = NULL;
-               free(buf);
-               return ret;
-       }
-       free(buf);
-
-       return CLR_ERR(ctx);
-}
-
-
-/*
- * mysql close
- */
-static void db_close(MYSQL *mysql) {
-       if (mysql) mysql_module.mysql_close(mysql);
-}
-
-
-/*
- * test transactions capability:
- */
-static int transaction_test(glite_lbu_DBContext ctx, int *caps) {
-       glite_lbu_Statement stmt;
-       char *table[1] = { NULL }, *res[2] = { NULL, NULL }, *cmd = NULL;
-       int retval;
-
-       (*caps) &= ~GLITE_LBU_DB_CAP_TRANSACTIONS;
-
-       if ((retval = glite_lbu_ExecSQLMysql(ctx, "SHOW TABLES", &stmt)) <= 0 || glite_lbu_FetchRowMysql(stmt, 1, NULL, table) < 0) goto quit;
-       glite_lbu_FreeStmtMysql(&stmt);
-
-       trio_asprintf(&cmd, "SHOW CREATE TABLE %|Ss", table[0]);
-       if (glite_lbu_ExecSQLMysql(ctx, cmd, &stmt) <= 0 || (retval = glite_lbu_FetchRowMysql(stmt, 2, NULL, res)) < 0 ) goto quit;
-       if (retval != 2 || strcmp(res[0], table[0])) {
-               ERR(ctx, EIO, "unexpected show create result");
-               goto quit;
-       }
-
-       if (strstr(res[1],"ENGINE=InnoDB"))
-               (*caps) |= GLITE_LBU_DB_CAP_TRANSACTIONS;
-
-#ifdef LBS_DB_PROFILE
-       fprintf(stderr, "[%d] use_transactions = %d\n", getpid(), USE_TRANS(ctx));
-#endif
-
-quit:
-       glite_lbu_FreeStmtMysql(&stmt);
-       free(table[0]);
-       free(res[0]);
-       free(res[1]);
-       free(cmd);
-       return STATUS(ctx);
-}
-
-
-/*
- * simple version of the fetch
- */
-static int FetchRowSimple(glite_lbu_DBContextMysql ctx, MYSQL_RES *result, unsigned long *lengths, char **results) {
-       MYSQL_ROW            row;
-       unsigned int         nr, i;
-       unsigned long       *len;
-
-       CLR_ERR(ctx);
-
-       if (!(row = mysql_module.mysql_fetch_row(result))) {
-               if (mysql_module.mysql_errno((MYSQL *) ctx->mysql)) {
-                       MY_ERR(ctx);
-                       return -1;
-               } else return 0;
-       }
-
-       nr = mysql_module.mysql_num_fields(result);
-       len = mysql_module.mysql_fetch_lengths(result);
-       for (i=0; i<nr; i++) {
-               if (lengths) lengths[i] = len[i];
-               if (len[i]) {
-                       results[i] = malloc(len[i] + 1);
-                       memcpy(results[i], row[i], len[i]);
-                       results[i][len[i]] = '\000';
-               } else
-                       results[i] = strdup("");
-       }
-
-       return nr;
-}
-
-
-/*
- * prepared version of the fetch
- */
-static int FetchRowPrepared(glite_lbu_DBContextMysql ctx, glite_lbu_StatementMysql stmt, unsigned int n, unsigned long *lengths, char **results) {
-       int ret, retry;
-       unsigned int i;
-       MYSQL_BIND *binds = NULL;
-       unsigned long *lens = NULL;
-
-       if (n != stmt->nrfields) {
-               ERR(ctx, EINVAL, "bad number of result fields");
-               return -1;
-       }
-
-       // space for results
-       if (n) binds = calloc(n, sizeof(MYSQL_BIND));
-       if (!lengths) {
-               lens = calloc(n, sizeof(unsigned long));
-               lengths = lens;
-       }
-       for (i = 0; i < n; i++) {
-               binds[i].buffer_type = MYSQL_TYPE_VAR_STRING;
-               binds[i].buffer_length = GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH - 1;
-               binds[i].length = &lengths[i];
-               binds[i].buffer = results[i] = calloc(1, GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH);
-       }
-       if (mysql_module.mysql_stmt_bind_result(stmt->stmt, binds) != 0) goto failedstmt;
-
-       // fetch data, all can be truncated
-       retry = 1;
-       do {
-               switch(mysql_module.mysql_stmt_fetch(stmt->stmt)) {
-#ifdef MYSQL_DATA_TRUNCATED
-                       case MYSQL_DATA_TRUNCATED:
-#endif
-                       case 0:
-                               ret = 1; break;
-                       case 1: ret = MY_ISOKSTMT(stmt, &retry); break;
-                       case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */
-                       default: ERR(ctx, EIO, "other fetch error"); goto failed;
-               }
-       } while (ret == 0);
-       if (ret == -1) goto failed;
-
-       // check if all fileds had enough buffer space
-       for (i = 0; i < n; i++) {
-               // fetch the rest if needed
-               if (lengths[i] > binds[i].buffer_length) {
-                       unsigned int fetched;
-
-                       fetched = binds[i].buffer_length;
-                       if ((results[i] = realloc(results[i], lengths[i] + 1)) == NULL) {
-                               ERR(ctx, ENOMEM, "insufficient memory for field data");
-                               goto failed;
-                       }
-                       results[i][lengths[i]] = '\000';
-                       binds[i].buffer = results[i] + fetched;
-                       binds[i].buffer_length = lengths[i] - fetched;
-
-                       retry = 1;
-                       do {
-                               switch (mysql_module.mysql_stmt_fetch_column(stmt->stmt, binds + i, i, fetched)) {
-                                       case 0: ret = 1; break;
-                                       case 1: ret = MY_ISOKSTMT(stmt, &retry); break;
-                                       case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */
-                                       default: ERR(ctx, EIO, "other fetch error"); goto failed;
-                               }
-                       } while (ret == 0);
-                       if (ret == -1) goto failed;
-               }
-       }
-
-       CLR_ERR(ctx);
-       free(binds);
-       free(lens);
-       return n;
-
-failedstmt:
-       MY_ERRSTMT(stmt);
-failed:
-       ret = -1;
-quit:
-       free(binds);
-       free(lens);
-       for (i = 0; i < n; i++) {
-               free(results[i]);
-               results[i] = NULL;
-       }
-       return ret;
-}
-
-
-static void set_time(MYSQL_TIME *mtime, const double time) {
-       struct tm tm;
-       time_t itime;
-
-       itime = time;
-       gmtime_r(&itime, &tm);
-       memset(mtime, 0, sizeof *mtime);
-       mtime->year = tm.tm_year + 1900;
-       mtime->month = tm.tm_mon + 1;
-       mtime->day = tm.tm_mday;
-       mtime->hour = tm.tm_hour;
-       mtime->minute = tm.tm_min;
-       mtime->second = tm.tm_sec;
-       mtime->second_part = (time - itime) * 1000;
-}
-
-
-static void glite_lbu_DBCleanup(void) {
-       pthread_mutex_lock(&mysql_module.lock);
-       if (mysql_module.lib) {
-               dlclose(mysql_module.lib);
-               mysql_module.lib = NULL;
-       }
-       pthread_mutex_unlock(&mysql_module.lock);
-}
-
-
diff --git a/org.glite.lbjp-common.db/src/db-pg.c b/org.glite.lbjp-common.db/src/db-pg.c
deleted file mode 100644 (file)
index 7d8d743..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/**
- * Simple postgres module with org.glite.lbjp-common.db interface.
- * 
- * PostgreSQL limitations:
- *  - prepared commands requires server >= 8.2
- *  - binary data need to be handled manually (libpq limitation)
- */
-
-#include <sys/types.h>
-#include <assert.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <libpq-fe.h>
-
-#include "glite/lbu/trio.h"
-#include "db.h"
-#include "db-int.h"
-
-#ifdef WIN32
-#define STDCALL __stdcall
-#else
-#define STDCALL
-#endif
-
-#define DB_CONNECT_TIMEOUT "20"
-
-#ifdef LOG
-  #define lprintf(FMT...) fprintf(stdout, "[db-pg] %s: ", __FUNCTION__); fprintf(stdout, ##FMT);
-#else
-  #define lprintf(FMT...)
-#endif
-
-#define set_error(CTX, CODE, DESC...) glite_lbu_DBSetError((glite_lbu_DBContext)(CTX), (CODE), __FUNCTION__, __LINE__, ##DESC)
-
-#define LOAD(SYM, SYM2) if ((*(void **)(&psql_module.SYM) = dlsym(psql_module.lib, SYM2)) == NULL) { \
-       err = set_error(ctx, ENOENT, "can't load symbol '%s' from psql library (%s)", SYM2, dlerror()); \
-       break; \
-}
-
-
-struct glite_lbu_DBContextPsql_s {
-       struct glite_lbu_DBContext_s generic;
-       PGconn *conn;
-       int prepared_counts[4];
-};
-typedef struct glite_lbu_DBContextPsql_s *glite_lbu_DBContextPsql;
-
-struct glite_lbu_StatementPsql_s {
-       glite_lbu_Statement_t generic;
-       PGresult *res;
-       int row, nrows;
-       char *sql, *name;
-};
-typedef struct glite_lbu_StatementPsql_s *glite_lbu_StatementPsql;
-
-typedef struct {
-       void *lib;
-       pthread_mutex_t lock;
-
-       /* functions from 8.3.8 client library version (libpq-fe.h) */
-       PGconn *STDCALL(*PQconnectdb)(const char *conninfo);
-       ConnStatusType STDCALL(*PQstatus)(const PGconn *conn);
-       void STDCALL(*PQfinish)(PGconn *conn);
-       char *STDCALL(*PQerrorMessage)(const PGconn *conn);
-       int STDCALL(*PQnfields)(const PGresult *res);
-       char *STDCALL(*PQgetvalue)(const PGresult *res, int tup_num, int field_num);
-       int STDCALL(*PQgetlength)(const PGresult *res, int tup_num, int field_num);
-       void STDCALL(*PQclear)(PGresult *res);
-       PGresult *STDCALL(*PQexec)(PGconn *conn, const char *query);
-       ExecStatusType STDCALL(*PQresultStatus)(const PGresult *res);
-       char *STDCALL(*PQresultErrorMessage)(const PGresult *res);
-       char *STDCALL(*PQcmdTuples)(PGresult *res);
-       int STDCALL(*PQntuples)(const PGresult *res);
-       char *STDCALL(*PQfname)(const PGresult *res, int field_num);
-       size_t STDCALL(*PQescapeStringConn)(PGconn *conn,
-               char *to, const char *from, size_t length,
-               int *error);
-       void STDCALL(*PQfreemem)(void *ptr);
-} psql_module_t;
-
-
-static void glite_lbu_DBCleanup(void);
-
-/* backend module declaration */
-int glite_lbu_InitDBContextPsql(glite_lbu_DBContext *ctx_gen);
-void glite_lbu_FreeDBContextPsql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_DBConnectPsql(glite_lbu_DBContext ctx_gen, const char *cs);
-void glite_lbu_DBClosePsql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_DBQueryCapsPsql(glite_lbu_DBContext ctx_gen);
-void glite_lbu_DBSetCapsPsql(glite_lbu_DBContext commmon_ctx, int caps);
-int glite_lbu_TransactionPsql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_CommitPsql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_RollbackPsql(glite_lbu_DBContext ctx_gen);
-int glite_lbu_FetchRowPsql(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
-void glite_lbu_FreeStmtPsql(glite_lbu_Statement *stmt);
-//int glite_lbu_QueryIndicesPsql(glite_lbu_DBContext ctx_gen, const char *table, char ***key_names, char ****column_names);
-int glite_lbu_ExecSQLPsql(glite_lbu_DBContext ctx_gen, const char *cmd, glite_lbu_Statement *stmt);
-int glite_lbu_QueryColumnsPsql(glite_lbu_Statement stmt_gen, char **cols);
-int glite_lbu_PrepareStmtPsql(glite_lbu_DBContext ctx_gen, const char *sql, glite_lbu_Statement *stmt_gen);
-int glite_lbu_ExecPreparedStmtPsql_v(glite_lbu_Statement stmt_gen, int n, va_list ap);
-//long int glite_lbu_LastidPsql(glite_lbu_Statement stmt_gen);
-
-glite_lbu_DBBackend_t psql_backend = {
-       backend: GLITE_LBU_DB_BACKEND_PSQL,
-
-       initContext: glite_lbu_InitDBContextPsql,
-       freeContext: glite_lbu_FreeDBContextPsql,
-       connect: glite_lbu_DBConnectPsql,
-       close: glite_lbu_DBClosePsql,
-       queryCaps: glite_lbu_DBQueryCapsPsql,
-       setCaps: glite_lbu_DBSetCapsPsql,
-       transaction: glite_lbu_TransactionPsql,
-       commit: glite_lbu_CommitPsql,
-       rollback: glite_lbu_RollbackPsql,
-       fetchRow: glite_lbu_FetchRowPsql,
-       freeStmt: glite_lbu_FreeStmtPsql,
-       queryIndices: NULL /*glite_lbu_QueryIndicesPsql*/,
-       execSQL: glite_lbu_ExecSQLPsql,
-       queryColumns: glite_lbu_QueryColumnsPsql,
-
-       timeToDB: glite_lbu_TimeToStr,
-       timestampToDB: glite_lbu_TimestampToStr,
-       DBToTime: glite_lbu_StrToTime,
-       DBToTimestamp: glite_lbu_StrToTimestamp,
-
-       prepareStmt: glite_lbu_PrepareStmtPsql,
-       execPreparedStmt_v: glite_lbu_ExecPreparedStmtPsql_v,
-       lastid: NULL/*glite_lbu_LastidPsql*/,
-};
-
-static psql_module_t psql_module = {
-       lib: NULL,
-       lock: PTHREAD_MUTEX_INITIALIZER,
-};
-
-
-/* nicer identifiers in PREPARE/EXECUTE commands */
-static const char *prepared_names[4] = {"select", "update", "insert", "other"};
-
-
-int glite_lbu_InitDBContextPsql(glite_lbu_DBContext *ctx_gen) {
-       glite_lbu_DBContextPsql ctx;
-       int err = 0;
-
-       ctx = calloc(1, sizeof *ctx);
-       if (!ctx) return ENOMEM;
-       *ctx_gen = (glite_lbu_DBContext)ctx;
-
-       /* dynamic load of the client library */
-       pthread_mutex_lock(&psql_module.lock);
-       if (!psql_module.lib) {
-               psql_module.lib = dlopen(PSQL_SONAME, RTLD_LAZY | RTLD_LOCAL);
-               if (!psql_module.lib) return set_error(ctx, ENOENT, "dlopen(): " PSQL_SONAME ": %s", dlerror());
-               do {
-                       LOAD(PQconnectdb, "PQconnectdb");
-                       LOAD(PQstatus, "PQstatus");
-                       LOAD(PQfinish, "PQfinish");
-                       LOAD(PQerrorMessage, "PQerrorMessage");
-                       LOAD(PQnfields, "PQnfields");
-                       LOAD(PQgetvalue, "PQgetvalue");
-                       LOAD(PQgetlength, "PQgetlength");
-                       LOAD(PQclear, "PQclear");
-                       LOAD(PQexec, "PQexec");
-                       LOAD(PQresultStatus, "PQresultStatus");
-                       LOAD(PQresultErrorMessage, "PQresultErrorMessage");
-                       LOAD(PQcmdTuples, "PQcmdTuples");
-                       LOAD(PQntuples, "PQntuples");
-                       LOAD(PQfname, "PQfname");
-                       LOAD(PQescapeStringConn, "PQescapeStringConn");
-                       LOAD(PQfreemem, "PQfreemem");
-
-                       pthread_mutex_unlock(&psql_module.lock);
-                       atexit(glite_lbu_DBCleanup);
-               } while(0);
-
-               if (err) {
-                       dlclose(psql_module.lib);
-                       psql_module.lib = NULL;
-                       pthread_mutex_unlock(&psql_module.lock);
-                       return err;
-               }
-       } else pthread_mutex_unlock(&psql_module.lock);
-
-       return 0;
-}
-
-
-void glite_lbu_FreeDBContextPsql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-
-       if (ctx) {
-               assert(ctx->conn == NULL);
-               free(ctx);
-       }
-}
-
-
-int glite_lbu_DBConnectPsql(glite_lbu_DBContext ctx_gen, const char *cs) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-       char *buf, *slash, *at, *colon, *host, *user, *pw, *db, *pgcsbuf, *pgcs;
-       char *err;
-
-       host = user = pw = db = NULL;
-       buf = strdup(cs);
-       slash = strchr(buf,'/');
-       at = strrchr(buf,'@');
-       colon = strrchr(buf,':');
-       if (!slash || !at || !colon) {
-               free(buf);
-               return set_error(ctx, EINVAL, "Invalid DB connect string");
-       }
-       *slash = *at = *colon = 0;
-       host = at+1;
-       user = buf;
-       pw = slash+1;
-       db = colon+1;
-
-       trio_asprintf(&pgcsbuf, "host='%|Ss' dbname='%|Ss' user='%|Ss' password='%|Ss' connect_timeout=" DB_CONNECT_TIMEOUT, host, db, user, pw);
-       /* simulate socket acces via localhost similar to MySQL */
-       if (strcmp(host, "localhost") == 0) pgcs = pgcsbuf + strlen("host='localhost' ");
-       else pgcs = pgcsbuf;
-       free(buf);
-
-       lprintf("connection string = %s\n", pgcs);
-       ctx->conn = psql_module.PQconnectdb(pgcs);
-       free(pgcsbuf);
-       if (!ctx->conn) return ENOMEM;
-
-       
-
-       if (psql_module.PQstatus(ctx->conn) != CONNECTION_OK) {
-               asprintf(&err, "Can't connect, %s", psql_module.PQerrorMessage(ctx->conn));
-               psql_module.PQfinish(ctx->conn);
-               ctx->conn = NULL;
-               set_error(ctx, EIO, err);
-               free(err);
-               return EIO;
-       }
-
-       return 0;
-}
-
-
-void glite_lbu_DBClosePsql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-
-       if (ctx->conn) {
-               psql_module.PQfinish(ctx->conn);
-               ctx->conn = NULL;
-       }
-}
-
-
-int glite_lbu_DBQueryCapsPsql(glite_lbu_DBContext ctx_gen) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-       glite_lbu_Statement stmt;
-       int major, minor, sub, version;
-       int has_prepared = 0;
-       char *res = NULL;
-
-       if (glite_lbu_ExecSQLPsql(ctx_gen, "SHOW server_version", &stmt) == -1) return -1;
-       switch (glite_lbu_FetchRowPsql(stmt, 1, NULL, &res)) {
-       case 1:
-               break;
-       case -1:
-               has_prepared = -1;
-               goto quit;
-       default:
-               goto quit;
-       }
-       if (sscanf(res, "%d.%d.%d", &major, &minor, &sub) != 3) {
-               set_error(ctx, EIO, "can't parse PostgreSQL version string");
-               goto quit;
-       }
-       version = 10000*major + 100*minor + sub;
-       has_prepared = version >= 80200 ? GLITE_LBU_DB_CAP_PREPARED : 0;
-
-quit:
-       free(res);
-       glite_lbu_FreeStmtPsql(&stmt);
-       return has_prepared;
-}
-
-
-void glite_lbu_DBSetCapsPsql(glite_lbu_DBContext ctx_gen, int caps) {
-       ctx_gen->caps = caps;
-}
-
-
-int glite_lbu_TransactionPsql(glite_lbu_DBContext ctx_gen __attribute((unused))) {
-       return 0;
-}
-
-
-int glite_lbu_CommitPsql(glite_lbu_DBContext ctx_gen __attribute((unused))) {
-       return 0;
-}
-
-
-int glite_lbu_RollbackPsql(glite_lbu_DBContext ctx_gen __attribute((unused))) {
-       return 0;
-}
-
-
-int glite_lbu_FetchRowPsql(glite_lbu_Statement stmt_gen, unsigned int maxn, unsigned long *lengths, char **results) {
-       glite_lbu_StatementPsql stmt = (glite_lbu_StatementPsql)stmt_gen;
-       unsigned int i, n;
-       char *s;
-
-       if (stmt->row >= stmt->nrows) return 0;
-
-       n = psql_module.PQnfields(stmt->res);
-       if (n <= 0) {
-               set_error(stmt->generic.ctx, EINVAL, "Result set w/o columns");
-               return -1;
-       }
-       if (n > maxn) {
-               set_error(stmt->generic.ctx, EINVAL, "Not enough room for the result");
-               return -1;
-       }
-       for (i = 0; i < n; i++) {
-               /* sanity check for internal error (NULL when invalid row) */
-               s = psql_module.PQgetvalue(stmt->res, stmt->row, i) ? : "";
-               results[i] = strdup(s);
-               if (lengths) lengths[i] = strlen(s);
-       }
-
-       stmt->row++;
-       return n;
-}
-
-
-void glite_lbu_FreeStmtPsql(glite_lbu_Statement *stmt_gen) {
-       glite_lbu_DBContextPsql ctx;
-       glite_lbu_StatementPsql stmt;
-       char *sql;
-
-       if (!*stmt_gen) return;
-       stmt = (glite_lbu_StatementPsql)(*stmt_gen);
-       ctx = (glite_lbu_DBContextPsql)stmt->generic.ctx;
-       if (stmt->res) psql_module.PQclear(stmt->res);
-       if (stmt->name) {
-               asprintf(&sql, "DEALLOCATE %s", stmt->name);
-               stmt->res = psql_module.PQexec(ctx->conn, sql);
-               free(sql);
-               psql_module.PQclear(stmt->res);
-       }
-       free(stmt->name);
-       free(stmt->sql);
-       free(stmt);
-       *stmt_gen = NULL;
-}
-
-
-int glite_lbu_ExecSQLPsql(glite_lbu_DBContext ctx_gen, const char *cmd, glite_lbu_Statement *stmt_out) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-       glite_lbu_StatementPsql stmt = NULL;
-       int status, n;
-       char *nstr, *errmsg, *pos;
-       PGresult *res;
-
-       lprintf("command = %s\n", cmd);
-       if (stmt_out) *stmt_out = NULL;
-       if ((res = psql_module.PQexec(ctx->conn, cmd)) == NULL) {
-               ctx->generic.err.code = ENOMEM;
-               return -1;
-       }
-
-       status = psql_module.PQresultStatus(res);
-       if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
-               errmsg = psql_module.PQresultErrorMessage(res);
-               if (errmsg) {
-                       errmsg = strdup(errmsg);
-                       if ((pos = strrchr(errmsg, '\n')) != NULL) pos[0] = '\0';
-               }
-               set_error(ctx, EIO, errmsg);
-               free(errmsg);
-               psql_module.PQclear(res);
-               return -1;
-       }
-
-       nstr = psql_module.PQcmdTuples(res);
-       if (nstr && nstr[0]) n = atoi(nstr);
-       else n = psql_module.PQntuples(res);
-       if (stmt_out) {
-               stmt = calloc(1, sizeof(*stmt));
-               stmt->generic.ctx = ctx_gen;
-               stmt->res = res;
-               stmt->nrows = n;
-               *stmt_out = (glite_lbu_Statement)stmt;
-       } else {
-               psql_module.PQclear(res);
-       }
-       return n;
-}
-
-
-int glite_lbu_QueryColumnsPsql(glite_lbu_Statement stmt_gen, char **cols) {
-       glite_lbu_StatementPsql stmt = (glite_lbu_StatementPsql)stmt_gen;
-       int n, i;
-
-       n = psql_module.PQnfields(stmt->res);
-       for (i = 0; i < n; i++) {
-               cols[i] = psql_module.PQfname(stmt->res, i);
-       }
-       return -1;
-}
-
-
-int glite_lbu_PrepareStmtPsql(glite_lbu_DBContext ctx_gen, const char *sql, glite_lbu_Statement *stmt_out) {
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)ctx_gen;
-       int i, retval = -1;
-       const char *selectp, *updatep, *insertp, *minp;
-       char *sqlPrep = NULL, *s = NULL;
-       glite_lbu_StatementPsql stmt;
-       PGresult *res = NULL;
-
-       // init
-       stmt = calloc(1, sizeof(*stmt));
-       stmt->generic.ctx = ctx_gen;
-       stmt->sql = strdup(sql);
-
-       // name of the prepared command used as ID in postgres
-       i = -1;
-       minp = stmt->sql + strlen(stmt->sql);
-       selectp = strcasestr(stmt->sql, "SELECT");
-       updatep = strcasestr(stmt->sql, "UPDATE");
-       insertp = strcasestr(stmt->sql, "INSERT");
-       if (selectp && selectp < minp) { minp = selectp; i = 0; }
-       if (updatep && updatep < minp) { minp = updatep; i = 1; }
-       if (insertp && insertp < minp) { minp = insertp; i = 2; }
-       if (i == -1 || minp[0] == '\0') i = 3;
-       asprintf(&stmt->name, "%s%d", prepared_names[i], ++ctx->prepared_counts[i]);
-
-       asprintf(&sqlPrep, "PREPARE %s AS %s", stmt->name, stmt->sql);
-       lprintf("prepare = %s\n", sqlPrep);
-       res = psql_module.PQexec(ctx->conn, sqlPrep);
-       if (psql_module.PQresultStatus(res) != PGRES_COMMAND_OK) {
-               asprintf(&s, "error preparing command: %s", psql_module.PQerrorMessage(ctx->conn));
-               set_error(ctx, EIO, s);
-               free(s); s = NULL;
-               goto quit;
-       }
-
-       *stmt_out = (glite_lbu_Statement)stmt;
-       retval = 0;
-
-quit:
-       free(sqlPrep);
-       if (res) psql_module.PQclear(res);
-       if (!retval) return 0;
-
-       free(stmt->name);
-       free(stmt->sql);
-       free(stmt);
-       return retval;
-}
-
-
-int glite_lbu_ExecPreparedStmtPsql_v(glite_lbu_Statement stmt_gen, int n, va_list ap) {
-       glite_lbu_StatementPsql stmt = (glite_lbu_StatementPsql)stmt_gen;
-       glite_lbu_DBContextPsql ctx = (glite_lbu_DBContextPsql)stmt_gen->ctx;
-       int i, retval = -1, status;
-       char **tmpdata = NULL;
-       char *sql = NULL, *s, *nstr;
-       size_t data_len = 0;
-
-       glite_lbu_DBType type;
-
-       if (!stmt || !stmt->sql || !stmt->name)
-               return set_error(ctx, EINVAL, "PrepareStmt() not called");
-
-       if (stmt->res) {
-               psql_module.PQclear(stmt->res);
-               stmt->res = NULL;
-       }
-
-       // gather parameters
-       if (n) {
-               tmpdata = calloc(n, sizeof(char *));
-       }
-       for (i = 0; i < n; i++) {
-               type = va_arg(ap, glite_lbu_DBType);
-
-               switch(type) {
-               case GLITE_LBU_DB_TYPE_TINYINT:
-                       asprintf(&tmpdata[i], "%d", va_arg(ap, int));
-                       break;
-
-               case GLITE_LBU_DB_TYPE_INT:
-                       asprintf(&tmpdata[i], "%ld", va_arg(ap, long int));
-                       break;
-
-               case GLITE_LBU_DB_TYPE_TINYBLOB:
-               case GLITE_LBU_DB_TYPE_TINYTEXT:
-               case GLITE_LBU_DB_TYPE_BLOB:
-               case GLITE_LBU_DB_TYPE_TEXT:
-               case GLITE_LBU_DB_TYPE_MEDIUMBLOB:
-               case GLITE_LBU_DB_TYPE_MEDIUMTEXT:
-               case GLITE_LBU_DB_TYPE_LONGBLOB:
-               case GLITE_LBU_DB_TYPE_LONGTEXT: {
-                       char *tmp, *s;
-                       unsigned long binary_len;
-
-                       s = va_arg(ap, char *);
-                       binary_len = va_arg(ap, unsigned long);
-                       lprintf("blob, len = %lu, ptr = %p\n", binary_len, s);
-                       if (s) {
-                               tmp = malloc(2*binary_len + 1);
-                               psql_module.PQescapeStringConn(ctx->conn, tmp, s, binary_len, NULL);
-                               asprintf(&tmpdata[i], "'%s'", tmp);
-                               lprintf("escaped: '%s'\n", tmpdata[i]);
-                               free(tmp);
-                       } else
-                               tmpdata[i] = strdup("NULL");
-                       break;
-               }
-
-
-               case GLITE_LBU_DB_TYPE_VARCHAR:
-               case GLITE_LBU_DB_TYPE_CHAR:
-                       s = va_arg(ap, char *);
-                       if (s) trio_asprintf(&tmpdata[i], "'%|Ss'", s);
-                       else tmpdata[i] = strdup("NULL");
-                       break;
-
-               case GLITE_LBU_DB_TYPE_DATE:
-               case GLITE_LBU_DB_TYPE_TIME:
-               case GLITE_LBU_DB_TYPE_DATETIME:
-                       glite_lbu_TimeToStr(va_arg(ap, time_t), &tmpdata[i]);
-                       break;
-
-               case GLITE_LBU_DB_TYPE_TIMESTAMP:
-                       glite_lbu_TimestampToStr(va_arg(ap, double), &tmpdata[i]);
-                       break;
-
-               case GLITE_LBU_DB_TYPE_NULL:
-                       tmpdata[i] = strdup("NULL");
-                       break;
-
-               case GLITE_LBU_DB_TYPE_BOOLEAN:
-                       tmpdata[i] = strdup(va_arg(ap, int) ? "true" : "false");
-                       break;
-
-               default:
-                       lprintf("unknown type %d\n", type);
-                       set_error(ctx, EINVAL, "unimplemented type");
-                       goto quit;
-               }
-
-               data_len += strlen(tmpdata[i]);
-       }
-
-       asprintf(&sql, "EXECUTE %s", stmt->name);
-       s = realloc(sql, strlen(sql) + (2 * n - 2) + strlen(" ()") + data_len + 1);
-       if (!s) goto quit;
-       sql = s;
-       for (i = 0; i < n; i++) {
-               strcat(sql, i ? ", " : " (" ); s += 2;
-               strcat(sql, tmpdata[i]);
-       }
-       if (n) strcat(sql, ")");
-
-       lprintf("exec prepared: n = %d, sql = '%s'\n", n, sql);
-       stmt->res = psql_module.PQexec(ctx->conn, sql);
-       status = psql_module.PQresultStatus(stmt->res);
-       if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
-               asprintf(&s, "error executing prepared command '%s' parameters '%s': %s", stmt->sql, sql, psql_module.PQerrorMessage(ctx->conn));
-               set_error(ctx, EIO, s);
-               free(s); s = NULL;
-               goto quit;
-       }
-       nstr = psql_module.PQcmdTuples(stmt->res);
-       //lprintf("cmdtuples: '%s'\n", nstr);
-       if (nstr && nstr[0]) retval = atoi(nstr);
-       else retval = psql_module.PQntuples(stmt->res);
-       stmt->nrows = retval;
-       stmt->row = 0;
-       //lprintf("ntuples/retval: %d\n", retval);
-
-quit:
-       for (i = 0; i < n; i++) free(tmpdata[i]);
-       free(tmpdata);
-       free(sql);
-       return retval;
-}
-
-
-static void glite_lbu_DBCleanup(void) {
-       pthread_mutex_lock(&psql_module.lock);
-       if (psql_module.lib) {
-               dlclose(psql_module.lib);
-               psql_module.lib = NULL;
-       }
-       pthread_mutex_unlock(&psql_module.lock);
-}
diff --git a/org.glite.lbjp-common.db/src/db.c b/org.glite.lbjp-common.db/src/db.c
deleted file mode 100644 (file)
index d65d5a8..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-#include <sys/types.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glite/lbu/trio.h>
-
-#include "db.h"
-#include "db-int.h"
-
-
-#define VALID(BACKEND) ((BACKEND) >= 0 && (BACKEND) < GLITE_LBU_DB_BACKEND_LAST)
-
-
-struct glite_lbu_bufInsert_s {
-       glite_lbu_DBContext ctx;
-       char    *table_name;
-       char    *columns;       /* names of columns to be inserted into 
-                                * (values separated with commas) */
-       char    **rows;         /* each row hold string of one row to be inserted
-                                * (values separated with commas) */
-       long    rec_num,        /* actual number of rows in structure */
-               rec_size;       /* approx. size of a real insert string */
-       long    size_limit,     /* size and # of records limit which trigger */
-               record_limit;   /* real insert; zero means unlimitted */
-};
-
-
-/* possible backends */
-#ifdef MYSQL_SONAME
-extern glite_lbu_DBBackend_t mysql_backend;
-#else
-#define mysql_backend no_backend
-#endif
-#ifdef PSQL_SONAME
-extern glite_lbu_DBBackend_t psql_backend;
-#else
-#define psql_backend no_backend
-#endif
-
-glite_lbu_DBBackend_t no_backend = {
-       backend: -1,
-
-       /* functions unspecified */
-};
-
-glite_lbu_DBBackend_t *backends[GLITE_LBU_DB_BACKEND_LAST] = {
-       &mysql_backend,
-       &psql_backend
-};
-
-
-/* --- internal functions ---- */
-
-int glite_lbu_DBClearError(glite_lbu_DBContext ctx) {
-       ctx->err.code = 0;
-       if (ctx->err.desc) {
-               free(ctx->err.desc);
-               ctx->err.desc = NULL;
-       }
-       return 0;
-}
-
-
-int glite_lbu_DBSetError(glite_lbu_DBContext ctx, int code, const char *func, int line, const char *desc, ...) {
-       va_list ap;
-
-       if (!code) return ctx->err.code;
-
-       ctx->err.code = code;
-       free(ctx->err.desc);
-       if (desc) {
-               va_start(ap, desc);
-               vasprintf(&ctx->err.desc, desc, ap);
-               va_end(ap);
-       } else
-               ctx->err.desc = NULL;
-       dprintf(ctx, "[db %d] %s:%d %s\n", getpid(), func, line, ctx->err.desc);
-       return code;
-}
-
-
-void glite_lbu_TimeToStrGeneric(time_t t, char **str, const char *amp) {
-       struct tm       *tm = gmtime(&t);
-
-       asprintf(str,"%s%4d-%02d-%02d %02d:%02d:%02d%s",amp,tm->tm_year+1900,tm->tm_mon+1,
-               tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,amp);
-}
-
-
-void glite_lbu_TimeToStr(time_t t, char **str) {
-       glite_lbu_TimeToStrGeneric(t, str, "'");
-}
-
-
-void glite_lbu_TimestampToStrGeneric(double t, char **str, const char *amp) {
-       time_t tsec = t;
-       struct tm *tm = gmtime(&tsec);
-
-       t = t - tsec + tm->tm_sec;
-       asprintf(str,"%s%4d-%02d-%02d %02d:%02d:%02.09f%s",amp,tm->tm_year+1900,tm->tm_mon+1,
-                tm->tm_mday,tm->tm_hour,tm->tm_min,t,amp);
-}
-
-
-void glite_lbu_TimestampToStr(double t, char **str) {
-       glite_lbu_TimestampToStrGeneric(t, str, "'");
-}
-
-
-time_t glite_lbu_StrToTime(const char *str) {
-       struct tm       tm;
-
-       memset(&tm,0,sizeof(tm));
-       putenv("TZ=UTC"); tzset();
-       sscanf(str,"%4d-%02d-%02d %02d:%02d:%02d",
-               &tm.tm_year,&tm.tm_mon,&tm.tm_mday,
-               &tm.tm_hour,&tm.tm_min,&tm.tm_sec);
-       tm.tm_year -= 1900;
-       tm.tm_mon--;
-
-       return mktime(&tm);
-}
-
-
-double glite_lbu_StrToTimestamp(const char *str) {
-       struct tm       tm;
-       double  sec;
-
-       memset(&tm,0,sizeof(tm));
-       putenv("TZ=UTC"); tzset();
-       sscanf(str,"%4d-%02d-%02d %02d:%02d:%lf",
-               &tm.tm_year,&tm.tm_mon,&tm.tm_mday,
-               &tm.tm_hour,&tm.tm_min,&sec);
-       tm.tm_year -= 1900;
-       tm.tm_mon--;
-       tm.tm_sec = sec;
-
-       return (sec - tm.tm_sec) + mktime(&tm);
-}
-
-
-/* ---- API ---- */
-
-
-int glite_lbu_DBError(glite_lbu_DBContext ctx, char **text, char **desc) {
-       if (text) *text = strdup(strerror(ctx->err.code));
-       if (desc) {
-               if (ctx->err.desc) *desc = strdup(ctx->err.desc);
-               else *desc = NULL;
-       }
-
-       return ctx->err.code;
-}
-
-
-int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx, int backend) {
-       int ret;
-
-       if (!VALID(backend)) return EINVAL;
-       if (backends[backend]->backend != backend) return ENOTSUP;
-       ret = backends[backend]->initContext(ctx);
-       if (ctx && *ctx) (*ctx)->backend = backend;
-       return ret;
-}
-
-
-void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx) {
-       if (!ctx || !VALID(ctx->backend)) return;
-
-       free(ctx->err.desc);
-       ctx->err.desc = NULL;
-       backends[ctx->backend]->freeContext(ctx);
-}
-
-
-int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->connect(ctx, cs);
-}
-
-
-void glite_lbu_DBClose(glite_lbu_DBContext ctx) {
-       if (!VALID(ctx->backend)) return;
-       backends[ctx->backend]->close(ctx);
-}
-
-
-int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->queryCaps(ctx);
-}
-
-
-void glite_lbu_DBSetCaps(glite_lbu_DBContext ctx, int caps) {
-       if (!VALID(ctx->backend)) return;
-       return backends[ctx->backend]->setCaps(ctx, caps);
-}
-
-
-int glite_lbu_Transaction(glite_lbu_DBContext ctx) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->transaction(ctx);
-}
-
-
-int glite_lbu_Commit(glite_lbu_DBContext ctx) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->commit(ctx);
-}
-
-
-int glite_lbu_Rollback(glite_lbu_DBContext ctx) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->rollback(ctx);
-}
-
-
-int glite_lbu_FetchRow(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) {
-       if (!VALID(stmt->ctx->backend)) return EINVAL;
-       return backends[stmt->ctx->backend]->fetchRow(stmt, n, lengths, results);
-}
-
-
-void glite_lbu_FreeStmt(glite_lbu_Statement *stmt) {
-       if (!stmt || !*stmt || !VALID((*stmt)->ctx->backend)) return;
-       return backends[(*stmt)->ctx->backend]->freeStmt(stmt);
-}
-
-
-int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->queryIndices(ctx, table, key_names, column_names);
-}
-
-
-int glite_lbu_ExecSQL(glite_lbu_DBContext ctx, const char *cmd, glite_lbu_Statement *stmt) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->execSQL(ctx, cmd, stmt);
-}
-
-
-int glite_lbu_QueryColumns(glite_lbu_Statement stmt, char **cols) {
-       if (!VALID(stmt->ctx->backend)) return EINVAL;
-       return backends[stmt->ctx->backend]->queryColumns(stmt, cols);
-}
-
-
-int glite_lbu_PrepareStmt(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt) {
-       if (!VALID(ctx->backend)) return EINVAL;
-       return backends[ctx->backend]->prepareStmt(ctx, sql, stmt);
-}
-
-
-int glite_lbu_ExecPreparedStmt_v(glite_lbu_Statement stmt, int n, va_list ap) {
-       if (!VALID(stmt->ctx->backend)) return EINVAL;
-       return backends[stmt->ctx->backend]->execPreparedStmt_v(stmt, n, ap);
-}
-
-
-int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) {
-       va_list ap;
-       int retval;
-
-       va_start(ap, n);
-       retval = glite_lbu_ExecPreparedStmt_v(stmt, n, ap);
-       va_end(ap);
-
-       return retval;
-}
-
-
-long int glite_lbu_Lastid(glite_lbu_Statement stmt) {
-       if (!VALID(stmt->ctx->backend)) return EINVAL;
-       return backends[stmt->ctx->backend]->lastid(stmt);
-}
-
-
-void glite_lbu_TimeToDB(glite_lbu_DBContext ctx, time_t t, char **str) {
-       if (!VALID(ctx->backend)) return;
-       return backends[ctx->backend]->timeToDB(t, str);
-}
-
-
-void glite_lbu_TimestampToDB(glite_lbu_DBContext ctx, double t, char **str) {
-       if (!VALID(ctx->backend)) return;
-       return backends[ctx->backend]->timestampToDB(t, str);
-}
-
-
-time_t glite_lbu_DBToTime(glite_lbu_DBContext ctx, const char *str) {
-       if (!VALID(ctx->backend)) return (time_t)-1;
-       return backends[ctx->backend]->DBToTime(str);
-}
-
-
-double glite_lbu_DBToTimestamp(glite_lbu_DBContext ctx, const char *str) {
-       if (!VALID(ctx->backend)) return -1;
-       return backends[ctx->backend]->DBToTimestamp(str);
-}
-
-
-#define STATUS(CTX) ((CTX)->err.code)
-#define CLR_ERR(CTX) glite_lbu_DBClearError((CTX))
-int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, const char *table_name, long size_limit, long record_limit, const char *columns)
-{
-       *bi = calloc(1, sizeof(*bi));
-       (*bi)->ctx = ctx;
-       (*bi)->table_name = strdup(table_name);
-       (*bi)->columns = strdup(columns);
-       (*bi)->rec_num = 0;
-       (*bi)->rec_size = 0;
-       (*bi)->rows = calloc(record_limit, sizeof(*((*bi)->rows)) );
-       (*bi)->size_limit = size_limit;
-       (*bi)->record_limit = record_limit;
-
-        return CLR_ERR(ctx);
-}
-
-
-static int flush_bufferd_insert(glite_lbu_bufInsert bi)
-{
-       char *stmt, *vals, *temp;
-       long i;
-
-
-       if (!bi->rec_num)
-               return STATUS(bi->ctx);
-
-       asprintf(&vals,"(%s)", bi->rows[0]);
-       for (i=1; i < bi->rec_num; i++) {
-               // XXX:  use string add (preallocated memory)
-               asprintf(&temp,"%s,(%s)", vals, bi->rows[i]);
-               free(vals); vals = temp; temp = NULL;
-               free(bi->rows[i]);
-               bi->rows[i] = NULL;
-       }
-       
-       trio_asprintf(&stmt, "insert into %|Ss(%|Ss) values %s;",
-               bi->table_name, bi->columns, vals);
-
-       if (glite_lbu_ExecSQL(bi->ctx,stmt,NULL) < 0) {
-                if (STATUS(bi->ctx) == EEXIST)
-                        CLR_ERR(bi->ctx);
-        }
-
-       /* reset bi counters */
-       bi->rec_size = 0;
-       bi->rec_num = 0;
-       
-       free(vals);
-       free(stmt);
-
-       return STATUS(bi->ctx);
-}
-
-
-int glite_lbu_bufferedInsert(glite_lbu_bufInsert bi, const char *row)
-{
-       bi->rows[bi->rec_num++] = strdup(row);
-       bi->rec_size += strlen(row);
-
-       if ((bi->size_limit && bi->rec_size >= bi->size_limit) ||
-               (bi->record_limit && bi->rec_num >= bi->record_limit))
-       {
-               if (flush_bufferd_insert(bi))
-                       return STATUS(bi->ctx);
-       }
-
-       return CLR_ERR(bi->ctx);
-}
-
-
-static void free_buffered_insert(glite_lbu_bufInsert bi) {
-       long i;
-
-       free(bi->table_name);
-       free(bi->columns);
-       for (i=0; i < bi->rec_num; i++) {
-               free(bi->rows[i]);
-       }
-       free(bi->rows);
-}
-
-
-int glite_lbu_bufferedInsertClose(glite_lbu_bufInsert bi)
-{
-       if (flush_bufferd_insert(bi))
-               return STATUS(bi->ctx);
-       free_buffered_insert(bi);
-
-       return CLR_ERR(bi->ctx);
-}