00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include "../../dprint.h"
00038 #include "db_ut.h"
00039 #include "db_query.h"
00040 #include "../../globals.h"
00041 #include "../../timer.h"
00042
00043 static str sql_str;
00044 static char *sql_buf = NULL;
00045
00046 static inline int db_do_submit_query(const db1_con_t* _h, const str *_query,
00047 int (*submit_query)(const db1_con_t*, const str*))
00048 {
00049 int ret;
00050 unsigned int ms = 0;
00051
00052 if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0))
00053 ms = TICKS_TO_MS(get_ticks_raw());
00054
00055 ret = submit_query(_h, _query);
00056
00057 if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)) {
00058 ms = TICKS_TO_MS(get_ticks_raw()) - ms;
00059 if(ms >= cfg_get(core, core_cfg, latency_limit_action)) {
00060 LOG(cfg_get(core, core_cfg, latency_log),
00061 "alert - query execution too long [%u ms] for [%.*s]\n",
00062 ms, _query->len<50?_query->len:50, _query->s);
00063 }
00064 }
00065
00066 return ret;
00067 }
00068
00069 int db_do_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
00070 const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
00071 const db_key_t _o, db1_res_t** _r, int (*val2str) (const db1_con_t*,
00072 const db_val_t*, char*, int* _len), int (*submit_query)(const db1_con_t*,
00073 const str*), int (*store_result)(const db1_con_t* _h, db1_res_t** _r))
00074 {
00075 int off, ret;
00076
00077 if (!_h || !val2str || !submit_query || !store_result) {
00078 LM_ERR("invalid parameter value\n");
00079 return -1;
00080 }
00081
00082 if (!_c) {
00083 ret = snprintf(sql_buf, sql_buffer_size, "select * from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00084 if (ret < 0 || ret >= sql_buffer_size) goto error;
00085 off = ret;
00086 } else {
00087 ret = snprintf(sql_buf, sql_buffer_size, "select ");
00088 if (ret < 0 || ret >= sql_buffer_size) goto error;
00089 off = ret;
00090
00091 ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _c, _nc);
00092 if (ret < 0) return -1;
00093 off += ret;
00094
00095 ret = snprintf(sql_buf + off, sql_buffer_size - off, "from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00096 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00097 off += ret;
00098 }
00099 if (_n) {
00100 ret = snprintf(sql_buf + off, sql_buffer_size - off, "where ");
00101 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00102 off += ret;
00103
00104 ret = db_print_where(_h, sql_buf + off,
00105 sql_buffer_size - off, _k, _op, _v, _n, val2str);
00106 if (ret < 0) return -1;;
00107 off += ret;
00108 }
00109 if (_o) {
00110 ret = snprintf(sql_buf + off, sql_buffer_size - off, " order by %.*s", _o->len, _o->s);
00111 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00112 off += ret;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 if (off + 1 >= sql_buffer_size) goto error;
00122 sql_buf[off + 1] = '\0';
00123 sql_str.s = sql_buf;
00124 sql_str.len = off;
00125
00126 if (db_do_submit_query(_h, &sql_str, submit_query) < 0) {
00127 LM_ERR("error while submitting query\n");
00128 return -2;
00129 }
00130
00131 if(_r) {
00132 int tmp = store_result(_h, _r);
00133 if (tmp < 0) {
00134 LM_ERR("error while storing result");
00135 return tmp;
00136 }
00137 }
00138 return 0;
00139
00140 error:
00141 LM_ERR("error while preparing query\n");
00142 return -1;
00143 }
00144
00145
00146 int db_do_raw_query(const db1_con_t* _h, const str* _s, db1_res_t** _r,
00147 int (*submit_query)(const db1_con_t* _h, const str* _c),
00148 int (*store_result)(const db1_con_t* _h, db1_res_t** _r))
00149 {
00150 if (!_h || !_s || !submit_query || !store_result) {
00151 LM_ERR("invalid parameter value\n");
00152 return -1;
00153 }
00154
00155 if (db_do_submit_query(_h, _s, submit_query) < 0) {
00156 LM_ERR("error while submitting query\n");
00157 return -2;
00158 }
00159
00160 if(_r) {
00161 int tmp = store_result(_h, _r);
00162 if (tmp < 0) {
00163 LM_ERR("error while storing result");
00164 return tmp;
00165 }
00166 }
00167 return 0;
00168 }
00169
00170
00171 int db_do_insert_cmd(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00172 const int _n, int (*val2str) (const db1_con_t*, const db_val_t*, char*, int*),
00173 int (*submit_query)(const db1_con_t* _h, const str* _c), int mode)
00174 {
00175 int off, ret;
00176
00177 if (!_h || !_k || !_v || !_n || !val2str || !submit_query) {
00178 LM_ERR("invalid parameter value\n");
00179 return -1;
00180 }
00181
00182 if(mode==1)
00183 ret = snprintf(sql_buf, sql_buffer_size, "insert delayed into %.*s (",
00184 CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00185 else
00186 ret = snprintf(sql_buf, sql_buffer_size, "insert into %.*s (",
00187 CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00188 if (ret < 0 || ret >= sql_buffer_size) goto error;
00189 off = ret;
00190
00191 ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _k, _n);
00192 if (ret < 0) return -1;
00193 off += ret;
00194
00195 ret = snprintf(sql_buf + off, sql_buffer_size - off, ") values (");
00196 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00197 off += ret;
00198
00199 ret = db_print_values(_h, sql_buf + off, sql_buffer_size - off, _v, _n, val2str);
00200 if (ret < 0) return -1;
00201 off += ret;
00202
00203 if (off + 2 > sql_buffer_size) goto error;
00204 sql_buf[off++] = ')';
00205 sql_buf[off] = '\0';
00206 sql_str.s = sql_buf;
00207 sql_str.len = off;
00208
00209 if (db_do_submit_query(_h, &sql_str, submit_query) < 0) {
00210 LM_ERR("error while submitting query\n");
00211 return -2;
00212 }
00213 return 0;
00214
00215 error:
00216 LM_ERR("error while preparing insert operation\n");
00217 return -1;
00218 }
00219
00220 int db_do_insert(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00221 const int _n, int (*val2str) (const db1_con_t*, const db_val_t*, char*, int*),
00222 int (*submit_query)(const db1_con_t* _h, const str* _c))
00223 {
00224 return db_do_insert_cmd(_h, _k, _v, _n, val2str, submit_query, 0);
00225 }
00226
00227 int db_do_insert_delayed(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00228 const int _n, int (*val2str) (const db1_con_t*, const db_val_t*, char*, int*),
00229 int (*submit_query)(const db1_con_t* _h, const str* _c))
00230 {
00231 return db_do_insert_cmd(_h, _k, _v, _n, val2str, submit_query, 1);
00232 }
00233
00234 int db_do_delete(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00235 const db_val_t* _v, const int _n, int (*val2str) (const db1_con_t*,
00236 const db_val_t*, char*, int*), int (*submit_query)(const db1_con_t* _h,
00237 const str* _c))
00238 {
00239 int off, ret;
00240
00241 if (!_h || !val2str || !submit_query) {
00242 LM_ERR("invalid parameter value\n");
00243 return -1;
00244 }
00245
00246 ret = snprintf(sql_buf, sql_buffer_size, "delete from %.*s", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00247 if (ret < 0 || ret >= sql_buffer_size) goto error;
00248 off = ret;
00249
00250 if (_n) {
00251 ret = snprintf(sql_buf + off, sql_buffer_size - off, " where ");
00252 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00253 off += ret;
00254
00255 ret = db_print_where(_h, sql_buf + off,
00256 sql_buffer_size - off, _k, _o, _v, _n, val2str);
00257 if (ret < 0) return -1;
00258 off += ret;
00259 }
00260 if (off + 1 > sql_buffer_size) goto error;
00261 sql_buf[off] = '\0';
00262 sql_str.s = sql_buf;
00263 sql_str.len = off;
00264
00265 if (db_do_submit_query(_h, &sql_str, submit_query) < 0) {
00266 LM_ERR("error while submitting query\n");
00267 return -2;
00268 }
00269 return 0;
00270
00271 error:
00272 LM_ERR("error while preparing delete operation\n");
00273 return -1;
00274 }
00275
00276
00277 int db_do_update(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00278 const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
00279 const int _un, int (*val2str) (const db1_con_t*, const db_val_t*, char*, int*),
00280 int (*submit_query)(const db1_con_t* _h, const str* _c))
00281 {
00282 int off, ret;
00283
00284 if (!_h || !_uk || !_uv || !_un || !val2str || !submit_query) {
00285 LM_ERR("invalid parameter value\n");
00286 return -1;
00287 }
00288
00289 ret = snprintf(sql_buf, sql_buffer_size, "update %.*s set ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00290 if (ret < 0 || ret >= sql_buffer_size) goto error;
00291 off = ret;
00292
00293 ret = db_print_set(_h, sql_buf + off, sql_buffer_size - off, _uk, _uv, _un, val2str);
00294 if (ret < 0) return -1;
00295 off += ret;
00296
00297 if (_n) {
00298 ret = snprintf(sql_buf + off, sql_buffer_size - off, " where ");
00299 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00300 off += ret;
00301
00302 ret = db_print_where(_h, sql_buf + off, sql_buffer_size - off, _k, _o, _v, _n, val2str);
00303 if (ret < 0) return -1;
00304 off += ret;
00305 }
00306 if (off + 1 > sql_buffer_size) goto error;
00307 sql_buf[off] = '\0';
00308 sql_str.s = sql_buf;
00309 sql_str.len = off;
00310
00311 if (db_do_submit_query(_h, &sql_str, submit_query) < 0) {
00312 LM_ERR("error while submitting query\n");
00313 return -2;
00314 }
00315 return 0;
00316
00317 error:
00318 LM_ERR("error while preparing update operation\n");
00319 return -1;
00320 }
00321
00322
00323 int db_do_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00324 const int _n, int (*val2str) (const db1_con_t*, const db_val_t*, char*,
00325 int*), int (*submit_query)(const db1_con_t* _h, const str* _c))
00326 {
00327 int off, ret;
00328
00329 if (!_h || !_k || !_v || !val2str|| !submit_query) {
00330 LM_ERR("invalid parameter value\n");
00331 return -1;
00332 }
00333
00334 ret = snprintf(sql_buf, sql_buffer_size, "replace %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00335 if (ret < 0 || ret >= sql_buffer_size) goto error;
00336 off = ret;
00337
00338 ret = db_print_columns(sql_buf + off, sql_buffer_size - off, _k, _n);
00339 if (ret < 0) return -1;
00340 off += ret;
00341
00342 ret = snprintf(sql_buf + off, sql_buffer_size - off, ") values (");
00343 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00344 off += ret;
00345
00346 ret = db_print_values(_h, sql_buf + off, sql_buffer_size - off, _v, _n,
00347 val2str);
00348 if (ret < 0) return -1;
00349 off += ret;
00350
00351 if (off + 2 > sql_buffer_size) goto error;
00352 sql_buf[off++] = ')';
00353 sql_buf[off] = '\0';
00354 sql_str.s = sql_buf;
00355 sql_str.len = off;
00356
00357 if (db_do_submit_query(_h, &sql_str, submit_query) < 0) {
00358 LM_ERR("error while submitting query\n");
00359 return -2;
00360 }
00361 return 0;
00362
00363 error:
00364 LM_ERR("error while preparing replace operation\n");
00365 return -1;
00366 }
00367
00368 int db_query_init(void)
00369 {
00370 if (sql_buf != NULL)
00371 {
00372 LM_DBG("sql_buf not NULL on init\n");
00373 return 0;
00374 }
00375 LM_DBG("About to allocate sql_buf size = %d\n", sql_buffer_size);
00376 sql_buf = (char*)malloc(sql_buffer_size);
00377 if (sql_buf == NULL)
00378 {
00379 LM_ERR("failed to allocate sql_buf\n");
00380 return -1;
00381 }
00382 return 0;
00383 }
00384
00389 int db_fetch_query(db_func_t *dbf, int frows,
00390 db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
00391 const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
00392 const db_key_t _o, db1_res_t** _r)
00393 {
00394
00395 int ret;
00396
00397 ret = 0;
00398 *_r = NULL;
00399
00400 if (DB_CAPABILITY(*dbf, DB_CAP_FETCH)) {
00401 if(dbf->query(_h, _k, _op, _v, _c, _n, _nc, _o, 0) < 0)
00402 {
00403 LM_ERR("unable to query db for fetch\n");
00404 goto error;
00405 }
00406 if(dbf->fetch_result(_h, _r, frows)<0)
00407 {
00408 LM_ERR("unable to fetch the db result\n");
00409 goto error;
00410 }
00411 ret = 1;
00412 } else {
00413 if(dbf->query(_h, _k, _op, _v, _c, _n, _nc, _o, _r) < 0)
00414 {
00415 LM_ERR("unable to do full db querry\n");
00416 goto error;
00417 }
00418 }
00419
00420 return ret;
00421
00422 error:
00423 if(*_r)
00424 {
00425 dbf->free_result(_h, *_r);
00426 *_r = NULL;
00427 }
00428 return -1;
00429 }
00430
00435 int db_fetch_next(db_func_t *dbf, int frows, db1_con_t* _h,
00436 db1_res_t** _r)
00437 {
00438 int ret;
00439
00440 ret = 0;
00441
00442 if (DB_CAPABILITY(*dbf, DB_CAP_FETCH)) {
00443 if(dbf->fetch_result(_h, _r, frows)<0) {
00444 LM_ERR("unable to fetch next rows\n");
00445 goto error;
00446 }
00447 ret = 1;
00448 }
00449 return ret;
00450
00451 error:
00452 if(*_r)
00453 {
00454 dbf->free_result(_h, *_r);
00455 *_r = NULL;
00456 }
00457 return -1;
00458 }