Module: sip-router Branch: master Commit: 199891c536e357b95b101b623f70527a4f57b70e URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=199891c5...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Sun Sep 14 09:33:44 2014 +0200
db_mongodb: build proper initial result structure
---
modules/db_mongodb/mongodb_connection.h | 11 ++- modules/db_mongodb/mongodb_dbase.c | 202 ++++++++++++++++++++++++++----- 2 files changed, 182 insertions(+), 31 deletions(-)
diff --git a/modules/db_mongodb/mongodb_connection.h b/modules/db_mongodb/mongodb_connection.h index 6b721ad..6a6eaa0 100644 --- a/modules/db_mongodb/mongodb_connection.h +++ b/modules/db_mongodb/mongodb_connection.h @@ -31,10 +31,15 @@
typedef struct km_mongodb_con { struct db_id* id; /*!< Connection identifier */ - unsigned int ref; /*!< Reference count */ - struct pool_con* next; /*!< Next connection in the pool */ + unsigned int ref; /*!< Reference count */ + struct pool_con* next; /*!< Next connection in the pool */
- mongoc_client_t *con; /*!< Connection representation */ + mongoc_client_t *con; /*!< Connection representation */ + mongoc_collection_t *collection; /*!< Collection link */ + mongoc_cursor_t *cursor; /*!< Cursor link */ + + bson_t *colsdoc; /*!< Names of columns */ + int nrcols; /*!< Nunmber of columns */ } km_mongodb_con_t;
#define MONGODB_CON(db_con) ((km_mongodb_con_t*)((db_con)->tail)) diff --git a/modules/db_mongodb/mongodb_dbase.c b/modules/db_mongodb/mongodb_dbase.c index 03f875f..a15e5ee 100644 --- a/modules/db_mongodb/mongodb_dbase.c +++ b/modules/db_mongodb/mongodb_dbase.c @@ -27,6 +27,14 @@ #include "mongodb_connection.h" #include "mongodb_dbase.h"
+typedef struct db_mongodb_result { + mongoc_collection_t *collection; /*!< Collection link */ + mongoc_cursor_t *cursor; /*!< Cursor link */ + bson_t *rdoc; + int idx; + bson_t *colsdoc; + int nrcols; +} db_mongodb_result_t;
/* * Initialize database module @@ -139,14 +147,77 @@ int db_mongodb_bson_add(bson_t *doc, int vtype, const db_key_t _k, const db_val_ error: return -1; } + +db1_res_t* db_mongodb_new_result(void) +{ + db1_res_t* obj; + + obj = db_new_result(); + if (!obj) + return NULL; + RES_PTR(obj) = pkg_malloc(sizeof(db_mongodb_result_t)); + if (!RES_PTR(obj)) { + db_free_result(obj); + return NULL; + } + memset(RES_PTR(obj), 0, sizeof(db_mongodb_result_t)); + return obj; +} /* * Retrieve result set */ static int db_mongodb_store_result(const db1_con_t* _h, db1_res_t** _r) { - if(_r) *_r = NULL; + km_mongodb_con_t *mgcon; + db_mongodb_result_t *mgres; + const bson_t *itdoc; + char *jstr; + + mgcon = MONGODB_CON(_h); + if(!_r) { + LM_ERR("invalid result parameter\n"); + return -1; + }
+ *_r = db_mongodb_new_result(); + if (!*_r) { + LM_ERR("no memory left for result \n"); + goto error; + } + mgres = (db_mongodb_result_t*)RES_PTR(*_r); + mgres->collection = mgcon->collection; + mgcon->collection = NULL; + mgres->cursor = mgcon->cursor; + mgcon->cursor = NULL; + mgres->colsdoc = mgcon->colsdoc; + mgcon->colsdoc = NULL; + mgres->nrcols = mgcon->nrcols; + mgcon->nrcols = 0; + while (mongoc_cursor_more (mgres->cursor) + && mongoc_cursor_next (mgres->cursor, &itdoc)) { + if(is_printable(L_DBG)) { + jstr = bson_as_json (itdoc, NULL); + LM_DBG("selected document: %s\n", jstr); + bson_free (jstr); + } + } return 0; + +error: + if(mgcon->colsdoc) { + bson_destroy (mgcon->colsdoc); + mgcon->colsdoc = NULL; + } + mgcon->nrcols = 0; + if(mgcon->cursor) { + mongoc_cursor_destroy (mgcon->cursor); + mgcon->cursor = NULL; + } + if(mgcon->collection) { + mongoc_collection_destroy (mgcon->collection); + mgcon->collection = NULL; + } + return -1; }
/* @@ -154,6 +225,29 @@ static int db_mongodb_store_result(const db1_con_t* _h, db1_res_t** _r) */ int db_mongodb_free_result(db1_con_t* _h, db1_res_t* _r) { + if(!_r) + return -1; + if(RES_PTR(_r)) { + if(((db_mongodb_result_t*)RES_PTR(_r))->rdoc) { + bson_destroy(((db_mongodb_result_t*)RES_PTR(_r))->rdoc); + ((db_mongodb_result_t*)RES_PTR(_r))->rdoc = NULL; + } + if(((db_mongodb_result_t*)RES_PTR(_r))->colsdoc) { + bson_destroy (((db_mongodb_result_t*)RES_PTR(_r))->colsdoc); + ((db_mongodb_result_t*)RES_PTR(_r))->colsdoc = NULL; + } + ((db_mongodb_result_t*)RES_PTR(_r))->nrcols = 0; + if(((db_mongodb_result_t*)RES_PTR(_r))->cursor) { + mongoc_cursor_destroy (((db_mongodb_result_t*)RES_PTR(_r))->cursor); + ((db_mongodb_result_t*)RES_PTR(_r))->cursor = NULL; + } + if(((db_mongodb_result_t*)RES_PTR(_r))->collection) { + mongoc_collection_destroy (((db_mongodb_result_t*)RES_PTR(_r))->collection); + ((db_mongodb_result_t*)RES_PTR(_r))->collection = NULL; + } + pkg_free(RES_PTR(_r)); + } + db_free_result(_r); return 0; }
@@ -175,10 +269,7 @@ int db_mongodb_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op int i; km_mongodb_con_t *mgcon; mongoc_client_t *client; - mongoc_collection_t *collection = NULL; - bson_t *doc = NULL; - const bson_t *itdoc; - mongoc_cursor_t *cursor = NULL; + bson_t *seldoc = NULL; char *cname; char b1; char *jstr; @@ -188,57 +279,112 @@ int db_mongodb_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op LM_ERR("connection to server is null\n"); return -1; } + if(mgcon->collection) { + mongoc_collection_destroy (mgcon->collection); + mgcon->collection = NULL; + } + if(mgcon->cursor) { + mongoc_cursor_destroy (mgcon->cursor); + mgcon->cursor = NULL; + } + if(mgcon->colsdoc) { + bson_destroy (mgcon->colsdoc); + mgcon->colsdoc = NULL; + } + mgcon->nrcols = 0; client = mgcon->con; if(CON_TABLE(_h)->s==NULL) { LM_ERR("collection (table) name not set\n"); return -1; } + + if(_r) *_r = NULL; + b1 = '\0'; if(CON_TABLE(_h)->s[CON_TABLE(_h)->len]!='\0') { b1 = CON_TABLE(_h)->s[CON_TABLE(_h)->len]; CON_TABLE(_h)->s[CON_TABLE(_h)->len] = '\0'; } cname = CON_TABLE(_h)->s; - collection = mongoc_client_get_collection(client, mgcon->id->database, cname); - if(collection==NULL) { + LM_DBG("query to collection [%s]\n", cname); + mgcon->collection = mongoc_client_get_collection(client, mgcon->id->database, cname); + if(mgcon->collection==NULL) { LM_ERR("cannot get collection (table): %s\n", cname); if(b1 != '\0') CON_TABLE(_h)->s[CON_TABLE(_h)->len] = b1; return -1; } if(b1 != '\0') CON_TABLE(_h)->s[CON_TABLE(_h)->len] = b1;
- doc = bson_new(); - if(doc==NULL) { - LM_ERR("cannot initialize bson document\n"); + seldoc = bson_new(); + if(seldoc==NULL) { + LM_ERR("cannot initialize query bson document\n"); goto error; }
for(i = 0; i < _n; i++) { - if(db_mongodb_bson_add(doc, VAL_TYPE(_v + i), _k[i], _v+i, i)<0) + if(db_mongodb_bson_add(seldoc, VAL_TYPE(_v + i), _k[i], _v+i, i)<0) goto error; } - - cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, - doc, NULL, NULL); - while (mongoc_cursor_more (cursor) && mongoc_cursor_next (cursor, &itdoc)) { - jstr = bson_as_json (itdoc, NULL); - LM_DBG("selected document: %s\n", jstr); - if(db_mongodb_store_result(_h, _r)<0) { - LM_ERR("failed to store result\n"); - bson_free (jstr); + if(is_printable(L_DBG)) { + jstr = bson_as_json (seldoc, NULL); + LM_DBG("query filter: %s\n", jstr); + bson_free (jstr); + } + if(_nc > 0) { + mgcon->colsdoc = bson_new(); + if(mgcon->colsdoc==NULL) { + LM_ERR("cannot initialize columns bson document\n"); goto error; } - bson_free (jstr); + for(i = 0; i < _n; i++) { + if(!bson_append_int32(mgcon->colsdoc, _c[i]->s, _c[i]->len, 1)) + { + LM_ERR("failed to append int to columns bson %.*s = %d [%d]\n", + _c[i]->len, _c[i]->s, 1, i); + goto error; + } + } + if(is_printable(L_DBG)) { + jstr = bson_as_json (mgcon->colsdoc, NULL); + LM_DBG("query filter: %s\n", jstr); + bson_free (jstr); + } + mgcon->nrcols = _nc; } - mongoc_cursor_destroy (cursor); - bson_destroy (doc); - mongoc_collection_destroy (collection); - + mgcon->cursor = mongoc_collection_find (mgcon->collection, + MONGOC_QUERY_NONE, 0, 0, 0, + seldoc, mgcon->colsdoc, NULL); + + if(!_r) { + goto done; + } + + if(db_mongodb_store_result(_h, _r)<0) { + LM_ERR("failed to store result\n"); + goto error; + } + +done: + bson_destroy (seldoc); return 0; + error: - if(cursor) mongoc_cursor_destroy (cursor); - if(doc) bson_destroy (doc); - if(collection) mongoc_collection_destroy (collection); + LM_ERR("failed to do the query\n"); + if(seldoc) bson_destroy (seldoc); + if(mgcon->colsdoc) { + bson_destroy (mgcon->colsdoc); + mgcon->colsdoc = NULL; + } + mgcon->nrcols = 0; + if(mgcon->collection) { + mongoc_collection_destroy (mgcon->collection); + mgcon->collection = NULL; + } + if(mgcon->cursor) { + mongoc_cursor_destroy (mgcon->cursor); + mgcon->cursor = NULL; + } + if(_r && *_r) { db_mongodb_free_result((db1_con_t*)_h, *_r); *_r = NULL; } return -1; }