/* * Release memory used by columns */ int db_free_columns(db1_res_t* _r) { int col; if (!_r) { LM_ERR("invalid parameter value\n"); return -1; } LM_DBG("freeing %d columns\n", RES_COL_N(_r)); /* free memory previously allocated to save column names */ for(col = 0; col < RES_COL_N(_r); col++) { if (RES_NAMES(_r)[col]!=NULL) { LM_DBG("freeing RES_NAMES[%d] at %p\n", col, RES_NAMES(_r)[col]); pkg_free((str *)RES_NAMES(_r)[col]); RES_NAMES(_r)[col] = NULL; } } RES_COL_N(_r) = 0; /* free names and types */ if (RES_NAMES(_r)) { LM_DBG("freeing result names at %p\n", RES_NAMES(_r)); pkg_free(RES_NAMES(_r)); RES_NAMES(_r) = NULL; } if (RES_TYPES(_r)) { LM_DBG("freeing result types at %p\n", RES_TYPES(_r)); pkg_free(RES_TYPES(_r)); RES_TYPES(_r) = NULL; } return 0; }
/* * Convert a row from result into db API representation */ int convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; #ifndef PARANOID if ((!_h) || (!_r) || (!_n)) { log(L_ERR, "convert_row(): Invalid parameter value\n"); return -1; } #endif ROW_VALUES(_r) = (db_val_t*)pkg_malloc(sizeof(db_val_t) * RES_COL_N(_res)); ROW_N(_r) = RES_COL_N(_res); if (!ROW_VALUES(_r)) { LOG(L_ERR, "convert_row(): No memory left\n"); return -1; } lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i]) < 0) { LOG(L_ERR, "convert_row(): Error while converting value\n"); free_row(_r); return -3; } } return 0; }
/* * Free all memory allocated by get_result */ int bdb_free_result(db_con_t* _h, db_res_t* _r) { db_row_t* r; db_val_t* v; int i, j; if (!_r) { #ifdef BDB_EXTRA_DEBUG LOG(L_NOTICE, "BDB:bdb_free_result: NULL pointer\n"); #endif return 0; } for (i = 0; i < RES_ROW_N(_r); i++) { r = &(RES_ROWS(_r)[i]); for (j = 0; j < RES_COL_N(_r); j++) { v = &(ROW_VALUES(r)[j]); if (VAL_TYPE(v) == DB_STRING || VAL_TYPE(v) == DB_STR || VAL_TYPE(v) == DB_BLOB) { free(VAL_STR(v).s); } } free(ROW_VALUES(r)); } free(RES_ROWS(_r)); for (i = 0; i < RES_COL_N(_r); i++) { pkg_free((void *)RES_NAMES(_r)[i]); } pkg_free(RES_NAMES(_r)); pkg_free(RES_TYPES(_r)); pkg_free(_r); return 0; }
int sql_do_pvquery(struct sip_msg *msg, sql_con_t *con, pv_elem_t *query, pvname_list_t *res) { db1_res_t* db_res = NULL; pvname_list_t* pv; str sv; int i, j; if(msg==NULL || query==NULL || res==NULL) { LM_ERR("bad parameters\n"); return -1; } if(pv_printf_s(msg, query, &sv)!=0) { LM_ERR("cannot print the sql query\n"); return -1; } if(con->dbf.raw_query(con->dbh, &sv, &db_res)!=0) { LM_ERR("cannot do the query\n"); 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; } for(i=RES_ROW_N(db_res)-1; i>=0; i--) { pv = res; for(j=0; j<RES_COL_N(db_res); j++) { if (pv == NULL) { LM_ERR("Missing pv spec for column %d\n", j+1); goto error; } if (db_val2pv_spec(msg, &RES_ROWS(db_res)[i].values[j], &pv->sname) != 0) { LM_ERR("Failed to convert value for column %.*s (row %d)\n", RES_NAMES(db_res)[j]->len, RES_NAMES(db_res)[j]->s, i); goto error; } pv = pv->next; } } con->dbf.free_result(con->dbh, db_res); return 1; error: con->dbf.free_result(con->dbh, db_res); return -1; }
/* * Get and convert columns from a result */ static int dbt_get_columns(db1_res_t* _r, dbt_result_p _dres) { int col; if (!_r || !_dres) { LM_ERR("invalid parameter\n"); return -1; } RES_COL_N(_r) = _dres->nrcols; if (!RES_COL_N(_r)) { LM_ERR("no columns\n"); return -2; } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { LM_ERR("could not allocate columns"); return -3; } for(col = 0; col < RES_COL_N(_r); col++) { /* * Its would be not necessary to allocate here new memory, because of * the internal structure of the db_text module. But we do this anyway * to stay confirm to the other database modules. */ RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str)); if (! RES_NAMES(_r)[col]) { LM_ERR("no private memory left\n"); db_free_columns(_r); return -4; } LM_DBG("allocate %d bytes for RES_NAMES[%d] at %p", (int)sizeof(str), col, RES_NAMES(_r)[col]); RES_NAMES(_r)[col]->s = _dres->colv[col].name.s; RES_NAMES(_r)[col]->len = _dres->colv[col].name.len; switch(_dres->colv[col].type) { case DB1_STR: case DB1_STRING: case DB1_BLOB: case DB1_INT: case DB1_DATETIME: case DB1_DOUBLE: RES_TYPES(_r)[col] = _dres->colv[col].type; break; default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use STR as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, _dres->colv[col].type); RES_TYPES(_r)[col] = DB1_STR; break; } } return 0; }
static int print_res(db_res_t* _r) { int i, j; for(i = 0; i < RES_COL_N(_r); i++) { printf("%s ", RES_NAMES(_r)[i]); } printf("\n"); for(i = 0; i < RES_ROW_N(_r); i++) { for(j = 0; j < RES_COL_N(_r); j++) { if (RES_ROWS(_r)[i].values[j].nul == TRUE) { printf("NULL "); continue; } switch(RES_ROWS(_r)[i].values[j].type) { case DB_INT: printf("%d ", RES_ROWS(_r)[i].values[j].val.int_val); break; case DB_DOUBLE: printf("%f ", RES_ROWS(_r)[i].values[j].val.double_val); break; case DB_DATETIME: printf("%s ", ctime(&(RES_ROWS(_r)[i].values[j].val.time_val))); break; case DB_STRING: printf("%s ", RES_ROWS(_r)[i].values[j].val.string_val); break; case DB_STR: printf("%.*s ", RES_ROWS(_r)[i].values[j].val.str_val.len, RES_ROWS(_r)[i].values[j].val.str_val.s); break; case DB_BLOB: printf("%.*s ", RES_ROWS(_r)[i].values[j].val.blob_val.len, RES_ROWS(_r)[i].values[j].val.blob_val.s); break; case DB_BITMAP: printf("%d ", RES_ROWS(_r)[i].values[j].val.bitmap_val); break; } } printf("\n"); } return TRUE; }
/** * Convert a row from the result query into db API representation */ int db_postgres_convert_row(const db_con_t* _h, db_res_t* _r, db_row_t* _row, char **row_buf) { int col, len; if (!_h || !_r || !_row) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_row) = RES_COL_N(_r); /* For each column in the row */ for(col = 0; col < ROW_N(_row); col++) { /* compute the len of the value */ if ( row_buf[col]==NULL || row_buf[col][0]=='\0') len = 0; else len = strlen(row_buf[col]); /* Convert the string representation into the value representation */ if (db_postgres_str2val(RES_TYPES(_r)[col], &(ROW_VALUES(_row)[col]), row_buf[col], len) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %pn", _row); db_free_row(_row); return -3; } } return 0; }
/*! * \brief Convert a row from result into DB API representation * \param _h database connection * \param _res database result in the DB API representation * \param _r database result row * \return 0 on success, -1 on failure */ int db_mysql_convert_row(const db1_con_t* _h, db1_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } if (db_allocate_row(_res, _r) != 0) { LM_ERR("could not allocate row"); return -2; } lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (db_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i], 0) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } return 0; }
/** * Allocate memory for row value. * \param _res result set * \param _row filled row * \return zero on success, negative on errors */ inline int db_allocate_row(const db1_res_t* _res, db_row_t* _row) { int len = sizeof(db_val_t) * RES_COL_N(_res); ROW_VALUES(_row) = (db_val_t*)pkg_malloc(len); if (!ROW_VALUES(_row)) { LM_ERR("no private memory left\n"); return -1; } LM_DBG("allocate %d bytes for row values at %p\n", len, ROW_VALUES(_row)); memset(ROW_VALUES(_row), 0, len); /* Save the number of columns in the ROW structure */ ROW_N(_row) = RES_COL_N(_res); return 0; }
int bdb_get_columns(table_p _tp, db_res_t* _res, int* _lres, int _nc) { int col; if (!_res) { LM_ERR("invalid parameter\n"); return -1; } if (_nc < 0 ) { LM_ERR("_nc parameter cannot be negative \n"); return -1; } /* the number of rows (tuples) in the query result. */ RES_NUM_ROWS(_res) = 1; if (!_lres) _nc = _tp->ncols; /* Save number of columns in the result structure */ RES_COL_N(_res) = _nc; if (db_allocate_columns(_res, RES_COL_N(_res)) != 0) { LM_ERR("could not allocate columns"); return -2; } /* * For each column both the name and the data type are saved. */ for(col = 0; col < RES_COL_N(_res); col++) { column_p cp = NULL; cp = (_lres) ? _tp->colp[_lres[col]] : _tp->colp[col]; /* The pointer that is here returned is part of the result structure.*/ RES_NAMES(_res)[col]->s = cp->name.s; RES_NAMES(_res)[col]->len = cp->name.len; LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_res)[col] , col, RES_NAMES(_res)[col]->len, RES_NAMES(_res)[col]->s); RES_TYPES(_res)[col] = cp->type; } return 0; }
/* * Get and convert columns from a result */ static int dbt_get_columns(db_con_t* _h, db_res_t* _r) { int col; if (!_h || !_r) { LM_ERR("invalid parameter\n"); return -1; } RES_COL_N(_r) = DBT_CON_RESULT(_h)->nrcols; if (!RES_COL_N(_r)) { LM_ERR("no columns\n"); return -2; } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { LM_ERR("could not allocate columns\n"); return -3; } for(col = 0; col < RES_COL_N(_r); col++) { RES_NAMES(_r)[col]->s = DBT_CON_RESULT(_h)->colv[col].name.s; RES_NAMES(_r)[col]->len = DBT_CON_RESULT(_h)->colv[col].name.len; switch(DBT_CON_RESULT(_h)->colv[col].type) { case DB_STR: case DB_STRING: case DB_BLOB: case DB_INT: case DB_BIGINT: case DB_DATETIME: case DB_DOUBLE: RES_TYPES(_r)[col] = DBT_CON_RESULT(_h)->colv[col].type; break; default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use STR as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, DBT_CON_RESULT(_h)->colv[col].type); RES_TYPES(_r)[col] = DB_STR; break; } } return 0; }
int db_build_userbl_tree(const str *username, const str *domain, const str *table, struct dtrie_node_t *root, int use_domain) { db_key_t columns[2] = { &userblacklist_prefix_col, &userblacklist_whitelist_col }; db_key_t key[2] = { &userblacklist_username_col, &userblacklist_domain_col }; db_val_t val[2]; db1_res_t *res; int i; int n = 0; void *nodeflags; VAL_TYPE(val) = VAL_TYPE(val + 1) = DB1_STR; VAL_NULL(val) = VAL_NULL(val + 1) = 0; VAL_STR(val).s = username->s; VAL_STR(val).len = username->len; VAL_STR(val + 1).s = domain->s; VAL_STR(val + 1).len = domain->len; if (userblacklist_dbf.use_table(userblacklist_dbh, table) < 0) { LM_ERR("cannot use table '%.*s'.\n", table->len, table->s); return -1; } if (userblacklist_dbf.query(userblacklist_dbh, key, 0, val, columns, (!use_domain) ? (1) : (2), 2, 0, &res) < 0) { LM_ERR("error while executing query.\n"); return -1; } dtrie_clear(root, NULL, match_mode); if (RES_COL_N(res) > 1) { for(i = 0; i < RES_ROW_N(res); i++) { if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) { if ((RES_ROWS(res)[i].values[0].type == DB1_STRING) && (RES_ROWS(res)[i].values[1].type == DB1_INT)) { /* LM_DBG("insert into tree prefix %s, whitelist %d", RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); */ if (RES_ROWS(res)[i].values[1].val.int_val == 0) { nodeflags=(void *)MARK_BLACKLIST; } else { nodeflags=(void *)MARK_WHITELIST; } if (dtrie_insert(root, RES_ROWS(res)[i].values[0].val.string_val, strlen(RES_ROWS(res)[i].values[0].val.string_val), nodeflags, match_mode) < 0) LM_ERR("could not insert values into trie.\n"); n++; } else { LM_ERR("got invalid result type from query.\n"); } } } } userblacklist_dbf.free_result(userblacklist_dbh, res); return n; }
/* * Get and convert columns from a result */ int dbt_get_columns(db_con_t* _h, db_res_t* _r) { int n, i; if ((!_h) || (!_r)) { #ifdef DBT_EXTRA_DEBUG LOG(L_ERR, "DBT:dbt_get_columns: Invalid parameter\n"); #endif return -1; } n = DBT_CON_RESULT(_h)->nrcols; if (!n) { LOG(L_ERR, "DBT:get_columns: No columns\n"); return -2; } RES_NAMES(_r) = (db_key_t*)pkg_malloc(sizeof(db_key_t) * n); if (!RES_NAMES(_r)) { LOG(L_ERR, "DBT:get_columns: No memory left\n"); return -3; } RES_TYPES(_r) = (db_type_t*)pkg_malloc(sizeof(db_type_t) * n); if (!RES_TYPES(_r)) { LOG(L_ERR, "DBT:get_columns: No memory left\n"); pkg_free(RES_NAMES(_r)); return -4; } RES_COL_N(_r) = n; for(i = 0; i < n; i++) { RES_NAMES(_r)[i] = DBT_CON_RESULT(_h)->colv[i].name.s; switch( DBT_CON_RESULT(_h)->colv[i].type) { case DB_INT: case DB_DATETIME: RES_TYPES(_r)[i] = DB_INT; break; case DB_DOUBLE: RES_TYPES(_r)[i] = DB_DOUBLE; break; default: RES_TYPES(_r)[i] = DB_STR; break; } } return 0; }
/** * Release a result set from memory. * \param _h handle to the database * \param _r result set that should be freed * \return zero on success, negative value on failure */ int db_sqlite_free_result(db_con_t* _h, db_res_t* _r) { int i; int j; db_val_t* v; db_row_t* res_col; if (!_h) { LM_ERR("invalid database handle\n"); return -1; } if (!_r) { LM_DBG("nothing to free!\n"); return 0; } if (RES_ROWS(_r)) { LM_DBG("freeing rows at %p\n", RES_ROWS(_r)); for (i = 0; i < RES_ROW_N(_r); i++) { for (j = 0; j < RES_COL_N(_r); j++) { res_col = &_r->rows[i]; v = &res_col->values[j]; if (VAL_NULL(v)) continue; /* only allocated types; STR and BLOB;*/ if (VAL_TYPE(v) == DB_STR) { pkg_free(VAL_STR(v).s); VAL_STR(v).s = 0; } else if (VAL_TYPE(v) == DB_BLOB) { pkg_free(VAL_BLOB(v).s); VAL_BLOB(v).s = 0; } } } pkg_free(_r->rows[0].values); pkg_free(_r->rows); RES_ROWS(_r) = NULL; } RES_ROW_N(_r) = 0; pkg_free(_r); _r = NULL; return 0; }
/** * Builds a d-tree using database entries. * \return negative on failure, postive on success, indicating the number of d-tree entries */ int db_build_userbl_tree(const str *username, const str *domain, const str *table, struct dt_node_t *root, int use_domain) { db_key_t columns[2] = { &prefix_col, &whitelist_col }; db_key_t key[2] = { &username_key, &domain_key }; db_val_t val[2]; VAL_TYPE(val) = VAL_TYPE(val + 1) = DB_STR; VAL_NULL(val) = VAL_NULL(val + 1) = 0; VAL_STR(val).s = username->s; VAL_STR(val).len = username->len; VAL_STR(val + 1).s = domain->s; VAL_STR(val + 1).len = domain->len; db_res_t *res; int i; int n = 0; if (dbf.use_table(dbc, table) < 0) { LM_ERR("cannot use table '%.*s'.\n", table->len, table->s); return -1; } if (dbf.query(dbc, key, 0, val, columns, (!use_domain) ? (1) : (2), 2, 0, &res) < 0) { LM_ERR("error while executing query.\n"); return -1; } dt_clear(root); if (RES_COL_N(res) > 1) { for(i = 0; i < RES_ROW_N(res); i++) { if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) { if ((RES_ROWS(res)[i].values[0].type == DB_STRING) && (RES_ROWS(res)[i].values[1].type == DB_INT)) { /* LM_DBG("insert into tree prefix %s, whitelist %d", RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); */ dt_insert(root, RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); n++; } else { LM_ERR("got invalid result type from query.\n"); } } } } dbf.free_result(dbc, res); return n; }
/* * Convert a row from result into db API representation */ int db_unixodbc_convert_row(const db_con_t* _h, const db_res_t* _res, db_row_t* _r, const unsigned long* lengths) { int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); for(i = 0; i < RES_COL_N(_res); i++) { if (db_unixodbc_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((CON_ROW(_h))[i]), lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } return 0; }
/** * Convert a row from result into db API representation */ int db_mysql_convert_row(const db_con_t* _h, db_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); if (CON_HAS_PS(_h)) { for(i=0; i < CON_MYSQL_PS(_h)->cols_out; i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), CON_PS_OUTCOL(_h, i).null?NULL:CON_PS_OUTCOL(_h, i).buf, CON_PS_OUTCOL(_h,i).len) < 0) { LM_ERR("failed to convert value from stmt\n"); db_free_row(_r); return -3; } } } else { lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } } return 0; }
/* * Create a new result structure and initialize it */ db_res_t* dbt_new_result(void) { db_res_t* r; r = (db_res_t*)pkg_malloc(sizeof(db_res_t)); if (!r) { LOG(L_ERR, "new_result(): No memory left\n"); return 0; } RES_NAMES(r) = 0; RES_TYPES(r) = 0; RES_COL_N(r) = 0; RES_ROWS(r) = 0; RES_ROW_N(r) = 0; return r; }
/* * Allocate storage for rows in existing * result structure. */ int db_allocate_rows(db_res_t* _res, const unsigned int rows) { unsigned int i; RES_ROWS(_res) = (struct db_row*)pkg_malloc (rows * (sizeof(db_row_t) + sizeof(db_val_t) * RES_COL_N(_res)) ); if (!RES_ROWS(_res)) { LM_ERR("no memory left\n"); return -1; } memset( RES_ROWS(_res), 0 , rows * (sizeof(db_row_t) + sizeof(db_val_t) * RES_COL_N(_res))); LM_DBG("allocate %d bytes for result rows and values at %p\n", (int)(rows * (sizeof(db_row_t) + sizeof(db_val_t) * RES_COL_N(_res))), RES_ROWS(_res)); for( i=0 ; i<rows ; i++ ) /* the values of the row i */ ROW_VALUES( &(RES_ROWS(_res)[i]) ) = ((db_val_t*)(RES_ROWS(_res)+rows)) + RES_COL_N(_res)*i; return 0; }
/** * Rebuild matrix using database entries * \return negative on failure, positive on success, indicating the number of matrix entries */ static int db_reload_matrix(void) { db_key_t columns[3] = { &matrix_first_col, &matrix_second_col, &matrix_res_col }; db1_res_t *res; int i; int n = 0; if (matrix_dbf.use_table(matrix_dbh, &matrix_table) < 0) { LM_ERR("cannot use table '%.*s'.\n", matrix_table.len, matrix_table.s); return -1; } if (matrix_dbf.query(matrix_dbh, NULL, NULL, NULL, columns, 0, 3, NULL, &res) < 0) { LM_ERR("error while executing query.\n"); return -1; } /* critical section start: avoids dirty reads when updating d-tree */ lock_get(lock); matrix_clear(); if (RES_COL_N(res) > 2) { for(i = 0; i < RES_ROW_N(res); i++) { if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) { if ((RES_ROWS(res)[i].values[0].type == DB1_INT) && (RES_ROWS(res)[i].values[1].type == DB1_INT) && (RES_ROWS(res)[i].values[2].type == DB1_INT)) { matrix_insert(RES_ROWS(res)[i].values[0].val.int_val, RES_ROWS(res)[i].values[1].val.int_val, RES_ROWS(res)[i].values[2].val.int_val); n++; } else { LM_ERR("got invalid result type from query.\n"); } } } } /* critical section end */ lock_release(lock); matrix_dbf.free_result(matrix_dbh, res); LM_INFO("loaded %d matrix entries.", n); return n; }
/** * This function check the CQLresult of the CQL query and * adds the columns to the returning result structure. * * \param _cql_res handle for the CQLResult * \param _r result set for storage * \return zero on success, negative value on failure */ int cql_get_columns(oac::CqlResult& _cql_res, db1_res_t* _r) { std::vector<oac::CqlRow> res_cql_rows = _cql_res.rows; int rows_no = res_cql_rows.size(); int cols_no = 0; LM_DBG("cqlrow Vector size =%d\n", rows_no); if (rows_no > 0) { cols_no = res_cql_rows[0].columns.size(); LM_DBG("There are %d columns available, this should be the case for all %d rows (consider cql).\n", cols_no, rows_no); } else { LM_DBG("Got 0 rows. There is no result from the query.\n"); return 0; } RES_COL_N(_r) = cols_no; if (!RES_COL_N(_r)) { LM_ERR("no columns returned from the query\n"); return -2; } else { LM_DBG("%d columns returned from the query\n", RES_COL_N(_r)); } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { LM_ERR("Could not allocate columns\n"); return -3; } /* For fields we will use the columns inside the first columns */ for(int col = 0; col < RES_COL_N(_r); col++) { RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str)); if (! RES_NAMES(_r)[col]) { LM_ERR("no private memory left\n"); RES_COL_N(_r) = col; db_free_columns(_r); return -4; } LM_DBG("Allocated %lu bytes for RES_NAMES[%d] at %p\n", (unsigned long)sizeof(str), col, RES_NAMES(_r)[col]); /* The pointer that is here returned is part of the result structure. */ RES_NAMES(_r)[col]->s = (char*) res_cql_rows[0].columns[col].name.c_str(); RES_NAMES(_r)[col]->len = strlen(RES_NAMES(_r)[col]->s); RES_TYPES(_r)[col] = DB1_STR; LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s); } return 0; }
/** * Rebuild d-tree using database entries * \return negative on failure, positive on success, indicating the number of d-tree entries */ int db_reload_source(const str *table, struct dtrie_node_t *root) { db_key_t columns[2] = { &globalblacklist_prefix_col, &globalblacklist_whitelist_col }; db1_res_t *res; int i; int n = 0; void *nodeflags; if (userblacklist_dbf.use_table(userblacklist_dbh, table) < 0) { LM_ERR("cannot use table '%.*s'.\n", table->len, table->s); return -1; } if (userblacklist_dbf.query(userblacklist_dbh, NULL, NULL, NULL, columns, 0, 2, NULL, &res) < 0) { LM_ERR("error while executing query.\n"); return -1; } dtrie_clear(root, NULL, match_mode); if (RES_COL_N(res) > 1) { for(i = 0; i < RES_ROW_N(res); i++) { if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) { if ((RES_ROWS(res)[i].values[0].type == DB1_STRING) && (RES_ROWS(res)[i].values[1].type == DB1_INT)) { /* LM_DBG("insert into tree prefix %s, whitelist %d", RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); */ if (RES_ROWS(res)[i].values[1].val.int_val == 0) nodeflags=(void *) MARK_BLACKLIST; else nodeflags=(void *)MARK_WHITELIST; if (dtrie_insert(root, RES_ROWS(res)[i].values[0].val.string_val, strlen(RES_ROWS(res)[i].values[0].val.string_val), nodeflags, match_mode) < 0) LM_ERR("could not insert values into trie.\n"); n++; } else { LM_ERR("got invalid result type from query.\n"); } } } } userblacklist_dbf.free_result(userblacklist_dbh, res); return n; }
/** * Rebuild d-tree using database entries * \return negative on failure, positive on success, indicating the number of d-tree entries */ int db_reload_source(const str *table, struct dt_node_t *root) { db_key_t columns[2] = { &prefix_col, &whitelist_col }; db_res_t *res; int i; int n = 0; if (dbf.use_table(dbc, table) < 0) { LM_ERR("cannot use table '%.*s'.\n", table->len, table->s); return -1; } if (dbf.query(dbc, NULL, NULL, NULL, columns, 0, 2, NULL, &res) < 0) { LM_ERR("error while executing query.\n"); return -1; } dt_clear(root); if (RES_COL_N(res) > 1) { for(i = 0; i < RES_ROW_N(res); i++) { if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) { if ((RES_ROWS(res)[i].values[0].type == DB_STRING) && (RES_ROWS(res)[i].values[1].type == DB_INT)) { /* LM_DBG("insert into tree prefix %s, whitelist %d", RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); */ dt_insert(root, RES_ROWS(res)[i].values[0].val.string_val, RES_ROWS(res)[i].values[1].val.int_val); n++; } else { LM_ERR("got invalid result type from query.\n"); } } } } dbf.free_result(dbc, res); return n; }
/* * Release a result set from memory */ int db_oracle_free_result(db_con_t* _h, db_res_t* _r) { ub4 i; if (!_h || !_r) { LM_ERR("invalid parameter value\n"); return -1; } if (RES_NAMES(_r)) for (i=0; i < RES_COL_N(_r); ++i) if (RES_NAMES(_r)[i]->s) pkg_free(RES_NAMES(_r)[i]->s); if (db_free_result(_r) < 0) { LM_ERR("failed to free result structure\n"); return -1; } return 0; }
int resume_async_dbquery(int fd, struct sip_msg *msg, void *_param) { db_res_t *res = NULL; query_async_param *param = (query_async_param *)_param; int rc, ret; rc = param->dbf->async_resume(param->hdl, fd, &res, param->db_param); if (async_status == ASYNC_CONTINUE || async_status == ASYNC_CHANGE_FD) { return rc; } if (rc != 0) { LM_ERR("async query returned error\n"); ret = -1; goto err_free; } if (!res || RES_ROW_N(res) <= 0 || RES_COL_N(res) <= 0) { LM_DBG("query returned no results\n"); ret = -2; goto err_free; } if (db_query_avp_print_results(msg, res, param->output_avps) != 0) { LM_ERR("failed to print results\n"); ret = -1; goto err_free; } async_status = ASYNC_DONE; param->dbf->async_free_result(param->hdl, res, param->db_param); pkg_free(param); return 1; err_free: param->dbf->async_free_result(param->hdl, res, param->db_param); pkg_free(param); return ret; }
/* * Release a result set from memory */ int perlvdb_db_free_result(db_con_t* _h, db_res_t* _r) { int i,j; SV* temp; /* free result set * use the order of allocation * first free values */ if(_r){ /* for each row */ for(i=0; i < RES_ROW_N(_r); i++){ /* for each column in row i */ for(j=0; j < RES_ROWS(_r)[i].n; j++){ switch ( (RES_ROWS(_r)[i].values)[j].type ) { /* the type of a value j in row i */ case DB_STRING: case DB_STR: pkg_free((RES_ROWS(_r)[i].values)[j].val.str_val.s); break; case DB_BLOB: pkg_free((RES_ROWS(_r)[i].values)[j].val.blob_val.s) ; break; case DB_INT: case DB_BIGINT: case DB_DOUBLE: case DB_BITMAP: case DB_DATETIME: break; } } /* for each column in row i*/ } /* for each row */ for(i=0; i< RES_COL_N(_r); i++){ pkg_free(RES_NAMES(_r)[i]->s); } db_free_result(_r); } return 0; }
/* * Convert a row from result into db API representation */ static int dbt_convert_row(db1_res_t* _res, db_row_t* _r, dbt_row_p _r1) { int i; if (!_r || !_res || !_r1) { LM_ERR("invalid parameter value\n"); return -1; } if (db_allocate_row(_res, _r) != 0) { LM_ERR("could not allocate row"); return -2; } for(i = 0; i < RES_COL_N(_res); i++) { (ROW_VALUES(_r)[i]).nul = _r1->fields[i].nul; switch(RES_TYPES(_res)[i]) { case DB1_INT: VAL_INT(&(ROW_VALUES(_r)[i])) = _r1->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_INT; break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_DOUBLE: VAL_DOUBLE(&(ROW_VALUES(_r)[i])) = _r1->fields[i].val.double_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_DOUBLE; break; case DB1_STRING: VAL_STR(&(ROW_VALUES(_r)[i])).s = _r1->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = _r1->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_STRING; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB1_STR: VAL_STR(&(ROW_VALUES(_r)[i])).s = _r1->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = _r1->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_STR; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB1_DATETIME: VAL_INT(&(ROW_VALUES(_r)[i])) = _r1->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_DATETIME; break; case DB1_BLOB: VAL_STR(&(ROW_VALUES(_r)[i])).s = _r1->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = _r1->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_BLOB; VAL_FREE(&(ROW_VALUES(_r)[i])) = 0; break; case DB1_BITMAP: VAL_INT(&(ROW_VALUES(_r)[i])) = _r1->fields[i].val.bitmap_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_INT; break; default: LM_ERR("val type [%d] not supported", RES_TYPES(_res)[i]); return -1; } } return 0; }
/*! * \brief Get and convert columns from a result * * Get and convert columns from a result, fills the result structure * with data from the database. * \param _h database connection * \param _r database result set * \return 0 on success, negative on failure */ int db_mysql_get_columns(const db1_con_t* _h, db1_res_t* _r) { int col; MYSQL_FIELD* fields; if ((!_h) || (!_r)) { LM_ERR("invalid parameter\n"); return -1; } RES_COL_N(_r) = mysql_field_count(CON_CONNECTION(_h)); if (!RES_COL_N(_r)) { LM_ERR("no columns returned from the query\n"); return -2; } else { LM_DBG("%d columns returned from the query\n", RES_COL_N(_r)); } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { RES_COL_N(_r) = 0; LM_ERR("could not allocate columns\n"); return -3; } fields = mysql_fetch_fields(RES_RESULT(_r)); for(col = 0; col < RES_COL_N(_r); col++) { RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str)); if (! RES_NAMES(_r)[col]) { LM_ERR("no private memory left\n"); db_free_columns(_r); return -4; } LM_DBG("allocate %lu bytes for RES_NAMES[%d] at %p\n", (unsigned long)sizeof(str), col, RES_NAMES(_r)[col]); /* The pointer that is here returned is part of the result structure. */ RES_NAMES(_r)[col]->s = fields[col].name; RES_NAMES(_r)[col]->len = strlen(fields[col].name); LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s); switch(fields[col].type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_TIMESTAMP: LM_DBG("use DB1_INT result type\n"); RES_TYPES(_r)[col] = DB1_INT; break; case MYSQL_TYPE_LONGLONG: LM_DBG("use DB1_BIGINT result type\n"); RES_TYPES(_r)[col] = DB1_BIGINT; break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: LM_DBG("use DB1_DOUBLE result type\n"); RES_TYPES(_r)[col] = DB1_DOUBLE; break; case MYSQL_TYPE_DATETIME: LM_DBG("use DB1_DATETIME result type\n"); RES_TYPES(_r)[col] = DB1_DATETIME; break; case MYSQL_TYPE_BLOB: LM_DBG("use DB1_BLOB result type\n"); RES_TYPES(_r)[col] = DB1_BLOB; break; case FIELD_TYPE_SET: LM_DBG("use DB1_BITMAP result type\n"); RES_TYPES(_r)[col] = DB1_BITMAP; break; case MYSQL_TYPE_DECIMAL: #if MYSQL_VERSION_ID > 49999 case MYSQL_TYPE_NEWDECIMAL: #endif case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: LM_DBG("use DB1_STRING result type\n"); RES_TYPES(_r)[col] = DB1_STRING; break; default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use DB1_STRING as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, fields[col].type); RES_TYPES(_r)[col] = DB1_STRING; break; } } return 0; }
/** * Get and convert columns from a result */ int db_mysql_get_columns(const db_con_t* _h, db_res_t* _r) { int col; MYSQL_FIELD* fields; if ((!_h) || (!_r)) { LM_ERR("invalid parameter\n"); return -1; } if (CON_HAS_PS(_h)) { RES_COL_N(_r) = CON_MYSQL_PS(_h)->cols_out; } else { RES_COL_N(_r) = mysql_field_count(CON_CONNECTION(_h)); } if (!RES_COL_N(_r)) { LM_ERR("no columns returned from the query\n"); return -2; } else { LM_DBG("%d columns returned from the query\n", RES_COL_N(_r)); } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { LM_ERR("could not allocate columns\n"); return -3; } fields = mysql_fetch_fields(CON_RESULT(_h)); for(col = 0; col < RES_COL_N(_r); col++) { /* The pointer that is here returned is part of the result structure */ RES_NAMES(_r)[col]->s = fields[col].name; RES_NAMES(_r)[col]->len = strlen(fields[col].name); LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s); switch(fields[col].type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_DECIMAL: #if MYSQL_VERSION_ID > 49999 case MYSQL_TYPE_NEWDECIMAL: #endif case MYSQL_TYPE_TIMESTAMP: LM_DBG("use DB_INT result type\n"); RES_TYPES(_r)[col] = DB_INT; break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: LM_DBG("use DB_DOUBLE result type\n"); RES_TYPES(_r)[col] = DB_DOUBLE; break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATE: LM_DBG("use DB_DATETIME result type\n"); RES_TYPES(_r)[col] = DB_DATETIME; break; case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: LM_DBG("use DB_BLOB result type\n"); RES_TYPES(_r)[col] = DB_BLOB; break; case FIELD_TYPE_SET: LM_DBG("use DB_BITMAP result type\n"); RES_TYPES(_r)[col] = DB_BITMAP; break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: LM_DBG("use DB_STRING result type\n"); RES_TYPES(_r)[col] = DB_STRING; break; case MYSQL_TYPE_LONGLONG: LM_DBG("use DB_BIGINT result type\n"); RES_TYPES(_r)[col] = DB_BIGINT; break; default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use DB_STRING as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, fields[col].type); RES_TYPES(_r)[col] = DB_STRING; break; } } return 0; }
/* * Get and convert columns from a result */ int db_mysql_get_columns(db_con_t* _h, db_res_t* _r) { int n, i; MYSQL_FIELD* fields; if ((!_h) || (!_r)) { LM_ERR("invalid parameter\n"); return -1; } n = mysql_field_count(CON_CONNECTION(_h)); if (!n) { LM_ERR("no columns\n"); return -2; } RES_NAMES(_r) = (db_key_t*)pkg_malloc(sizeof(db_key_t) * n); if (!RES_NAMES(_r)) { LM_ERR("no private memory left\n"); return -3; } RES_TYPES(_r) = (db_type_t*)pkg_malloc(sizeof(db_type_t) * n); if (!RES_TYPES(_r)) { LM_ERR("no private memory left\n"); pkg_free(RES_NAMES(_r)); return -4; } RES_COL_N(_r) = n; fields = mysql_fetch_fields(CON_RESULT(_h)); for(i = 0; i < n; i++) { RES_NAMES(_r)[i] = fields[i].name; switch(fields[i].type) { case FIELD_TYPE_TINY: case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: case FIELD_TYPE_INT24: case FIELD_TYPE_LONGLONG: case FIELD_TYPE_DECIMAL: case FIELD_TYPE_TIMESTAMP: RES_TYPES(_r)[i] = DB_INT; break; case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: RES_TYPES(_r)[i] = DB_DOUBLE; break; case FIELD_TYPE_DATETIME: RES_TYPES(_r)[i] = DB_DATETIME; break; case FIELD_TYPE_BLOB: case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_LONG_BLOB: RES_TYPES(_r)[i] = DB_BLOB; break; case FIELD_TYPE_SET: RES_TYPES(_r)[i] = DB_BITMAP; break; default: RES_TYPES(_r)[i] = DB_STRING; break; } } return 0; }