00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <mysql/mysql.h>
00039 #include <mysql/errmsg.h>
00040 #include <mysql/mysql_version.h>
00041 #include "../../mem/mem.h"
00042 #include "../../dprint.h"
00043 #include "../../lib/srdb1/db_query.h"
00044 #include "../../lib/srdb1/db_ut.h"
00045 #include "mysql_mod.h"
00046 #include "km_val.h"
00047 #include "km_my_con.h"
00048 #include "km_res.h"
00049 #include "km_row.h"
00050 #include "km_db_mysql.h"
00051 #include "km_dbase.h"
00052
00053 static char *mysql_sql_buf;
00054
00055
00071 static int db_mysql_submit_query(const db1_con_t* _h, const str* _s)
00072 {
00073 time_t t;
00074 int i, code;
00075
00076 if (!_h || !_s || !_s->s) {
00077 LM_ERR("invalid parameter value\n");
00078 return -1;
00079 }
00080
00081 if (my_ping_interval) {
00082 t = time(0);
00083 if ((t - CON_TIMESTAMP(_h)) > my_ping_interval) {
00084 if (mysql_ping(CON_CONNECTION(_h))) {
00085 LM_WARN("driver error on ping: %s\n", mysql_error(CON_CONNECTION(_h)));
00086 counter_inc(mysql_cnts_h.driver_err);
00087 }
00088 }
00089
00090
00091
00092
00093
00094 CON_TIMESTAMP(_h) = t;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 for (i=0; i < (db_mysql_auto_reconnect ? 3 : 1); i++) {
00113 if (mysql_real_query(CON_CONNECTION(_h), _s->s, _s->len) == 0) {
00114 return 0;
00115 }
00116 code = mysql_errno(CON_CONNECTION(_h));
00117 if (code != CR_SERVER_GONE_ERROR && code != CR_SERVER_LOST) {
00118 break;
00119 }
00120 counter_inc(mysql_cnts_h.driver_err);
00121 }
00122 LM_ERR("driver error on query: %s\n", mysql_error(CON_CONNECTION(_h)));
00123 return -2;
00124 }
00125
00126
00127
00134 db1_con_t* db_mysql_init(const str* _url)
00135 {
00136 return db_do_init(_url, (void *)db_mysql_new_connection);
00137 }
00138
00139
00146 void db_mysql_close(db1_con_t* _h)
00147 {
00148 db_do_close(_h, db_mysql_free_connection);
00149 }
00150
00151
00158 static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
00159 {
00160 int code;
00161 if ((!_h) || (!_r)) {
00162 LM_ERR("invalid parameter value\n");
00163 return -1;
00164 }
00165
00166 *_r = db_new_result();
00167 if (*_r == 0) {
00168 LM_ERR("no memory left\n");
00169 return -2;
00170 }
00171
00172 CON_RESULT(_h) = mysql_store_result(CON_CONNECTION(_h));
00173 if (!CON_RESULT(_h)) {
00174 if (mysql_field_count(CON_CONNECTION(_h)) == 0) {
00175 (*_r)->col.n = 0;
00176 (*_r)->n = 0;
00177 goto done;
00178 } else {
00179 LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
00180 code = mysql_errno(CON_CONNECTION(_h));
00181 if (code == CR_SERVER_GONE_ERROR || code == CR_SERVER_LOST) {
00182 counter_inc(mysql_cnts_h.driver_err);
00183 }
00184 db_free_result(*_r);
00185 *_r = 0;
00186 return -3;
00187 }
00188 }
00189
00190 if (db_mysql_convert_result(_h, *_r) < 0) {
00191 LM_ERR("error while converting result\n");
00192 LM_DBG("freeing result set at %p\n", _r);
00193 pkg_free(*_r);
00194 *_r = 0;
00195
00196
00197
00198 mysql_free_result(CON_RESULT(_h));
00199 #if (MYSQL_VERSION_ID >= 40100)
00200 while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
00201 MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
00202 mysql_free_result(res);
00203 }
00204 #endif
00205 CON_RESULT(_h) = 0;
00206 return -4;
00207 }
00208
00209 done:
00210 #if (MYSQL_VERSION_ID >= 40100)
00211 while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
00212 MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
00213 mysql_free_result(res);
00214 }
00215 #endif
00216
00217 return 0;
00218 }
00219
00220
00227 int db_mysql_free_result(db1_con_t* _h, db1_res_t* _r)
00228 {
00229 if ((!_h) || (!_r)) {
00230 LM_ERR("invalid parameter value\n");
00231 return -1;
00232 }
00233
00234 if (db_free_result(_r) < 0) {
00235 LM_ERR("unable to free result structure\n");
00236 return -1;
00237 }
00238 mysql_free_result(CON_RESULT(_h));
00239 CON_RESULT(_h) = 0;
00240 return 0;
00241 }
00242
00243
00257 int db_mysql_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
00258 const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
00259 const db_key_t _o, db1_res_t** _r)
00260 {
00261 return db_do_query(_h, _k, _op, _v, _c, _n, _nc, _o, _r,
00262 db_mysql_val2str, db_mysql_submit_query, db_mysql_store_result);
00263 }
00264
00280 int db_mysql_fetch_result(const db1_con_t* _h, db1_res_t** _r, const int nrows)
00281 {
00282 int rows, i, code;
00283
00284 if (!_h || !_r || nrows < 0) {
00285 LM_ERR("Invalid parameter value\n");
00286 return -1;
00287 }
00288
00289
00290 if (nrows == 0) {
00291 db_free_result(*_r);
00292 *_r = 0;
00293 return 0;
00294 }
00295
00296 if(*_r==0) {
00297
00298 *_r = db_new_result();
00299 if (*_r == 0) {
00300 LM_ERR("no memory left\n");
00301 return -2;
00302 }
00303
00304 CON_RESULT(_h) = mysql_store_result(CON_CONNECTION(_h));
00305 if (!CON_RESULT(_h)) {
00306 if (mysql_field_count(CON_CONNECTION(_h)) == 0) {
00307 (*_r)->col.n = 0;
00308 (*_r)->n = 0;
00309 return 0;
00310 } else {
00311 LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
00312 code = mysql_errno(CON_CONNECTION(_h));
00313 if (code == CR_SERVER_GONE_ERROR || code == CR_SERVER_LOST) {
00314 counter_inc(mysql_cnts_h.driver_err);
00315 }
00316 db_free_result(*_r);
00317 *_r = 0;
00318 return -3;
00319 }
00320 }
00321 if (db_mysql_get_columns(_h, *_r) < 0) {
00322 LM_ERR("error while getting column names\n");
00323 return -4;
00324 }
00325
00326 RES_NUM_ROWS(*_r) = mysql_num_rows(CON_RESULT(_h));
00327 if (!RES_NUM_ROWS(*_r)) {
00328 LM_DBG("no rows returned from the query\n");
00329 RES_ROWS(*_r) = 0;
00330 return 0;
00331 }
00332
00333 } else {
00334
00335 if(RES_ROWS(*_r)!=0)
00336 db_free_rows(*_r);
00337 RES_ROWS(*_r) = 0;
00338 RES_ROW_N(*_r) = 0;
00339 }
00340
00341
00342 rows = RES_NUM_ROWS(*_r) - RES_LAST_ROW(*_r);
00343
00344
00345 if(rows<=0)
00346 return 0;
00347
00348
00349
00350 if(nrows < rows)
00351 rows = nrows;
00352
00353 RES_ROW_N(*_r) = rows;
00354
00355 LM_DBG("converting row %d of %d count %d\n", RES_LAST_ROW(*_r),
00356 RES_NUM_ROWS(*_r), RES_ROW_N(*_r));
00357
00358 RES_ROWS(*_r) = (struct db_row*)pkg_malloc(sizeof(db_row_t) * rows);
00359 if (!RES_ROWS(*_r)) {
00360 LM_ERR("no memory left\n");
00361 return -5;
00362 }
00363
00364 for(i = 0; i < rows; i++) {
00365 CON_ROW(_h) = mysql_fetch_row(CON_RESULT(_h));
00366 if (!CON_ROW(_h)) {
00367 LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
00368 RES_ROW_N(*_r) = i;
00369 db_free_rows(*_r);
00370 return -6;
00371 }
00372 if (db_mysql_convert_row(_h, *_r, &(RES_ROWS(*_r)[i])) < 0) {
00373 LM_ERR("error while converting row #%d\n", i);
00374 RES_ROW_N(*_r) = i;
00375 db_free_rows(*_r);
00376 return -7;
00377 }
00378 }
00379
00380
00381 RES_LAST_ROW(*_r) += rows;
00382 return 0;
00383 }
00384
00392 int db_mysql_raw_query(const db1_con_t* _h, const str* _s, db1_res_t** _r)
00393 {
00394 return db_do_raw_query(_h, _s, _r, db_mysql_submit_query,
00395 db_mysql_store_result);
00396 }
00397
00398
00407 int db_mysql_insert(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n)
00408 {
00409 return db_do_insert(_h, _k, _v, _n, db_mysql_val2str,
00410 db_mysql_submit_query);
00411 }
00412
00413
00423 int db_mysql_delete(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00424 const db_val_t* _v, const int _n)
00425 {
00426 return db_do_delete(_h, _k, _o, _v, _n, db_mysql_val2str,
00427 db_mysql_submit_query);
00428 }
00429
00430
00443 int db_mysql_update(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00444 const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
00445 const int _un)
00446 {
00447 return db_do_update(_h, _k, _o, _v, _uk, _uv, _n, _un, db_mysql_val2str,
00448 db_mysql_submit_query);
00449 }
00450
00451
00460 int db_mysql_replace(const db1_con_t* _h, const db_key_t* _k,
00461 const db_val_t* _v, const int _n, const int _un, const int _m)
00462 {
00463 return db_do_replace(_h, _k, _v, _n, db_mysql_val2str,
00464 db_mysql_submit_query);
00465 }
00466
00467
00474 int db_mysql_last_inserted_id(const db1_con_t* _h)
00475 {
00476 if (!_h) {
00477 LM_ERR("invalid parameter value\n");
00478 return -1;
00479 }
00480 return mysql_insert_id(CON_CONNECTION(_h));
00481 }
00482
00483
00489 int db_mysql_affected_rows(const db1_con_t* _h)
00490 {
00491 if (!_h) {
00492 LM_ERR("invalid parameter value\n");
00493 return -1;
00494 }
00495 return (int)mysql_affected_rows(CON_CONNECTION(_h));
00496 }
00497
00498
00506 int db_mysql_insert_update(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00507 const int _n)
00508 {
00509 int off, ret;
00510 static str sql_str;
00511
00512 if ((!_h) || (!_k) || (!_v) || (!_n)) {
00513 LM_ERR("invalid parameter value\n");
00514 return -1;
00515 }
00516
00517 ret = snprintf(mysql_sql_buf, sql_buffer_size, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00518 if (ret < 0 || ret >= sql_buffer_size) goto error;
00519 off = ret;
00520
00521 ret = db_print_columns(mysql_sql_buf + off, sql_buffer_size - off, _k, _n);
00522 if (ret < 0) return -1;
00523 off += ret;
00524
00525 ret = snprintf(mysql_sql_buf + off, sql_buffer_size - off, ") values (");
00526 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00527 off += ret;
00528 ret = db_print_values(_h, mysql_sql_buf + off, sql_buffer_size - off, _v, _n, db_mysql_val2str);
00529 if (ret < 0) return -1;
00530 off += ret;
00531
00532 *(mysql_sql_buf + off++) = ')';
00533
00534 ret = snprintf(mysql_sql_buf + off, sql_buffer_size - off, " on duplicate key update ");
00535 if (ret < 0 || ret >= (sql_buffer_size - off)) goto error;
00536 off += ret;
00537
00538 ret = db_print_set(_h, mysql_sql_buf + off, sql_buffer_size - off, _k, _v, _n, db_mysql_val2str);
00539 if (ret < 0) return -1;
00540 off += ret;
00541
00542 sql_str.s = mysql_sql_buf;
00543 sql_str.len = off;
00544
00545 if (db_mysql_submit_query(_h, &sql_str) < 0) {
00546 LM_ERR("error while submitting query\n");
00547 return -2;
00548 }
00549 return 0;
00550
00551 error:
00552 LM_ERR("error while preparing insert_update operation\n");
00553 return -1;
00554 }
00555
00556
00565 int db_mysql_insert_delayed(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n)
00566 {
00567 return db_do_insert_delayed(_h, _k, _v, _n, db_mysql_val2str,
00568 db_mysql_submit_query);
00569 }
00570
00571
00578 int db_mysql_use_table(db1_con_t* _h, const str* _t)
00579 {
00580 return db_use_table(_h, _t);
00581 }
00582
00583
00589 int db_mysql_alloc_buffer(void)
00590 {
00591 if (db_api_init())
00592 {
00593 LM_ERR("Failed to initialise db api\n");
00594 return -1;
00595 }
00596
00597 mysql_sql_buf = (char*)malloc(sql_buffer_size);
00598 if (mysql_sql_buf == NULL)
00599 return -1;
00600 else
00601 return 0;
00602 }