00001
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 #include <sys/types.h>
00045 #include <sys/ipc.h>
00046 #include <unistd.h>
00047 #include <fcntl.h>
00048
00049 #include "../../sr_module.h"
00050 #include "../../dprint.h"
00051
00052 #include "../../pvar.h"
00053 #include "sql_api.h"
00054 #include "sql_var.h"
00055 #include "sql_trans.h"
00056
00057
00058 MODULE_VERSION
00059
00060 static int bind_sqlops(sqlops_api_t* api);
00061
00063 static int sql_query(struct sip_msg*, char*, char*, char*);
00064 static int sql_query2(struct sip_msg*, char*, char*);
00065 #ifdef WITH_XAVP
00066 static int sql_xquery(struct sip_msg *msg, char *dbl, char *query, char *res);
00067 #endif
00068 static int sql_pvquery(struct sip_msg *msg, char *dbl, char *query, char *res);
00069 static int sql_rfree(struct sip_msg*, char*, char*);
00070 static int child_init(int rank);
00071 static void destroy(void);
00072
00073 static int fixup_sql_query(void** param, int param_no);
00074 #ifdef WITH_XAVP
00075 static int fixup_sql_xquery(void** param, int param_no);
00076 #endif
00077 static int fixup_sql_pvquery(void** param, int param_no);
00078 static int fixup_sql_rfree(void** param, int param_no);
00079
00080 static int sql_con_param(modparam_t type, void* val);
00081 static int sql_res_param(modparam_t type, void* val);
00082
00083 static pv_export_t mod_pvs[] = {
00084 { {"dbr", sizeof("dbr")-1}, PVT_OTHER, pv_get_dbr, 0,
00085 pv_parse_dbr_name, 0, 0, 0 },
00086 { {"sqlrows", sizeof("sqlrows")-1}, PVT_OTHER, pv_get_sqlrows, 0,
00087 pv_parse_con_name, 0, 0, 0 },
00088 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00089 };
00090
00091 static cmd_export_t cmds[]={
00092 {"sql_query", (cmd_function)sql_query, 3, fixup_sql_query, 0,
00093 ANY_ROUTE},
00094 {"sql_query", (cmd_function)sql_query2, 2, fixup_sql_query, 0,
00095 ANY_ROUTE},
00096 #ifdef WITH_XAVP
00097 {"sql_xquery", (cmd_function)sql_xquery, 3, fixup_sql_xquery, 0,
00098 ANY_ROUTE},
00099 #endif
00100 {"sql_pvquery", (cmd_function)sql_pvquery, 3, fixup_sql_pvquery, 0,
00101 ANY_ROUTE},
00102 {"sql_result_free", (cmd_function)sql_rfree, 1, fixup_sql_rfree, 0,
00103 ANY_ROUTE},
00104 {"bind_sqlops", (cmd_function)bind_sqlops, 0, 0, 0, 0},
00105 {0,0,0,0,0,0}
00106 };
00107
00108 static param_export_t params[]={
00109 {"sqlcon", STR_PARAM|USE_FUNC_PARAM, (void*)sql_con_param},
00110 {"sqlres", STR_PARAM|USE_FUNC_PARAM, (void*)sql_res_param},
00111 {0,0,0}
00112 };
00113
00114 static tr_export_t mod_trans[] = {
00115 { {"sql", sizeof("sql")-1}, tr_parse_sql },
00116 { { 0, 0 }, 0 }
00117 };
00118
00119
00121 struct module_exports exports= {
00122 "sqlops",
00123 DEFAULT_DLFLAGS,
00124 cmds,
00125 params,
00126 0,
00127 0 ,
00128 mod_pvs,
00129 0,
00130 0,
00131 0,
00132 (destroy_function) destroy,
00133 child_init
00134 };
00135
00136 int mod_register(char *path, int *dlflags, void *p1, void *p2)
00137 {
00138 return register_trans_mod(path, mod_trans);
00139 }
00140
00141 static int child_init(int rank)
00142 {
00143 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00144 return 0;
00145 return sql_connect();
00146 }
00147
00151 static void destroy(void)
00152 {
00153 sql_destroy();
00154 }
00155
00159 int sql_con_param(modparam_t type, void *val)
00160 {
00161 if(val==NULL)
00162 goto error;
00163
00164 return sql_parse_param((char*)val);
00165 error:
00166 return -1;
00167
00168 }
00169
00173 int sql_res_param(modparam_t type, void *val)
00174 {
00175 sql_result_t *res = NULL;
00176 str s;
00177
00178 if(val==NULL)
00179 {
00180 LM_ERR("invalid parameter\n");
00181 goto error;
00182 }
00183
00184 s.s = (char*)val;
00185 s.len = strlen(s.s);
00186
00187 res = sql_get_result(&s);
00188 if(res==NULL)
00189 {
00190 LM_ERR("invalid result [%s]\n", s.s);
00191 goto error;
00192 }
00193 return 0;
00194 error:
00195 return -1;
00196 }
00197
00201 static int sql_query(struct sip_msg *msg, char *dbl, char *query, char *res)
00202 {
00203 str sq;
00204 if(pv_printf_s(msg, (pv_elem_t*)query, &sq)!=0)
00205 {
00206 LM_ERR("cannot print the sql query\n");
00207 return -1;
00208 }
00209 return sql_do_query((sql_con_t*)dbl, &sq, (sql_result_t*)res);
00210 }
00211
00212 static int sql_query2(struct sip_msg *msg, char *dbl, char *query)
00213 {
00214 return sql_query(msg, dbl, query, NULL);
00215 }
00216
00217 #ifdef WITH_XAVP
00218
00221 static int sql_xquery(struct sip_msg *msg, char *dbl, char *query, char *res)
00222 {
00223 return sql_do_xquery(msg, (sql_con_t*)dbl, (pv_elem_t*)query, (pv_elem_t*)res);
00224 }
00225 #endif
00226
00230 static int sql_pvquery(struct sip_msg *msg, char *dbl, char *query, char *res)
00231 {
00232 return sql_do_pvquery(msg, (sql_con_t*)dbl, (pv_elem_t*)query, (pvname_list_t*)res);
00233 }
00234
00238 static int sql_rfree(struct sip_msg *msg, char *res, char *s2)
00239 {
00240 sql_reset_result((sql_result_t*)res);
00241 return 1;
00242 }
00243
00247 static int fixup_sql_query(void** param, int param_no)
00248 {
00249 sql_con_t *con = NULL;
00250 pv_elem_t *query = NULL;
00251 sql_result_t *res = NULL;
00252 str s;
00253
00254 s.s = (char*)(*param);
00255 s.len = strlen(s.s);
00256
00257 if (param_no==1) {
00258 con = sql_get_connection(&s);
00259 if(con==NULL)
00260 {
00261 LM_ERR("invalid connection [%s]\n", s.s);
00262 return E_UNSPEC;
00263 }
00264 *param = (void*)con;
00265 } else if (param_no==2) {
00266 if(pv_parse_format(&s, &query)<0)
00267 {
00268 LM_ERR("invalid query string [%s]\n", s.s);
00269 return E_UNSPEC;
00270 }
00271 *param = (void*)query;
00272 } else if (param_no==3) {
00273 res = sql_get_result(&s);
00274 if(res==NULL)
00275 {
00276 LM_ERR("invalid result [%s]\n", s.s);
00277 return E_UNSPEC;
00278 }
00279 *param = (void*)res;
00280 }
00281 return 0;
00282 }
00283
00284 #ifdef WITH_XAVP
00285
00288 static int fixup_sql_xquery(void** param, int param_no)
00289 {
00290 sql_con_t *con = NULL;
00291 pv_elem_t *pv = NULL;
00292 str s;
00293
00294 s.s = (char*)(*param);
00295 s.len = strlen(s.s);
00296
00297 if (param_no==1) {
00298 con = sql_get_connection(&s);
00299 if(con==NULL)
00300 {
00301 LM_ERR("invalid connection [%s]\n", s.s);
00302 return E_UNSPEC;
00303 }
00304 *param = (void*)con;
00305 } else if (param_no==2) {
00306 if(pv_parse_format(&s, &pv)<0)
00307 {
00308 LM_ERR("invalid query string [%s]\n", s.s);
00309 return E_UNSPEC;
00310 }
00311 *param = (void*)pv;
00312 } else if (param_no==3) {
00313 if(pv_parse_format(&s, &pv)<0)
00314 {
00315 LM_ERR("invalid result [%s]\n", s.s);
00316 return E_UNSPEC;
00317 }
00318 *param = (void*)pv;
00319 }
00320 return 0;
00321 }
00322 #endif
00323
00327 static int fixup_sql_pvquery(void** param, int param_no)
00328 {
00329 sql_con_t *con = NULL;
00330 pv_elem_t *pv = NULL;
00331 pvname_list_t *res = NULL;
00332 pvname_list_t *pvl = NULL;
00333 str s;
00334 int i;
00335
00336 if(*param == NULL)
00337 {
00338 LM_ERR("missing parameter %d\n", param_no);
00339 return E_UNSPEC;
00340 }
00341 s.s = (char*)(*param);
00342 s.len = strlen(s.s);
00343
00344 if (param_no==1) {
00345 con = sql_get_connection(&s);
00346 if(con==NULL)
00347 {
00348 LM_ERR("invalid connection [%s]\n", s.s);
00349 return E_UNSPEC;
00350 }
00351 *param = (void*)con;
00352 } else if (param_no==2) {
00353 if(pv_parse_format(&s, &pv)<0)
00354 {
00355 LM_ERR("invalid query string [%s]\n", s.s);
00356 return E_UNSPEC;
00357 }
00358 *param = (void*)pv;
00359 } else if (param_no==3) {
00360
00361 res = parse_pvname_list(&s, 0);
00362 if(res==NULL)
00363 {
00364 LM_ERR("invalid result parameter [%s]\n", s.s);
00365 return E_UNSPEC;
00366 }
00367
00368 pvl = res;
00369 i = 1;
00370 while (pvl) {
00371 if (pvl->sname.setf == NULL)
00372 {
00373 LM_ERR("result variable [%d] is read-only\n", i);
00374 return E_UNSPEC;
00375 }
00376 i++;
00377 pvl = pvl->next;
00378 }
00379 *param = (void*)res;
00380 return 0;
00381 }
00382 return 0;
00383 }
00384
00388 static int fixup_sql_rfree(void** param, int param_no)
00389 {
00390 sql_result_t *res = NULL;
00391 str s;
00392
00393 s.s = (char*)(*param);
00394 s.len = strlen(s.s);
00395
00396 if (param_no==1) {
00397 res = sql_get_result(&s);
00398 if(res==NULL)
00399 {
00400 LM_ERR("invalid result [%s]\n", s.s);
00401 return E_UNSPEC;
00402 }
00403 *param = (void*)res;
00404 }
00405 return 0;
00406 }
00407
00411 static int bind_sqlops(sqlops_api_t* api)
00412 {
00413 if (!api) {
00414 ERR("Invalid parameter value\n");
00415 return -1;
00416 }
00417 api->query = sqlops_do_query;
00418 api->value = sqlops_get_value;
00419 api->is_null = sqlops_is_null;
00420 api->column = sqlops_get_column;
00421 api->reset = sqlops_reset_result;
00422 api->nrows = sqlops_num_rows;
00423 api->ncols = sqlops_num_columns;
00424 api->xquery = sqlops_do_xquery;
00425
00426 return 0;
00427 }