/* * Convert db_val to pv_spec */ int db_val2pv_spec(struct sip_msg* msg, db_val_t *dbval, pv_spec_t *pvs) { pv_value_t pv; #define LL_LEN 21 /* sign, 19 digits and \0 */ static char ll_buf[LL_LEN]; if(dbval->nul) { pv.flags = PV_VAL_NULL; } else { switch(dbval->type) { case DB1_STRING: pv.flags = PV_VAL_STR; pv.rs.s = (char*)dbval->val.string_val; pv.rs.len = strlen(pv.rs.s); break; case DB1_STR: pv.flags = PV_VAL_STR; pv.rs.s = (char*)dbval->val.str_val.s; pv.rs.len = dbval->val.str_val.len; break; case DB1_BLOB: pv.flags = PV_VAL_STR; pv.rs.s = (char*)dbval->val.blob_val.s; pv.rs.len = dbval->val.blob_val.len; break; case DB1_INT: pv.flags = PV_VAL_INT | PV_TYPE_INT; pv.ri = (int)dbval->val.int_val; break; case DB1_DATETIME: pv.flags = PV_VAL_INT | PV_TYPE_INT; pv.ri = (int)dbval->val.time_val; break; case DB1_BITMAP: pv.flags = PV_VAL_INT | PV_TYPE_INT; pv.ri = (int)dbval->val.bitmap_val; break; case DB1_BIGINT: /* BIGINT is stored as string */ pv.flags = PV_VAL_STR; pv.rs.len = LL_LEN; db_longlong2str(dbval->val.ll_val, ll_buf, &pv.rs.len); pv.rs.s = ll_buf; /* if it fits, also store as 32 bit integer*/ if (! ((unsigned long long)dbval->val.ll_val & 0xffffffff00000000ULL)) { pv.flags |= PV_VAL_INT | PV_TYPE_INT; pv.ri = (int)dbval->val.ll_val; } break; default: LM_NOTICE("unknown field type: %d, setting value to null\n", dbval->type); pv.flags = PV_VAL_NULL; } } /* null values are ignored for avp type PV */ if (pv.flags == PV_VAL_NULL && pvs->type == PVT_AVP) return 0; /* add value to result pv */ if (pv_set_spec_value(msg, pvs, 0, &pv) != 0) { LM_ERR("Failed to add value to spec\n"); return -1; } return 0; }
int sql_do_query(sql_con_t *con, str *query, sql_result_t *res) { db1_res_t* db_res = NULL; int i, j; str sv; if(res) sql_reset_result(res); if(query==NULL) { LM_ERR("bad parameters\n"); return -1; } if(con->dbf.raw_query(con->dbh, query, &db_res)!=0) { LM_ERR("cannot do the query [%.*s]\n", (query->len>32)?32:query->len, query->s); return -1; } if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0) { LM_DBG("no result after query\n"); con->dbf.free_result(con->dbh, db_res); return 2; } if(!res) { LM_DBG("no sqlresult parameter, ignoring result from query\n"); con->dbf.free_result(con->dbh, db_res); return 3; } res->ncols = RES_COL_N(db_res); res->nrows = RES_ROW_N(db_res); LM_DBG("rows [%d] cols [%d]\n", res->nrows, res->ncols); res->cols = (sql_col_t*)pkg_malloc(res->ncols*sizeof(sql_col_t)); if(res->cols==NULL) { res->ncols = 0; res->nrows = 0; LM_ERR("no more memory\n"); return -1; } memset(res->cols, 0, res->ncols*sizeof(sql_col_t)); for(i=0; i<res->ncols; i++) { res->cols[i].name.len = (RES_NAMES(db_res)[i])->len; res->cols[i].name.s = (char*)pkg_malloc((res->cols[i].name.len+1) *sizeof(char)); if(res->cols[i].name.s==NULL) { LM_ERR("no more memory\n"); goto error; } memcpy(res->cols[i].name.s, RES_NAMES(db_res)[i]->s, res->cols[i].name.len); res->cols[i].name.s[res->cols[i].name.len]='\0'; res->cols[i].colid = core_case_hash(&res->cols[i].name, 0, 0); } res->vals = (sql_val_t**)pkg_malloc(res->nrows*sizeof(sql_val_t*)); if(res->vals==NULL) { LM_ERR("no more memory\n"); goto error; } memset(res->vals, 0, res->nrows*sizeof(sql_val_t*)); for(i=0; i<res->nrows; i++) { res->vals[i] = (sql_val_t*)pkg_malloc(res->ncols*sizeof(sql_val_t)); if(res->vals[i]==NULL) { LM_ERR("no more memory\n"); goto error; } memset(res->vals[i], 0, res->ncols*sizeof(sql_val_t)); for(j=0; j<res->ncols; j++) { if(RES_ROWS(db_res)[i].values[j].nul) { res->vals[i][j].flags = PV_VAL_NULL; continue; } sv.s = NULL; sv.len = 0; switch(RES_ROWS(db_res)[i].values[j].type) { case DB1_STRING: res->vals[i][j].flags = PV_VAL_STR; sv.s= (char*)RES_ROWS(db_res)[i].values[j].val.string_val; sv.len=strlen(sv.s); break; case DB1_STR: res->vals[i][j].flags = PV_VAL_STR; sv.len= RES_ROWS(db_res)[i].values[j].val.str_val.len; sv.s= (char*)RES_ROWS(db_res)[i].values[j].val.str_val.s; break; case DB1_BLOB: res->vals[i][j].flags = PV_VAL_STR; sv.len= RES_ROWS(db_res)[i].values[j].val.blob_val.len; sv.s= (char*)RES_ROWS(db_res)[i].values[j].val.blob_val.s; break; case DB1_INT: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = (int)RES_ROWS(db_res)[i].values[j].val.int_val; break; case DB1_DATETIME: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = (int)RES_ROWS(db_res)[i].values[j].val.time_val; break; case DB1_BITMAP: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = (int)RES_ROWS(db_res)[i].values[j].val.bitmap_val; break; case DB1_BIGINT: res->vals[i][j].flags = PV_VAL_STR; res->vals[i][j].value.s.len = 21*sizeof(char); res->vals[i][j].value.s.s = (char*)pkg_malloc(res->vals[i][j].value.s.len); if(res->vals[i][j].value.s.s==NULL) { LM_ERR("no more memory\n"); goto error; } db_longlong2str(RES_ROWS(db_res)[i].values[j].val.ll_val, res->vals[i][j].value.s.s, &res->vals[i][j].value.s.len); break; default: res->vals[i][j].flags = PV_VAL_NULL; } if(res->vals[i][j].flags == PV_VAL_STR && sv.s) { if(sv.len<=0) { res->vals[i][j].value.s.s = _sql_empty_buf; res->vals[i][j].value.s.len = 0; continue; } res->vals[i][j].value.s.s = (char*)pkg_malloc(sv.len*sizeof(char)); if(res->vals[i][j].value.s.s==NULL) { LM_ERR("no more memory\n"); goto error; } memcpy(res->vals[i][j].value.s.s, sv.s, sv.len); res->vals[i][j].value.s.len = sv.len; } } } con->dbf.free_result(con->dbh, db_res); return 1; error: con->dbf.free_result(con->dbh, db_res); sql_reset_result(res); return -1; }