int acc_db_request( struct sip_msg *rq, struct sip_msg *rpl, query_list_t **ins_list) { static db_ps_t my_ps_ins = NULL; static db_ps_t my_ps = NULL; int m; int n; int i; /* formated database columns */ m = core2strar( rq, val_arr ); for(i = 0; i < m; i++) VAL_STR(db_vals+i) = val_arr[i]; /* time value */ VAL_TIME(db_vals+(m++)) = acc_env.ts; /* extra columns */ m += extra2strar( db_extra, rq, rpl, val_arr+m, 0); for( i++; i < m; i++) VAL_STR(db_vals+i) = val_arr[i]; acc_dbf.use_table(db_handle, &acc_env.text/*table*/); CON_PS_REFERENCE(db_handle) = ins_list? &my_ps_ins : &my_ps; /* multi-leg columns */ if ( !leg_info ) { if (con_set_inslist(&acc_dbf,db_handle,ins_list,db_keys,m) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle, db_keys, db_vals, m) < 0) { LM_ERR("failed to insert into database\n"); return -1; } } else { n = legs2strar(leg_info,rq,val_arr+m,1); do { for ( i = m; i < m + n; i++) VAL_STR(db_vals+i)=val_arr[i]; if (con_set_inslist(&acc_dbf,db_handle,ins_list,db_keys,m+n) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle, db_keys, db_vals, m+n) < 0) { LM_ERR("failed to insert into database\n"); return -1; } }while ( (n = legs2strar(leg_info,rq,val_arr+m,0))!=0 ); } return 1; }
static inline int insert_siptrace_avp(struct usr_avp *avp, int_str *first_val,db_key_t *keys,db_val_t *vals) { int_str avp_value; if (avp == 0) return 0; if (!is_avp_str_val(avp)) { avp_value.s.s=int2str(first_val->n,&avp_value.s.len); LM_DBG("int val [%.*s]\n",avp_value.s.len,avp_value.s.s); } else { avp_value = *first_val; LM_DBG("str val [%.*s]\n",avp_value.s.len,avp_value.s.s); } db_vals[13].val.str_val.s = avp_value.s.s; db_vals[13].val.str_val.len = avp_value.s.len; LM_DBG("storing info 14...\n"); CON_PS_REFERENCE(db_con) = &siptrace_ps; if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 ) CON_RESET_INSLIST(db_con); if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0) { LM_ERR("error storing trace\n"); return -1; } avp = search_next_avp( avp, &avp_value); while(avp!=NULL) { if (!is_avp_str_val(avp)) avp_value.s.s=int2str(avp_value.n,&avp_value.s.len); db_vals[13].val.str_val.s = avp_value.s.s; db_vals[13].val.str_val.len = avp_value.s.len; LM_DBG("### - storing info 14 \n"); CON_PS_REFERENCE(db_con) = &siptrace_ps; if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 ) CON_RESET_INSLIST(db_con); if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0) { LM_ERR("error storing trace\n"); return -1; } avp = search_next_avp( avp, &avp_value); } return 0; }
/* * Insert a row into specified table * _con: structure representing database connection * _k: key names * _v: values of the keys * _n: number of key=value pairs */ int db_postgres_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n) { db_res_t* _r = NULL; CON_RESET_CURR_PS(_h); /* no prepared statements support */ int tmp = db_do_insert(_h, _k, _v, _n, db_postgres_val2str, db_postgres_submit_query); if (submit_func_called) { /* finish the async query, * otherwise the next query will not complete */ /* only call this if the DB API has effectively called * our submit_query function * * in case of insert queueing, * it may postpone calling the insert func until * enough rows have piled up */ if (db_postgres_store_result(_h, &_r) != 0) LM_WARN("unexpected result returned\n"); submit_func_called = 0; } if (_r) db_free_result(_r); if (CON_HAS_INSLIST(_h)) CON_RESET_INSLIST(_h); return tmp; }
/* * Insert a row into specified table * _con: structure representing database connection * _k: key names * _v: values of the keys * _n: number of key=value pairs */ int db_postgres_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n) { db_res_t* _r = NULL; CON_RESET_CURR_PS(_h); /* no prepared statements support */ /* This needs to be reset before each call to db_do_insert. This is only used by inserts, but as a side effect delete and updates will set it to 1 without resetting it. */ submit_func_called = 0; int tmp = db_do_insert(_h, _k, _v, _n, db_postgres_val2str, db_postgres_submit_query); /* For bulk queries the insert may not be submitted until enough rows are queued */ if (submit_func_called) { /* Query was submitted. Result must be handled. */ if (db_postgres_store_result(_h, &_r) != 0) LM_WARN("unexpected result returned\n"); } if (_r) db_free_result(_r); if (CON_HAS_INSLIST(_h)) CON_RESET_INSLIST(_h); return tmp; }
static inline int insert_siptrace_flag(struct sip_msg *msg, db_key_t *keys,db_val_t *vals) { db_vals[13].val.str_val.s = ""; db_vals[13].val.str_val.len = 0; LM_DBG("storing info 1...\n"); if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 ) CON_RESET_INSLIST(db_con); CON_PS_REFERENCE(db_con) = &siptrace_ps; if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0) { LM_ERR("error storing trace\n"); return -1; } return 0; }
int acc_db_cdrs(struct dlg_cell *dlg, struct sip_msg *msg) { int total, nr_vals, i, j, ret, res = -1; time_t created, start_time; str core_s, leg_s, extra_s, table; short nr_legs; static db_ps_t my_ps = NULL; static query_list_t *ins_list = NULL; core_s.s = extra_s.s = leg_s.s = 0; ret = prebuild_core_arr(dlg, &core_s, &start_time); if (ret < 0) { LM_ERR("cannot copy core arguments\n"); goto end; } ret = prebuild_extra_arr(dlg, msg, &extra_s, &db_extra_str, db_extra_bye, ret); if (ret < 0) { LM_ERR("cannot copy extra arguments\n"); goto end; } /* here starts the extra leg */ nr_vals = prebuild_leg_arr(dlg, &leg_s, &nr_legs); if (nr_vals < 0) { LM_ERR("cannot compute leg values\n"); goto end; } if (!(created = acc_get_created(dlg))) { LM_ERR("cannot get created\n"); goto end; } if (dlg_api.fetch_dlg_value(dlg, &table_str, &table, 0) < 0) { LM_ERR("error getting table name\n"); return -1; } for (i=0;i<ACC_CORE_LEN;i++) VAL_STR(db_vals+i) = val_arr[i]; for (i=ACC_CORE_LEN; i<ret; i++) VAL_STR(db_vals+i+1) = val_arr[i]; VAL_TIME(db_vals+ACC_CORE_LEN) = start_time; VAL_INT(db_vals+ret+nr_vals+1) = time(NULL) - start_time; VAL_INT(db_vals+ret+nr_vals+2) = start_time - created; VAL_TIME(db_vals+ret+nr_vals+3) = created; total = ret + 4; acc_dbf.use_table(db_handle, &table); CON_PS_REFERENCE(db_handle) = &my_ps; if (!leg_info) { if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle, db_keys, db_vals, total) < 0) { LM_ERR("failed to insert into database\n"); goto end; } } else { total += nr_vals; leg_s.len = 4; for (i=0;i<nr_legs;i++) { complete_dlg_values(&leg_s,val_arr+ret,nr_vals); for (j = 0; j<nr_vals; j++) VAL_STR(db_vals+ret+j+1) = val_arr[ret+j]; if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle,db_keys,db_vals,total) < 0) { LM_ERR("failed inserting into database\n"); goto end; } } } res = 1; end: if (core_s.s) pkg_free(core_s.s); if (extra_s.s) pkg_free(extra_s.s); if (leg_s.s) pkg_free(leg_s.s); return res; }
/* store data in the table emergency_report */ int report(struct emergency_report *report, str db_url, str table_report) { static query_list_t *ins_list = NULL; static db_ps_t emergency_ps = NULL; LM_DBG("Report emergency call in db\n"); db_funcs.use_table(db_con, &table_report); db_key_t db_keys[NR_KEYS]; db_val_t db_vals[NR_KEYS]; if (report == NULL) { LM_DBG("invalid parameter\n"); return -1; } db_keys[0] = &id_rep_col; db_vals[0].type = DB_BIGINT; db_vals[0].val.bigint_val = 0; db_keys[1] = &callid_rep_col; db_vals[1].type = DB_STR; db_vals[1].val.str_val = report->callid; LM_DBG("CALLID_REPORT %.*s \n", report->callid.len, report->callid.s); LM_DBG("CALLID_REPORT_LEN %d \n", report->callid.len); db_keys[2] = &srid_rep_col; db_vals[2].type = DB_STR; db_vals[2].val.str_val = report->ert_srid; LM_DBG("SRID_REPORT %.*s \n", report->ert_srid.len, report->ert_srid.s); LM_DBG("SRID_REPORT_LEN %d \n", report->ert_srid.len); db_keys[3] = &resn_rep_col; db_vals[3].type = DB_BIGINT; db_vals[3].val.bigint_val = report->ert_resn; LM_DBG("RESN_REPORT %d \n", report->ert_resn); db_keys[4] = &npa_rep_col; db_vals[4].type = DB_BIGINT; db_vals[4].val.bigint_val = report->ert_npa; LM_DBG("NPA_REPORT %d \n", report->ert_npa); db_keys[5] = &esgwri_rep_col; db_vals[5].type = DB_STR; db_vals[5].val.str_val = report->esgwri; LM_DBG("ESGWRI_REPORT %.*s \n", report->esgwri.len, report->esgwri.s); LM_DBG("ESGWRI_REPORT_LEN %d \n", report->esgwri.len); db_keys[6] = &lro_rep_col; db_vals[6].type = DB_STR; db_vals[6].val.str_val = report->lro; LM_DBG("LRO_REPORT %.*s \n", report->lro.len, report->lro.s); LM_DBG("LRO_REPORT_LEN %d \n", report->lro.len); db_keys[7] = &vpc_name_rep_col; db_vals[7].type = DB_STR; db_vals[7].val.str_val = report->vpc_name; LM_DBG("VPC_NAME_REPORT %.*s \n", report->vpc_name.len, report->vpc_name.s); LM_DBG("VPC_NAME_REPORT_LEN %d \n", report->vpc_name.len); db_keys[8] = &vpc_host_rep_col; db_vals[8].type = DB_STR; db_vals[8].val.str_val = report->vpc_host; LM_DBG("VPC_HOST_REPORT %.*s \n", report->vpc_host.len, report->vpc_host.s); LM_DBG("VPC_HOST_REPORT_LEN %d \n", report->vpc_host.len); db_keys[9] = ×tamp_rep_col; db_vals[9].type = DB_STR; db_vals[9].val.str_val = report->timestamp; LM_DBG("VPC_TIMESTAMP_REPORT %.*s \n", report->timestamp.len, report->timestamp.s); LM_DBG("VPC_TIMESTAMP_REPORT_LEN %d \n", report->timestamp.len); db_keys[10] = &result_rep_col; db_vals[10].type = DB_STR; db_vals[10].val.str_val = report->result; LM_DBG("RESULT_REPORT %.*s \n", report->result.len, report->result.s); LM_DBG("RESULT_REPORT_LEN %d \n", report->result.len); db_keys[11] = &disposition_rep_col; db_vals[11].type = DB_STR; db_vals[11].val.str_val = report->disposition; LM_DBG("DISPOSITION_REPORT %.*s \n", report->disposition.len, report->disposition.s); LM_DBG("DISPOSITION_REPORT_LEN %d \n", report->disposition.len); // no field can be null int i = 0; for (i = 0; i < NR_KEYS; i++) db_vals[i].nul = 0; LM_DBG("storing info...\n"); if (con_set_inslist(&db_funcs, db_con, &ins_list, db_keys, NR_KEYS) < 0) CON_RESET_INSLIST(db_con); CON_PS_REFERENCE(db_con) = &emergency_ps; if (db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) { LM_ERR("failed to insert into database\n"); return -1;; } return 1; }
void dialog_update_db(unsigned int ticks, void * param) { static db_ps_t my_ps_update = NULL; static db_ps_t my_ps_insert = NULL; static db_ps_t my_ps_update_vp = NULL; int index; db_val_t values[DIALOG_TABLE_TOTAL_COL_NO]; struct dlg_entry entry; struct dlg_cell * cell; unsigned char on_shutdown; int callee_leg,ins_done=0; static query_list_t *ins_list = NULL; db_key_t insert_keys[DIALOG_TABLE_TOTAL_COL_NO] = { &h_entry_column, &h_id_column, &call_id_column, &from_uri_column, &from_tag_column, &to_uri_column, &to_tag_column, &from_sock_column, &to_sock_column, &start_time_column, &from_route_column, &to_route_column, &from_contact_column, &to_contact_column, &mangled_fu_column, &mangled_tu_column, /*update chunk */ &state_column, &timeout_column, &from_cseq_column, &to_cseq_column, &from_ping_cseq_column, &to_ping_cseq_column, &vars_column, &profiles_column, &sflags_column, &flags_column}; if (dialog_db_handle==0 || use_dialog_table()!=0) return; on_shutdown = (ticks==0); /*save the current dialogs information*/ VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = VAL_TYPE(values+16) = VAL_TYPE(values+17) = VAL_TYPE(values+20) = VAL_TYPE(values+21) = VAL_TYPE(values+24) = VAL_TYPE(values+25)= DB_INT; VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = VAL_TYPE(values+8) = VAL_TYPE(values+10) = VAL_TYPE(values+11) = VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+14) = VAL_TYPE(values+15) = VAL_TYPE(values+18) = VAL_TYPE(values+19) = VAL_TYPE(values+22) = VAL_TYPE(values+23) = DB_STR; for(index = 0; index< d_table->size; index++){ /* lock the whole entry */ entry = (d_table->entries)[index]; dlg_lock( d_table, &entry); for(cell = entry.first; cell != NULL; cell = cell->next){ callee_leg = callee_idx(cell); if( (cell->flags & DLG_FLAG_NEW) != 0 ) { if ( cell->state == DLG_STATE_DELETED ) { /* don't need to insert dialogs already terminated */ continue; } LM_DBG("inserting new dialog %p\n",cell); SET_INT_VALUE(values, cell->h_entry); SET_INT_VALUE(values+1, cell->h_id); SET_STR_VALUE(values+2, cell->callid); SET_STR_VALUE(values+3, cell->from_uri); SET_STR_VALUE(values+4, cell->legs[DLG_CALLER_LEG].tag); SET_STR_VALUE(values+5, cell->to_uri); SET_STR_VALUE(values+6, cell->legs[callee_leg].tag); SET_STR_VALUE(values+7, cell->legs[DLG_CALLER_LEG].bind_addr->sock_str); if (cell->legs[callee_leg].bind_addr) { SET_STR_VALUE(values+8, cell->legs[callee_leg].bind_addr->sock_str); } else { VAL_NULL(values+8) = 1; } SET_INT_VALUE(values+9, cell->start_ts); SET_STR_VALUE(values+10, cell->legs[DLG_CALLER_LEG].route_set); SET_STR_VALUE(values+11, cell->legs[callee_leg].route_set); SET_STR_VALUE(values+12, cell->legs[DLG_CALLER_LEG].contact); SET_STR_VALUE(values+13, cell->legs[callee_leg].contact); SET_STR_VALUE(values+14,cell->legs[callee_leg].from_uri); SET_STR_VALUE(values+15,cell->legs[callee_leg].to_uri); SET_INT_VALUE(values+16, cell->state); SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0) + cell->tl.timeout - get_ticks()) ); SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq); SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq); SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq); SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq); set_final_update_cols(values+22, cell, on_shutdown); SET_INT_VALUE(values+25, cell->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED)); CON_PS_REFERENCE(dialog_db_handle) = &my_ps_insert; if (con_set_inslist(&dialog_dbf,dialog_db_handle, &ins_list,insert_keys,DIALOG_TABLE_TOTAL_COL_NO) < 0 ) CON_RESET_INSLIST(dialog_db_handle); if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, DIALOG_TABLE_TOTAL_COL_NO)) !=0){ LM_ERR("could not add another dialog to db\n"); goto error; } if (ins_done==0) ins_done=1; /* dialog saved */ run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0); cell->flags &= ~(DLG_FLAG_NEW |DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED); } else if ( (cell->flags & DLG_FLAG_CHANGED)!=0 || on_shutdown ){ LM_DBG("updating existing dialog %p\n",cell); SET_INT_VALUE(values, cell->h_entry); SET_INT_VALUE(values+1, cell->h_id); SET_INT_VALUE(values+16, cell->state); SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0) + cell->tl.timeout - get_ticks()) ); SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq); SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq); SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq); SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq); set_final_update_cols(values+22, cell, 1); SET_INT_VALUE(values+25, cell->flags); CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update; if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, (values), (insert_keys+16), (values+16), 2, 10)) !=0) { LM_ERR("could not update database info\n"); goto error; } /* dialog saved */ run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0); cell->flags &= ~(DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED); } else if (cell->flags & DLG_FLAG_VP_CHANGED) { SET_INT_VALUE(values, cell->h_entry); SET_INT_VALUE(values+1, cell->h_id); set_final_update_cols(values+22, cell, 0); CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update_vp; if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, (values), (insert_keys+22), (values+22), 2, 3)) !=0) { LM_ERR("could not update database info\n"); goto error; } run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0); cell->flags &= ~DLG_FLAG_VP_CHANGED; } } dlg_unlock( d_table, &entry); } if (ins_done) { LM_DBG("dlg timer attempting to flush rows to DB\n"); /* flush everything to DB * so that next-time timer fires * we are sure that DB updates will be succesful */ if (ql_flush_rows(&dialog_dbf,dialog_db_handle,ins_list) < 0) LM_ERR("failed to flush rows to DB\n"); } return; error: dlg_unlock( d_table, &entry); }