db_query.c

Go to the documentation of this file.
00001 /*
00002  * $Id: db_query.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Copyright (C) 2007-2008 1&1 Internet AG
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 /**
00025  * \file db/db_query.c
00026  * \brief Query helper for database drivers
00027  * \ingroup db
00028  *
00029  * This helper methods for database queries are used from the database
00030  * SQL driver to do the actual work. Each function uses some functions from
00031  * the actual driver with function pointers to the concrete, specific
00032  * implementation.
00033 */
00034 
00035 #include <stdio.h>
00036 #include "../dprint.h"
00037 #include "db_ut.h"
00038 #include "db_query.h"
00039 
00040 static str  sql_str;
00041 static char sql_buf[SQL_BUF_LEN];
00042 
00043 int db_do_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op,
00044    const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
00045    const db_key_t _o, db_res_t** _r, int (*val2str) (const db_con_t*,
00046    const db_val_t*, char*, int* _len), int (*submit_query)(const db_con_t*,
00047    const str*), int (*store_result)(const db_con_t* _h, db_res_t** _r))
00048 {
00049    int off, ret;
00050 
00051    if (!_h || !val2str || !submit_query || !store_result) {
00052       LM_ERR("invalid parameter value\n");
00053       return -1;
00054    }
00055 
00056    if (!_c) {
00057       ret = snprintf(sql_buf, SQL_BUF_LEN, "select * from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00058       if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00059       off = ret;
00060    } else {
00061       ret = snprintf(sql_buf, SQL_BUF_LEN, "select ");
00062       if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00063       off = ret;
00064 
00065       ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _c, _nc);
00066       if (ret < 0) return -1;
00067       off += ret;
00068 
00069       ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "from %.*s ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00070       if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00071       off += ret;
00072    }
00073    if (_n) {
00074       ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "where ");
00075       if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00076       off += ret;
00077 
00078       ret = db_print_where(_h, sql_buf + off,
00079             SQL_BUF_LEN - off, _k, _op, _v, _n, val2str);
00080       if (ret < 0) return -1;;
00081       off += ret;
00082    }
00083    if (_o) {
00084       ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " order by %.*s", _o->len, _o->s);
00085       if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00086       off += ret;
00087    }
00088    /*
00089     * Null-terminate the string for the postgres driver. Its query function
00090     * don't support a length parameter, so they need this for the correct
00091     * function of strlen. This zero is not included in the 'str' length.
00092     * We need to check the length here, otherwise we could overwrite the buffer
00093     * boundaries if off is equal to SQL_BUF_LEN.
00094     */
00095    if (off + 1 >= SQL_BUF_LEN) goto error;
00096    sql_buf[off + 1] = '\0';
00097    sql_str.s = sql_buf;
00098    sql_str.len = off;
00099 
00100    if (submit_query(_h, &sql_str) < 0) {
00101       LM_ERR("error while submitting query\n");
00102       return -2;
00103    }
00104 
00105    if(_r) {
00106       int tmp = store_result(_h, _r);
00107       if (tmp < 0) {
00108          LM_ERR("error while storing result");
00109          return tmp;
00110       }
00111    }
00112    return 0;
00113 
00114 error:
00115    LM_ERR("error while preparing query\n");
00116    return -1;
00117 }
00118 
00119 
00120 int db_do_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r,
00121    int (*submit_query)(const db_con_t* _h, const str* _c),
00122    int (*store_result)(const db_con_t* _h, db_res_t** _r))
00123 {
00124    if (!_h || !_s || !submit_query || !store_result) {
00125       LM_ERR("invalid parameter value\n");
00126       return -1;
00127    }
00128 
00129    if (submit_query(_h, _s) < 0) {
00130       LM_ERR("error while submitting query\n");
00131       return -2;
00132    }
00133 
00134    if(_r) {
00135       int tmp = store_result(_h, _r);
00136       if (tmp < 0) {
00137          LM_ERR("error while storing result");
00138          return tmp;
00139       }
00140    }
00141    return 0;
00142 }
00143 
00144 
00145 int db_do_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00146    const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*),
00147    int (*submit_query)(const db_con_t* _h, const str* _c))
00148 {
00149    int off, ret;
00150 
00151    if (!_h || !_k || !_v || !_n || !val2str || !submit_query) {
00152       LM_ERR("invalid parameter value\n");
00153       return -1;
00154    }
00155 
00156    ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00157    if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00158    off = ret;
00159 
00160    ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
00161    if (ret < 0) return -1;
00162    off += ret;
00163 
00164    ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
00165    if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00166    off += ret;
00167 
00168    ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n, val2str);
00169    if (ret < 0) return -1;
00170    off += ret;
00171 
00172    if (off + 2 > SQL_BUF_LEN) goto error;
00173    sql_buf[off++] = ')';
00174    sql_buf[off] = '\0';
00175    sql_str.s = sql_buf;
00176    sql_str.len = off;
00177 
00178    if (submit_query(_h, &sql_str) < 0) {
00179            LM_ERR("error while submitting query\n");
00180       return -2;
00181    }
00182    return 0;
00183 
00184 error:
00185    LM_ERR("error while preparing insert operation\n");
00186    return -1;
00187 }
00188 
00189 
00190 int db_do_delete(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00191    const db_val_t* _v, const int _n, int (*val2str) (const db_con_t*,
00192    const db_val_t*, char*, int*), int (*submit_query)(const db_con_t* _h,
00193    const str* _c))
00194 {
00195    int off, ret;
00196 
00197    if (!_h || !val2str || !submit_query) {
00198       LM_ERR("invalid parameter value\n");
00199       return -1;
00200    }
00201 
00202    ret = snprintf(sql_buf, SQL_BUF_LEN, "delete from %.*s", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00203    if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00204    off = ret;
00205 
00206    if (_n) {
00207       ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
00208       if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00209       off += ret;
00210 
00211       ret = db_print_where(_h, sql_buf + off,
00212             SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
00213       if (ret < 0) return -1;
00214       off += ret;
00215    }
00216    if (off + 1 > SQL_BUF_LEN) goto error;
00217    sql_buf[off] = '\0';
00218    sql_str.s = sql_buf;
00219    sql_str.len = off;
00220 
00221    if (submit_query(_h, &sql_str) < 0) {
00222       LM_ERR("error while submitting query\n");
00223       return -2;
00224    }
00225    return 0;
00226 
00227 error:
00228    LM_ERR("error while preparing delete operation\n");
00229    return -1;
00230 }
00231 
00232 
00233 int db_do_update(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
00234    const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
00235    const int _un, int (*val2str) (const db_con_t*, const db_val_t*, char*, int*),
00236    int (*submit_query)(const db_con_t* _h, const str* _c))
00237 {
00238    int off, ret;
00239 
00240    if (!_h || !_uk || !_uv || !_un || !val2str || !submit_query) {
00241       LM_ERR("invalid parameter value\n");
00242       return -1;
00243    }
00244 
00245    ret = snprintf(sql_buf, SQL_BUF_LEN, "update %.*s set ", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00246    if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00247    off = ret;
00248 
00249    ret = db_print_set(_h, sql_buf + off, SQL_BUF_LEN - off, _uk, _uv, _un, val2str);
00250    if (ret < 0) return -1;
00251    off += ret;
00252 
00253    if (_n) {
00254       ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");
00255       if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00256       off += ret;
00257 
00258       ret = db_print_where(_h, sql_buf + off, SQL_BUF_LEN - off, _k, _o, _v, _n, val2str);
00259       if (ret < 0) return -1;
00260       off += ret;
00261    }
00262    if (off + 1 > SQL_BUF_LEN) goto error;
00263    sql_buf[off] = '\0';
00264    sql_str.s = sql_buf;
00265    sql_str.len = off;
00266 
00267    if (submit_query(_h, &sql_str) < 0) {
00268       LM_ERR("error while submitting query\n");
00269       return -2;
00270    }
00271    return 0;
00272 
00273 error:
00274    LM_ERR("error while preparing update operation\n");
00275    return -1;
00276 }
00277 
00278 
00279 int db_do_replace(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
00280    const int _n, int (*val2str) (const db_con_t*, const db_val_t*, char*,
00281    int*), int (*submit_query)(const db_con_t* _h, const str* _c))
00282 {
00283    int off, ret;
00284 
00285    if (!_h || !_k || !_v || !val2str|| !submit_query) {
00286       LM_ERR("invalid parameter value\n");
00287       return -1;
00288    }
00289 
00290    ret = snprintf(sql_buf, SQL_BUF_LEN, "replace %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
00291    if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
00292    off = ret;
00293 
00294    ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
00295    if (ret < 0) return -1;
00296    off += ret;
00297 
00298    ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
00299    if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
00300    off += ret;
00301 
00302    ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n,
00303    val2str);
00304    if (ret < 0) return -1;
00305    off += ret;
00306 
00307    if (off + 2 > SQL_BUF_LEN) goto error;
00308    sql_buf[off++] = ')';
00309    sql_buf[off] = '\0';
00310    sql_str.s = sql_buf;
00311    sql_str.len = off;
00312 
00313    if (submit_query(_h, &sql_str) < 0) {
00314            LM_ERR("error while submitting query\n");
00315       return -2;
00316    }
00317    return 0;
00318 
00319  error:
00320    LM_ERR("error while preparing replace operation\n");
00321    return -1;
00322 }

Generated on Tue May 22 14:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6