--- a/src/evsql_test.c Fri Nov 28 23:46:11 2008 +0200
+++ b/src/evsql_test.c Sat Nov 29 00:39:47 2008 +0200
@@ -5,13 +5,44 @@
#include "lib/misc.h"
#include <event2/event.h>
+#include <event2/event_struct.h>
#include <assert.h>
#define CONNINFO_DEFAULT "dbname=dbfs port=5433"
+struct evsql_test_ctx {
+ struct evsql *db;
+ struct evsql_trans *trans;
+};
+
+// forward-declare
+void query_send (struct evsql *db, struct evsql_trans *trans);
+
+
+void query_timer (int fd, short what, void *arg) {
+ struct evsql *db = arg;
+
+ INFO("[evsql_test.timer] *tick*");
+
+ query_send(db, NULL);
+}
+
+void query_start (struct event_base *base, struct evsql *db) {
+ static struct event ev;
+ struct timeval tv = { 5, 0 };
+
+ evperiodic_assign(&ev, base, &tv, &query_timer, db);
+ event_add(&ev, &tv);
+
+ INFO("[evsql_test.timer_start] started timer");
+}
+
void query_results (struct evsql_result *result, void *arg) {
+ struct evsql *db = arg;
uint32_t val;
+ (void) db;
+
static struct evsql_result_info result_info = {
0, {
{ EVSQL_FMT_BINARY, EVSQL_TYPE_UINT32 },
@@ -48,80 +79,143 @@
};
// query
- assert((query = evsql_query_exec(db, trans, &query_info, query_results, NULL,
+ if ((query = evsql_query_exec(db, trans, &query_info, query_results, db,
(uint32_t) ++query_id
- )) != NULL);
+ )) == NULL)
+ WARNING("evsql_query_exec failed");
INFO("[evsql_test.query_send] enqueued query, trans=%p: %p: %d", trans, query, query_id);
}
+void trans_insert_result (struct evsql_result *res, void *arg) {
+ struct evsql_test_ctx *ctx = arg;
+ err_t err;
+
+ // the result info
+ uint32_t id;
+ const char *str;
+
+ static struct evsql_result_info result_info = {
+ 0, {
+ { EVSQL_FMT_BINARY, EVSQL_TYPE_UINT32 },
+ { EVSQL_FMT_BINARY, EVSQL_TYPE_STRING },
+ { 0, 0 }
+ }
+ };
+
+ // begin
+ if ((err = evsql_result_begin(&result_info, res)))
+ EFATAL(err, "query failed%s", err == EIO ? evsql_result_error(res) : "");
+
+ INFO("[evsql_test.insert] got %zu rows:", evsql_result_rows(res));
+
+ // iterate over rows
+ while ((err = evsql_result_next(res, &id, &str)) > 0) {
+ INFO("\t%-4lu %s", (unsigned long) id, str);
+ }
+
+ if (err)
+ EFATAL(err, "evsql_result_next failed");
+
+ INFO("\t(done)");
+
+ // done
+ evsql_result_end(res);
+}
+
+void trans_insert (struct evsql_test_ctx *ctx) {
+ struct evsql_query *query = NULL;
+
+ // the query info
+ static struct evsql_query_info query_info = {
+ .sql = "INSERT INTO evsql_test (str) VALUES ($1::varchar), ($2::varchar) RETURNING id, str",
+
+ .params = {
+ { EVSQL_FMT_BINARY, EVSQL_TYPE_STRING },
+ { EVSQL_FMT_BINARY, EVSQL_TYPE_STRING },
+ { 0, 0 }
+ }
+ };
+
+ // run the query
+ assert((query = evsql_query_exec(ctx->db, ctx->trans, &query_info, trans_insert_result, ctx,
+ (const char *) "row A",
+ (const char *) "row B"
+ )) != NULL);
+
+ INFO("[evsql_test.insert] enqueued query: %p", query);
+}
+
void trans_create_result (struct evsql_result *res, void *arg) {
+ struct evsql_test_ctx *ctx = arg;
+
// check
if (evsql_result_check(res))
FATAL("query failed: %s", evsql_result_error(res));
INFO("[evsql_test.create_result] table created succesfully: %p", res);
- // free
+ // free result
evsql_result_free(res);
+
+ // insert
+ trans_insert(ctx);
}
-void trans_create_query (struct evsql *db, struct evsql_trans *trans) {
+void trans_create_query (struct evsql_test_ctx *ctx) {
struct evsql_query *query = NULL;
// the query info
static struct evsql_query_info query_info = {
- .sql = "CREATE TEMPORARY TABLE evsql_test ( id serial4, str varchar(32) DEFAULT $1::varchar ) ON COMMIT DROP",
+ .sql = "CREATE TEMPORARY TABLE evsql_test ( id serial4, str varchar(32) DEFAULT 'foobar' ) ON COMMIT DROP",
.params = {
- { EVSQL_FMT_BINARY, EVSQL_TYPE_STRING },
+// { EVSQL_FMT_BINARY, EVSQL_TYPE_STRING },
{ 0, 0, }
}
};
// run the query
- assert((query = evsql_query_exec(db, trans, &query_info, trans_create_result, NULL,
- (const char *) "foobar"
+ assert((query = evsql_query_exec(ctx->db, ctx->trans, &query_info, trans_create_result, ctx
+// (const char *) "foobar"
)) != NULL);
INFO("[evsql_test.trans_create_query] enqueued query: %p", query);
}
void trans_error (struct evsql_trans *trans, void *arg) {
- struct evsql *db = arg;
+ struct evsql_test_ctx *ctx = arg;
FATAL("[evsql_test.trans_error] failure: %s", evsql_trans_error(trans));
}
void trans_ready (struct evsql_trans *trans, void *arg) {
- struct evsql *db = arg;
+ struct evsql_test_ctx *ctx = arg;
INFO("[evsql_test.trans_ready] ready");
- trans_create_query(db, trans);
+ trans_create_query(ctx);
}
void trans_done (struct evsql_trans *trans, void *arg) {
- struct evsql *db = arg;
+ struct evsql_test_ctx *ctx = arg;
INFO("[evsql_test.trans_done] done");
}
-void begin_transaction (struct evsql *db) {
- struct evsql_trans *trans;
-
- assert((trans = evsql_trans(db, EVSQL_TRANS_DEFAULT,
+void begin_transaction (struct evsql_test_ctx *ctx) {
+ assert((ctx->trans = evsql_trans(ctx->db, EVSQL_TRANS_DEFAULT,
&trans_error, &trans_ready, &trans_done,
- db
+ ctx
)) != NULL);
INFO("[evsql_test.begin_trans] created transaction");
}
int main (int argc, char **argv) {
+ struct evsql_test_ctx ctx;
struct event_base *ev_base = NULL;
struct signals *signals = NULL;
- struct evsql *db = NULL;
const char *db_conninfo;
@@ -137,20 +231,23 @@
ERROR("signals_default");
// setup evsql
- if ((db = evsql_new_pq(ev_base, db_conninfo, NULL, NULL)) == NULL)
+ if ((ctx.db = evsql_new_pq(ev_base, db_conninfo, NULL, NULL)) == NULL)
ERROR("evsql_new_pq");
// send query
- query_send(db, NULL);
+ query_send(ctx.db, NULL);
// being transaction
- begin_transaction(db);
+ begin_transaction(&ctx);
// send query
- query_send(db, NULL);
+ query_send(ctx.db, NULL);
+
+ // start query timer
+ query_start(ev_base, ctx.db);
// run libevent
- INFO("running libevent loop");
+ INFO("[evsql_test.main] running libevent loop");
if (event_base_dispatch(ev_base))
PERROR("event_base_dispatch");
@@ -158,7 +255,7 @@
// clean shutdown
error :
- if (db) {
+ if (ctx.db) {
/* evsql_close(db); */
}