src/evsql/evsql.c
branchnew-evsql
changeset 45 424ce5ab82fd
parent 44 9e76ee9729b6
child 47 8c6c459eacb7
--- a/src/evsql/evsql.c	Thu Nov 20 01:16:24 2008 +0200
+++ b/src/evsql/evsql.c	Fri Nov 28 23:46:11 2008 +0200
@@ -63,12 +63,7 @@
     return err;
 }
 
-/*
- * Free the query and related resources, doesn't trigger any callbacks or remove from any queues.
- *
- * The command should already be taken care of (NULL).
- */
-static void _evsql_query_free (struct evsql_query *query) {
+void _evsql_query_free (struct evsql_query *query) {
     if (!query)
         return;
         
@@ -89,13 +84,17 @@
  *
  * The query has been aborted, it will simply be freed
  */
-static void _evsql_query_done (struct evsql_query *query, const struct evsql_result_info *res) {
+static void _evsql_query_done (struct evsql_query *query, struct evsql_result *res) {
     if (res) {
         if (query->cb_fn)
             // call the callback
             query->cb_fn(res, query->cb_arg);
-        else
+        else {
             WARNING("supressing cb_fn because query was aborted");
+            
+            // free the results
+            evsql_result_free(res);
+        }
     }
 
     // free
@@ -105,7 +104,7 @@
 /*
  * XXX:
  * /
-static void _evsql_destroy (struct evsql *evsql, const struct evsql_result_info *res) {
+static void _evsql_destroy (struct evsql *evsql, const struct evsql_result *res) {
     struct evsql_query *query;
     
     // clear the queue
@@ -184,11 +183,10 @@
  * NOTE: Only for *TRANSACTIONLESS* queries.
  */
 static void _evsql_query_fail (struct evsql* evsql, struct evsql_query *query) {
-    struct evsql_result_info res; ZINIT(res);
+    struct evsql_result res; ZINIT(res);
     
     // set up the result_info
     res.evsql = evsql;
-    res.trans = NULL;
     res.error = 1;
     
     // finish off the query
@@ -303,23 +301,23 @@
 /*
  * Callback for a trans's 'BEGIN' query, which means the transaction is now ready for use.
  */
-static void _evsql_trans_ready (const struct evsql_result_info *res, void *arg) {
-    (void) arg;
+static void _evsql_trans_ready (struct evsql_result *res, void *arg) {
+    struct evsql_trans *trans = arg;
 
-    assert(res->trans);
+    assert(trans != NULL);
 
     // check for errors
     if (res->error)
         ERROR("transaction 'BEGIN' failed: %s", evsql_result_error(res));
     
     // transaction is now ready for use
-    res->trans->ready_fn(res->trans, res->trans->cb_arg);
+    trans->ready_fn(trans, trans->cb_arg);
     
     // good
     return;
 
 error:
-    _evsql_trans_fail(res->trans);
+    _evsql_trans_fail(trans);
 }
 
 /*
@@ -364,7 +362,7 @@
         ERROR("trans_sql overflow: %d >= %d", ret, EVSQL_QUERY_BEGIN_BUF);
     
     // execute the query
-    if (evsql_query(evsql, trans, trans_sql, _evsql_trans_ready, NULL) == NULL)
+    if (evsql_query(evsql, trans, trans_sql, _evsql_trans_ready, trans) == NULL)
         ERROR("evsql_query");
     
     // success
@@ -403,14 +401,14 @@
     assert(query != NULL);
 
     // if we get multiple results, only return the first one
-    if (query->result.evpq) {
+    if (query->result.pq) {
         WARNING("[evsql] evpq query returned multiple results, discarding previous one");
         
-        PQclear(query->result.evpq); query->result.evpq = NULL;
+        PQclear(query->result.pq); query->result.pq = NULL;
     }
     
     // remember the result
-    query->result.evpq = result;
+    query->result.pq = result;
 }
 
 /*
@@ -419,28 +417,27 @@
 static void _evsql_evpq_done (struct evpq_conn *_conn, void *arg) {
     struct evsql_conn *conn = arg;
     struct evsql_query *query = conn->query;
-    struct evsql_result_info res; ZINIT(res);
+    struct evsql_result res; ZINIT(res);
     
     assert(query != NULL);
     
     // set up the result_info
     res.evsql = conn->evsql;
-    res.trans = conn->trans;
+    res.result = query->result;
     
-    if (query->result.evpq == NULL) {
+    if (query->result.pq == NULL) {
         // if a query didn't return any results (bug?), warn and fail the query
         WARNING("[evsql] evpq query didn't return any results");
 
         res.error = 1;
     
-    } else if (strcmp(PQresultErrorMessage(query->result.evpq), "") != 0) {
+    } else if (strcmp(PQresultErrorMessage(query->result.pq), "") != 0) {
         // the query failed with some error
         res.error = 1;
-        res.result.pq = query->result.evpq;
 
     } else {
+        // the query succeeded \o/
         res.error = 0;
-        res.result.pq = query->result.evpq;
 
     }
 
@@ -733,7 +730,7 @@
 /*
  * Internal query functions
  */
-static struct evsql_query *_evsql_query_new (struct evsql *evsql, struct evsql_trans *trans, evsql_query_cb query_fn, void *cb_arg) {
+struct evsql_query *_evsql_query_new (struct evsql *evsql, struct evsql_trans *trans, evsql_query_cb query_fn, void *cb_arg) {
     struct evsql_query *query = NULL;
     
     // if it's part of a trans, then make sure the trans is idle
@@ -755,7 +752,7 @@
     return NULL;
 }
 
-static int _evsql_query_enqueue (struct evsql *evsql, struct evsql_trans *trans, struct evsql_query *query, const char *command) {
+int _evsql_query_enqueue (struct evsql *evsql, struct evsql_trans *trans, struct evsql_query *query, const char *command) {
     // transaction queries are handled differently
     if (trans) {
         // it's an in-transaction query
@@ -813,26 +810,24 @@
 }
 
 
-void _evsql_trans_commit_res (const struct evsql_result_info *res, void *arg) {
-    (void) arg;
-
-    assert(res->trans);
+void _evsql_trans_commit_res (struct evsql_result *res, void *arg) {
+    struct evsql_trans *trans = arg;
 
     // check for errors
     if (res->error)
         ERROR("transaction 'COMMIT' failed: %s", evsql_result_error(res));
     
     // transaction is now done
-    res->trans->done_fn(res->trans, res->trans->cb_arg);
+    trans->done_fn(trans, trans->cb_arg);
     
     // release it
-    _evsql_trans_release(res->trans);
+    _evsql_trans_release(trans);
 
     // success
     return;
 
 error:
-    _evsql_trans_fail(res->trans);
+    _evsql_trans_fail(trans);
 }
 
 int evsql_trans_commit (struct evsql_trans *trans) {
@@ -855,37 +850,35 @@
     return -1;
 }
 
-void _evsql_trans_rollback_res (const struct evsql_result_info *res, void *arg) {
-    (void) arg;
-
-    assert(res->trans);
+void _evsql_trans_rollback_res (struct evsql_result *res, void *arg) {
+    struct evsql_trans *trans = arg;
 
     // fail the connection on errors
     if (res->error)
         ERROR("transaction 'ROLLBACK' failed: %s", evsql_result_error(res));
 
     // release it
-    _evsql_trans_release(res->trans);
+    _evsql_trans_release(trans);
 
     // success
     return;
 
 error:
     // fail the connection too, errors are supressed
-    _evsql_trans_fail(res->trans);
+    _evsql_trans_fail(trans);
 }
 
 /*
  * Used as the ready_fn callback in case of abort, otherwise directly
  */
-void _evsql_trans_rollback (struct evsql_trans *trans, void *unused) {
+void _evsql_trans_rollback (struct evsql_trans *trans, void *arg) {
     static const char *sql = "ROLLBACK TRANSACTION";
 
-    (void) unused;
+    (void) arg;
 
     // query
-    if (evsql_query(trans->evsql, trans, sql, _evsql_trans_rollback_res, NULL) == NULL) {
-        // fail the transaction/connection
+    if (evsql_query(trans->evsql, trans, sql, _evsql_trans_rollback_res, trans) == NULL) {
+        // fail the transaction/connection, errors are supressed
         _evsql_trans_fail(trans);
     }
 
@@ -904,7 +897,7 @@
         // gah, some query is running
         WARNING("aborting pending query");
         
-        // prepare to rollback once complete
+        // prepare to rollback once complete by hijacking ready_fn
         trans->ready_fn = _evsql_trans_rollback;
         
         // abort