int db_sqlite_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op, const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc, const db_key_t _o, db_res_t** _r) { int ret=-1; #ifdef SQLITE_BIND db_ps_t ps; CON_SET_CURR_PS(_h, &ps); #else CON_RESET_CURR_PS(_h); #endif CON_RAW_QUERY(_h) = 0; ret = db_do_query(_h, _k, _op, _v, _c, _n, _nc, _o, NULL, db_sqlite_val2str, db_sqlite_submit_dummy_query, NULL); if (ret != 0) { if (_r) *_r = NULL; return ret; } if (db_copy_rest_of_count(&query_holder, &count_str)) { LM_ERR("failed to build row counter query\n"); return -1; } again: ret=sqlite3_prepare_v2(CON_CONNECTION(_h), query_holder.s, query_holder.len, &CON_SQLITE_PS(_h), NULL); if (ret==SQLITE_BUSY) goto again; if (ret!=SQLITE_OK) LM_ERR("failed to prepare: (%s)\n", sqlite3_errmsg(CON_CONNECTION(_h))); #ifdef SQLITE_BIND if (db_sqlite_bind_values(CON_SQLITE_PS(_h), _v, _n) != SQLITE_OK) { LM_ERR("failed to bind values\n"); return -1; } #endif if (_r) { ret = db_sqlite_store_result(_h, _r, _v, _n); CON_SQLITE_PS(_h) = NULL; } else { /* need to fetch now the total number of rows in query * because later won't have the query string */ CON_PS_ROWS(_h) = db_sqlite_get_query_rows(_h, &count_str, _v, _n); } return ret; }
/** * Execute a raw SQL query. * \param _h handle for the database * \param _s raw query string * \param _r result set for storage * \return zero on success, negative value on failure */ int db_sqlite_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r) { int ret=-1; char* errmsg; str select_str={"select", 6}; CON_RESET_CURR_PS(_h); if (!str_strstr(_s, &select_str)) { /* not a select statement; can execute the query and exit*/ if (sqlite3_exec(CON_CONNECTION(_h), query_holder.s, NULL, NULL, &errmsg)) { LM_ERR("query failed: %s\n", errmsg); return -2; } return 0; } CON_RAW_QUERY(_h) = 1; if (db_copy_rest_of_count(_s, &count_str)) { LM_ERR("failed to build count str!\n"); return -1; } again: ret=sqlite3_prepare_v2(CON_CONNECTION(_h), _s->s, _s->len, &CON_SQLITE_PS(_h), NULL); if (ret==SQLITE_BUSY) goto again; if (ret!=SQLITE_OK) LM_ERR("failed to prepare: (%s)\n", sqlite3_errmsg(CON_CONNECTION(_h))); if (_r) { ret = db_sqlite_store_result(_h, _r, NULL, 0); } else { /* need to fetch now the total number of rows in query * because later won't have the query string */ CON_PS_ROWS(_h) = db_sqlite_get_query_rows(_h, &count_str, NULL, 0); } return ret; }
/** * Execute a raw SQL query. * \param _h handle for the database * \param _s raw query string * \param _r result set for storage * \return zero on success, negative value on failure */ int db_sqlite_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r) { static char sql_str[SQL_BUF_LEN]; int ret=-1, i=0; char* errmsg; str select_str={"select", 6}; str _scpy; CON_RESET_CURR_PS(_h); while (i < _s->len && !isalpha(_s->s[i])) i++; /* if any blank spaces or anything else before the actual query */ if (i) { _scpy.s = _s->s+i; _scpy.len = _s->len-i; } else { _scpy = *_s; } if (_scpy.len >= select_str.len && str_strncasecmp(&_scpy, &select_str, select_str.len)) { /* not a select statement; can execute the query and exit*/ if (_s->len + 1 > SQL_BUF_LEN) { LM_ERR("query too big! try reducing the size of your query!" "Current max size [%d]!\n", SQL_BUF_LEN); return -1; } memcpy(sql_str, _s->s, _s->len); sql_str[_s->len] = '\0'; if (sqlite3_exec(CON_CONNECTION(_h), sql_str, NULL, NULL, &errmsg)) { LM_ERR("query failed: %s\n", errmsg); return -2; } return 0; } CON_RAW_QUERY(_h) = 1; if (db_copy_rest_of_count(&_scpy, &count_str)) { LM_ERR("failed to build count str!\n"); return -1; } again: ret=sqlite3_prepare_v2(CON_CONNECTION(_h), _s->s, _s->len, &CON_SQLITE_PS(_h), NULL); if (ret==SQLITE_BUSY) goto again; if (ret!=SQLITE_OK) LM_ERR("failed to prepare: (%s)\n", sqlite3_errmsg(CON_CONNECTION(_h))); if (_r) { ret = db_sqlite_store_result(_h, _r, NULL, 0); } else { /* need to fetch now the total number of rows in query * because later won't have the query string */ CON_PS_ROWS(_h) = db_sqlite_get_query_rows(_h, &count_str, NULL, 0); } return ret; }
/** * Gets a partial result set. * \param _h structure representing the database connection * \param _r pointer to a structure representing the result * \param nrows number of fetched rows * \return zero on success, negative value on failure */ int db_sqlite_fetch_result(const db_con_t* _h, db_res_t** _r, const int nrows) { int ret; int rows, i; sqlite3_stmt* stmt; if (!_h || !_r || nrows < 0) { LM_ERR("Invalid parameter value\n"); return -1; } /* exit if the fetch count is zero */ if (nrows == 0) { db_free_result(*_r); *_r = 0; return 0; } if(*_r==0) { /* Allocate a new result structure */ *_r = db_new_result(); if (*_r == 0) { LM_ERR("no memory left\n"); return -2; } if (db_sqlite_get_columns(_h, *_r) < 0) { LM_ERR("error while getting column names\n"); return -4; } RES_NUM_ROWS(*_r) = CON_PS_ROWS(_h); if (!RES_NUM_ROWS(*_r)) { LM_DBG("no rows returned from the query\n"); RES_ROWS(*_r) = 0; return 0; } } else { /* free old rows */ if(RES_ROWS(*_r)!=0) db_free_rows(*_r); RES_ROWS(*_r) = 0; RES_ROW_N(*_r) = 0; } /* determine the number of rows remaining to be processed */ rows = RES_NUM_ROWS(*_r) - RES_LAST_ROW(*_r); /* If there aren't any more rows left to process, exit */ if(rows<=0) return 0; /* if the fetch count is less than the remaining rows to process */ /* set the number of rows to process (during this call) equal to the fetch count */ if(nrows < rows) rows = nrows; RES_ROW_N(*_r) = rows; if (db_sqlite_allocate_rows(*_r, rows)!=0) { LM_ERR("no memory left\n"); return -5; } i = 0; ret=-1; stmt = CON_SQLITE_PS(_h); while (ret != SQLITE_DONE) { if (i == nrows) { RES_LAST_ROW(*_r) = i - 1; break; } ret = sqlite3_step(stmt); if (ret == SQLITE_DONE) { RES_ROW_N(*_r) = RES_LAST_ROW(*_r) = RES_NUM_ROWS(*_r) = i; sqlite3_finalize(CON_SQLITE_PS(_h)); CON_SQLITE_PS(_h) = NULL; break; } if (i >= RES_ROW_N(*_r) && i < nrows) { db_sqlite_realloc_rows(*_r, RES_ROW_N(*_r) + db_sqlite_alloc_limit); RES_ROW_N(*_r) += db_sqlite_alloc_limit; } if ((ret=db_sqlite_convert_row(_h, *_r, &(RES_ROWS(*_r)[i]))) < 0) { LM_ERR("error while converting row #%d\n", i); RES_ROW_N(*_r) = i; db_free_rows(*_r); return -4; } i++; } return 0; }