diff --git a/src/modules/imc/doc/imc_admin.xml b/src/modules/imc/doc/imc_admin.xml index 6f7f5a02582..4b71c5f6806 100644 --- a/src/modules/imc/doc/imc_admin.xml +++ b/src/modules/imc/doc/imc_admin.xml @@ -88,6 +88,27 @@ ... modparam("imc", "db_url", "&exampledb;") ... + + + +
+ <varname>db_mode</varname>(integer) + + The module supports 2 modes of operation, high speed memory + based storage (mode 0), and database only (mode 2) where all + data is stored in a database, allowing scalability at the + expense of speed. Mode 1 is reserved. + + + Default value is 0 + + + + Set <varname>db_mode</varname> parameter + +... +modparam("imc", "db_mode", 2) +...
diff --git a/src/modules/imc/imc.c b/src/modules/imc/imc.c index f9f931d7b55..14989e67578 100644 --- a/src/modules/imc/imc.c +++ b/src/modules/imc/imc.c @@ -30,14 +30,12 @@ #include #include #include "../../lib/srdb1/db.h" -#include "../../lib/srdb1/db_res.h" #include "../../core/sr_module.h" #include "../../core/dprint.h" #include "../../core/ut.h" #include "../../core/timer.h" #include "../../core/str.h" #include "../../core/mem/shm_mem.h" -#include "../../lib/srdb1/db.h" #include "../../core/parser/parse_from.h" #include "../../core/parser/parse_content.h" #include "../../core/parser/contact/parse_contact.h" @@ -61,20 +59,22 @@ char hdr_buf[1024]; str all_hdrs; /** parameters */ - db1_con_t *imc_db = NULL; db_func_t imc_dbf; + static str db_url = str_init(DEFAULT_DB_URL); -str outbound_proxy = {NULL, 0}; +int db_mode = 0; -static str rooms_table = str_init("imc_rooms"); -static str members_table = str_init("imc_members"); +str rooms_table = str_init("imc_rooms"); +str members_table = str_init("imc_members"); -static str imc_col_username = str_init("username"); -static str imc_col_domain = str_init("domain"); -static str imc_col_flag = str_init("flag"); -static str imc_col_room = str_init("room"); -static str imc_col_name = str_init("name"); +str imc_col_username = str_init("username"); +str imc_col_domain = str_init("domain"); +str imc_col_flag = str_init("flag"); +str imc_col_room = str_init("room"); +str imc_col_name = str_init("name"); + +str outbound_proxy = {NULL, 0}; imc_hentry_p _imc_htable = NULL; int imc_hash_size = 4; @@ -108,11 +108,12 @@ static cmd_export_t cmds[]={ static param_export_t params[]={ {"db_url", PARAM_STR, &db_url}, + {"db_mode", INT_PARAM, &db_mode}, {"hash_size", INT_PARAM, &imc_hash_size}, {"imc_cmd_start_char", PARAM_STR, &imc_cmd_start_str}, {"rooms_table", PARAM_STR, &rooms_table}, {"members_table", PARAM_STR, &members_table}, - {"outbound_proxy", PARAM_STR, &outbound_proxy}, + {"outbound_proxy", PARAM_STR, &outbound_proxy}, {"extra_hdrs", PARAM_STR, &extra_hdrs}, {"create_on_join", INT_PARAM, &imc_create_on_join}, {"check_on_create", INT_PARAM, &imc_check_on_create}, @@ -146,183 +147,6 @@ struct module_exports exports= { destroy /* module destroy function */ }; -/** - * the initiating function - */ -int add_from_db(void) -{ - imc_member_p member = NULL; - int i, j, flag; - db_key_t mq_result_cols[4], mquery_cols[2]; - db_key_t rq_result_cols[4]; - db_val_t mquery_vals[2]; - db1_res_t *r_res= NULL; - db1_res_t *m_res= NULL; - db_row_t *m_row = NULL, *r_row = NULL; - db_val_t *m_row_vals, *r_row_vals = NULL; - str name, domain; - imc_room_p room = NULL; - int er_ret = -1; - - rq_result_cols[0] = &imc_col_name; - rq_result_cols[1] = &imc_col_domain; - rq_result_cols[2] = &imc_col_flag; - - mq_result_cols[0] = &imc_col_username; - mq_result_cols[1] = &imc_col_domain; - mq_result_cols[2] = &imc_col_flag; - - mquery_cols[0] = &imc_col_room; - mquery_vals[0].type = DB1_STR; - mquery_vals[0].nul = 0; - - if(imc_dbf.use_table(imc_db, &rooms_table)< 0) - { - LM_ERR("use_table failed\n"); - return -1; - } - - if(imc_dbf.query(imc_db,0, 0, 0, rq_result_cols,0, 3, 0,&r_res)< 0) - { - LM_ERR("failed to querry table\n"); - return -1; - } - if(r_res==NULL || r_res->n<=0) - { - LM_INFO("the query returned no result\n"); - if(r_res) imc_dbf.free_result(imc_db, r_res); - r_res = NULL; - return 0; - } - - LM_DBG("found %d rooms\n", r_res->n); - - for(i =0 ; i< r_res->n ; i++) - { - /*add rooms*/ - r_row = &r_res->rows[i]; - r_row_vals = ROW_VALUES(r_row); - - name.s = r_row_vals[0].val.str_val.s; - name.len = strlen(name.s); - - domain.s = r_row_vals[1].val.str_val.s; - domain.len = strlen(domain.s); - - flag = r_row_vals[2].val.int_val; - - room = imc_add_room(&name, &domain, flag); - if(room == NULL) - { - LM_ERR("failed to add room\n "); - goto error; - } - - /* add members */ - if(imc_dbf.use_table(imc_db, &members_table)< 0) - { - LM_ERR("use_table failed\n "); - goto error; - } - - mquery_vals[0].val.str_val= room->uri; - - if(imc_dbf.query(imc_db, mquery_cols, 0, mquery_vals, mq_result_cols, - 1, 3, 0, &m_res)< 0) - { - LM_ERR("failed to querry table\n"); - goto error; - } - - if(m_res==NULL || m_res->n<=0) - { - LM_INFO("the query returned no result\n"); - er_ret = 0; - goto error; /* each room must have at least one member*/ - } - for(j =0; j< m_res->n; j++) - { - m_row = &m_res->rows[j]; - m_row_vals = ROW_VALUES(m_row); - - name.s = m_row_vals[0].val.str_val.s; - name.len = strlen(name.s); - - domain.s = m_row_vals[1].val.str_val.s; - domain.len = strlen(domain.s); - - flag = m_row_vals[2].val.int_val; - - LM_DBG("adding memeber: [name]=%.*s [domain]=%.*s" - " in [room]= %.*s\n", STR_FMT(&name), STR_FMT(&domain), - STR_FMT(&room->uri)); - - member = imc_add_member(room, &name, &domain, flag); - if(member == NULL) - { - LM_ERR("failed to adding member\n "); - goto error; - } - imc_release_room(room); - } - - if(m_res) - { - imc_dbf.free_result(imc_db, m_res); - m_res = NULL; - } - } - - if(imc_dbf.use_table(imc_db, &members_table)< 0) - { - LM_ERR("use table failed\n "); - goto error; - } - - if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0) - { - LM_ERR("failed to delete information from db\n"); - goto error; - } - - if(imc_dbf.use_table(imc_db, &rooms_table)< 0) - { - LM_ERR("use table failed\n "); - goto error; - } - - if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0) - { - LM_ERR("failed to delete information from db\n"); - goto error; - } - - if(r_res) - { - imc_dbf.free_result(imc_db, r_res); - r_res = NULL; - } - - return 0; - -error: - if(r_res) - { - imc_dbf.free_result(imc_db, r_res); - r_res = NULL; - } - if(m_res) - { - imc_dbf.free_result(imc_db, m_res); - m_res = NULL; - } - if(room) - imc_release_room(room); - return er_ret; - -} - - static int mod_init(void) { #ifdef STATISTICS @@ -333,22 +157,19 @@ static int mod_init(void) } #endif - if(imc_rpc_init()<0) - { + if(imc_rpc_init()<0) { LM_ERR("failed to register RPC commands\n"); return -1; } - if(imc_hash_size <= 0) - { + if(imc_hash_size <= 0) { LM_ERR("invalid hash size\n"); return -1; } imc_hash_size = 1 << imc_hash_size; - if(imc_htable_init() < 0) - { + if(imc_htable_init() < 0) { LM_ERR("initializing hash table\n"); return -1; } @@ -365,29 +186,34 @@ static int mod_init(void) all_hdrs.len = extra_hdrs.len + imc_hdrs.len; } else { all_hdrs = imc_hdrs; - } + } - /* binding to mysql module */ - LM_DBG("db_url=%s/%d/%p\n", ZSW(db_url.s), db_url.len, db_url.s); + if(db_mode == 2) { + /* binding to mysql module */ + LM_DBG("db_url=%s/%d/%p\n", ZSW(db_url.s), db_url.len, db_url.s); - if (db_bind_mod(&db_url, &imc_dbf)) - { - LM_DBG("database module not found\n"); - return -1; - } + if (db_bind_mod(&db_url, &imc_dbf)) { + LM_DBG("database module not found\n"); + return -1; + } - imc_db = imc_dbf.init(&db_url); - if (!imc_db) - { - LM_ERR("failed to connect to the database\n"); - return -1; - } - /* read the informations stored in db */ - if(add_from_db() <0) - { - LM_ERR("failed to get information from db\n"); - return -1; - } + imc_db = imc_dbf.init(&db_url); + if (!imc_db) { + LM_ERR("failed to connect to the database\n"); + return -1; + } + + /* read the informations stored in db */ + if (load_rooms_from_db() < 0) { + LM_ERR("failed to get information from db\n"); + return -1; + } + + if(imc_db) + imc_dbf.close(imc_db); + + imc_db = NULL; + } /* load TM API */ if (load_tm_api(&tmb)!=0) { @@ -395,11 +221,7 @@ static int mod_init(void) return -1; } - imc_cmd_start_char = imc_cmd_start_str.s[0]; - - if(imc_db) - imc_dbf.close(imc_db); - imc_db = NULL; + imc_cmd_start_char = imc_cmd_start_str.s[0]; return 0; } @@ -412,32 +234,30 @@ static int child_init(int rank) if (rank==PROC_INIT || rank==PROC_TCP_MAIN) return 0; /* do nothing for the main process */ - if (imc_dbf.init==0) - { - LM_ERR("database not bound\n"); - return -1; - } - imc_db = imc_dbf.init(&db_url); - if (!imc_db) - { - LM_ERR("child %d: Error while connecting database\n", rank); - return -1; - } - else - { - if (imc_dbf.use_table(imc_db, &rooms_table) < 0) - { - LM_ERR("child %d: Error in use_table '%.*s'\n", rank, STR_FMT(&rooms_table)); + if (db_mode == 2) { + if (imc_dbf.init == 0) { + LM_ERR("database not bound\n"); return -1; } - if (imc_dbf.use_table(imc_db, &members_table) < 0) - { - LM_ERR("child %d: Error in use_table '%.*s'\n", rank, STR_FMT(&members_table)); + + imc_db = imc_dbf.init(&db_url); + if (!imc_db) { + LM_ERR("child %d: Error while connecting database\n", rank); return -1; } + else { + if (imc_dbf.use_table(imc_db, &rooms_table) < 0) { + LM_ERR("child %d: Error in use_table '%.*s'\n", rank, STR_FMT(&rooms_table)); + return -1; + } + if (imc_dbf.use_table(imc_db, &members_table) < 0) { + LM_ERR("child %d: Error in use_table '%.*s'\n", rank, STR_FMT(&members_table)); + return -1; + } - LM_DBG("child %d: Database connection opened successfully\n", rank); - } + LM_DBG("child %d: Database connection opened successfully\n", rank); + } + } return 0; } @@ -451,8 +271,7 @@ static int ki_imc_manager(struct sip_msg* msg) int ret = -1; body.s = get_body( msg ); - if (body.s==0) - { + if (body.s==0) { LM_ERR("cannot extract body from msg\n"); goto error; } @@ -508,7 +327,7 @@ static int ki_imc_manager(struct sip_msg* msg) LM_ERR("failed to handle 'create'\n"); ret = -30; goto error; - } + } break; case IMC_CMDID_JOIN: if(imc_handle_join(msg, &cmd, &src, &dst)<0) @@ -532,7 +351,7 @@ static int ki_imc_manager(struct sip_msg* msg) LM_ERR("failed to handle 'add'\n"); ret = -50; goto error; - } + } break; case IMC_CMDID_ACCEPT: if(imc_handle_accept(msg, &cmd, &src, &dst)<0) @@ -556,7 +375,7 @@ static int ki_imc_manager(struct sip_msg* msg) LM_ERR("failed to handle 'remove'\n"); ret = -80; goto error; - } + } break; case IMC_CMDID_LEAVE: if(imc_handle_leave(msg, &cmd, &src, &dst)<0) diff --git a/src/modules/imc/imc.h b/src/modules/imc/imc.h index b57cb5c3ab7..204bb5f78e5 100644 --- a/src/modules/imc/imc.h +++ b/src/modules/imc/imc.h @@ -33,6 +33,7 @@ extern str imc_cmd_start_str; extern char imc_cmd_start_char; extern struct tm_binds tmb; extern str outbound_proxy; +extern int db_mode; extern str all_hdrs; extern str extra_hdrs; extern int imc_create_on_join; diff --git a/src/modules/imc/imc_cmd.c b/src/modules/imc/imc_cmd.c index 4f8a1501425..adff66e24f8 100644 --- a/src/modules/imc/imc_cmd.c +++ b/src/modules/imc/imc_cmd.c @@ -62,6 +62,7 @@ static str msg_join_attempt_bcast = STR_STATIC_INIT(PREFIX "%.*s attempted to jo static str msg_join_attempt_ucast = STR_STATIC_INIT(PREFIX "Private rooms are by invitation only. Room owners have been notified."); static str msg_invite = STR_STATIC_INIT(PREFIX "%.*s invites you to join the room (send '%.*saccept' or '%.*sreject')"); static str msg_add_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to add members to this room"); +static str msg_user_modified = STR_STATIC_INIT(PREFIX "%.*s is now %.*s"); static str msg_modify_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to modify members in this room"); #if 0 static str msg_rejected = STR_STATIC_INIT(PREFIX "%.*s has rejected invitation"); @@ -415,6 +416,14 @@ int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd, } LM_DBG("Added room [%.*s]\n", STR_FMT(&rm->uri)); + if (db_mode == 2) { + if (add_room_to_db(rm) < 0) { + LM_ERR("failed to add room to db\n"); + goto error; + } + LM_DBG("Add room [%.*s] to db\n", STR_FMT(&rm->uri)); + } + flag_member |= IMC_MEMBER_OWNER; /* adding the owner as the first member*/ member = imc_add_member(rm, &src->parsed.user, &src->parsed.host, flag_member); @@ -425,6 +434,13 @@ int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd, LM_DBG("Added [%.*s] as the first member in room [%.*s]\n", STR_FMT(&member->uri), STR_FMT(&rm->uri)); + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, flag_member) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } + imc_send_message(&rm->uri, &member->uri, build_headers(msg), &msg_room_created); goto done; } @@ -457,6 +473,13 @@ int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd, LM_DBG("Added [%.*s] as member to room [%.*s]\n", STR_FMT(&member->uri), STR_FMT(&rm->uri)); + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, flag_member) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } + body.s = imc_body_buf; body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri))); @@ -501,6 +524,7 @@ int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd, goto error; rm = imc_get_room(&room.parsed.user, &room.parsed.host); + if (rm == NULL || (rm->flags & IMC_ROOM_DELETED)) { LM_DBG("Room [%.*s] not found\n", STR_FMT(&room.uri)); @@ -516,12 +540,28 @@ int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd, goto error; } LM_DBG("Created a new room [%.*s]\n", STR_FMT(&rm->uri)); + + if (db_mode == 2) { + if (add_room_to_db(rm) < 0) { + LM_ERR("failed to add room to db\n"); + goto error; + } + LM_DBG("Add room [%.*s] to db\n", STR_FMT(&rm->uri)); + } + flag_member |= IMC_MEMBER_OWNER; member = imc_add_member(rm, &src->parsed.user, &src->parsed.host, flag_member); if (member == NULL) { LM_ERR("Failed to add new member [%.*s]\n", STR_FMT(&src->uri)); goto error; } + + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, flag_member) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } /* send info message */ imc_send_message(&rm->uri, &member->uri, build_headers(msg), &msg_room_created); goto done; @@ -545,6 +585,13 @@ int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd, goto error; } + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, flag_member) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } + body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(src->uri))); } else { @@ -638,6 +685,13 @@ int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd, goto error; } + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, flag_member) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } + body.s = imc_body_buf; body.len = snprintf(body.s, sizeof(imc_body_buf), msg_invite.s, STR_FMT(format_uri(src->uri)), STR_FMT(&imc_cmd_start_str), STR_FMT(&imc_cmd_start_str)); @@ -743,6 +797,13 @@ int imc_handle_add(struct sip_msg* msg, imc_cmd_t *cmd, goto error; } + if (db_mode == 2) { + if (add_room_member_to_db(member, rm, 0) < 0) { + LM_ERR("failed to add room member [%.*s] to db\n", STR_FMT(&member->uri)); + goto error; + } + } + body.s = imc_body_buf; body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri))); @@ -796,6 +857,13 @@ int imc_handle_accept(struct sip_msg* msg, imc_cmd_t *cmd, member->flags &= ~IMC_MEMBER_INVITED; + if (db_mode == 2) { + if (modify_room_member_in_db(member, rm, member->flags) < 0) { + LM_ERR("failed to modify room member [%.*s] in db\n", STR_FMT(&member->uri)); + goto error; + } + } + body.s = imc_body_buf; body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri))); @@ -879,6 +947,13 @@ int imc_handle_remove(struct sip_msg* msg, imc_cmd_t *cmd, member->flags |= IMC_MEMBER_DELETED; imc_del_member(rm, &user.parsed.user, &user.parsed.host); + if (db_mode == 2) { + if (remove_room_member_from_db(member, rm) < 0) { + LM_ERR("failed to remove room member\n"); + goto error; + } + } + body.s = imc_body_buf; body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_left.s, STR_FMT(format_uri(member->uri))); @@ -940,6 +1015,13 @@ int imc_handle_reject(struct sip_msg* msg, imc_cmd_t *cmd, imc_del_member(rm, &src->parsed.user, &src->parsed.host); + if (db_mode == 2) { + if( remove_room_member_from_db(member, rm) < 0) { + LM_ERR("failed to remove room member\n"); + goto error; + } + } + rv = 0; error: if (room.uri.s != NULL) pkg_free(room.uri.s); @@ -1146,6 +1228,13 @@ int imc_handle_leave(struct sip_msg* msg, imc_cmd_t *cmd, member->flags |= IMC_MEMBER_DELETED; imc_del_member(rm, &src->parsed.user, &src->parsed.host); + if (db_mode == 2) { + if (remove_room_member_from_db(member, rm) < 0) { + LM_ERR("failed to remove room member\n"); + goto error; + } + } + done: rv = 0; error: @@ -1189,14 +1278,22 @@ int imc_handle_destroy(struct sip_msg* msg, imc_cmd_t *cmd, rm->flags |= IMC_ROOM_DELETED; /* braodcast message */ - imc_room_broadcast(rm, build_headers(msg), &msg_room_destroyed); + imc_room_broadcast(rm, build_headers(msg), &msg_room_destroyed); + + if (db_mode == 2) { + LM_DBG("Deleting room [%.*s] from db\n", STR_FMT(&room.uri)); + if (remove_room_from_db(rm) < 0) { + LM_ERR("Failed to delete room [%.*s] from db\n", STR_FMT(&room.uri)); + goto error; + } + } + + LM_DBG("Deleting room [%.*s] from htable\n", STR_FMT(&room.uri)); + imc_del_room(&room.parsed.user, &room.parsed.host); imc_release_room(rm); rm = NULL; - LM_DBG("Deleting room [%.*s]\n", STR_FMT(&room.uri)); - imc_del_room(&room.parsed.user, &room.parsed.host); - rv = 0; error: if (room.uri.s != NULL) pkg_free(room.uri.s); @@ -1341,10 +1438,10 @@ int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd, && !strncasecmp(cmd->param[1].s, IMC_MEMBER_ADMIN_STR, cmd->param[1].len)) { flag_member |= IMC_MEMBER_ADMIN; - } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_INVITED_STR)-1) - && !strncasecmp(cmd->param[1].s, IMC_MEMBER_INVITED_STR, cmd->param[1].len)) + } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_STR)-1) + && !strncasecmp(cmd->param[1].s, IMC_MEMBER_STR, cmd->param[1].len)) { - flag_member |= IMC_MEMBER_INVITED; + flag_member = 0; } else { LM_INFO("Modify command with unknown argument role [%.*s]\n", STR_FMT(&cmd->param[1])); goto error; @@ -1386,15 +1483,22 @@ int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd, goto error; } - rv = imc_modify_member(rm, &src->parsed.user, &src->parsed.host, flag_member); + rv = imc_modify_member(rm, &member->user, &member->domain, flag_member); if (rv == -1) { LM_ERR("Failed to modify member [%.*s] role [%.*s]\n", STR_FMT(&member->uri), STR_FMT(&cmd->param[1])); goto error; } + if (db_mode == 2) { + if (modify_room_member_in_db(member, rm, flag_member) < 0){ + LM_ERR("Failed to modify member [%.*s] role [%.*s] in db\n", STR_FMT(&member->uri), STR_FMT(&cmd->param[1])); + goto error; + } + } + body.s = imc_body_buf; - body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri))); + body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_modified.s, STR_FMT(&member->uri), STR_FMT(&cmd->param[1])); if (body.len < 0) { LM_ERR("Error while building response\n"); diff --git a/src/modules/imc/imc_mng.c b/src/modules/imc/imc_mng.c index 7740a74b681..73c2d68cafb 100644 --- a/src/modules/imc/imc_mng.c +++ b/src/modules/imc/imc_mng.c @@ -26,12 +26,15 @@ #include #include +#include "../../lib/srdb1/db_res.h" #include "../../core/mem/mem.h" #include "../../core/mem/shm_mem.h" #include "../../core/dprint.h" #include "../../core/hashes.h" #include "imc_mng.h" +#include "imc.h" + /* imc hash table */ extern imc_hentry_p _imc_htable; extern int imc_hash_size; @@ -65,7 +68,7 @@ int imc_htable_init(void) goto error; } } - + return 0; error: @@ -106,6 +109,370 @@ int imc_htable_destroy(void) return 0; } +int load_rooms_from_db() +{ + imc_member_p member = NULL; + int i, j, flag; + db_key_t mq_result_cols[4], mquery_cols[2]; + db_key_t rq_result_cols[4]; + db_val_t mquery_vals[2]; + db1_res_t *r_res= NULL; + db1_res_t *m_res= NULL; + db_row_t *m_row = NULL, *r_row = NULL; + db_val_t *m_row_vals, *r_row_vals = NULL; + str name, domain; + imc_room_p room = NULL; + int er_ret = -1; + + rq_result_cols[0] = &imc_col_name; + rq_result_cols[1] = &imc_col_domain; + rq_result_cols[2] = &imc_col_flag; + + mq_result_cols[0] = &imc_col_username; + mq_result_cols[1] = &imc_col_domain; + mq_result_cols[2] = &imc_col_flag; + + mquery_cols[0] = &imc_col_room; + mquery_vals[0].type = DB1_STR; + mquery_vals[0].nul = 0; + + if(imc_dbf.use_table(imc_db, &rooms_table)< 0) + { + LM_ERR("use_table failed\n"); + return -1; + } + + if(imc_dbf.query(imc_db,0, 0, 0, rq_result_cols,0, 3, 0,&r_res)< 0) + { + LM_ERR("failed to query table\n"); + return -1; + } + if(r_res==NULL || r_res->n<=0) + { + LM_INFO("the query returned no result\n"); + if(r_res) imc_dbf.free_result(imc_db, r_res); + r_res = NULL; + return 0; + } + + LM_DBG("found %d rooms\n", r_res->n); + + for(i =0 ; i< r_res->n ; i++) + { + /*add rooms*/ + r_row = &r_res->rows[i]; + r_row_vals = ROW_VALUES(r_row); + + name.s = r_row_vals[0].val.str_val.s; + name.len = strlen(name.s); + + domain.s = r_row_vals[1].val.str_val.s; + domain.len = strlen(domain.s); + + flag = r_row_vals[2].val.int_val; + + room = imc_add_room(&name, &domain, flag); + if(room == NULL) + { + LM_ERR("failed to add room\n "); + goto error; + } + + /* add members */ + if(imc_dbf.use_table(imc_db, &members_table)< 0) + { + LM_ERR("use_table failed\n "); + goto error; + } + + mquery_vals[0].val.str_val= room->uri; + + if(imc_dbf.query(imc_db, mquery_cols, 0, mquery_vals, mq_result_cols, + 1, 3, 0, &m_res)< 0) + { + LM_ERR("failed to query table\n"); + goto error; + } + + if(m_res==NULL || m_res->n<=0) + { + LM_INFO("the query returned no result\n"); + er_ret = 0; + goto error; /* each room must have at least one member*/ + } + for(j =0; j< m_res->n; j++) + { + m_row = &m_res->rows[j]; + m_row_vals = ROW_VALUES(m_row); + + name.s = m_row_vals[0].val.str_val.s; + name.len = strlen(name.s); + + domain.s = m_row_vals[1].val.str_val.s; + domain.len = strlen(domain.s); + + flag = m_row_vals[2].val.int_val; + + LM_DBG("adding memeber: [name]=%.*s [domain]=%.*s" + " in [room]= %.*s\n", STR_FMT(&name), STR_FMT(&domain), + STR_FMT(&room->uri)); + + member = imc_add_member(room, &name, &domain, flag); + if(member == NULL) + { + LM_ERR("failed to adding member\n "); + goto error; + } + imc_release_room(room); + } + + if(m_res) + { + imc_dbf.free_result(imc_db, m_res); + m_res = NULL; + } + } + + return 0; + +error: + if(r_res) + { + imc_dbf.free_result(imc_db, r_res); + r_res = NULL; + } + if(m_res) + { + imc_dbf.free_result(imc_db, m_res); + m_res = NULL; + } + if(room) + imc_release_room(room); + return er_ret; +} + +int add_room_to_db(imc_room_p room) +{ + db_key_t rkeys[3]; + db_val_t rvalues[3]; + + rkeys[0] = &imc_col_name; + rkeys[1] = &imc_col_domain; + rkeys[2] = &imc_col_flag; + + rvalues[0].type = DB1_STR; + rvalues[0].nul = 0; + rvalues[0].val.str_val.s = room->name.s; + rvalues[0].val.str_val.len = room->name.len; + + rvalues[1].type = DB1_STR; + rvalues[1].nul = 0; + rvalues[1].val.str_val.s = room->domain.s; + rvalues[1].val.str_val.len = room->domain.len; + + rvalues[2].type = DB1_INT; + rvalues[2].nul = 0; + rvalues[2].val.int_val = 0; + + if(imc_dbf.use_table(imc_db, &rooms_table)< 0) + { + LM_ERR("use_table failed on rooms_table\n"); + return -1; + } + + if(imc_dbf.insert(imc_db, rkeys, rvalues, 3)< 0) + { + LM_ERR("failed to insert room\n"); + return -1; + } + + return 0; +} + +int remove_room_from_db(imc_room_p room) +{ + db_key_t rkeys[2]; + db_val_t rvalues[2]; + db_key_t mkeys[1]; + db_val_t mvalues[1]; + + mkeys[0] = &imc_col_room; + + mvalues[0].type = DB1_STR; + mvalues[0].nul = 0; + mvalues[0].val.str_val.s = room->uri.s; + mvalues[0].val.str_val.len = room->uri.len; + + if(imc_dbf.use_table(imc_db, &members_table)< 0) + { + LM_ERR("use table failed\n "); + return -1; + } + + if(imc_dbf.delete(imc_db, mkeys, 0 , mvalues, 1) < 0) + { + LM_ERR("failed to delete room member from db\n"); + return -1; + } + + rkeys[0] = &imc_col_name; + rkeys[1] = &imc_col_domain; + + rvalues[0].type = DB1_STR; + rvalues[0].nul = 0; + rvalues[0].val.str_val.s = room->name.s; + rvalues[0].val.str_val.len = room->name.len; + + rvalues[1].type = DB1_STR; + rvalues[1].nul = 0; + rvalues[1].val.str_val.s = room->domain.s; + rvalues[1].val.str_val.len = room->domain.len; + + if(imc_dbf.use_table(imc_db, &rooms_table)< 0) + { + LM_ERR("use_table failed on rooms_table\n"); + return -1; + } + + if(imc_dbf.delete(imc_db, rkeys, 0 , rvalues, 2) < 0) + { + LM_ERR("failed to delete room from db\n"); + return -1; + } + + return 0; +} + +int add_room_member_to_db(imc_member_p member, imc_room_p room, int flag) +{ + db_key_t mkeys[4]; + db_val_t mvalues[4]; + + mkeys[0] = &imc_col_username; + mkeys[1] = &imc_col_domain; + mkeys[2] = &imc_col_room; + mkeys[3] = &imc_col_flag; + + mvalues[0].type = DB1_STR; + mvalues[0].nul = 0; + mvalues[0].val.str_val.s = member->user.s; + mvalues[0].val.str_val.len = member->user.len; + + mvalues[1].type = DB1_STR; + mvalues[1].nul = 0; + mvalues[1].val.str_val.s = member->domain.s; + mvalues[1].val.str_val.len = member->domain.len; + + mvalues[2].type = DB1_STR; + mvalues[2].nul = 0; + mvalues[2].val.str_val.s = room->uri.s; + mvalues[2].val.str_val.len = room->uri.len; + + mvalues[3].type = DB1_INT; + mvalues[3].nul = 0; + mvalues[3].val.int_val = flag; + + if(imc_dbf.use_table(imc_db, &members_table)< 0) + { + LM_ERR("use_table failed on members_table\n"); + return -1; + } + + if(imc_dbf.insert(imc_db, mkeys, mvalues, 4)< 0) + { + LM_ERR("failed to insert member\n"); + return -1; + } + + return 0; +} + +int remove_room_member_from_db(imc_member_p member, imc_room_p room) { + db_key_t mkeys[3]; + db_val_t mvalues[3]; + + mkeys[0] = &imc_col_username; + mkeys[1] = &imc_col_domain; + mkeys[2] = &imc_col_room; + + mvalues[0].type = DB1_STR; + mvalues[0].nul = 0; + mvalues[0].val.str_val.s = member->user.s; + mvalues[0].val.str_val.len = member->user.len; + + mvalues[1].type = DB1_STR; + mvalues[1].nul = 0; + mvalues[1].val.str_val.s = member->domain.s; + mvalues[1].val.str_val.len = member->domain.len; + + mvalues[2].type = DB1_STR; + mvalues[2].nul = 0; + mvalues[2].val.str_val.s = room->uri.s; + mvalues[2].val.str_val.len = room->uri.len; + + if(imc_dbf.use_table(imc_db, &members_table)< 0) + { + LM_ERR("use table failed\n "); + return -1; + } + + if(imc_dbf.delete(imc_db, mkeys, 0 , mvalues, 3) < 0) + { + LM_ERR("failed to delete room member from db\n"); + return -1; + } + + return 0; +} + +int modify_room_member_in_db(imc_member_p member, imc_room_p room, int flag) +{ + db_key_t mkeys[3]; + db_val_t mvalues[3]; + + db_key_t mukeys[1]; + db_val_t muvalues[1]; + + mkeys[0] = &imc_col_username; + mkeys[1] = &imc_col_domain; + mkeys[2] = &imc_col_room; + + mvalues[0].type = DB1_STR; + mvalues[0].nul = 0; + mvalues[0].val.str_val.s = member->user.s; + mvalues[0].val.str_val.len = member->user.len; + + mvalues[1].type = DB1_STR; + mvalues[1].nul = 0; + mvalues[1].val.str_val.s = member->domain.s; + mvalues[1].val.str_val.len = member->domain.len; + + mvalues[2].type = DB1_STR; + mvalues[2].nul = 0; + mvalues[2].val.str_val.s = room->uri.s; + mvalues[2].val.str_val.len = room->uri.len; + + mukeys[0] = &imc_col_flag; + + muvalues[0].type = DB1_INT; + muvalues[0].nul = 0; + muvalues[0].val.int_val = flag; + + if(imc_dbf.use_table(imc_db, &members_table)< 0) + { + LM_ERR("use_table failed on members_table\n"); + return -1; + } + + if(imc_dbf.update(imc_db, mkeys, 0, mvalues, mukeys, muvalues, 3, 1)< 0) + { + LM_ERR("failed to update member\n"); + return -1; + } + + return 0; +} + /** * add room */ @@ -344,7 +711,7 @@ imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags) return imp; } -imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags) { +int imc_modify_member(imc_room_p room, str* user, str* domain, int flags) { imc_member_p imp = NULL; unsigned int hashid; @@ -352,7 +719,7 @@ imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flag || domain == NULL || domain->s==NULL || domain->len<=0) { LM_ERR("invalid parameters\n"); - return NULL; + return -1; } hashid = core_case_hash(user, domain, 0); @@ -366,6 +733,8 @@ imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flag { LM_DBG("member found. modify flags\n"); imp->flags = flags; + imp->hashid = core_case_hash(&imp->user, &imp->domain, 0); + return 0; } imp = imp->next; diff --git a/src/modules/imc/imc_mng.h b/src/modules/imc/imc_mng.h index 866a1fa56dd..34ac74cd573 100644 --- a/src/modules/imc/imc_mng.h +++ b/src/modules/imc/imc_mng.h @@ -27,7 +27,7 @@ #define _IMC_MNG_H_ - +#include "../../lib/srdb1/db.h" #include "../../core/locking.h" #include "../../core/str.h" #include "../../core/parser/parse_from.h" @@ -40,7 +40,21 @@ #define IMC_MEMBER_OWNER_STR "owner" #define IMC_MEMBER_ADMIN_STR "admin" -#define IMC_MEMBER_INVITED_STR "member" +#define IMC_MEMBER_STR "member" + +extern db1_con_t *imc_db; +extern db_func_t imc_dbf; + +extern int db_mode; + +extern str rooms_table; +extern str members_table; + +extern str imc_col_username; +extern str imc_col_domain; +extern str imc_col_flag; +extern str imc_col_room; +extern str imc_col_name; typedef struct _imc_member { @@ -84,8 +98,15 @@ typedef struct _imc_hentry gen_lock_t lock; } imc_hentry_t, *imc_hentry_p; +int load_rooms_from_db(); +int add_room_to_db(imc_room_p room); +int remove_room_from_db(imc_room_p room); +int add_room_member_to_db(imc_member_p member, imc_room_p room, int flag); +int modify_room_member_in_db(imc_member_p member, imc_room_p room, int flag); +int remove_room_member_from_db(imc_member_p member, imc_room_p room); + imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags); -imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags); +int imc_modify_member(imc_room_p room, str* user, str* domain, int flags); imc_member_p imc_get_member(imc_room_p room, str* user, str* domain); int imc_del_member(imc_room_p room, str* user, str* domain);