* mysql -u root -p -e 'GRANT ALL on test.* to testuser@localhost'
* ./db_test
*
- * Use CS environment variable when using different user/pwd@machine:dbname.
+ * Then you can launch:
+ *
+ * ./db_expire
+ *
+ * Use CS environment variable for different user/pwd@machine:dbname.
*/
#include <stdio.h>
}
+static void print_error(glite_lbu_DBContext ctx) {
+ if (ctx) {
+ char *t, *d;
+
+ if (glite_lbu_DBError(ctx, &t, &d)) {
+ printf("Error %s: %s\n", t, d);
+ free(t); free(d);
+ }
+ }
+}
+
+
int main(int argn, char *argv[]) {
char *name, *user;
const char *cs;
glite_lbu_DBContext ctx;
glite_lbu_Statement stmt;
- int caps, i, nr, c;
+ int caps, nr, c;
unsigned long lens[3];
char *res[3];
// init
dprintf(("connecting to %s...\n", cs));
- if (glite_lbu_InitDBContext(&ctx) != 0) goto fail;
- if (glite_lbu_DBConnect(ctx, cs) != 0) goto failctx;
- if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) goto failcon;
+ if (glite_lbu_InitDBContext(&ctx) != 0) {
+ print_error(ctx);
+ goto failctx;
+ }
+ if (glite_lbu_DBConnect(ctx, cs) != 0) {
+ print_error(ctx);
+ goto failctx;
+ }
+ if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) {
+ print_error(ctx);
+ goto failcon;
+ }
if ((caps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
+ print_error(ctx);
dprintf(("can't do prepared commands, exiting."));
goto failcon;
}
// caps
- glite_lbu_DBSetCaps(ctx, caps);
+ glite_lbu_DBSetCaps(ctx, caps | GLITE_LBU_DB_CAP_ERRORS);
dprintf(("capabilities: %d\n", caps));
user = NULL;
dprintf(("preparing '%s'...\n", user));
- if ((glite_lbu_PrepareStmt(ctx, SELECT_CMD, &stmt)) != 0) goto failcon;
+ if ((glite_lbu_PrepareStmt(ctx, SELECT_CMD, &stmt)) != 0) {
+ print_error(ctx);
+ goto failcon;
+ }
do {
user = "cicomexocitl.civ";
dprintf(("executing '%s'...\n", user));
- if (glite_lbu_ExecPreparedStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt;
+ if (glite_lbu_ExecPreparedStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) {
+ print_error(ctx);
+ goto failstmt;
+ }
dprintf(("fetching '%s'...\n", user));
while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) {
dprintf(("Result: n=%d, res=%p\n", nr, res));
glite_lbu_DBClose(ctx);
failctx:
glite_lbu_FreeDBContext(ctx);
-fail:
dprintf(("failed\n"));
return 1;
}
// init
dprintf(("connecting to %s...\n", cs));
- if (glite_lbu_InitDBContext(&ctx) != 0) goto fail;
+ if (glite_lbu_InitDBContext(&ctx) != 0) goto failctx;
if (glite_lbu_DBConnect(ctx, cs) != 0) goto failctx;
if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) goto failcon;
if ((caps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
dprintf(("closing...\n"));
glite_lbu_DBClose(ctx);
failctx:
- {
+ if (ctx) {
char *t, *d;
glite_lbu_DBError(ctx, &t, &d);
free(t); free(d);
}
glite_lbu_FreeDBContext(ctx);
-fail:
free(cmd);
dprintf(("failed\n"));
return 1;
/* for prepared commands */
MYSQL_STMT *stmt;
unsigned long nrfields;
+ char *sql;
};
static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
static void set_time(MYSQL_TIME *mtime, const time_t time);
static void glite_lbu_DBCleanup(void);
+static void glite_lbu_FreeStmt_int(glite_lbu_Statement stmt);
/* ---- common ---- */
}
-void glite_lbu_FreeStmt(glite_lbu_Statement *stmt) {
- if (*stmt) {
- if ((*stmt)->result) db_handle.mysql_free_result((*stmt)->result);
- if ((*stmt)->stmt) db_handle.mysql_stmt_close((*stmt)->stmt);
- free(*stmt);
- *stmt = NULL;
+static void glite_lbu_FreeStmt_int(glite_lbu_Statement stmt) {
+ if (stmt) {
+ if (stmt->result) db_handle.mysql_free_result(stmt->result);
+ if (stmt->stmt) db_handle.mysql_stmt_close(stmt->stmt);
+ free(stmt->sql);
}
}
+void glite_lbu_FreeStmt(glite_lbu_Statement *stmt) {
+ glite_lbu_FreeStmt_int(*stmt);
+ free(*stmt);
+ *stmt = NULL;
+}
+
+
int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names) {
glite_lbu_Statement stmt = NULL;
} else
(*stmt)->nrfields = 0;
+ // remember the command
+ (*stmt)->sql = strdup(sql);
+
return CLR_ERR(ctx);
failed:
int glite_lbu_ExecPreparedStmt_v(glite_lbu_Statement stmt, int n, va_list ap) {
- int i;
+ int i, prepare_retry;
glite_lbu_DBType type;
char *pchar;
long int *plint;
MYSQL_BIND *binds = NULL;
void **data = NULL;
unsigned long *lens;
+ glite_lbu_Statement newstmt;
// gather parameters
if (n) {
binds[i].buffer_type = glite_type_to_mysql[type];
}
- // bind parameters
- if (n)
- if (db_handle.mysql_stmt_bind_param(stmt->stmt, binds) != 0) {
- MY_ERRSTMT(stmt);
- goto failed;
+ prepare_retry = 2;
+ do {
+ // bind parameters
+ if (n) {
+ if (db_handle.mysql_stmt_bind_param(stmt->stmt, binds) != 0) {
+ MY_ERRSTMT(stmt);
+ ret = -1;
+ goto statement_failed;
+ }
}
- // run
- ctx = stmt->ctx;
- retry = 1;
- do {
- db_handle.mysql_stmt_execute(stmt->stmt);
- ret = MY_ISOKSTMT(stmt, &retry);
- } while (ret == 0);
- if (ret == -1) goto failed;
+ // run
+ ctx = stmt->ctx;
+ retry = 1;
+ do {
+ db_handle.mysql_stmt_execute(stmt->stmt);
+ ret = MY_ISOKSTMT(stmt, &retry);
+ } while (ret == 0);
+ statement_failed:
+ if (ret == -1) {
+ if (db_handle.mysql_stmt_errno(stmt->stmt) == ER_UNKNOWN_STMT_HANDLER) {
+ // expired the prepared command ==> restore it
+ if (glite_lbu_PrepareStmt(stmt->ctx, stmt->sql, &newstmt) == -1) goto failed;
+ glite_lbu_FreeStmt_int(stmt);
+ memcpy(stmt, newstmt, sizeof(struct glite_lbu_Statement_s));
+ prepare_retry--;
+ ret = 0;
+ } else goto failed;
+ }
+ } while (ret == 0 && prepare_retry > 0);
// result
retry = 1;