dbt_table_p dbt_load_file(const str *tbn, const str *dbn) { FILE *fin=NULL; char path[512], buf[4096]; int c, crow, ccol, bp, sign, max_auto; dbt_val_t dtval; dbt_table_p dtp = NULL; dbt_column_p colp, colp0 = NULL; dbt_row_p rowp, rowp0 = NULL; enum {DBT_FLINE_ST, DBT_NLINE_ST, DBT_DATA_ST} state; LM_DBG("request for table [%.*s]\n", tbn->len, tbn->s); if(!tbn || !tbn->s || tbn->len<=0 || tbn->len>=255) return NULL; path[0] = 0; if(dbn && dbn->s && dbn->len>0) { LM_DBG("db is [%.*s]\n", dbn->len, dbn->s); if(dbn->len+tbn->len<511) { strncpy(path, dbn->s, dbn->len); path[dbn->len] = '/'; strncpy(path+dbn->len+1, tbn->s, tbn->len); path[dbn->len+tbn->len+1] = 0; } } if(path[0] == 0) { strncpy(path, tbn->s, tbn->len); path[tbn->len] = 0; } LM_DBG("loading file [%s]\n", path); fin = fopen(path, "rt"); if(!fin) return NULL; dtp = dbt_table_new(tbn, dbn, path); if(!dtp) goto done; state = DBT_FLINE_ST; crow = ccol = -1; colp = colp0 = NULL; rowp = rowp0 = NULL; c = fgetc(fin); max_auto = 0; while(c!=EOF) { switch(state) { case DBT_FLINE_ST: //LM_DBG("state FLINE!\n"); bp = 0; while(c==DBT_DELIM_C) c = fgetc(fin); if(c==DBT_DELIM_R && !colp0) goto clean; if(c==DBT_DELIM_R) { if(dtp->nrcols <= 0) goto clean; dtp->colv = (dbt_column_p*) shm_malloc(dtp->nrcols*sizeof(dbt_column_p)); if(!dtp->colv) goto clean; colp0 = dtp->cols; for(ccol=0; ccol<dtp->nrcols && colp0; ccol++) { dtp->colv[ccol] = colp0; colp0 = colp0->next; } state = DBT_NLINE_ST; break; } while(c!=DBT_DELIM_C && c!='(' && c!=DBT_DELIM_R) { if(c==EOF) goto clean; buf[bp++] = c; c = fgetc(fin); } colp = dbt_column_new(buf, bp); if(!colp) goto clean; //LM_DBG("new col [%.*s]\n", bp, buf); while(c==DBT_DELIM_C) c = fgetc(fin); if(c!='(') goto clean; c = fgetc(fin); while(c==DBT_DELIM_C) c = fgetc(fin); switch(c) { case 's': case 'S': colp->type = DB_STR; LM_DBG("column[%d] is STR!\n", ccol+1); break; case 'i': case 'I': colp->type = DB_INT; LM_DBG("column[%d] is INT!\n", ccol+1); break; case 'l': case 'L': colp->type = DB_BIGINT; LM_DBG("column[%d] is BIGINT!\n", ccol+1); break; case 'd': case 'D': colp->type = DB_DOUBLE; LM_DBG("column[%d] is DOUBLE!\n", ccol+1); break; case 'b': case 'B': colp->type = DB_BLOB; LM_DBG("column[%d] is BLOB!\n", ccol+1); break; case 't': case 'T': colp->type = DB_DATETIME; LM_DBG("column[%d] is TIME!\n", ccol+1); break; default: LM_DBG("wrong column type!\n"); goto clean; } while(c!='\n' && c!=EOF && c!=')' && c!= ',') { if(colp->type == DB_STR && (c=='i'|| c=='I')) { colp->type = DB_STRING; LM_DBG("column[%d] is actually STRING!\n", ccol+1); } c = fgetc(fin); } if(c==',') { //LM_DBG("c=%c!\n", c); c = fgetc(fin); while(c==DBT_DELIM_C) c = fgetc(fin); if(c=='N' || c=='n') { //LM_DBG("NULL flag set!\n"); colp->flag |= DBT_FLAG_NULL; } else if(colp->type==DB_INT && dtp->auto_col<0 && (c=='A' || c=='a')) { //LM_DBG("AUTO flag set!\n"); colp->flag |= DBT_FLAG_AUTO; dtp->auto_col = ccol+1; } else goto clean; while(c!=')' && c!=DBT_DELIM_R && c!=EOF) c = fgetc(fin); } if(c == ')') { //LM_DBG("c=%c!\n", c); if(colp0) { colp->prev = colp0; colp0->next = colp; } else dtp->cols = colp; colp0 = colp; dtp->nrcols++; c = fgetc(fin); } else goto clean; ccol++; break; case DBT_NLINE_ST: //LM_DBG("state NLINE!\n"); while(c==DBT_DELIM_R) c = fgetc(fin); if(rowp) { if(dbt_table_check_row(dtp, rowp)) goto clean; if(!rowp0) dtp->rows = rowp; else { rowp0->next = rowp; rowp->prev = rowp0; } rowp0 = rowp; dtp->nrrows++; } if(c==EOF) break; crow++; ccol = 0; rowp = dbt_row_new(dtp->nrcols); if(!rowp) goto clean; state = DBT_DATA_ST; break; case DBT_DATA_ST: //LM_DBG("state DATA!\n"); //while(c==DBT_DELIM) // c = fgetc(fin); if(ccol == dtp->nrcols && (c==DBT_DELIM_R || c==EOF)) { state = DBT_NLINE_ST; break; } if(ccol>= dtp->nrcols) goto clean; switch(dtp->colv[ccol]->type) { case DB_INT: case DB_BIGINT: case DB_DATETIME: //LM_DBG("INT value!\n"); dtval.val.int_val = 0; dtval.type = dtp->colv[ccol]->type; if(c==DBT_DELIM || (ccol==dtp->nrcols-1 && (c==DBT_DELIM_R || c==EOF))) dtval.nul = 1; else { dtval.nul = 0; sign = 1; if(c=='-') { sign = -1; c = fgetc(fin); } if(c<'0' || c>'9') goto clean; while(c>='0' && c<='9') { dtval.val.int_val=dtval.val.int_val*10+c-'0'; c = fgetc(fin); } dtval.val.int_val *= sign; //LM_DBG("data[%d,%d]=%d\n", crow, // ccol, dtval.val.int_val); } if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF) goto clean; if(dbt_row_set_val(rowp,&dtval,dtp->colv[ccol]->type, ccol)) goto clean; if(ccol == dtp->auto_col) max_auto = (max_auto<dtval.val.int_val)? dtval.val.int_val:max_auto; break; case DB_DOUBLE: //LM_DBG("DOUBLE value!\n"); dtval.val.double_val = 0.0; dtval.type = DB_DOUBLE; if(c==DBT_DELIM || (ccol==dtp->nrcols-1 && (c==DBT_DELIM_R || c==EOF))) dtval.nul = 1; else { dtval.nul = 0; sign = 1; if(c=='-') { sign = -1; c = fgetc(fin); } if(c<'0' || c>'9') goto clean; while(c>='0' && c<='9') { dtval.val.double_val = dtval.val.double_val*10 + c - '0'; c = fgetc(fin); } if(c=='.') { c = fgetc(fin); bp = 1; while(c>='0' && c<='9') { bp *= 10; dtval.val.double_val+=((double)(c-'0'))/bp; c = fgetc(fin); } } dtval.val.double_val *= sign; //LM_DBG("data[%d,%d]=%10.2f\n", // crow, ccol, dtval.val.double_val); } if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF) goto clean; if(dbt_row_set_val(rowp,&dtval,DB_DOUBLE,ccol)) goto clean; break; case DB_STR: case DB_STRING: case DB_BLOB: //LM_DBG("STR value!\n"); dtval.val.str_val.s = NULL; dtval.val.str_val.len = 0; dtval.type = dtp->colv[ccol]->type; bp = 0; if(c==DBT_DELIM || (ccol == dtp->nrcols-1 && (c == DBT_DELIM_R || c==EOF))) dtval.nul = 1; else { dtval.nul = 0; while(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF) { if(c=='\\') { c = fgetc(fin); switch(c) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case '\\': c = '\\'; break; case DBT_DELIM: c = DBT_DELIM; break; case '0': c = 0; break; default: goto clean; } } buf[bp++] = c; c = fgetc(fin); } dtval.val.str_val.s = buf; dtval.val.str_val.len = bp; //LM_DBG("data[%d,%d]=%.*s\n", /// crow, ccol, bp, buf); } if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF) goto clean; if(dbt_row_set_val(rowp,&dtval,dtp->colv[ccol]->type, ccol)) goto clean; break; default: goto clean; } if(c==DBT_DELIM) c = fgetc(fin); ccol++; break; // state DBT_DATA_ST } } if(max_auto) dtp->auto_val = max_auto; done: if(fin) fclose(fin); return dtp; clean: /// ????? FILL IT IN - incomplete row/column // memory leak?!?! with last incomplete row LM_DBG("error at row=%d col=%d c=%c\n", crow+1, ccol+1, c); if(dtp) dbt_table_free(dtp); return NULL; }
/* * Insert a row into table */ int dbt_insert(db1_con_t* _h, db_key_t* _k, db_val_t* _v, int _n) { dbt_table_p _tbc = NULL; dbt_row_p _drp = NULL; int *lkey=NULL, i, j; if (!_h || !CON_TABLE(_h)) { LM_ERR("invalid parameter\n"); return -1; } ((dbt_con_p)_h->tail)->affected = 0; if(!_k || !_v || _n<=0) { LM_ERR("no key-value to insert\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); return -1; } if(_tbc->nrcols<_n) { LM_ERR("more values than columns!!\n"); goto error; } if(_k) { lkey = dbt_get_refs(_tbc, _k, _n); if(!lkey) goto error; } _drp = dbt_row_new(_tbc->nrcols); if(!_drp) { LM_ERR("no shm memory for a new row!!\n"); goto error; } for(i=0; i<_n; i++) { j = (lkey)?lkey[i]:i; if(dbt_is_neq_type(_tbc->colv[j]->type, _v[i].type)) { LM_ERR("incompatible types v[%d] - c[%d]!\n", i, j); goto clean; } if(_v[i].type == DB1_STRING && !_v[i].nul) _v[i].val.str_val.len = strlen(_v[i].val.string_val); if(dbt_row_set_val(_drp, &(_v[i]), _tbc->colv[j]->type, j)) { LM_ERR("cannot set v[%d] in c[%d]!\n", i, j); goto clean; } } if(dbt_table_add_row(_tbc, _drp)) { LM_ERR("cannot insert the new row!!\n"); goto clean; } ((dbt_con_p)_h->tail)->affected = 1; /* dbt_print_table(_tbc, NULL); */ /* unlock databse */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); if(lkey) pkg_free(lkey); return 0; error: /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); if(lkey) pkg_free(lkey); LM_ERR("failed to insert row in table!\n"); return -1; clean: if(lkey) pkg_free(lkey); if(_drp) // free row dbt_row_free(_tbc, _drp); /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); return -1; }
int dbt_replace(db1_con_t* _h, db_key_t* _k, db_val_t* _v, int _n, int _nk, int _m) { dbt_table_p _tbc = NULL; dbt_row_p _drp = NULL; int i, j; int *lkey=NULL, *lres=NULL; if (!_h || !CON_TABLE(_h) || _nk <= 0) { LM_ERR("invalid parameters\n"); return -1; } ((dbt_con_p)_h->tail)->affected = 0; /* 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); return -1; } if(_k) { lkey = dbt_get_refs(_tbc, _k, _nk); if(!lkey) goto error; } lres = dbt_get_refs(_tbc, _k, _n); if(!lres) goto error; _drp = _tbc->rows; while(_drp) { if(dbt_row_match(_tbc, _drp, lkey, NULL, _v, _nk)) { // update fields for(i=0; i<_n; i++) { if(dbt_is_neq_type(_tbc->colv[lres[i]]->type, _v[i].type)) { LM_ERR("incompatible types!\n"); goto error; } if(dbt_row_update_val(_drp, &(_v[i]), _tbc->colv[lres[i]]->type, lres[i])) { LM_ERR("cannot set v[%d] in c[%d]!\n", i, lres[i]); goto error; } } ((dbt_con_p)_h->tail)->affected++; break; } _drp = _drp->next; } if(((dbt_con_p)_h->tail)->affected == 0) { _drp = dbt_row_new(_tbc->nrcols); if(!_drp) { LM_ERR("no shm memory for a new row!!\n"); goto error; } for(i=0; i<_n; i++) { j = lres[i]; if(dbt_is_neq_type(_tbc->colv[j]->type, _v[i].type)) { LM_ERR("incompatible types v[%d] - c[%d]!\n", i, j); goto error; } if(_v[i].type == DB1_STRING && !_v[i].nul) _v[i].val.str_val.len = strlen(_v[i].val.string_val); if(dbt_row_set_val(_drp, &(_v[i]), _tbc->colv[j]->type, j)) { LM_ERR("cannot set v[%d] in c[%d]!\n", i, j); goto error; } } if(dbt_table_add_row(_tbc, _drp)) { LM_ERR("cannot insert the new row!!\n"); goto error; } ((dbt_con_p)_h->tail)->affected = 1; } if( ((dbt_con_p)_h->tail)->affected ) dbt_table_update_flags(_tbc, DBT_TBFL_MODI, DBT_FL_SET, 1); /* dbt_print_table(_tbc, NULL); */ /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); if(lkey) pkg_free(lkey); if(lres) pkg_free(lres); return 0; error: if(lkey) pkg_free(lkey); if(lres) pkg_free(lres); if(_drp) // free row dbt_row_free(_tbc, _drp); /* unlock database */ dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h)); LM_ERR("failed to update the table!\n"); return -1; }
/* * Insert a row into table */ int dbt_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n) { tbl_cache_p _tbc = NULL; dbt_table_p _dtp = NULL; dbt_row_p _drp = NULL; str stbl; int *lkey=NULL, i, j; if (!_h || !CON_TABLE(_h)) { #ifdef DBT_EXTRA_DEBUG LOG(L_ERR, "DBT:dbt_insert: Invalid parameter value\n"); #endif return -1; } if(!_k || !_v || _n<=0) { #ifdef DBT_EXTRA_DEBUG DBG("DBT:dbt_insert: no key-value to insert\n"); #endif return -1; } stbl.s = (char*)CON_TABLE(_h); stbl.len = strlen(CON_TABLE(_h)); _tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), &stbl); if(!_tbc) { DBG("DBT:db_insert: table does not exist!\n"); return -1; } lock_get(&_tbc->sem); _dtp = _tbc->dtp; if(!_dtp) { DBG("DBT:db_insert: table does not exist!!\n"); goto error; } if(_dtp->nrcols<_n) { DBG("DBT:db_insert: more values than columns!!\n"); goto error; } if(_k) { lkey = dbt_get_refs(_dtp, _k, _n); if(!lkey) goto error; } _drp = dbt_row_new(_dtp->nrcols); if(!_drp) { DBG("DBT:db_insert: no memory for a new row!!\n"); goto error; } for(i=0; i<_n; i++) { j = (lkey)?lkey[i]:i; if(dbt_is_neq_type(_dtp->colv[j]->type, _v[i].type)) { DBG("DBT:db_insert: incompatible types v[%d] - c[%d]!\n", i, j); goto clean; } if(dbt_row_set_val(_drp, &(_v[i]), _v[i].type, j)) { DBG("DBT:db_insert: cannot set v[%d] in c[%d]!\n", i, j); goto clean; } } if(dbt_table_add_row(_dtp, _drp)) { DBG("DBT:db_insert: cannot insert the new row!!\n"); goto clean; } #ifdef DBT_EXTRA_DEBUG dbt_print_table(_dtp, NULL); #endif lock_release(&_tbc->sem); if(lkey) pkg_free(lkey); DBG("DBT:db_insert: done!\n"); return 0; error: lock_release(&_tbc->sem); if(lkey) pkg_free(lkey); DBG("DBT:db_insert: error inserting row in table!\n"); return -1; clean: lock_release(&_tbc->sem); if(lkey) pkg_free(lkey); if(_drp) // free row dbt_row_free(_dtp, _drp); DBG("DBT:db_insert: make clean!\n"); return -1; }