-/*
+/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ * Copyright (C) 2005-2013, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Tamas Cseke <cstomi.levlist@gmail.com>
*
* mod_mongo.cpp -- API for MongoDB
switch_assert(ns != NULL);
if ((json_query = strchr(ns, DELIMITER))) {
- *json_query++ = '\0';
+ *json_query++ = '\0';
}
if (!zstr(ns) && !zstr(json_query)) {
conn->runCommand(conn->nsGetDB(ns), cmd.done(), out);
mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE);
- stream->write_function(stream, "-OK\n%s\n", out.toString().c_str());
+ stream->write_function(stream, "-OK\n%s\n", out.jsonString().c_str());
} else {
stream->write_function(stream, "-ERR\nNo connection\n");
}
stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str());
}
} else {
- stream->write_function(stream, "-ERR\n%s\n", MAPREDUCE_SYNTAX);
+ stream->write_function(stream, "-ERR\n%s\n", MAPREDUCE_SYNTAX);
}
switch_safe_free(ns);
SWITCH_STANDARD_API(mongo_find_one_function)
{
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *ns = NULL, *json_query = NULL, *json_fields = NULL;
-
- ns = strdup(cmd);
- switch_assert(ns != NULL);
-
- if ((json_query = strchr(ns, DELIMITER))) {
- *json_query++ = '\0';
- if ((json_fields = strchr(json_query, DELIMITER))) {
- *json_fields++ = '\0';
- }
- }
-
- if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) {
-
- DBClientBase *conn = NULL;
-
- try {
- BSONObj query = fromjson(json_query);
- BSONObj fields = fromjson(json_fields);
-
- conn = mongo_connection_pool_get(globals.conn_pool);
- if (conn) {
- BSONObj res = conn->findOne(ns, Query(query), &fields);
- mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE);
-
- stream->write_function(stream, "-OK\n%s\n", res.toString().c_str());
- } else {
- stream->write_function(stream, "-ERR\nNo connection\n");
- }
- } catch (DBException &e) {
- if (conn) {
- mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_TRUE);
- }
- stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str());
- }
-
- } else {
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ char *ns = NULL, *json_query = NULL, *json_fields = NULL;
+
+ ns = strdup(cmd);
+ switch_assert(ns != NULL);
+
+ if ((json_query = strchr(ns, DELIMITER))) {
+ *json_query++ = '\0';
+ if ((json_fields = strchr(json_query, DELIMITER))) {
+ *json_fields++ = '\0';
+ }
+ }
+
+ if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) {
+
+ DBClientBase *conn = NULL;
+
+ try {
+ BSONObj query = fromjson(json_query);
+ BSONObj fields = fromjson(json_fields);
+
+ conn = mongo_connection_pool_get(globals.conn_pool);
+ if (conn) {
+ BSONObj res = conn->findOne(ns, Query(query), &fields);
+ mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE);
+
+ stream->write_function(stream, "-OK\n%s\n", res.jsonString().c_str());
+ } else {
+ stream->write_function(stream, "-ERR\nNo connection\n");
+ }
+ } catch (DBException &e) {
+ if (conn) {
+ mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_TRUE);
+ }
+ stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str());
+ }
+
+ } else {
stream->write_function(stream, "-ERR\n%s\n", FIND_ONE_SYNTAX);
- }
+ }
- switch_safe_free(ns);
+ switch_safe_free(ns);
- return status;
+ return status;
}
static switch_status_t config(void)
SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load)
{
- switch_api_interface_t *api_interface;
- switch_application_interface_t *app_interface;
+ switch_api_interface_t *api_interface;
+ switch_application_interface_t *app_interface;
+
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ memset(&globals, 0, sizeof(globals));
- memset(&globals, 0, sizeof(globals));
+ if (config() != SWITCH_STATUS_SUCCESS) {
+ return SWITCH_STATUS_TERM;
+ }
- if (config() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_TERM;
- }
-
- SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX);
- SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX);
+ SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX);
+ SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX);
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown)
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
+ * Copyright (C) 2005-2013, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
switch_status_t mongo_connection_create(DBClientBase **connection, const char *conn_str)
{
- DBClientBase *conn = NULL;
- string conn_string(conn_str), err_msg;
- ConnectionString cs = ConnectionString::parse(conn_string, err_msg);
- switch_status_t status = SWITCH_STATUS_FALSE;
-
- if (!cs.isValid()) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str());
- return status;
- }
-
- try {
- conn = cs.connect(err_msg);
- } catch (DBException &e) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str());
- return status;
- }
-
- if (conn) {
- *connection = conn;
- status = SWITCH_STATUS_SUCCESS;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str);
- }
-
- return status;
+ DBClientBase *conn = NULL;
+ string conn_string(conn_str), err_msg;
+ ConnectionString cs = ConnectionString::parse(conn_string, err_msg);
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (!cs.isValid()) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str());
+ return status;
+ }
+
+ try {
+ conn = cs.connect(err_msg);
+ } catch (DBException &e) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str());
+ return status;
+ }
+
+ if (conn) {
+ *connection = conn;
+ status = SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str);
+ }
+
+ return status;
}
void mongo_connection_destroy(DBClientBase **conn)
{
- switch_assert(*conn != NULL);
- delete *conn;
+ switch_assert(*conn != NULL);
+ delete *conn;
- *conn = NULL;
+ *conn = NULL;
}
switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections,
- const char *conn_str)
+ const char *conn_str)
{
- switch_memory_pool_t *pool = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- mongo_connection_pool_t *cpool = NULL;
- DBClientBase *conn = NULL;
-
- if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
-
- if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) {
- switch_goto_status(SWITCH_STATUS_MEMERR, done);
- }
-
- if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) {
- goto done;
- }
-
- if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) {
- goto done;
- }
-
- cpool->min_connections = min_connections;
- cpool->max_connections = max_connections;
- cpool->conn_str = switch_core_strdup(pool, conn_str);
-
- cpool->pool = pool;
-
- for (cpool->size = 0; cpool->size < min_connections; cpool->size++) {
-
- if (mongo_connection_create(&conn, conn_str) == SWITCH_STATUS_SUCCESS) {
- mongo_connection_pool_put(cpool, conn, SWITCH_FALSE);
- } else {
- break;
- }
- }
+ switch_memory_pool_t *pool = NULL;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ mongo_connection_pool_t *cpool = NULL;
+ DBClientBase *conn = NULL;
+
+ if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
+ return status;
+ }
+
+ if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) {
+ switch_goto_status(SWITCH_STATUS_MEMERR, done);
+ }
+
+ if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
+
+ if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
+
+ cpool->min_connections = min_connections;
+ cpool->max_connections = max_connections;
+ cpool->conn_str = switch_core_strdup(pool, conn_str);
+ cpool->pool = pool;
+
+ for (cpool->size = 0; cpool->size < min_connections; cpool->size++) {
+
+ if (mongo_connection_create(&conn, conn_str) == SWITCH_STATUS_SUCCESS) {
+ mongo_connection_pool_put(cpool, conn, SWITCH_FALSE);
+ } else {
+ break;
+ }
+ }
done:
- if (status == SWITCH_STATUS_SUCCESS) {
- *conn_pool = cpool;
- } else {
- switch_core_destroy_memory_pool(&pool);
- }
+ if (status == SWITCH_STATUS_SUCCESS) {
+ *conn_pool = cpool;
+ } else {
+ switch_core_destroy_memory_pool(&pool);
+ }
- return status;
+ return status;
}
void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool)
{
- mongo_connection_pool_t *cpool = *conn_pool;
- void *data = NULL;
+ mongo_connection_pool_t *cpool = *conn_pool;
+ void *data = NULL;
- switch_assert(cpool != NULL);
+ switch_assert(cpool != NULL);
- while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) {
- mongo_connection_destroy((DBClientBase **)&data);
- }
+ while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) {
+ mongo_connection_destroy((DBClientBase **)&data);
+ }
- switch_mutex_destroy(cpool->mutex);
- switch_core_destroy_memory_pool(&cpool->pool);
+ switch_mutex_destroy(cpool->mutex);
+ switch_core_destroy_memory_pool(&cpool->pool);
- *conn_pool = NULL;
+ *conn_pool = NULL;
}
DBClientBase *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool)
{
- DBClientBase *conn = NULL;
- void *data = NULL;
+ DBClientBase *conn = NULL;
+ void *data = NULL;
- switch_assert(conn_pool != NULL);
+ switch_assert(conn_pool != NULL);
- switch_mutex_lock(conn_pool->mutex);
+ switch_mutex_lock(conn_pool->mutex);
- if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) {
- conn = (DBClientBase *) data;
- } else if (mongo_connection_create(&conn, conn_pool->conn_str) == SWITCH_STATUS_SUCCESS) {
- if (++conn_pool->size > conn_pool->max_connections) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n");
- }
- }
+ if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) {
+ conn = (DBClientBase *) data;
+ } else if (mongo_connection_create(&conn, conn_pool->conn_str) == SWITCH_STATUS_SUCCESS) {
+ if (++conn_pool->size > conn_pool->max_connections) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n");
+ }
+ }
- switch_mutex_unlock(conn_pool->mutex);
+ switch_mutex_unlock(conn_pool->mutex);
#ifdef MONGO_POOL_DEBUG
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
#endif
- return conn;
+ return conn;
}
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientBase *conn, switch_bool_t destroy)
{
- switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_assert(conn_pool != NULL);
- switch_assert(conn != NULL);
+ switch_assert(conn_pool != NULL);
+ switch_assert(conn != NULL);
- switch_mutex_lock(conn_pool->mutex);
- if (destroy || conn_pool->size > conn_pool->max_connections) {
+ switch_mutex_lock(conn_pool->mutex);
+ if (destroy || conn_pool->size > conn_pool->max_connections) {
#ifdef MONGO_POOL_DEBUG
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn);
#endif
- mongo_connection_destroy(&conn);
- conn_pool->size--;
- } else {
+ mongo_connection_destroy(&conn);
+ conn_pool->size--;
+ } else {
#ifdef MONGO_POOL_DEBUG
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn);
#endif
- status = switch_queue_push(conn_pool->connections, conn);
- }
+ status = switch_queue_push(conn_pool->connections, conn);
+ }
- switch_mutex_unlock(conn_pool->mutex);
+ switch_mutex_unlock(conn_pool->mutex);
#ifdef MONGO_POOL_DEBUG
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
#endif
- return status;
+ return status;
}
/* For Emacs: