00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <string.h>
00028 #include <ctype.h>
00029 #include <stdio.h>
00030
00031 #include "perlvdb.h"
00032 #include "perlvdbfunc.h"
00033 #include "../../str.h"
00034
00035
00036
00037
00038
00039
00040 inline long IV2int(SV *in) {
00041 int ret = -1;
00042
00043 if (SvOK(in)) {
00044 if (SvIOK(in)) {
00045 ret = SvIV(in);
00046 }
00047 SvREFCNT_dec(in);
00048 }
00049
00050 return ret;
00051 }
00052
00053
00054
00055
00056 char *parseurl(const char* url) {
00057 char *cn;
00058
00059 cn = strchr(url, ':') + 1;
00060 if (strlen(cn) > 0)
00061 return cn;
00062 else
00063 return NULL;
00064 }
00065
00066
00067 SV *newvdbobj(const char* cn) {
00068 SV* obj;
00069 SV *class;
00070
00071 class = newSVpv(cn, 0);
00072
00073 obj = perlvdb_perlmethod(class, PERL_CONSTRUCTOR_NAME,
00074 NULL, NULL, NULL, NULL);
00075
00076 return obj;
00077 }
00078
00079 SV *getobj(db_con_t *con) {
00080 return ((SV*)CON_TAIL(con));
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 int checkobj(SV* obj) {
00091 if (obj != NULL) {
00092 if (obj != &PL_sv_undef) {
00093 if (sv_isobject(obj)) {
00094 if (sv_derived_from(obj, PERL_VDB_BASECLASS)) {
00095 return 1;
00096 }
00097 }
00098 }
00099 }
00100
00101 return 0;
00102 }
00103
00104
00105
00106
00107
00108 db_con_t* perlvdb_db_init(const char* url) {
00109 db_con_t* res;
00110
00111 char *cn;
00112 SV *obj = NULL;
00113
00114 int consize = sizeof(db_con_t) + sizeof(SV);
00115
00116 if (!url) {
00117 LM_ERR("invalid parameter value\n");
00118 return NULL;
00119 }
00120
00121 cn = parseurl(url);
00122 if (!cn) {
00123 LM_ERR("invalid perl vdb url.\n");
00124 return NULL;
00125 }
00126
00127 obj = newvdbobj(cn);
00128 if (!checkobj(obj)) {
00129 LM_ERR("could not initialize module. Not inheriting from %s?\n",
00130 PERL_VDB_BASECLASS);
00131 return NULL;
00132 }
00133
00134 res = pkg_malloc(consize);
00135 if (!res) {
00136 LM_ERR("no pkg memory left\n");
00137 return NULL;
00138 }
00139 memset(res, 0, consize);
00140 CON_TAIL(res) = (unsigned int)(unsigned long)obj;
00141
00142 return res;
00143 }
00144
00145
00146
00147
00148
00149
00150 int perlvdb_use_table(db_con_t* h, const str* t) {
00151 SV *ret;
00152
00153 if (!h || !t || !t->s) {
00154 LM_ERR("invalid parameter value\n");
00155 return -1;
00156 }
00157
00158 ret = perlvdb_perlmethod(getobj(h), PERL_VDB_USETABLEMETHOD,
00159 sv_2mortal(newSVpv(t->s, t->len)), NULL, NULL, NULL);
00160
00161 return IV2int(ret);
00162 }
00163
00164
00165 void perlvdb_db_close(db_con_t* h) {
00166 if (!h) {
00167 LM_ERR("invalid parameter value\n");
00168 return;
00169 }
00170
00171 pkg_free(h);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 int perlvdb_db_insertreplace(db_con_t* h, db_key_t* k, db_val_t* v,
00183 int n, char *insertreplace) {
00184 AV *arr;
00185 SV *arrref;
00186 SV *ret;
00187
00188 arr = pairs2perlarray(k, v, n);
00189 arrref = newRV_noinc((SV*)arr);
00190 ret = perlvdb_perlmethod(getobj(h), insertreplace,
00191 arrref, NULL, NULL, NULL);
00192
00193 av_undef(arr);
00194
00195 return IV2int(ret);
00196 }
00197
00198 int perlvdb_db_insert(db_con_t* h, db_key_t* k, db_val_t* v, int n) {
00199 return perlvdb_db_insertreplace(h, k, v, n, PERL_VDB_INSERTMETHOD);
00200 }
00201
00202
00203
00204
00205 int perlvdb_db_replace(db_con_t* h, db_key_t* k, db_val_t* v, int n) {
00206 return perlvdb_db_insertreplace(h, k, v, n, PERL_VDB_REPLACEMETHOD);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 int perlvdb_db_delete(db_con_t* h, db_key_t* k, db_op_t* o, db_val_t* v,
00218 int n) {
00219 AV *arr;
00220 SV *arrref;
00221 SV *ret;
00222
00223 arr = conds2perlarray(k, o, v, n);
00224 arrref = newRV_noinc((SV*)arr);
00225 ret = perlvdb_perlmethod(getobj(h), PERL_VDB_DELETEMETHOD,
00226 arrref, NULL, NULL, NULL);
00227
00228 av_undef(arr);
00229
00230 return IV2int(ret);
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 int perlvdb_db_update(db_con_t* h, db_key_t* k, db_op_t* o, db_val_t* v,
00246 db_key_t* uk, db_val_t* uv, int n, int un) {
00247
00248 AV *condarr;
00249 AV *updatearr;
00250
00251 SV *condarrref;
00252 SV *updatearrref;
00253
00254 SV *ret;
00255
00256 condarr = conds2perlarray(k, o, v, n);
00257 updatearr = pairs2perlarray(uk, uv, un);
00258
00259 condarrref = newRV_noinc((SV*)condarr);
00260 updatearrref = newRV_noinc((SV*)updatearr);
00261
00262 ret = perlvdb_perlmethod(getobj(h), PERL_VDB_UPDATEMETHOD,
00263 condarrref, updatearrref, NULL, NULL);
00264
00265 av_undef(condarr);
00266 av_undef(updatearr);
00267
00268 return IV2int(ret);
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 int perlvdb_db_query(db_con_t* h, db_key_t* k, db_op_t* op, db_val_t* v,
00284 db_key_t* c, int n, int nc,
00285 db_key_t o, db_res_t** r) {
00286
00287
00288 AV *condarr;
00289 AV *retkeysarr;
00290 SV *order;
00291
00292 SV *condarrref;
00293 SV *retkeysref;
00294
00295 SV *resultset;
00296
00297 int retval = 0;
00298
00299
00300 condarr = conds2perlarray(k, op, v, n);
00301 retkeysarr = keys2perlarray(c, nc);
00302
00303 if (o) order = newSVpv(o->s, o->len);
00304 else order = &PL_sv_undef;
00305
00306
00307 condarrref = newRV_noinc((SV*)condarr);
00308 retkeysref = newRV_noinc((SV*)retkeysarr);
00309
00310
00311 resultset = perlvdb_perlmethod(getobj(h), PERL_VDB_QUERYMETHOD,
00312 condarrref, retkeysref, order, NULL);
00313
00314 av_undef(condarr);
00315 av_undef(retkeysarr);
00316
00317
00318 if (!resultset) {
00319
00320 LM_ERR("no perl result set.\n");
00321 retval = -1;
00322 } else {
00323 if (sv_isa(resultset, "OpenSER::VDB::Result")) {
00324 retval = perlresult2dbres(resultset, r);
00325
00326 SvREFCNT_dec(resultset);
00327 } else {
00328 LM_ERR("invalid result set retrieved from perl call.\n");
00329 retval = -1;
00330 }
00331 }
00332
00333 return retval;
00334 }
00335
00336
00337
00338
00339
00340 int perlvdb_db_free_result(db_con_t* _h, db_res_t* _r) {
00341 int i;
00342
00343 if (_r) {
00344 for (i = 0; i < _r->n; i++) {
00345 if (_r->rows[i].values)
00346 pkg_free(_r->rows[i].values);
00347 }
00348
00349 if (_r->col.types)
00350 pkg_free(_r->col.types);
00351 if (_r->col.names)
00352 pkg_free(_r->col.names);
00353 if (_r->rows)
00354 pkg_free(_r->rows);
00355 pkg_free(_r);
00356 }
00357 return 0;
00358 }