/*! * \brief Loads from DB all contacts for a RUID * \param _c database connection * \param _d domain * \param _aor address of record * \return pointer to the record on success, 0 on errors or if nothing is found */ urecord_t* db_load_urecord_by_ruid(udomain_t* _d, str *_ruid) { ucontact_info_t *ci; db_key_t columns[18]; db_key_t keys[1]; db_key_t order; db_val_t vals[1]; db1_res_t* res = NULL; db_row_t *row; str contact; str aor; char aorbuf[512]; str domain; urecord_t* r; ucontact_t* c; keys[0] = &ruid_col; vals[0].type = DB1_STR; vals[0].nul = 0; vals[0].val.str_val = *_ruid; columns[0] = &contact_col; columns[1] = &expires_col; columns[2] = &q_col; columns[3] = &callid_col; columns[4] = &cseq_col; columns[5] = &flags_col; columns[6] = &cflags_col; columns[7] = &user_agent_col; columns[8] = &received_col; columns[9] = &path_col; columns[10] = &sock_col; columns[11] = &methods_col; columns[12] = &last_mod_col; columns[13] = &ruid_col; columns[14] = &instance_col; columns[15] = &user_col; columns[16] = ®_id_col; columns[17] = &domain_col; if (desc_time_order) order = &last_mod_col; else order = &q_col; if (ul_db_layer_query(_d, &vals[0].val.str_val, &vals[1].val.str_val, keys, 0, vals, columns, 1, 18, order, &res) < 0) { LM_ERR("db_query failed\n"); return 0; } if (RES_ROW_N(res) == 0) { LM_DBG("aor %.*s not found in table %.*s\n",_ruid->len, _ruid->s, _d->name->len, _d->name->s); ul_db_layer_free_result(_d, res); return 0; } r = 0; /* use first row - shouldn't be more */ row = RES_ROWS(res); ci = dbrow2info(ROW_VALUES(RES_ROWS(res)), &contact); if (ci==0) { LM_ERR("skipping record for %.*s in table %s\n", _ruid->len, _ruid->s, _d->name->s); goto done; } aor.s = (char*)VAL_STRING(ROW_VALUES(row) + 15); aor.len = strlen(aor.s); if (use_domain) { domain.s = (char*)VAL_STRING(ROW_VALUES(row) + 17); if (VAL_NULL(ROW_VALUES(row)+17) || domain.s==0 || domain.s[0]==0) { LM_CRIT("empty domain record for user %.*s...skipping\n", aor.len, aor.s); goto done; } domain.len = strlen(domain.s); if(aor.len + domain.len + 2 >= 512) { LM_ERR("AoR is too big\n"); goto done; } memcpy(aorbuf, aor.s, aor.len); aorbuf[aor.len] = '@'; memcpy(aorbuf + aor.len + 1, domain.s, domain.len); aor.len += 1 + domain.len; aor.s = aorbuf; aor.s[aor.len] = '\0'; } get_static_urecord( _d, &aor, &r); if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) { LM_ERR("mem_insert failed\n"); free_urecord(r); ul_db_layer_free_result(_d, res); return 0; } /* We have to do this, because insert_ucontact sets state to CS_NEW * and we have the contact in the database already */ c->state = CS_SYNC; done: ul_db_layer_free_result(_d, res); ; return r; }
/*! * \brief Load all records from a udomain * * Load all records from a udomain, useful to populate the * memory cache on startup. * \param _c database connection * \param _d loaded domain * \return 0 on success, -1 on failure */ int preload_udomain(db1_con_t* _c, udomain_t* _d) { pcontact_info_t *ci; db_row_t *row; db_key_t columns[18]; db1_res_t* res = NULL; str aor, contact; int i, n; pcontact_t* c; LM_DBG("pre-loading domain from DB\n"); columns[0] = &domain_col; columns[1] = &aor_col; columns[2] = &contact_col; columns[3] = &received_col; columns[4] = &rx_session_id_col; columns[5] = ®_state_col; columns[6] = &expires_col; columns[7] = &socket_col; columns[8] = &service_routes_col; columns[9] = &public_ids_col; columns[10] = &path_col; if (ul_dbf.use_table(_c, _d->name) < 0) { LM_ERR("sql use_table failed\n"); return -1; } #ifdef EXTRA_DEBUG LM_NOTICE("load start time [%d]\n", (int)time(NULL)); #endif if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) { if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, 0) < 0) { LM_ERR("db_query (1) failed\n"); return -1; } if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) { LM_ERR("fetching rows failed\n"); return -1; } } else { if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, &res) < 0) { LM_ERR("db_query failed\n"); return -1; } } if (RES_ROW_N(res) == 0) { LM_DBG("table is empty\n"); ul_dbf.free_result(_c, res); return 0; } LM_DBG("%d rows returned in preload\n", RES_ROW_N(res)); n = 0; do { LM_DBG("loading records - cycle [%d]\n", ++n); for(i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; aor.s = (char*) VAL_STRING(ROW_VALUES(row) + 1); if (VAL_NULL(ROW_VALUES(row) + 1) || aor.s == 0 || aor.s[0] == 0) { LM_CRIT("empty aor record in table %s...skipping\n", _d->name->s); continue; } aor.len = strlen(aor.s); ci = dbrow2info( ROW_VALUES(row)+1, &contact); if (ci==0) { LM_ERR("usrloc record for %.*s in table %s\n", aor.len, aor.s, _d->name->s); continue; } lock_udomain(_d, &aor); if ( (mem_insert_pcontact(_d, &aor, ci, &c)) != 0) { LM_ERR("inserting contact failed\n"); unlock_udomain(_d, &aor); goto error1; } unlock_udomain(_d, &aor); } if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) { if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) { LM_ERR("fetching rows (1) failed\n"); ul_dbf.free_result(_c, res); return -1; } } else { break; } } while(RES_ROW_N(res)>0); ul_dbf.free_result(_c, res); #ifdef EXTRA_DEBUG LM_NOTICE("load end time [%d]\n", (int)time(NULL)); #endif return 0; error1: free_pcontact(c); ul_dbf.free_result(_c, res); return -1; }
/*! * \brief Loads from DB all contacts for an AOR * \param _c database connection * \param _d domain * \param _aor address of record * \return pointer to the record on success, 0 on errors or if nothing is found */ urecord_t* db_load_urecord(udomain_t* _d, str *_aor) { ucontact_info_t *ci; db_key_t columns[16]; db_key_t keys[2]; db_key_t order; db_val_t vals[2]; db1_res_t* res = NULL; str contact; char *domain; int i; urecord_t* r; ucontact_t* c; keys[0] = &user_col; vals[0].type = DB1_STR; vals[0].nul = 0; if (use_domain) { keys[1] = &domain_col; vals[1].type = DB1_STR; vals[1].nul = 0; domain = memchr(_aor->s, '@', _aor->len); vals[0].val.str_val.s = _aor->s; if (domain==0) { vals[0].val.str_val.len = 0; vals[1].val.str_val = *_aor; } else { vals[0].val.str_val.len = domain - _aor->s; vals[1].val.str_val.s = domain+1; vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1; } } else { vals[0].val.str_val = *_aor; } columns[0] = &contact_col; columns[1] = &expires_col; columns[2] = &q_col; columns[3] = &callid_col; columns[4] = &cseq_col; columns[5] = &flags_col; columns[6] = &cflags_col; columns[7] = &user_agent_col; columns[8] = &received_col; columns[9] = &path_col; columns[10] = &sock_col; columns[11] = &methods_col; columns[12] = &last_mod_col; columns[13] = &ruid_col; columns[14] = &instance_col; columns[15] = ®_id_col; if (desc_time_order) order = &last_mod_col; else order = &q_col; if (ul_db_layer_query(_d, &vals[0].val.str_val, &vals[1].val.str_val, keys, 0, vals, columns, (use_domain)?2:1, 16, order, &res) < 0) { LM_ERR("db_query failed\n"); return 0; } if (RES_ROW_N(res) == 0) { LM_DBG("aor %.*s not found in table %.*s\n",_aor->len, _aor->s, _d->name->len, _d->name->s); ul_db_layer_free_result(_d, res); return 0; } r = 0; for(i = 0; i < RES_ROW_N(res); i++) { ci = dbrow2info( ROW_VALUES(RES_ROWS(res) + i), &contact); if (ci==0) { LM_ERR("skipping record for %.*s in table %s\n", _aor->len, _aor->s, _d->name->s); continue; } if ( r==0 ) get_static_urecord( _d, _aor, &r); if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) { LM_ERR("mem_insert failed\n"); free_urecord(r); ul_db_layer_free_result(_d, res); return 0; } /* We have to do this, because insert_ucontact sets state to CS_NEW * and we have the contact in the database already */ c->state = CS_SYNC; } ul_db_layer_free_result(_d, res); return r; }