From e9fddae4eef56acdcadce216e277618c861678a5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Wed, 12 Dec 2007 15:36:36 +0000 Subject: [PATCH] Big switch of the jp.index to new db module. Enhanced API of the db module. Fixed prepared statement without arguments. --- org.glite.jp.index/Makefile | 17 +- org.glite.jp.index/examples/jpis-test.c | 5 +- org.glite.jp.index/src/bones_server.c | 2 +- org.glite.jp.index/src/context.h | 6 +- org.glite.jp.index/src/db_ops.c | 259 +++++------- org.glite.jp.index/src/soap_ops.c | 64 +-- org.glite.jp.server-common/Makefile | 37 +- org.glite.jp.server-common/interface/db.h | 247 +---------- org.glite.jp.server-common/src/db.c | 668 ++---------------------------- org.glite.lbjp-common.db/interface/db.h | 6 + org.glite.lbjp-common.db/src/db.c | 36 +- 11 files changed, 220 insertions(+), 1127 deletions(-) diff --git a/org.glite.jp.index/Makefile b/org.glite.jp.index/Makefile index 84a7b81..4c7a124 100644 --- a/org.glite.jp.index/Makefile +++ b/org.glite.jp.index/Makefile @@ -6,7 +6,7 @@ stagedir=. distdir=. globalprefix=glite jpprefix=jp -package=glite-lb-server +package=glite-jp-index version=0.0.0 PREFIX=/opt/glite @@ -104,19 +104,6 @@ doc: ${MANS} ${HTMLS} stage: compile doc ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - install: -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d -mkdir -p ${PREFIX}/share/doc/${package}-${version} @@ -140,6 +127,8 @@ install: ${INSTALL} -m 644 ${top_srcdir}/interface/JobProvenanceISClient.xsd ${PREFIX}/interface clean: + rm -rvf *.c *.h *.ch *.xh *.xml *.nsmap *.o *.lo .libs glite-jp* + rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ soap_ops.o bones_server.o simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h diff --git a/org.glite.jp.index/examples/jpis-test.c b/org.glite.jp.index/examples/jpis-test.c index 04d5f7d..30e3e73 100644 --- a/org.glite.jp.index/examples/jpis-test.c +++ b/org.glite.jp.index/examples/jpis-test.c @@ -41,7 +41,6 @@ int main(int argc,char *argv[]) /*---------------------------------------------------------------------------*/ // simulate FeedIndex PS response { - glite_jp_db_stmt_t stmt; glite_jp_context_t ctx; glite_jpis_context_t isctx = NULL; glite_jp_is_conf *conf; @@ -64,8 +63,8 @@ int main(int argc,char *argv[]) goto end; } - if (glite_jp_db_execstmt(ctx, DELETE, &stmt) < 0) goto end; - if (glite_jp_db_execstmt(ctx, INSERT, &stmt) < 0) goto end; + if (glite_jp_db_ExecSQL(ctx, DELETE, NULL) < 0) goto end; + if (glite_jp_db_ExecSQL(ctx, INSERT, NULL) < 0) goto end; end: glite_jpis_free_context(isctx); glite_jp_free_context(ctx); diff --git a/org.glite.jp.index/src/bones_server.c b/org.glite.jp.index/src/bones_server.c index 3bb1b78..5830781 100644 --- a/org.glite.jp.index/src/bones_server.c +++ b/org.glite.jp.index/src/bones_server.c @@ -411,7 +411,7 @@ int newconn(int conn,struct timeval *to,void *data) { printf("[%d] reloading credentials\n",getpid()); /* XXX: log */ - edg_wll_gss_release_cred(mycred, NULL); + edg_wll_gss_release_cred(&mycred, NULL); mycred = newcred; } break; diff --git a/org.glite.jp.index/src/context.h b/org.glite.jp.index/src/context.h index eb1edea..94ab565 100644 --- a/org.glite.jp.index/src/context.h +++ b/org.glite.jp.index/src/context.h @@ -10,11 +10,7 @@ typedef struct _glite_jpis_context { glite_jp_context_t jpctx; glite_jp_is_conf *conf; - glite_jp_db_stmt_t select_unlocked_feed_stmt, lock_feed_stmt, init_feed_stmt, unlock_feed_stmt, select_info_feed_stmt, update_state_feed_stmt, select_info_attrs_indexed, select_jobid_stmt, select_user_stmt, insert_job_stmt, insert_user_stmt; - long int param_uniqueid, param_state; - char param_feedid[33], param_ps[256], param_indexed[256], param_jobid[33], param_dg_jobid[256], param_ownerid[33], param_cert[256]; - unsigned long param_ps_len, param_feedid_len, param_indexed_len, param_jobid_len, param_dg_jobid_len, param_ownerid_len, param_cert_len; - void *param_expires; + glite_lbu_Statement select_unlocked_feed_stmt, lock_feed_stmt, init_feed_stmt, unlock_feed_stmt, select_info_feed_stmt, update_state_feed_stmt, select_info_attrs_indexed, select_jobid_stmt, select_user_stmt, insert_job_stmt, insert_user_stmt; char *hname; diff --git a/org.glite.jp.index/src/db_ops.c b/org.glite.jp.index/src/db_ops.c index 5ea7619..d728083 100644 --- a/org.glite.jp.index/src/db_ops.c +++ b/org.glite.jp.index/src/db_ops.c @@ -282,27 +282,19 @@ char *glite_jpis_attr_name2id(const char *name) { */ int glite_jpis_initDatabase(glite_jpis_context_t ctx) { - char **attrs, *tmp; + char **attrs, *attrid; const char *type_index, *type_full; size_t i; - void *param; - unsigned long attrid_len, name_len, type_len, source_len, dbconds_len; - char attrid[33], name[256], type[33], source[256], dbconds[1024]; int indexed, state, locked; size_t conds_len; char sql[512]; glite_jp_is_feed **feeds; void *conds; glite_jp_context_t jpctx = ctx->jpctx; - glite_jp_db_stmt_t stmt = NULL; + glite_lbu_Statement stmt = NULL; jpctx = ctx->jpctx; - glite_jp_db_create_params(¶m, 4, - GLITE_JP_DB_TYPE_VARCHAR, attrid, &attrid_len, - GLITE_JP_DB_TYPE_VARCHAR, name, &name_len, - GLITE_JP_DB_TYPE_INT, &indexed, - GLITE_JP_DB_TYPE_VARCHAR, type, &type_len); - if (glite_jp_db_prepare(jpctx, "INSERT INTO attrs (attrid, name, indexed, type) VALUES (?, ?, ?, ?)", &stmt, param, NULL) != 0) goto fail; + if (glite_jp_db_PrepareStmt(jpctx, "INSERT INTO attrs (attrid, name, indexed, type) VALUES (?, ?, ?, ?)", &stmt) != 0) goto fail; // attrs table and attrid_* tables attrs = ctx->conf->attrs; @@ -311,69 +303,62 @@ int glite_jpis_initDatabase(glite_jpis_context_t ctx) { type_full = glite_jp_attrval_db_type_full(jpctx, attrs[i]); type_index = glite_jp_attrval_db_type_index(jpctx, attrs[i], INDEX_LENGTH); - // attrid column - tmp = glite_jpis_attr_name2id(attrs[i]); - GLITE_JPIS_PARAM(attrid, attrid_len, tmp); - free(tmp); - GLITE_JPIS_PARAM(name, name_len, attrs[i]); - // indexed column - indexed = is_indexed(ctx->conf, name); - // type column - GLITE_JPIS_PARAM(type, type_len, type_full); - // insert - if (glite_jp_db_execute(stmt) == -1) goto fail; + attrid = glite_jpis_attr_name2id(attrs[i]); + indexed = is_indexed(ctx->conf, attrs[i]); + if (glite_jp_db_ExecPreparedStmt(jpctx, stmt, 4, + GLITE_LBU_DB_TYPE_VARCHAR, attrid, + GLITE_LBU_DB_TYPE_VARCHAR, attrs[i], + GLITE_LBU_DB_TYPE_INT, indexed, + GLITE_LBU_DB_TYPE_VARCHAR, type_full) == -1) goto fail; + free(attrid); // silently drop sql[sizeof(sql) - 1] = '\0'; snprintf(sql, sizeof(sql), SQLCMD_DROP_DATA_TABLE, attrid); llprintf(LOG_SQL, "preventive dropping '%s' ==> '%s'\n", attrid, sql); - glite_jp_db_execstmt(jpctx, sql, NULL); + glite_jp_db_ExecSQL(jpctx, sql, NULL); // create table sql[sizeof(sql) - 1] = '\0'; snprintf(sql, sizeof(sql) - 1, SQLCMD_CREATE_DATA_TABLE, attrid, type_index, type_full); llprintf(LOG_SQL, "creating table: '%s'\n", sql); - if ((glite_jp_db_execstmt(jpctx, sql, NULL)) == -1) { + if ((glite_jp_db_ExecSQL(jpctx, sql, NULL)) == -1) { glite_jpis_stack_error(ctx->jpctx, EAGAIN, "if the atribute table already exists, restart may help"); goto fail; } i++; } - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); // feeds table - glite_jp_db_create_params(¶m, 4, - GLITE_JP_DB_TYPE_INT, &state, - GLITE_JP_DB_TYPE_INT, &locked, - GLITE_JP_DB_TYPE_VARCHAR, source, &source_len, - GLITE_JP_DB_TYPE_MEDIUMBLOB, dbconds, &dbconds_len); - if (glite_jp_db_prepare(jpctx, "INSERT INTO feeds (state, locked, source, condition) VALUES (?, ?, ?, ?)", &stmt, param, NULL) != 0) goto fail; + if (glite_jp_db_PrepareStmt(jpctx, "INSERT INTO feeds (state, locked, source, condition) VALUES (?, ?, ?, ?)", &stmt) != 0) goto fail; feeds = ctx->conf->feeds; i = 0; if (feeds) while (feeds[i]) { state = (feeds[i]->history ? GLITE_JP_IS_STATE_HIST : 0) | (feeds[i]->continuous ? GLITE_JP_IS_STATE_CONT : 0); locked = 0; - GLITE_JPIS_PARAM(source, source_len, feeds[i]->PS_URL); assert(glite_jpis_db_queries_serialize(ctx, &conds, &conds_len, feeds[i]->query) == 0); - assert(conds_len <= sizeof(dbconds)); - dbconds_len = conds_len; - memcpy(dbconds, conds, conds_len); + if (glite_jp_db_ExecPreparedStmt(jpctx, stmt, 4, + GLITE_LBU_DB_TYPE_INT, state, + GLITE_LBU_DB_TYPE_INT, locked, + GLITE_LBU_DB_TYPE_VARCHAR, feeds[i]->PS_URL, + GLITE_LBU_DB_TYPE_MEDIUMBLOB, conds, conds_len) == -1) + goto fail_conds; free(conds); - if (glite_jp_db_execute(stmt) == -1) goto fail_conds; - feeds[i]->uniqueid = glite_jp_db_lastid(stmt); + feeds[i]->uniqueid = glite_lbu_Lastid(stmt); i++; } - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return 0; fail_conds: free(conds); fail: - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return jpctx->error->code; } @@ -385,130 +370,98 @@ fail: */ int glite_jpis_dropDatabase(glite_jpis_context_t ctx) { - void *res; - char attrid[33], sql[256]; + char *attrid, sql[256]; unsigned long len; int ret; glite_jp_context_t jpctx = ctx->jpctx; - glite_jp_db_stmt_t stmt_tabs = NULL; + glite_lbu_Statement stmt_tabs = NULL; // search data tables and drop them - glite_jp_db_create_results(&res, 1, GLITE_JP_DB_TYPE_CHAR, NULL, attrid, sizeof(attrid), &len); - if (glite_jp_db_prepare(jpctx, "SELECT attrid FROM attrs", &stmt_tabs, NULL, res) != 0) goto fail; - if (glite_jp_db_execute(stmt_tabs) == -1) goto fail; - while ((ret = glite_jp_db_fetch(stmt_tabs)) == 0) { + if (glite_jp_db_PrepareStmt(jpctx, "SELECT attrid FROM attrs", &stmt_tabs) != 0) goto fail; + if (glite_jp_db_ExecPreparedStmt(jpctx, stmt_tabs, 0) == -1) goto fail; + while ((ret = glite_jp_db_FetchRow(jpctx, stmt_tabs, 1, &len, &attrid)) > 0) { snprintf(sql, sizeof(sql), SQLCMD_DROP_DATA_TABLE, attrid); llprintf(LOG_SQL, "dropping '%s' ==> '%s'\n", attrid, sql); - if (glite_jp_db_execstmt(jpctx, sql, NULL) == -1) printf("warning: can't drop table '" TABLE_PREFIX_DATA "%s': %s (%s)\n", attrid, jpctx->error->desc, jpctx->error->source); + if (glite_jp_db_ExecSQL(jpctx, sql, NULL) == -1) printf("warning: can't drop table '" TABLE_PREFIX_DATA "%s': %s (%s)\n", attrid, jpctx->error->desc, jpctx->error->source); } - if (ret != ENODATA) goto fail; - glite_jp_db_freestmt(&stmt_tabs); + if (ret != 0) goto fail; + glite_jp_db_FreeStmt(&stmt_tabs); // drop feeds and atributes - if (glite_jp_db_execstmt(jpctx, "DELETE FROM attrs", NULL) == -1) goto fail; - if (glite_jp_db_execstmt(jpctx, "DELETE FROM feeds", NULL) == -1) goto fail; - if (glite_jp_db_execstmt(jpctx, "DELETE FROM jobs", NULL) == -1) goto fail; - if (glite_jp_db_execstmt(jpctx, "DELETE FROM users", NULL) == -1) goto fail; - if (glite_jp_db_execstmt(jpctx, "DELETE FROM acls", NULL) == -1) goto fail; + if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM attrs", NULL) == -1) goto fail; + if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM feeds", NULL) == -1) goto fail; + if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM jobs", NULL) == -1) goto fail; + if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM users", NULL) == -1) goto fail; + if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM acls", NULL) == -1) goto fail; return 0; fail: - glite_jp_db_freestmt(&stmt_tabs); + glite_jp_db_FreeStmt(&stmt_tabs); return jpctx->error->code; } int glite_jpis_init_db(glite_jpis_context_t isctx) { int ret; - void *myparam; - void *myres; const char *cs; glite_jp_context_t jpctx; jpctx = isctx->jpctx; + if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&jpctx->dbhandle)) != 0) goto fail_db; if ((cs = isctx->conf->cs) == NULL) cs = GLITE_JP_IS_DEFAULTCS; - if ((ret = glite_jp_db_connect(jpctx, cs)) != 0) goto fail; + if (glite_lbu_DBConnect(jpctx->dbhandle, cs) != 0) goto fail_db; // sql command: lock the feed (via uniqueid) - glite_jp_db_create_params(&myparam, 1, GLITE_JP_DB_TYPE_INT, &isctx->param_uniqueid); - if ((ret = glite_jp_db_prepare(jpctx, "UPDATE feeds SET locked=1 WHERE (locked = 0) AND (uniqueid = ?)", &isctx->lock_feed_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET locked=1 WHERE (locked = 0) AND (uniqueid = ?)", &isctx->lock_feed_stmt)) != 0) goto fail; // sql command: assign the feed (via uniqueid) - glite_jp_db_create_params(&myparam, 4, - GLITE_JP_DB_TYPE_CHAR, isctx->param_feedid, &isctx->param_feedid_len, - GLITE_JP_DB_TYPE_DATETIME, &isctx->param_expires, - GLITE_JP_DB_TYPE_INT, &isctx->param_state, - GLITE_JP_DB_TYPE_INT, &isctx->param_uniqueid); - if ((ret = glite_jp_db_prepare(jpctx, "UPDATE feeds SET feedid=?, expires=?, state=? WHERE (uniqueid=?)", &isctx->init_feed_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET feedid=?, expires=?, state=? WHERE (uniqueid=?)", &isctx->init_feed_stmt)) != 0) goto fail; // sql command: unlock the feed (via uniqueid) - glite_jp_db_create_params(&myparam, 1, GLITE_JP_DB_TYPE_INT, &isctx->param_uniqueid); - if ((ret = glite_jp_db_prepare(jpctx, "UPDATE feeds SET locked=0 WHERE (uniqueid=?)", &isctx->unlock_feed_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET locked=0 WHERE (uniqueid=?)", &isctx->unlock_feed_stmt)) != 0) goto fail; // sql command: get info about the feed (via feedid) - glite_jp_db_create_params(&myparam, 1, GLITE_JP_DB_TYPE_CHAR, isctx->param_feedid, &isctx->param_feedid_len); - glite_jp_db_create_results(&myres, 3, - GLITE_JP_DB_TYPE_INT, NULL, &isctx->param_uniqueid, - GLITE_JP_DB_TYPE_INT, NULL, &isctx->param_state, - GLITE_JP_DB_TYPE_VARCHAR, NULL, isctx->param_ps, sizeof(isctx->param_ps), &isctx->param_ps_len); - if ((ret = glite_jp_db_prepare(jpctx, "SELECT uniqueid, state, source FROM feeds WHERE (feedid=?)", &isctx->select_info_feed_stmt, myparam, myres)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT uniqueid, state, source FROM feeds WHERE (feedid=?)", &isctx->select_info_feed_stmt)) != 0) goto fail; // sql command: update state of the feed (via uniqueid) - glite_jp_db_create_params(&myparam, 2, - GLITE_JP_DB_TYPE_INT, &isctx->param_state, - GLITE_JP_DB_TYPE_INT, &isctx->param_uniqueid); - if ((ret = glite_jp_db_prepare(jpctx, "UPDATE feeds SET state=? WHERE (uniqueid=?)", &isctx->update_state_feed_stmt, myparam, NULL)) != 0) goto fail; - - // sql command: get info about indexed attributes - glite_jp_db_create_results(&myres, 1, - GLITE_JP_DB_TYPE_VARCHAR, NULL, isctx->param_indexed, sizeof(isctx->param_indexed), &isctx->param_indexed_len); - if ((ret = glite_jp_db_prepare(jpctx, "SELECT name FROM attrs WHERE (indexed=1)", &isctx->select_info_attrs_indexed, NULL, myres)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET state=? WHERE (uniqueid=?)", &isctx->update_state_feed_stmt)) != 0) goto fail; // sql command: check for job with jobid - glite_jp_db_create_params(&myparam, 1, - GLITE_JP_DB_TYPE_CHAR, isctx->param_jobid, &isctx->param_jobid_len); - if ((glite_jp_db_prepare(jpctx, "SELECT jobid FROM jobs WHERE jobid=?", &isctx->select_jobid_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT jobid FROM jobs WHERE jobid=?", &isctx->select_jobid_stmt)) != 0) goto fail; // sql command: insert the job - glite_jp_db_create_params(&myparam, 4, - GLITE_JP_DB_TYPE_CHAR, isctx->param_jobid, &isctx->param_jobid_len, - GLITE_JP_DB_TYPE_VARCHAR, isctx->param_dg_jobid, &isctx->param_dg_jobid_len, - GLITE_JP_DB_TYPE_CHAR, isctx->param_ownerid, &isctx->param_ownerid_len, - GLITE_JP_DB_TYPE_CHAR, isctx->param_feedid, &isctx->param_feedid_len); - if ((glite_jp_db_prepare(jpctx, "INSERT INTO jobs (jobid, dg_jobid, ownerid, ps) VALUES (?, ?, ?, (SELECT source FROM feeds WHERE feedid=?))", &isctx->insert_job_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "INSERT INTO jobs (jobid, dg_jobid, ownerid, ps) VALUES (?, ?, ?, ?)", &isctx->insert_job_stmt)) != 0) goto fail; // sql command: check the user - glite_jp_db_create_params(&myparam, 1, - GLITE_JP_DB_TYPE_CHAR, isctx->param_ownerid, &isctx->param_ownerid_len); - if ((glite_jp_db_prepare(jpctx, "SELECT userid FROM users WHERE userid=?", &isctx->select_user_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT userid FROM users WHERE userid=?", &isctx->select_user_stmt)) != 0) goto fail; // sql command: insert the user - glite_jp_db_create_params(&myparam, 2, - GLITE_JP_DB_TYPE_CHAR, isctx->param_ownerid, &isctx->param_ownerid_len, - GLITE_JP_DB_TYPE_VARCHAR, isctx->param_cert, &isctx->param_cert_len); - if ((glite_jp_db_prepare(jpctx, "INSERT INTO users (userid, cert_subj) VALUES (?, ?)", &isctx->insert_user_stmt, myparam, NULL)) != 0) goto fail; + if ((ret = glite_jp_db_PrepareStmt(jpctx, "INSERT INTO users (userid, cert_subj) VALUES (?, ?)", &isctx->insert_user_stmt)) != 0) goto fail; return 0; -fail: +fail_db: + ret = glite_jp_db_SetError(jpctx, __FUNCTION__); +fail: glite_jpis_free_db(isctx); return ret; } void glite_jpis_free_db(glite_jpis_context_t ctx) { - glite_jp_db_freestmt(&ctx->lock_feed_stmt); - glite_jp_db_freestmt(&ctx->init_feed_stmt); - glite_jp_db_freestmt(&ctx->unlock_feed_stmt); - glite_jp_db_freestmt(&ctx->select_info_feed_stmt); - glite_jp_db_freestmt(&ctx->update_state_feed_stmt); - glite_jp_db_freestmt(&ctx->select_info_attrs_indexed); - glite_jp_db_freestmt(&ctx->select_jobid_stmt); - glite_jp_db_freestmt(&ctx->select_user_stmt); - glite_jp_db_freestmt(&ctx->insert_job_stmt); - glite_jp_db_freestmt(&ctx->insert_user_stmt); - glite_jp_db_close(ctx->jpctx); + glite_jp_db_FreeStmt(&ctx->lock_feed_stmt); + glite_jp_db_FreeStmt(&ctx->init_feed_stmt); + glite_jp_db_FreeStmt(&ctx->unlock_feed_stmt); + glite_jp_db_FreeStmt(&ctx->select_info_feed_stmt); + glite_jp_db_FreeStmt(&ctx->update_state_feed_stmt); + glite_jp_db_FreeStmt(&ctx->select_jobid_stmt); + glite_jp_db_FreeStmt(&ctx->select_user_stmt); + glite_jp_db_FreeStmt(&ctx->insert_job_stmt); + glite_jp_db_FreeStmt(&ctx->insert_user_stmt); + glite_lbu_DBClose(ctx->jpctx->dbhandle); + glite_lbu_FreeDBContext(ctx->jpctx->dbhandle); + ctx->jpctx->dbhandle = NULL; } @@ -523,59 +476,56 @@ int glite_jpis_lockSearchFeed(glite_jpis_context_t ctx, int initialized, long in { int ret; static int uninit_msg = 1; - char *sql, *res[4], *t; - glite_jp_db_stmt_t stmt; + char *sql, *res[4], *t, *ps; + glite_lbu_Statement stmt; if (feedid) *feedid = NULL; do { - t = glite_jp_db_timetodb(time(NULL)); + glite_lbu_TimeToDB(time(NULL), &t); if (initialized) { trio_asprintf(&sql, "SELECT uniqueid, source, state, feedid FROM feeds WHERE (locked=0) AND (feedid IS NOT NULL) AND (expires <= %s)", t); } else trio_asprintf(&sql, "SELECT uniqueid, source, state, feedid FROM feeds WHERE (locked=0) AND (feedid IS NULL) AND ((state < " GLITE_JP_IS_STATE_ERROR_STR ") OR (expires <= %s))", t); free(t); - ret = glite_jp_db_execstmt(ctx->jpctx, sql, &stmt); + ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, &stmt); free(sql); switch (ret) { case -1: glite_jpis_stack_error(ctx->jpctx, ENOLCK, "error selecting unlocked feed"); uninit_msg = 1; - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return ENOLCK; case 0: if (uninit_msg) { lprintf("no more %s feeds for now\n", initialized ? "not-refreshed" : "uninitialized"); uninit_msg = 0; } - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return ENOENT; default: break; } uninit_msg = 1; - if (glite_jp_db_fetchrow(stmt, res) <= 0) { + if (glite_jp_db_FetchRow(ctx->jpctx, stmt, sizeof(res)/sizeof(res[0]), NULL, res) <= 0) { glite_jpis_stack_error(ctx->jpctx, ENOLCK, "error fetching unlocked feed"); - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return ENOLCK; } - glite_jp_db_freestmt(&stmt); - ctx->param_uniqueid = atol(res[0]); - strncpy(ctx->param_ps, res[1], sizeof ctx->param_ps); - lprintf("selected feed, uniqueid=%s\n", res[0]); - if (status) *status = atoi(res[2]); - free(res[0]); - free(res[1]); - free(res[2]); + glite_jp_db_FreeStmt(&stmt); + *uniqueid = atol(res[0]); free(res[0]); + ps = res[1]; + if (status) *status = atoi(res[2]); free(res[2]); + lprintf("selected feed, uniqueid=%s\n", *uniqueid); if (feedid) { free(*feedid); *feedid = res[3]; } else free(res[3]); - ret = glite_jp_db_execute(ctx->lock_feed_stmt); - lprintf("locked %d feeds (uniqueid=%ld)\n", ret, ctx->param_uniqueid); + ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->lock_feed_stmt, 1, GLITE_LBU_DB_TYPE_INT, *uniqueid); + lprintf("locked %d feeds (uniqueid=%ld)\n", ret, *uniqueid); } while (ret != 1); - *uniqueid = ctx->param_uniqueid; - if (PS_URL) *PS_URL = strdup(ctx->param_ps); + if (PS_URL) *PS_URL = ps; + else free(ps); return 0; } @@ -586,15 +536,16 @@ int glite_jpis_lockSearchFeed(glite_jpis_context_t ctx, int initialized, long in int glite_jpis_initFeed(glite_jpis_context_t ctx, long int uniqueid, const char *feedId, time_t feedExpires, int status) { int ret; - time_t tnow; + time_t tnow, expires; - GLITE_JPIS_PARAM(ctx->param_feedid, ctx->param_feedid_len, feedId); tnow = time(NULL); - glite_jp_db_set_time(ctx->param_expires, tnow + (feedExpires - tnow) / 2); - ctx->param_uniqueid = uniqueid; - ctx->param_state = status; + expires = tnow + (feedExpires - tnow) / 2; - ret = glite_jp_db_execute(ctx->init_feed_stmt); + ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->init_feed_stmt, 4, + GLITE_LBU_DB_TYPE_CHAR, feedId, + GLITE_LBU_DB_TYPE_DATETIME, expires, + GLITE_LBU_DB_TYPE_INT, status, + GLITE_LBU_DB_TYPE_INT, uniqueid); lprintf("initializing feed, uniqueid=%ld, result=%d\n", uniqueid, ret); return ret == 1 ? 0 : ENOLCK; @@ -606,8 +557,7 @@ int glite_jpis_initFeed(glite_jpis_context_t ctx, long int uniqueid, const char int glite_jpis_unlockFeed(glite_jpis_context_t ctx, long int uniqueid) { int ret; - ctx->param_uniqueid = uniqueid; - ret = glite_jp_db_execute(ctx->unlock_feed_stmt); + ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->unlock_feed_stmt, 1, GLITE_LBU_DB_TYPE_INT, uniqueid); lprintf("unlocking feed, uniqueid=%ld, result=%d\n", uniqueid, ret); return ret == 1 ? 0 : ENOLCK; @@ -620,11 +570,11 @@ int glite_jpis_tryReconnectFeed(glite_jpis_context_t ctx, long int uniqueid, tim int ret; char *sql, *t; - t = glite_jp_db_timetodb(reconn_time); + glite_lbu_TimeToDB(reconn_time, &t); lprintf("reconnect, un=%ld, %s\n", uniqueid, t); trio_asprintf(&sql, "UPDATE feeds SET state=%d, expires=%s WHERE (uniqueid=%ld)", state, t, uniqueid); free(t); - if ((ret = glite_jp_db_execstmt(ctx->jpctx, sql, NULL)) != 1) + if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL)) != 1) glite_jpis_stack_error(ctx->jpctx, EIO, "can't update feed no. %ld in DB", uniqueid); free(sql); return ret == -1 ? ctx->jpctx->error->code : 0; @@ -636,11 +586,11 @@ int glite_jpis_destroyTryReconnectFeed(glite_jpis_context_t ctx, long int unique int ret; char *sql, *t; - t = glite_jp_db_timetodb(reconn_time); + glite_lbu_TimeToDB(reconn_time, &t); lprintf("destroy not refreshed feed, un=%ld, %s\n", uniqueid, t); trio_asprintf(&sql, "UPDATE feeds SET feedid=NULL, state=0, expires=%s WHERE (uniqueid=%ld)", t, uniqueid); free(t); - if ((ret = glite_jp_db_execstmt(ctx->jpctx, sql, NULL)) != 1) + if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL)) != 1) glite_jpis_stack_error(ctx->jpctx, EIO, "can't destroy non-refreshable feed no. %ld in DB", uniqueid); free(sql); return ret == -1 ? ctx->jpctx->error->code : 0; @@ -662,7 +612,7 @@ int glite_jpis_insertAttrVal(glite_jpis_context_t ctx, const char *jobid, glite_ free(value); free(full_value); llprintf(LOG_SQL, "(%s) sql=%s\n", av->name, sql); - if (glite_jp_db_execstmt(ctx->jpctx, sql, NULL) != 1) { + if (glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL) != 1) { free(sql); return ctx->jpctx->error->code; } @@ -684,28 +634,27 @@ int glite_jpis_lazyInsertJob(glite_jpis_context_t ctx, const char *ps, const cha } md5_jobid = str2md5(jobid); md5_cert = str2md5(owner); - GLITE_JPIS_PARAM(ctx->param_jobid, ctx->param_jobid_len, md5_jobid); - switch (ret = glite_jp_db_execute(ctx->select_jobid_stmt)) { + switch (ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_jobid_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, md5_jobid)) { case 1: lprintf("jobid '%s' found\n", jobid); goto ok0; case 0: lprintf("inserting jobid %s (%s)\n", jobid, md5_jobid); - - GLITE_JPIS_PARAM(ctx->param_dg_jobid, ctx->param_dg_jobid_len, jobid); - GLITE_JPIS_PARAM(ctx->param_ownerid, ctx->param_ownerid_len, md5_cert); - GLITE_JPIS_PARAM(ctx->param_ps, ctx->param_ps_len, ps); - if (glite_jp_db_execute(ctx->insert_job_stmt) != 1) goto fail; + if (glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->insert_job_stmt, 4, + GLITE_LBU_DB_TYPE_CHAR, md5_jobid, + GLITE_LBU_DB_TYPE_VARCHAR, jobid, + GLITE_LBU_DB_TYPE_CHAR, md5_cert, + GLITE_LBU_DB_TYPE_CHAR, ps) != 1) goto fail; break; default: assert(ret != 1); break; } ok0: - GLITE_JPIS_PARAM(ctx->param_ownerid, ctx->param_ownerid_len, md5_cert); - switch (ret = glite_jp_db_execute(ctx->select_user_stmt)) { + switch (ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_user_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, md5_cert)) { case 1: lprintf("owner '%s' found\n", owner); goto ok; case 0: lprintf("inserting user %s (%s)\n", owner, md5_cert); - GLITE_JPIS_PARAM(ctx->param_cert, ctx->param_cert_len, owner); - if (glite_jp_db_execute(ctx->insert_user_stmt) != 1) goto fail; + if (glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->insert_user_stmt, 2, + GLITE_LBU_DB_TYPE_CHAR, md5_cert, + GLITE_LBU_DB_TYPE_VARCHAR, owner) != 1) goto fail; break; default: assert(ret != 1); break; } diff --git a/org.glite.jp.index/src/soap_ops.c b/org.glite.jp.index/src/soap_ops.c index bd266fe..c269e03 100644 --- a/org.glite.jp.index/src/soap_ops.c +++ b/org.glite.jp.index/src/soap_ops.c @@ -69,6 +69,8 @@ SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__UpdateJobs( CONTEXT_FROM_SOAP(soap, ctx); glite_jp_context_t jpctx = ctx->jpctx; char *err, *ps; + char *res[3]; + long int uniqueid; // XXX: test client in examples/jpis-test // sends to this function some data for testing @@ -79,28 +81,31 @@ SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__UpdateJobs( feedid = jpelem__UpdateJobs->feedId; lprintf("feedid='%s'\n", feedid); - GLITE_JPIS_PARAM(ctx->param_feedid, ctx->param_feedid_len, feedid); - if ((ret = glite_jp_db_execute(ctx->select_info_feed_stmt)) != 1) { + if ((ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_info_feed_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, feedid)) != 1) { fprintf(stderr, "can't get info about feed '%s', returned %d records", feedid, ret); if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); else fprintf(stderr, "\n"); goto fail; } - if (glite_jp_db_fetch(ctx->select_info_feed_stmt) != 0) { + if (glite_jp_db_FetchRow(ctx->jpctx, ctx->select_info_feed_stmt, 3, NULL, res) <= 0) { fprintf(stderr, "can't fetch feed '%s'", feedid); if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); else fprintf(stderr, "\n"); + glite_jpis_stack_error(ctx->jpctx, ENODATA, "can't fetch feed '%s'", feedid); goto fail; } - lprintf("uniqueid=%ld, state=%d, source='%s'\n", ctx->param_uniqueid, ctx->param_state, ctx->param_ps); - ps = strdup(ctx->param_ps); + lprintf("uniqueid=%s, state=%s, source='%s'\n", res[0], res[1], res[2]); + uniqueid = atol(res[0]); free(res[0]); + status = atoi(res[1]); free(res[1]); + ps = res[2]; // update status, if needed (only orig) - status = ctx->param_state; done = jpelem__UpdateJobs->feedDone ? GLITE_JP_IS_STATE_DONE : 0; if ((done != (status & GLITE_JP_IS_STATE_DONE)) && done) { - ctx->param_state |= done; - if ((ret = glite_jp_db_execute(ctx->update_state_feed_stmt)) != 1) { + status |= done; + if ((ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->update_state_feed_stmt, 2, + GLITE_LBU_DB_TYPE_INT, status, + GLITE_LBU_DB_TYPE_INT, uniqueid)) != 1) { fprintf(stderr, "can't update state of '%s', returned %d records", feedid, ret); if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); else fprintf(stderr, "\n"); @@ -132,21 +137,20 @@ static int checkIndexedConditions(glite_jpis_context_t ctx, struct _jpelem__Quer { char **indexed_attrs = NULL, *res; int i, j, k, ret; - glite_jp_db_stmt_t stmt; + glite_lbu_Statement stmt; - if ((ret = glite_jp_db_execstmt(ctx->jpctx, + if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, "SELECT name FROM attrs WHERE (indexed=1)", &stmt)) < 0) goto end; i = 0; - while ( (ret = glite_jp_db_fetchrow(stmt, &res)) > 0 ) { + while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &res)) > 0 ) { if (!(i % INDEXED_STRIDE)) { indexed_attrs = realloc(indexed_attrs, ((i / INDEXED_STRIDE + 1) * INDEXED_STRIDE) * sizeof(*indexed_attrs)); } - indexed_attrs[i++] = strdup(res); - free(res); + indexed_attrs[i++] = res; } if ( ret < 0 ) goto end; @@ -340,7 +344,7 @@ static int get_jobids(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in, c *qwhere = NULL, *query = NULL, *res[2], **jids = NULL, **pss = NULL, **attr_tables = NULL; int i, ret; - glite_jp_db_stmt_t stmt = NULL; + glite_lbu_Statement stmt = NULL; glite_jp_attr_orig_t orig; @@ -404,11 +408,11 @@ static int get_jobids(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in, c free(qwhere); free(qa); - if ((ret = glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) goto err; + if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; free(query); i = 0; - while ( (ret = glite_jp_db_fetchrow(stmt, res)) > 0 ) { + while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, sizeof(res)/sizeof(res[0]), NULL, res)) > 0 ) { if (!(i % JOBIDS_STRIDE)) { jids = realloc(jids, ((i / JOBIDS_STRIDE + 1) * JOBIDS_STRIDE + 1) @@ -428,7 +432,7 @@ static int get_jobids(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in, c if ( ret < 0 ) goto err; - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); *jobids = jids; *ps_list = pss; @@ -441,7 +445,7 @@ err: free(pss); for (i=0; (jids && jids[i]); i++) free(jids[i]); free(jids); - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); return ret; } @@ -466,7 +470,7 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch enum jptype__attrOrig *origin; char *query, *fv, *jobid_md5, *attr_md5; int i, ret; - glite_jp_db_stmt_t stmt; + glite_lbu_Statement stmt; memset(&jav,0,sizeof(jav)); jobid_md5 = str2md5(jobid); @@ -476,7 +480,7 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch free(attr_md5); free(jobid_md5); - if ((ret = glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) { + if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) { glite_jpis_stack_error(ctx->jpctx, EIO, "SELECT from attribute '%s' failed", attr_name); goto err; } @@ -484,7 +488,7 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch av = *out; i = *size; - while ( (ret = glite_jp_db_fetchrow(stmt, &fv)) > 0 ) { + while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv)) > 0 ) { av = realloc(av, (i+1) * sizeof(*av)); memset(&av[i], 0, sizeof(av[i])); @@ -516,14 +520,14 @@ static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, ch } if (ret < 0) goto err; - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); *size = i; *out = av; return 0; err: - glite_jp_db_freestmt(&stmt); + glite_jp_db_FreeStmt(&stmt); freeAttval_t(jav); return 1; } @@ -533,7 +537,7 @@ err: static int get_owner(glite_jpis_context_t ctx, char *jobid, char **owner) { char *ownerid = NULL, *jobid_md5, *query, *fv = NULL; - glite_jp_db_stmt_t stmt; + glite_lbu_Statement stmt; /* get ownerid correspondig to jobid */ @@ -542,26 +546,26 @@ static int get_owner(glite_jpis_context_t ctx, char *jobid, char **owner) jobid_md5); free(jobid_md5); - if ((glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) goto err; + if ((glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; free(query); - if (glite_jp_db_fetchrow(stmt, &ownerid) <= 0 ) goto err; + if (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &ownerid) <= 0 ) goto err; /* DB consistency check - only one record per jobid ! */ - assert (glite_jp_db_fetchrow(stmt, &fv) <=0); free(fv); + assert (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv) <=0); free(fv); /* get cert_subj corresponding to ownerid */ trio_asprintf(&query,"SELECT cert_subj FROM users WHERE userid = \"%s\"", ownerid); - if ((glite_jp_db_execstmt(ctx->jpctx, query, &stmt)) < 0) goto err; + if ((glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; free(query); - if (glite_jp_db_fetchrow(stmt, owner) <= 0 ) goto err; + if (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, owner) <= 0 ) goto err; /* DB consistency check - only one record per userid ! */ - assert (glite_jp_db_fetchrow(stmt, &fv) <=0); free(fv); + assert (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv) <=0); free(fv); return 0; diff --git a/org.glite.jp.server-common/Makefile b/org.glite.jp.server-common/Makefile index bba47ed..8b79e39 100644 --- a/org.glite.jp.server-common/Makefile +++ b/org.glite.jp.server-common/Makefile @@ -45,34 +45,14 @@ HDRS:=db.h OBJS:=${SRCS:.c=.o} LOBJS:=${OBJS:.o=.lo} -archlib:=lib -host_cpu:=${shell uname -m} -ifeq (${host_cpu},x86_64) - archlib:=lib64 -endif - -ifneq (${mysql_prefix},/usr) - ifeq ($(shell test -f ${mysql_prefix}/${archlib}/libmysqlclient.a -o -f ${mysql_prefix}/${archlib}/libmysqlclient.so && echo ok),ok) - MYSQLIB := -L${mysql_prefix}/${archlib} -lmysqlclient -lz - else - MYSQLIB := -L${mysql_prefix}/${archlib}/mysql -lmysqlclient -lz - endif -else - MYSQLIB := -lmysqlclient -lz -endif - - default all: compile examples compile: ${LTLIB} ${STATICLIB} ${LTLIB} ${STATICLIB}: ${OBJS} - ${LIBLINK} ${version_info} -o $@ ${LOBJS} ${MYSQLIB} - -examples: db-test-int + ${LIBLINK} -o $@ ${LOBJS} -lglite_lbu_db -db-test-int: db-test-int.o - ${LINK} -o $@ $+ ${STATICLIB} ${MYSQLIB} -lglite_jp_common_${nothrflavour} +examples: check: -echo nothing yet @@ -82,19 +62,6 @@ doc: stage: compile $(MAKE) install PREFIX=${stagedir} -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - install: -mkdir -p ${PREFIX}/lib ${PREFIX}/include/${globalprefix}/${jpprefix} ${INSTALL} -m 755 ${LTLIB} ${PREFIX}/lib diff --git a/org.glite.jp.server-common/interface/db.h b/org.glite.jp.server-common/interface/db.h index d3ad2a8..147719c 100644 --- a/org.glite.jp.server-common/interface/db.h +++ b/org.glite.jp.server-common/interface/db.h @@ -3,250 +3,19 @@ #ident "$Header$" -#include -#include +#include "glite/jp/types.h" +#include "glite/lbu/db.h" #ifdef __cplusplus extern "C" { #endif -#include -#include - -typedef struct _glite_jp_db_stmt_t *glite_jp_db_stmt_t; - -typedef enum { - GLITE_JP_DB_TYPE_NULL = 0, - GLITE_JP_DB_TYPE_TINYINT = 1, - GLITE_JP_DB_TYPE_INT = 2, - GLITE_JP_DB_TYPE_TINYBLOB = 3, - GLITE_JP_DB_TYPE_TINYTEXT = 4, - GLITE_JP_DB_TYPE_BLOB = 5, - GLITE_JP_DB_TYPE_TEXT = 6, - GLITE_JP_DB_TYPE_MEDIUMBLOB = 7, - GLITE_JP_DB_TYPE_MEDIUMTEXT = 8, - GLITE_JP_DB_TYPE_LONGBLOB = 9, - GLITE_JP_DB_TYPE_LONGTEXT = 10, - GLITE_JP_DB_TYPE_VARCHAR = 11, - GLITE_JP_DB_TYPE_CHAR = 12, - GLITE_JP_DB_TYPE_DATE = 13, - GLITE_JP_DB_TYPE_TIME = 14, - GLITE_JP_DB_TYPE_DATETIME = 15, - GLITE_JP_DB_TYPE_TIMESTAMP = 16, - GLITE_JP_DB_TYPE_LAST = 17 -} glite_jp_db_type_t; - -/** - * Connect to the database. - * - * \param[inout] cxt context to work with - * \param[in] cs connect string user/password@host:database - * - \return JP error code - */ -int glite_jp_db_connect(glite_jp_context_t, const char *); - - -/** - * Close the connection to database. - * - * \param[inout] ctx context to work with - */ -void glite_jp_db_close(glite_jp_context_t); - - -/** - * Parse and execute SQL statement. - * - * \param[inout] ctx context to work with - * \param[in] txt SQL statement - * \param[out] stmt statement handle, usable for select only - * - * \return number of rows selected, created or affected by update, or -1 on error - */ -int glite_jp_db_execstmt(glite_jp_context_t, const char *, glite_jp_db_stmt_t *); - - -/** Fetch next row of select statement. - * All columns are returned as fresh allocated strings - * - * \param[inout] stmt statement from glite_jp_db_execstmt() - * \param[out] array of fetched values. - * As number of columns is fixed and known, - * expects allocated array of pointers here. - * - * \retval >0 number of fields of the retrieved row - * \retval 0 no more rows - * \retval -1 error - * - * Errors are stored in context passed to previous glite_jp_db_execstmt() - */ -int glite_jp_db_fetchrow(glite_jp_db_stmt_t, char **); - - -/** - * Retrieve column names of a query statement - * - * \param[inout] stmt statement - * \param[out] cols result set column names. Expects allocated array. - * - * \return 0 if OK, nonzero on error - */ -int glite_jp_db_querycolumns(glite_jp_db_stmt_t, char **); - - -/** - * Free the statement structure and destroy its parameters. - * - * \param[inout] stmt statement - */ -void glite_jp_db_freestmt(glite_jp_db_stmt_t *); - - -/** - * Convert time_t into database-specific time string. - * - * \param[in] t the converted time - * \return XXX: pointer to static area that is changed by subsequent calls - */ -char *glite_jp_db_timetodb(time_t); - - -/** - * Convert database-specific time string into time_t. - * - * \param[in] t the converted string - * - * \return result time - */ -time_t glite_jp_db_dbtotime(const char *); - - -/** - * Check database version. - * - * \param[inout] ctx context to work with - * - * \return JP error code - */ -int glite_jp_db_dbcheckversion(glite_jp_context_t); - - -/** - * Create and assign parameters for mysql prepared commands. - * - * \param[out] params internal structure array - * - * Variable parameters: - * always: - * glite_jp_db_type_t type DB item type - * then one of them: - * GLITE_JP_DB_TYPE_TINYINT: char *buffer - * GLITE_JP_DB_TYPE_INT: int *buffer - * GLITE_JP_DB_TYPE_*BLOB/TEXT: void *buffer, unsigned long *length - * GLITE_JP_DB_TYPE_[VAR]CHAR: char *buffer, unsigned long *length - * GLITE_JP_DB_TYPE_DATE: void **buffer - * GLITE_JP_DB_TYPE_TIME: void **buffer - * GLITE_JP_DB_TYPE_DATETIME: void **buffer - * GLITE_JP_DB_TYPE_TIMESTAMP: void **buffer - * GLITE_JP_DB_TYPE_NULL: - - */ -void glite_jp_db_create_params(void **params, int n, ...); - -/** - * Create and assign result variables for mysql prepared commands. - * - * \param[inout] result mysql bind strusture array - * - * Variable parameters: - * always: - * \param[in] glite_jp_db_type_t type DB item type - * \param[in] int *is_null pointer to is_null boolean or NULL - * then one of them: - * GLITE_JP_DB_TYPE_TINYINT: char *buffer - * GLITE_JP_DB_TYPE_INT: long int *buffer - * GLITE_JP_DB_TYPE_*BLOB/TEXT: void *buffer, unsigned long max_length, unsigned long *length - * GLITE_JP_DB_TYPE_[VAR]CHAR: char *buffer, unsigned long max_length, unsigned long *length - * GLITE_JP_DB_TYPE_DATE: void **buffer - * GLITE_JP_DB_TYPE_TIME: void **buffer - * GLITE_JP_DB_TYPE_DATETIME: void **buffer - * GLITE_JP_DB_TYPE_TIMESTAMP: void **buffer - */ -void glite_jp_db_create_results(void **results, int n, ...); - -/** - * Destroy prepared parameters. - */ -void glite_jp_db_destroy_params(void *params); - -/** - * Destroy prepared results. - */ -void glite_jp_db_destroy_results(void *results); - -#if 0 -void glite_jp_db_assign_param(MYSQL_BIND *param, enum enum_field_types type, ...); -void glite_jp_db_assign_result(MYSQL_BIND *result, enum enum_field_types type, my_bool *is_null, ...); -#endif - -/** - * Assign time_t to buffer. - */ -void glite_jp_db_set_time(void *buffer, const time_t time); - -/** - * Get the time from buffer. - */ -time_t glite_jp_db_get_time(const void *buffer); - -/** - * Rebind the parameters and/or results. - * - * \param[inout] jpstmt JP SQL statement to work with - * \param[inout] params mysql static structure with parameters or NULL - * \param[inout] cols mysql static structure with result buffer or NULL - * - * \return JP error code - */ -int glite_jp_db_rebind(glite_jp_db_stmt_t jpstmt, void *params, void *cols); - -/** - * Prepare the SQL statement. Use glite_jp_db_freestmt() to free it. - * - * \param[inout] ctx context to work with - * \param[in] sql SQL command - * \param[out] jpstmt returned JP SQL statement - * \param[inout] params mysql static structure with parameters or NULL - * \param[inout] cols mysql static structure with result buffer or NULL - * - * \return JP error code - */ -int glite_jp_db_prepare(glite_jp_context_t ctx, const char *sql, glite_jp_db_stmt_t *jpstmt, void *params, void *cols); - -/** - * Execute prepared SQL statement. - * - * \param[inout] jpstmt JP SQL statement - * - * \return number of affected rows, -1 on error - */ -int glite_jp_db_execute(glite_jp_db_stmt_t jpstmt); - -/** - * - * \param[inout] jpstmt JP SQL statement - * - * \return JP error code (ENODATA when no more row are available) - */ -int glite_jp_db_fetch(glite_jp_db_stmt_t jpstmt); - -/** - * - * \param[inout] jpstmt JP SQL statement - * - * \return value of autoincremented field after last insert/update - */ -long int glite_jp_db_lastid(glite_jp_db_stmt_t jpstmt); +int glite_jp_db_SetError(glite_jp_context_t ctx, const char *source); +int glite_jp_db_ExecSQL(glite_jp_context_t ctx, const char *cmd, glite_lbu_Statement *stmt); +int glite_jp_db_FetchRow(glite_jp_context_t ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); +int glite_jp_db_PrepareStmt(glite_jp_context_t ctx, const char *sql, glite_lbu_Statement *stmt); +int glite_jp_db_ExecPreparedStmt(glite_jp_context_t ctx, glite_lbu_Statement stmt, int n,...); +void glite_jp_db_FreeStmt(glite_lbu_Statement *stmt); #ifdef __cplusplus } diff --git a/org.glite.jp.server-common/src/db.c b/org.glite.jp.server-common/src/db.c index e5bf905..285d439 100644 --- a/org.glite.jp.server-common/src/db.c +++ b/org.glite.jp.server-common/src/db.c @@ -1,18 +1,10 @@ #ident "$Header$" -#include -#include -#include - -#include +#include #include #include -#include #include -#include -#include -#include -#include +#include #include "glite/jp/types.h" #include "glite/jp/context.h" @@ -20,655 +12,65 @@ #include "db.h" -#define GLITE_JP_DB_MYSQL_VERSION 40102 - -#if !defined(MYSQL_VERSION_ID) || MYSQL_VERSION_ID < GLITE_JP_DB_MYSQL_VERSION -#error required MySQL version 4.1.2 -#endif - -#define JP_ERR(CTX, CODE, DESC) jp_err((CTX), (CODE), (DESC), __FUNCTION__, __LINE__) -#define MY_ERR(CTX) my_err((CTX), __FUNCTION__, __LINE__) -#define MY_ERRSTMT(JPSTMT) my_errstmt((JPSTMT), __FUNCTION__, __LINE__) -#define MY_ISOKSTMT(JPSTMT, RETRY) my_isokstmt((JPSTMT), __FUNCTION__, __LINE__, (RETRY)) - - -typedef struct { - int n; - MYSQL_BIND params[1]; -} params_t; - -struct _glite_jp_db_stmt_t { - glite_jp_context_t ctx; - MYSQL_RES *result; - MYSQL_STMT *stmt; - params_t *params, *results; -}; - - -static int glite_to_mysql_type[] = { - 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, -}; - - -static int jp_err(glite_jp_context_t ctx, int code, const char *desc, const char *source, int line) -{ - glite_jp_error_t err; - char *fullsource; - int ret; - - asprintf(&fullsource, "%s:%d", source, line); - memset(&err,0,sizeof err); - err.code = code; - err.source = fullsource; - err.desc = desc && desc[0] ? desc : "(error without description)"; - - ret = glite_jp_stack_error(ctx,&err); - free(fullsource); - return ret; -} - - -static int my_err(glite_jp_context_t ctx, const char *source, int line) -{ - return jp_err(ctx, EIO, mysql_error((MYSQL *)ctx->dbhandle), source, line); -} - - -static int my_errstmt(glite_jp_db_stmt_t jpstmt, const char *source, int line) { - return jp_err(jpstmt->ctx, EIO, mysql_stmt_error(jpstmt->stmt), source, line); -} - - -/* - * Error handle. - * - * \return -1 failed - * \return 0 retry - * \return 1 OK - */ -static int my_isokstmt(glite_jp_db_stmt_t jpstmt, const char *source, int line, int *retry) { - switch (mysql_stmt_errno(jpstmt->stmt)) { - case 0: - return 1; - break; - case ER_DUP_ENTRY: - jp_err(jpstmt->ctx, EEXIST, mysql_stmt_error(jpstmt->stmt), source, line); - return -1; - break; - case CR_SERVER_LOST: - if (*retry > 0) { - (*retry)--; - return 0; - } else - jp_err(jpstmt->ctx, EIO, "CR_SERVER_LOST", source, line); - return -1; - break; - default: - my_errstmt(jpstmt, source, line); - return -1; - break; - } -} - - -int glite_jp_db_connect(glite_jp_context_t ctx,const char *cs) -{ - char *buf = NULL; - char *host,*user,*pw,*db; - char *slash,*at,*colon; - int ret; - - // needed for SQL result parameters - assert(sizeof(int) >= sizeof(my_bool)); - - glite_jp_clear_error(ctx); - - if (!cs) return JP_ERR(ctx, EINVAL, "connect string not specified"); - - if (!(ctx->dbhandle = (void *) mysql_init(NULL))) return JP_ERR(ctx, ENOMEM, NULL); - - mysql_options(ctx->dbhandle, MYSQL_READ_DEFAULT_FILE, "my"); - - host = user = pw = db = NULL; - - buf = strdup(cs); - slash = strchr(buf,'/'); - at = strrchr(buf,'@'); - colon = strrchr(buf,':'); - - if (!slash || !at || !colon) { - free(buf); - glite_jp_db_close(ctx); - return JP_ERR(ctx, EINVAL, "Invalid DB connect string"); - } - - *slash = *at = *colon = 0; - host = at+1; - user = buf; - pw = slash+1; - db = colon+1; - - if (!mysql_real_connect((MYSQL *) ctx->dbhandle,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { - free(buf); - ret = MY_ERR(ctx); - glite_jp_db_close(ctx); - return ret; - } - free(buf); +int glite_jp_db_SetError(glite_jp_context_t ctx, const char *source) { + glite_jp_error_t jperr; + char *desc; - if ((ret = glite_jp_db_dbcheckversion(ctx)) != 0) { - glite_jp_db_close(ctx); - return ret; - } - - return 0; -} - - -void glite_jp_db_close(glite_jp_context_t ctx) -{ + memset(&jperr, 0, sizeof jperr); if (ctx->dbhandle) { - mysql_close((MYSQL *) ctx->dbhandle); - ctx->dbhandle = NULL; - } -} - - -int glite_jp_db_execstmt(glite_jp_context_t ctx,const char *txt,glite_jp_db_stmt_t *stmt) -{ - int merr; - int retry_nr = 0; - int do_reconnect = 0; - - glite_jp_clear_error(ctx); - - if (stmt) { - *stmt = NULL; - } - - while (retry_nr == 0 || do_reconnect) { - do_reconnect = 0; - if (mysql_query((MYSQL *) ctx->dbhandle,txt)) { - /* error occured */ - switch (merr = mysql_errno((MYSQL *) ctx->dbhandle)) { - case 0: - break; - case ER_DUP_ENTRY: - JP_ERR(ctx, EEXIST, mysql_error((MYSQL *) ctx->dbhandle)); - return -1; - break; - case CR_SERVER_LOST: - if (retry_nr <= 0) - do_reconnect = 1; - break; - default: - MY_ERR(ctx); - return -1; - break; - } - } - retry_nr++; - } - - if (stmt) { - *stmt = malloc(sizeof(**stmt)); - if (!*stmt) { - JP_ERR(ctx, ENOMEM, NULL); - return -1; - } - memset(*stmt,0,sizeof(**stmt)); - (**stmt).ctx = ctx; - (**stmt).result = mysql_store_result((MYSQL *) ctx->dbhandle); - if (!(**stmt).result) { - if (mysql_errno((MYSQL *) ctx->dbhandle)) { - MY_ERR(ctx); - return -1; - } - } + jperr.code = glite_lbu_DBError(ctx->dbhandle, NULL, &desc); + if (jperr.code && source) jperr.source = source; + jperr.desc = desc; } else { - MYSQL_RES *r = mysql_store_result((MYSQL *) ctx->dbhandle); - mysql_free_result(r); - } - - return mysql_affected_rows((MYSQL *) ctx->dbhandle); -} - - -int glite_jp_db_fetchrow(glite_jp_db_stmt_t stmt,char **res) -{ - MYSQL_ROW row; - glite_jp_context_t ctx = stmt->ctx; - int nr,i; - unsigned long *len; - - glite_jp_clear_error(ctx); - - if (!stmt->result) return 0; - - if (!(row = mysql_fetch_row(stmt->result))) { - if (mysql_errno((MYSQL *) ctx->dbhandle)) { - MY_ERR(ctx); - return -1; - } else return 0; + asprintf(&desc, "DB context isn't created"); + jperr.code = EINVAL; + jperr.desc = desc; + jperr.source = __FUNCTION__; } - - nr = mysql_num_fields(stmt->result); - len = mysql_fetch_lengths(stmt->result); - for (i=0; iresult))) cols[i++] = f->name; - return i == 0; -} - - -void glite_jp_db_freestmt(glite_jp_db_stmt_t *stmt) -{ - if (*stmt) { - if ((**stmt).result) mysql_free_result((**stmt).result); - if ((*stmt)->stmt) mysql_stmt_close((*stmt)->stmt); - if ((*stmt)->params) glite_jp_db_destroy_params((*stmt)->params); - if ((*stmt)->results) glite_jp_db_destroy_results((*stmt)->results); - free(*stmt); - *stmt = NULL; + if (jperr.code) { + glite_jp_stack_error(ctx, &jperr); + free(desc); } -} - - -char *glite_jp_db_timetodb(time_t t) -{ - struct tm *tm = gmtime(&t); - char tbuf[256]; - - /* XXX: the very end of our days */ - if (!tm && t == (time_t) LONG_MAX) return strdup("9999-12-31 23:59:59"); - sprintf(tbuf,"'%4d-%02d-%02d %02d:%02d:%02d'",tm->tm_year+1900,tm->tm_mon+1, - tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); - - return strdup(tbuf); + return jperr.code; } -time_t glite_jp_db_dbtotime(const char *t) -{ - struct tm tm; +int glite_jp_db_ExecSQL(glite_jp_context_t ctx, const char *cmd, glite_lbu_Statement *stmt) { + int num; - memset(&tm,0,sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - sscanf(t,"%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--; + num = glite_lbu_ExecSQL(ctx->dbhandle, cmd, stmt); + if (num < 0) glite_jp_db_SetError(ctx, __FUNCTION__); - return mktime(&tm); + return num; } -int glite_jp_db_dbcheckversion(glite_jp_context_t ctx) -{ - MYSQL *m = (MYSQL *) ctx->dbhandle; - const char *ver_s = mysql_get_server_info(m); - int major,minor,sub,version; - - glite_jp_clear_error(ctx); - - if (!ver_s || 3 != sscanf(ver_s,"%d.%d.%d",&major,&minor,&sub)) { - return JP_ERR(ctx, EINVAL, "problem checking MySQL version"); - } - - version = 10000*major + 100*minor + sub; - - if (version < GLITE_JP_DB_MYSQL_VERSION) { - char msg[300]; +int glite_jp_db_FetchRow(glite_jp_context_t ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) { + int num; - return JP_ERR(ctx, EINVAL, msg); - } - - return 0; + num = glite_lbu_FetchRow(stmt, n, lengths, results); + if (num < 0) glite_jp_db_SetError(ctx, __FUNCTION__); + return num; } -void glite_jp_db_create_params(void **params, int n, ...) { - params_t *myparams; - MYSQL_BIND *myparam; - MYSQL_TIME **mytime; - int i; - va_list ap; - glite_jp_db_type_t type; - - myparams = calloc(n, sizeof(params_t) + (n - 1) * sizeof(MYSQL_BIND)); - va_start(ap, n); - - for (i = 0; i < n; i++) { - myparam = myparams->params + i; - type = va_arg(ap, glite_jp_db_type_t); - - switch (type) { - case GLITE_JP_DB_TYPE_TINYINT: - myparam->buffer = va_arg(ap, char *); - break; - - case GLITE_JP_DB_TYPE_INT: - myparam->buffer = va_arg(ap, long int *); - break; - - case GLITE_JP_DB_TYPE_TINYBLOB: - case GLITE_JP_DB_TYPE_TINYTEXT: - case GLITE_JP_DB_TYPE_BLOB: - case GLITE_JP_DB_TYPE_TEXT: - case GLITE_JP_DB_TYPE_MEDIUMBLOB: - case GLITE_JP_DB_TYPE_MEDIUMTEXT: - case GLITE_JP_DB_TYPE_LONGBLOB: - case GLITE_JP_DB_TYPE_LONGTEXT: - myparam->buffer = va_arg(ap, void *); - myparam->length = va_arg(ap, unsigned long *); - break; - - case GLITE_JP_DB_TYPE_VARCHAR: - case GLITE_JP_DB_TYPE_CHAR: - myparam->buffer = va_arg(ap, char *); - myparam->length = va_arg(ap, unsigned long *); - break; - - case GLITE_JP_DB_TYPE_DATE: - case GLITE_JP_DB_TYPE_TIME: - case GLITE_JP_DB_TYPE_DATETIME: - case GLITE_JP_DB_TYPE_TIMESTAMP: - mytime = (MYSQL_TIME **)va_arg(ap, void **); - *mytime = calloc(1, sizeof(MYSQL_TIME)); - myparam->buffer = *mytime; - break; - - case GLITE_JP_DB_TYPE_NULL: - break; - - default: - assert("unimplemented parameter assign" == NULL); - break; - } - myparam->buffer_type = glite_to_mysql_type[type]; - } - myparams->n = n; - - va_end(ap); - *params = myparams; +int glite_jp_db_PrepareStmt(glite_jp_context_t ctx, const char *sql, glite_lbu_Statement *stmt) { + glite_lbu_PrepareStmt(ctx->dbhandle, sql, stmt); + return glite_jp_db_SetError(ctx, __FUNCTION__); } -void glite_jp_db_create_results(void **results, int n, ...) { - params_t *myresults; - MYSQL_BIND *myresult; - MYSQL_TIME **mytime; +int glite_jp_db_ExecPreparedStmt(glite_jp_context_t ctx, glite_lbu_Statement stmt, int n,...) { va_list ap; - int i; - glite_jp_db_type_t type; - int *is_null; - myresults = calloc(n, sizeof(params_t) + (n - 1) * sizeof(MYSQL_BIND)); va_start(ap, n); - - for (i = 0; i < n; i++) { - myresult = myresults->params + i; - type = va_arg(ap, glite_jp_db_type_t); - is_null = va_arg(ap, int *); - myresult->is_null = (my_bool *)is_null; - if (is_null) *is_null = 0; - - switch(type) { - case GLITE_JP_DB_TYPE_TINYINT: - myresult->buffer = va_arg(ap, char *); - myresult->buffer_length = sizeof(char); - break; - - case GLITE_JP_DB_TYPE_INT: - myresult->buffer = va_arg(ap, long int *); - myresult->buffer_length = sizeof(long int); - break; - - case GLITE_JP_DB_TYPE_TINYBLOB: - case GLITE_JP_DB_TYPE_TINYTEXT: - case GLITE_JP_DB_TYPE_BLOB: - case GLITE_JP_DB_TYPE_TEXT: - case GLITE_JP_DB_TYPE_MEDIUMBLOB: - case GLITE_JP_DB_TYPE_MEDIUMTEXT: - case GLITE_JP_DB_TYPE_LONGBLOB: - case GLITE_JP_DB_TYPE_LONGTEXT: - myresult->buffer = va_arg(ap, void *); - myresult->buffer_length = va_arg(ap, unsigned long); - myresult->length = va_arg(ap, unsigned long *); - break; - - case GLITE_JP_DB_TYPE_VARCHAR: - case GLITE_JP_DB_TYPE_CHAR: - myresult->buffer = va_arg(ap, char *); - myresult->buffer_length = va_arg(ap, unsigned long); - myresult->length = va_arg(ap, unsigned long *); - break; - - case GLITE_JP_DB_TYPE_DATE: - case GLITE_JP_DB_TYPE_TIME: - case GLITE_JP_DB_TYPE_DATETIME: - case GLITE_JP_DB_TYPE_TIMESTAMP: - mytime = (MYSQL_TIME **)va_arg(ap, void **); - *mytime = calloc(1, sizeof(MYSQL_TIME)); - myresult->buffer = *mytime; - break; - - default: - assert("unimplemented result assign" == NULL); - } - myresult->buffer_type = glite_to_mysql_type[type]; - if (myresult->buffer && myresult->buffer_length) memset(myresult->buffer, 0, myresult->buffer_length); - } - myresults->n = n; - + glite_lbu_ExecPreparedStmt_v(stmt, n, ap); va_end(ap); - *results = myresults; -} - - -static void glite_jp_db_destroy_respam(params_t *params) { - MYSQL_BIND *myparam; - int i; - enum enum_field_types type; - - for (i = 0; i < params->n; i++) { - myparam = params->params + i; - type = myparam->buffer_type; - if (type == MYSQL_TYPE_DATE || type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATETIME || type == MYSQL_TYPE_TIMESTAMP) { - free(myparam->buffer); - myparam->buffer = NULL; - } - } - free(params); -} - - -void glite_jp_db_destroy_params(void *params) { - glite_jp_db_destroy_respam(params); -} - - -void glite_jp_db_destroy_results(void *results) { - glite_jp_db_destroy_respam(results); + return glite_jp_db_SetError(ctx, __FUNCTION__); } -void glite_jp_db_set_time(void *buffer, const time_t time) { - MYSQL_TIME *mybuffer; - struct tm tm; - - mybuffer = (MYSQL_TIME *)buffer; - gmtime_r(&time, &tm); - memset(mybuffer, 0, sizeof *mybuffer); - mybuffer->year = tm.tm_year + 1900; - mybuffer->month = tm.tm_mon + 1; - mybuffer->day = tm.tm_mday; - mybuffer->hour = tm.tm_hour; - mybuffer->minute = tm.tm_min; - mybuffer->second = tm.tm_sec; -} - - -time_t glite_jp_db_get_time(const void *buffer) { - MYSQL_TIME *mybuffer; - struct tm tm; - - mybuffer = (MYSQL_TIME *)buffer; - memset(&tm, 0, sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - tm.tm_year = mybuffer->year - 1900; - tm.tm_mon = mybuffer->month - 1; - tm.tm_mday = mybuffer->day; - tm.tm_hour = mybuffer->hour; - tm.tm_min = mybuffer->minute; - tm.tm_sec = mybuffer->second; - - return mktime(&tm); -} - - -int glite_jp_db_rebind(glite_jp_db_stmt_t jpstmt, void *params, void *cols) { - if (jpstmt->params) { - glite_jp_db_destroy_params(jpstmt->params); - jpstmt->params = NULL; - } - if (jpstmt->results) { - glite_jp_db_destroy_results(jpstmt->results); - jpstmt->results = NULL; - } - if (params) { - jpstmt->params = (params_t *)params; - if (mysql_stmt_bind_param(jpstmt->stmt, jpstmt->params->params) != 0) return MY_ERRSTMT(jpstmt); - } - if (cols) { - jpstmt->results = (params_t *)cols; - if (mysql_stmt_bind_result(jpstmt->stmt, jpstmt->results->params) != 0) return MY_ERRSTMT(jpstmt); - } - - return 0; -} - - -int glite_jp_db_prepare(glite_jp_context_t ctx, const char *sql, glite_jp_db_stmt_t *jpstmt, void *params, void *cols) { - int ret, retry; - - glite_jp_clear_error(ctx); - - // init - *jpstmt = calloc(1, sizeof(struct _glite_jp_db_stmt_t)); - (*jpstmt)->ctx = ctx; - - // create the SQL command - if (((*jpstmt)->stmt = mysql_stmt_init((MYSQL *)ctx->dbhandle)) == NULL) { - ret = MY_ERRSTMT(*jpstmt); - goto failed; - } - - // prepare the SQL command - retry = 1; - do { - mysql_stmt_prepare((*jpstmt)->stmt, sql, strlen(sql)); - ret = MY_ISOKSTMT(*jpstmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // parameters and results - if ((ret = glite_jp_db_rebind(*jpstmt, params, cols)) != 0) goto failed; - - return 0; - -failed: - if (params) glite_jp_db_destroy_params(params); - if (cols) glite_jp_db_destroy_params(cols); - glite_jp_db_freestmt(jpstmt); - return ctx->error->code; -} - - -int glite_jp_db_execute(glite_jp_db_stmt_t jpstmt) { - glite_jp_context_t ctx; - int ret, retry; - - ctx = jpstmt->ctx; - glite_jp_clear_error(ctx); - - // run - retry = 1; - do { - mysql_stmt_execute(jpstmt->stmt); - ret = MY_ISOKSTMT(jpstmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // result - mysql_stmt_store_result(jpstmt->stmt); - if (mysql_stmt_errno(jpstmt->stmt)) { - MY_ERRSTMT(jpstmt); - goto failed; - } - - return mysql_stmt_affected_rows(jpstmt->stmt); - -failed: - return -1; -} - - -int glite_jp_db_fetch(glite_jp_db_stmt_t jpstmt) { - int ret, retry; - - glite_jp_clear_error(jpstmt->ctx); - - retry = 1; - do { - switch(mysql_stmt_fetch(jpstmt->stmt)) { - case 0: ret = 1; break; - case 1: ret = MY_ISOKSTMT(jpstmt, &retry); break; - case MYSQL_NO_DATA: JP_ERR(jpstmt->ctx, ENODATA, "no more rows"); ret = -1; break; - default: JP_ERR(jpstmt->ctx, EIO, "other fetch error"); ret = -1; break; - } - } while (ret == 0); - if (ret == -1) goto failed; - - return 0; - -failed: - return jpstmt->ctx->error->code; -} - - -long int glite_jp_db_lastid(glite_jp_db_stmt_t jpstmt) { - my_ulonglong i; - - glite_jp_clear_error(jpstmt->ctx); - i = mysql_stmt_insert_id(jpstmt->stmt); - assert(i < ((unsigned long int)-1) >> 1); - return (long int)i; +void glite_jp_db_FreeStmt(glite_lbu_Statement *stmt) { + glite_lbu_FreeStmt(stmt); } diff --git a/org.glite.lbjp-common.db/interface/db.h b/org.glite.lbjp-common.db/interface/db.h index f968bc2..d4967a2 100644 --- a/org.glite.lbjp-common.db/interface/db.h +++ b/org.glite.lbjp-common.db/interface/db.h @@ -334,6 +334,12 @@ int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...); /** + * "va_list version" of glite_lbu_ExecPreparedStmt(). + */ +int glite_lbu_ExecPreparedStmt_v(glite_lbu_Statement stmt, int n, va_list ap); + + +/** * Returns the last automatically generated id, if any. */ long int glite_lbu_Lastid(glite_lbu_Statement stmt); diff --git a/org.glite.lbjp-common.db/src/db.c b/org.glite.lbjp-common.db/src/db.c index 5624a05..214ee9d 100644 --- a/org.glite.lbjp-common.db/src/db.c +++ b/org.glite.lbjp-common.db/src/db.c @@ -597,9 +597,8 @@ failed: } -int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) { +int glite_lbu_ExecPreparedStmt_v(glite_lbu_Statement stmt, int n, va_list ap) { int i; - va_list ap; glite_lbu_DBType type; char *pchar; long int *plint; @@ -616,7 +615,6 @@ int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) { data = calloc(n, sizeof(void *)); lens = calloc(n, sizeof(unsigned long *)); } - va_start(ap, n); for (i = 0; i < n; i++) { type = va_arg(ap, glite_lbu_DBType); switch (type) { @@ -667,13 +665,13 @@ int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) { } binds[i].buffer_type = glite_type_to_mysql[type]; } - va_end(ap); // bind parameters - if (db_handle.mysql_stmt_bind_param(stmt->stmt, binds) != 0) { - MY_ERRSTMT(stmt); - goto failed; - } + if (n) + if (db_handle.mysql_stmt_bind_param(stmt->stmt, binds) != 0) { + MY_ERRSTMT(stmt); + goto failed; + } // run ctx = stmt->ctx; @@ -693,10 +691,12 @@ int glite_lbu_ExecPreparedStmt(glite_lbu_Statement stmt, int n, ...) { if (ret == -1) goto failed; // free params - for (i = 0; i < n; i++) free(data[i]); - free(data); - free(binds); - free(lens); + if (n) { + for (i = 0; i < n; i++) free(data[i]); + free(data); + free(binds); + free(lens); + } CLR_ERR(ctx); return db_handle.mysql_stmt_affected_rows(stmt->stmt); @@ -709,6 +709,18 @@ failed: } +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; +} + + 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)); -- 1.8.2.3