dbt_table_p dbt_db_get_table(dbt_cache_p _dc, const str *_s) { dbt_table_p _tbc = NULL; int hash; int hashidx; if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) return NULL; hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE); hashidx = hash % DBT_CACHETBL_SIZE; lock_get(&_dbt_cachetbl[hashidx].sem); _tbc = _dbt_cachetbl[hashidx].dtp; while(_tbc) { if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len && _tbc->name.len == _s->len && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len) && !strncasecmp(_tbc->name.s, _s->s, _s->len)) { /* found - if cache mode or no-change, return */ if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1) { LM_DBG("cache or mtime succeeded for [%.*s]\n", _tbc->name.len, _tbc->name.s); return _tbc; } break; } _tbc = _tbc->next; } /* new table */ if(_tbc) /* free old one */ { dbt_db_del_table(_dc, _s, 0); } _tbc = dbt_load_file(_s, &(_dc->name)); if(!_tbc) { lock_release(&_dbt_cachetbl[hashidx].sem); return NULL; } _tbc->hash = hash; _tbc->next = _dbt_cachetbl[hashidx].dtp; if(_dbt_cachetbl[hashidx].dtp) _dbt_cachetbl[hashidx].dtp->prev = _tbc; _dbt_cachetbl[hashidx].dtp = _tbc; /* table is locked */ return _tbc; }
int dbt_query(db1_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v, db_key_t* _c, int _n, int _nc, db_key_t _o, db1_res_t** _r) { dbt_table_p _tbc = NULL; dbt_table_p _tbc_temp = NULL; dbt_row_p _drp = NULL; dbt_row_p *_res = NULL; // dbt_result_p _dres = NULL; int result = 0; int counter = 0; int i=0; int *lkey=NULL, *lres=NULL; db_key_t *_o_k=NULL; /* columns in order-by */ char *_o_op=NULL; /* operators for oder-by */ int _o_n; /* no of elements in order-by */ int *_o_l=NULL; /* column selection for order-by */ // int _o_nc; /* no of elements in _o_l but not lres */ if(_r) *_r = NULL; if ((!_h) || !CON_TABLE(_h)) { LM_ERR("invalid parameters\n"); return -1; } if (_o) { if (dbt_parse_orderbyclause(&_o_k, &_o_op, &_o_n, _o) < 0) return -1; } _tbc_temp = dbt_db_get_temp_table(DBT_CON_CONNECTION(_h)); if(!_tbc_temp) { LM_ERR("unable to allocate temp table\n"); return -1; } /* lock database */ _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); if(!_tbc) { LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s); dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 0); return -1; } if(!_tbc || _tbc->nrcols < _nc) { LM_ERR("table %s not loaded! (too few columns)\n", CON_TABLE(_h)->s); goto error; } if(_k) { lkey = dbt_get_refs(_tbc, _k, _n); if(!lkey) goto error; } if(_c) { lres = dbt_get_refs(_tbc, _c, _nc); if(!lres) goto error; } if(_o_k) { _o_l = dbt_get_refs(_tbc, _o_k, _o_n); if (!_o_l) goto error; /* enlarge select-columns lres by all order-by columns, _o_nc is how many */ // if (dbt_mangle_columnselection(&lres, &_nc, &_o_nc, _o_l, _o_n) < 0) // goto error; } /* LM_DBG("new res with %d cols\n", _nc); _dres = dbt_result_new(_tbc, lres, _nc); if(!_dres) goto error; */ dbt_column_p pPrevCol = NULL; _tbc_temp->colv = (dbt_column_p*) shm_malloc(_nc*sizeof(dbt_column_p)); for(i=0; i < _nc; i++) { dbt_column_p pCol = dbt_column_new(_tbc->colv[ lres[i] ]->name.s, _tbc->colv[ lres[i] ]->name.len); pCol->type = _tbc->colv[ lres[i] ]->type; pCol->flag = _tbc->colv[ lres[i] ]->flag; if(pPrevCol) { pCol->prev = pPrevCol; pPrevCol->next = pCol; } else _tbc_temp->cols = pCol; _tbc_temp->colv[i] = pCol; pPrevCol = pCol; _tbc_temp->nrcols++; } _res = (dbt_row_p*) pkg_malloc(_db_text_max_result_rows * sizeof(dbt_row_p)); if(!_res) { LM_ERR("no more space to allocate for query rows\n"); goto error; } _drp = _tbc->rows; while(_drp && counter < _db_text_max_result_rows) { if(dbt_row_match(_tbc, _drp, lkey, _op, _v, _n)) { _res[counter] = _drp; // if(dbt_result_extract_fields(_tbc, _drp, lres, _dres)) // { // LM_ERR("failed to extract result fields!\n"); // goto clean; // } counter++; } _drp = _drp->next; } if (_o_l) { if (counter > 1) { if (dbt_sort_result_temp(_res, counter, _o_l, _o_op, _o_n) < 0) goto error; } /* last but not least, remove surplus columns */ // if (_o_nc) // dbt_project_result(_dres, _o_nc); } // copy results to temp table _tbc_temp->rows = dbt_result_extract_results(_tbc, _res, counter, lres, _nc); _tbc_temp->nrrows = (_tbc_temp->rows == NULL ? 0 : counter); dbt_table_update_flags(_tbc, DBT_TBFL_ZERO, DBT_FL_IGN, 1); /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); // DBT_CON_TEMP_TABLE(_h) = _tbc_temp; last_temp_table = _tbc_temp; // dbt_release_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name); // dbt_result_print(_tbc_temp); if(lkey) pkg_free(lkey); if(lres) pkg_free(lres); if(_o_k) pkg_free(_o_k); if(_o_op) pkg_free(_o_op); if(_o_l) pkg_free(_o_l); if(_res) pkg_free(_res); if(_r) { result = dbt_get_result(_r, _tbc_temp); // dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 1); if(result != 0) dbt_result_free(_h, _tbc_temp); } return result; error: /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); /* delete temp table */ dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 1); if(_res) pkg_free(_res); if(lkey) pkg_free(lkey); if(lres) pkg_free(lres); if(_o_k) pkg_free(_o_k); if(_o_op) pkg_free(_o_op); if(_o_l) pkg_free(_o_l); LM_ERR("failed to query the table!\n"); return -1; /* clean: dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); if(lkey) pkg_free(lkey); if(lres) pkg_free(lres); if(_o_k) pkg_free(_o_k); if(_o_op) pkg_free(_o_op); if(_o_l) pkg_free(_o_l); return -1; */ }