cpl_db.c

Go to the documentation of this file.
00001 /*
00002  * $Id: cpl_db.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
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   * History:
00024   * --------
00025   *  2004-06-06  updated to the new DB api (andrei)
00026   */
00027 
00028 #include "../../mem/shm_mem.h"
00029 #include "../../db/db.h"
00030 #include "../../dprint.h"
00031 #include "../../str.h"
00032 #include "cpl_db.h"
00033 
00034 #define TABLE_VERSION 1
00035 
00036 static db_con_t* db_hdl=0;
00037 static db_func_t cpl_dbf;
00038 
00039 str cpl_username_col = str_init("username");
00040 str cpl_domain_col = str_init("domain");
00041 str cpl_xml_col  = str_init("cpl_xml");
00042 str cpl_bin_col  = str_init("cpl_bin");
00043 
00044 
00045 int cpl_db_bind(const str* db_url, const str *db_table)
00046 {
00047    if (db_bind_mod(db_url, &cpl_dbf )) {
00048       LM_CRIT("cannot bind to database module! "
00049           "Did you forget to load a database module ?\n");
00050       return -1;
00051    }
00052    
00053    /* CPL module uses all database functions */
00054    if (!DB_CAPABILITY(cpl_dbf, DB_CAP_ALL)) {
00055       LM_CRIT("Database modules does not "
00056           "provide all functions needed by cpl-c module\n");
00057       return -1;
00058    }
00059 
00060    if ( cpl_db_init( db_url, db_table) )
00061       return -1;
00062 
00063    if(db_check_table_version(&cpl_dbf, db_hdl, db_table, TABLE_VERSION) < 0) {
00064       LM_ERR("error during table version check.\n");
00065       cpl_db_close();
00066       return -1;
00067    }
00068 
00069    cpl_db_close();
00070    return 0;
00071 }
00072 
00073 
00074 
00075 int cpl_db_init(const str* db_url, const str* db_table)
00076 {
00077    if (cpl_dbf.init==0){
00078       LM_CRIT("BUG - unbound database module\n");
00079       return -1;
00080    }
00081 
00082    db_hdl=cpl_dbf.init(db_url);
00083    
00084    if (db_hdl==0){
00085       LM_CRIT("cannot initialize database connection\n");
00086       return -1;
00087    }
00088    
00089    if (cpl_dbf.use_table(db_hdl, db_table)<0) {
00090       LM_CRIT("cannot select table \"%.*s\"\n",db_table->len, db_table->s);
00091       cpl_db_close();
00092       return -1;
00093    }
00094 
00095    return 0;
00096 }
00097 
00098 
00099 void cpl_db_close(void)
00100 {
00101    if (db_hdl && cpl_dbf.close){
00102       cpl_dbf.close(db_hdl);
00103       db_hdl=0;
00104    }
00105 }
00106 
00107 
00108 /* gets from database the cpl script in binary format; the returned script is
00109  * allocated in shared memory
00110  * Returns:  1 - success
00111  *          -1 - error
00112  */
00113 int get_user_script(str *username, str *domain, str *script, str* key)
00114 {
00115    db_key_t   keys_cmp[2];
00116    db_key_t   keys_ret[1];
00117    db_val_t   vals[2];
00118    db_res_t   *res = NULL;
00119    int n;
00120 
00121    keys_cmp[0] = &cpl_username_col;
00122    keys_cmp[1] = &cpl_domain_col;
00123    keys_ret[0] = key;
00124 
00125    LM_DBG("fetching script for user <%.*s>\n",
00126       username->len,username->s);
00127    vals[0].type = DB_STR;
00128    vals[0].nul  = 0;
00129    vals[0].val.str_val = *username;
00130    n = 1;
00131    if (domain) {
00132       vals[1].type = DB_STR;
00133       vals[1].nul  = 0;
00134       vals[1].val.str_val = *domain;
00135       n++;
00136    }
00137 
00138    if (cpl_dbf.query(db_hdl, keys_cmp, 0, vals, keys_ret, n, 1, NULL, &res)
00139          < 0){
00140       LM_ERR("db_query failed\n");
00141       goto error;
00142    }
00143 
00144    if (res->n==0) {
00145       LM_DBG("user <%.*s> not found in db -> probably "
00146          "he has no script\n",username->len, username->s);
00147       script->s = 0;
00148       script->len = 0;
00149    } else {
00150       if (res->rows[0].values[0].nul) {
00151          LM_DBG("user <%.*s> has a NULL script\n",
00152             username->len, username->s);
00153          script->s = 0;
00154          script->len = 0;
00155       } else {
00156          LM_DBG("we got the script len=%d\n",
00157             res->rows[0].values[0].val.blob_val.len);
00158          script->len = res->rows[0].values[0].val.blob_val.len;
00159          script->s = shm_malloc( script->len );
00160          if (!script->s) {
00161             LM_ERR("no free sh_mem\n");
00162             goto error;
00163          }
00164          memcpy( script->s, res->rows[0].values[0].val.blob_val.s,
00165             script->len);
00166       }
00167    }
00168 
00169    cpl_dbf.free_result( db_hdl, res);
00170    return 1;
00171 error:
00172    if (res)
00173       cpl_dbf.free_result( db_hdl, res);
00174    script->s = 0;
00175    script->len = 0;
00176    return -1;
00177 }
00178 
00179 
00180 
00181 /* inserts into database a cpl script in XML format(xml) along with its binary
00182  * format (bin)
00183  * Returns:  1 - success
00184  *          -1 - error
00185  */
00186 int write_to_db(str *username, str *domain, str *xml, str *bin)
00187 {
00188    db_key_t   keys[4];
00189    db_val_t   vals[4];
00190    db_res_t   *res = NULL;
00191    int n;
00192 
00193    /* lets see if the user is already in database */
00194    keys[2] = &cpl_username_col;
00195    vals[2].type = DB_STR;
00196    vals[2].nul  = 0;
00197    vals[2].val.str_val = *username;
00198    n = 1;
00199    if (domain) {
00200       keys[3] = &cpl_domain_col;
00201       vals[3].type = DB_STR;
00202       vals[3].nul  = 0;
00203       vals[3].val.str_val = *domain;
00204       n++;
00205    }
00206    if (cpl_dbf.query(db_hdl, keys+2, 0, vals+2, keys+2, n, 1, NULL, &res)<0) {
00207       LM_ERR("db_query failed\n");
00208       goto error;
00209    }
00210    if (res->n>1) {
00211       LM_ERR("Inconsistent CPL database:"
00212          " %d records for user %.*s\n",res->n,username->len,username->s);
00213       goto error;
00214    }
00215 
00216    /* cpl text */
00217    keys[0] = &cpl_xml_col;
00218    vals[0].type = DB_BLOB;
00219    vals[0].nul  = 0;
00220    vals[0].val.blob_val.s = xml->s;
00221    vals[0].val.blob_val.len = xml->len;
00222    n++;
00223    /* cpl bin */
00224    keys[1] = &cpl_bin_col;
00225    vals[1].type = DB_BLOB;
00226    vals[1].nul  = 0;
00227    vals[1].val.blob_val.s = bin->s;
00228    vals[1].val.blob_val.len = bin->len;
00229    n++;
00230    /* insert or update ? */
00231    if (res->n==0) {
00232       LM_DBG("no user %.*s in CPL database->insert\n",
00233          username->len,username->s);
00234       if (cpl_dbf.insert(db_hdl, keys, vals, n) < 0) {
00235          LM_ERR("insert failed !\n");
00236          goto error;
00237       }
00238    } else {
00239       LM_DBG("user %.*s already in CPL database ->"
00240          " update\n",username->len,username->s);
00241       if (cpl_dbf.update(db_hdl, keys+2, 0, vals+2, keys, vals, n-2, 2) < 0) {
00242          LM_ERR("update failed !\n");
00243          goto error;
00244       }
00245    }
00246 
00247    return 1;
00248 error:
00249    return -1;
00250 }
00251 
00252 
00253 
00254 /* delete from database the entity record for a given user - if a user has no
00255  * script, he will be removed completely from db; users without script are not
00256  * allowed into db ;-)
00257  * Returns:  1 - success
00258  *          -1 - error
00259  */
00260 int rmv_from_db(str *username, str *domain)
00261 {
00262    db_key_t   keys[2];
00263    db_val_t   vals[2];
00264    int n;
00265 
00266    /* username */
00267    keys[0] = &cpl_username_col;
00268    vals[0].type = DB_STR;
00269    vals[0].nul  = 0;
00270    vals[0].val.str_val = *username;
00271    n = 1;
00272    if (domain) {
00273       keys[1] = &cpl_domain_col;
00274       vals[1].type = DB_STR;
00275       vals[1].nul  = 0;
00276       vals[1].val.str_val = *domain;
00277       n++;
00278    }
00279 
00280    if (cpl_dbf.delete(db_hdl, keys, NULL, vals, n) < 0) {
00281       LM_ERR("failed to delete script for "
00282          "user \"%.*s\"\n",username->len,username->s);
00283       return -1;
00284    }
00285 
00286    return 1;
00287 }
00288 

Generated on Mon May 21 18:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6