/* * from a token in form of * tag->value extract the tag and the value * @param token * @param tag reference * @param value reference * @return 0 (success) / < 0 (error) * * tag and value must be allocated beforehand */ static int parse_extra_token(str* token, str* tag, str* value) { /* insanity checks */ if (token == NULL || token->len == 0 || token->s == NULL || tag == NULL || value == NULL) { LM_ERR("bad input!\n"); return -1; } /* value will not point exactly where the value is * will point where the - character from the '->' delimiter will be */ if ((value->s = str_strstr(token, &tag_delim)) == NULL) { /* if not found then the value is the same as the token */ str_trim_spaces_lr(*token); *value = *tag = *token; } else { tag->s = token->s; tag->len = value->s - token->s; /* jump over '->' delimiter */ value->s += tag_delim.len; value->len = token->len - (value->s - token->s); str_trim_spaces_lr(*tag); str_trim_spaces_lr(*value); } return 0; }
/** * 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; }
static inline int db_copy_rest_of_count(const str* _qh, str* count_query) { char* found; const str searched_str = {" from ", sizeof(" from ")-1}; count_query->len = sizeof(COUNT_QUERY)-1; if ((found=str_strstr(_qh, &searched_str)) != NULL) { const int len=_qh->len-(found-_qh->s); /* check for overflow */ if (len > COUNT_BUF_SIZE-(sizeof(COUNT_QUERY)-1)) { LM_ERR("query too big! try reducing the size of your query!" "Current max size [%d]!\n", COUNT_BUF_SIZE); return -1; } memcpy(count_query->s+count_query->len, found, len); count_query->len += len; return 0; } return -1; }