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 "perlvdb_conv.h"
00028 #include "perlvdb_oohelpers.h"
00029
00030 #include "../../dprint.h"
00031 #include "../../mem/mem.h"
00032
00033
00034
00035
00036 AV *pairs2perlarray(db_key_t* keys, db_val_t* vals, int n) {
00037
00038 AV *array = newAV();
00039 SV *element;
00040 int i;
00041
00042 for (i = 0; i < n; i++) {
00043 element = pair2perlpair(*(keys + i), vals + i);
00044 av_push(array, element);
00045 }
00046
00047 return array;
00048 }
00049
00050
00051
00052
00053 AV *conds2perlarray(db_key_t* keys, db_op_t* ops, db_val_t* vals, int n) {
00054 AV *array = newAV();
00055 SV *element = NULL;
00056 int i = 0;
00057
00058 for (i = 0; i < n; i++) {
00059 if (ops) {
00060 if (ops + i)
00061 if (*(ops + i))
00062 element = cond2perlcond(*(keys + i),
00063 *(ops + i), vals + i);
00064 } else {
00065
00066 #ifdef OP_EQ
00067 element = cond2perlcond(*(keys + i), OP_EQ, vals + i);
00068 #else
00069 element = cond2perlcond(*(keys + i), "=", vals + i);
00070 #endif
00071 }
00072
00073 av_push(array, element);
00074 }
00075
00076 return array;
00077 }
00078
00079
00080
00081
00082
00083 AV *keys2perlarray(db_key_t* keys, int n) {
00084 AV *array = newAV();
00085 SV *element;
00086 int i;
00087 for (i = 0; i < n; i++) {
00088 element = newSVpv((keys[i])->s, (keys[i])->len);
00089 av_push(array, element);
00090 }
00091
00092 return array;
00093 }
00094
00095 inline SV *valdata(db_val_t* val) {
00096 SV *data = &PL_sv_undef;
00097 const char* stringval;
00098
00099 switch(VAL_TYPE(val)) {
00100 case DB_INT:
00101 data = newSViv(VAL_INT(val));
00102 break;
00103
00104 case DB_BIGINT:
00105 LM_ERR("BIGINT not supported");
00106 data = &PL_sv_undef;
00107 break;
00108
00109 case DB_DOUBLE:
00110 data = newSVnv(VAL_DOUBLE(val));
00111 break;
00112
00113 case DB_STRING:
00114 stringval = VAL_STRING(val);
00115 if (strlen(stringval) > 0)
00116 data = newSVpv(stringval, strlen(stringval));
00117 else
00118 data = &PL_sv_undef;
00119 break;
00120
00121 case DB_STR:
00122 if (VAL_STR(val).len > 0)
00123 data = newSVpv(VAL_STR(val).s, VAL_STR(val).len);
00124 else
00125 data = &PL_sv_undef;
00126 break;
00127
00128 case DB_DATETIME:
00129 data = newSViv((unsigned int)VAL_TIME(val));
00130 break;
00131
00132 case DB_BLOB:
00133 if (VAL_BLOB(val).len > 0)
00134 data = newSVpv(VAL_BLOB(val).s,
00135 VAL_BLOB(val).len);
00136 else
00137 data = &PL_sv_undef;
00138 break;
00139
00140 case DB_BITMAP:
00141 data = newSViv(VAL_BITMAP(val));
00142 break;
00143 }
00144
00145 return data;
00146 }
00147
00148 SV *val2perlval(db_val_t* val) {
00149 SV* retval;
00150 SV *class;
00151
00152 SV *p_data;
00153 SV *p_type;
00154
00155 class = newSVpv(PERL_CLASS_VALUE, 0);
00156
00157 p_data = valdata(val);
00158 p_type = newSViv(val->type);
00159
00160 retval = perlvdb_perlmethod(class, PERL_CONSTRUCTOR_NAME,
00161 p_type, p_data, NULL, NULL);
00162
00163 return retval;
00164
00165 }
00166
00167 SV *pair2perlpair(db_key_t key, db_val_t* val) {
00168 SV* retval;
00169 SV *class;
00170
00171 SV *p_key;
00172 SV *p_type;
00173 SV *p_data;
00174
00175 class = newSVpv(PERL_CLASS_PAIR, 0);
00176
00177 p_key = newSVpv(key->s, key->len);
00178 p_type = newSViv(val->type);
00179 p_data = valdata(val);
00180
00181 retval = perlvdb_perlmethod(class, PERL_CONSTRUCTOR_NAME,
00182 p_key, p_type, p_data, NULL);
00183
00184 SvREFCNT_dec(class);
00185
00186 return retval;
00187
00188 }
00189
00190 SV *cond2perlcond(db_key_t key, db_op_t op, db_val_t* val) {
00191 SV* retval;
00192 SV *class;
00193
00194 SV *p_key;
00195 SV *p_op;
00196 SV *p_type;
00197 SV *p_data;
00198
00199 class = newSVpv(PERL_CLASS_REQCOND, 0);
00200
00201 p_key = newSVpv(key->s, key->len);
00202 p_op = newSVpv(op, strlen(op));
00203 p_type = newSViv(val->type);
00204 p_data = valdata(val);
00205
00206 retval = perlvdb_perlmethod(class, PERL_CONSTRUCTOR_NAME,
00207 p_key, p_op, p_type, p_data);
00208
00209 return retval;
00210 }
00211
00212
00213
00214 int perlresult2dbres(SV *perlres, db_res_t **r) {
00215
00216 SV *colarrayref = NULL;
00217 AV *colarray = NULL;
00218 SV *acol = NULL;
00219 int colcount = 0;
00220
00221
00222 SV *rowarrayref = NULL;
00223 AV *rowarray = NULL;
00224 int rowcount = 0;
00225
00226 SV *arowref = NULL;
00227 AV *arow = NULL;
00228 int arowlen = 0;
00229
00230 SV *aelement = NULL;
00231 SV *atypesv = 0;
00232 int atype = 0;
00233 SV *aval = NULL;
00234
00235 char *charbuf;
00236 char *currentstring;
00237
00238 int i, j;
00239
00240 int retval = 0;
00241 STRLEN len;
00242
00243 SV *d1;
00244
00245
00246
00247
00248 if (!(SvROK(perlres) &&
00249 (sv_derived_from(perlres, "OpenSER::VDB::Result")))) {
00250 goto error;
00251 }
00252
00253 *r = (db_res_t *)pkg_malloc(sizeof(db_res_t));
00254 if (!(*r)) {
00255 LM_ERR("no pkg memory left\n");
00256 return -1;
00257 }
00258 memset(*r, 0, sizeof(db_res_t));
00259
00260
00261 colarrayref = perlvdb_perlmethod(perlres, PERL_VDB_COLDEFSMETHOD,
00262 NULL, NULL, NULL, NULL);
00263 if (!(SvROK(colarrayref))) goto error;
00264 colarray = (AV *)SvRV(colarrayref);
00265 if (!(SvTYPE(colarray) == SVt_PVAV)) goto error;
00266
00267 colcount = av_len(colarray) + 1;
00268
00269
00270 (*r)->col.n = colcount;
00271 (*r)->col.types = (db_type_t*)pkg_malloc(colcount*sizeof(db_type_t));
00272 (*r)->col.names = (db_key_t*)pkg_malloc(colcount*sizeof(db_key_t));
00273
00274
00275 for (i = colcount-1; i >= 0; i--) {
00276 acol = *av_fetch(colarray, i, 0);
00277 d1 = perlvdb_perlmethod(acol, PERL_VDB_TYPEMETHOD,
00278 NULL, NULL, NULL, NULL);
00279 if (!SvIOK(d1)) goto error;
00280 (*r)->col.types[i] = SvIV(d1);
00281
00282 SvREFCNT_dec(d1);
00283
00284 d1 = perlvdb_perlmethod(acol, PERL_VDB_NAMEMETHOD,
00285 NULL, NULL, NULL, NULL);
00286 if (!SvPOK(d1)) goto error;
00287 currentstring = SvPV(d1, len);
00288 charbuf = pkg_malloc(len+1);
00289 strncpy(charbuf, currentstring, len+1);
00290 (*r)->col.names[i]->s = charbuf;
00291 (*r)->col.names[i]->len = strlen(charbuf);
00292
00293 SvREFCNT_dec(d1);
00294
00295 }
00296
00297 rowarrayref = perlvdb_perlmethod(perlres, PERL_VDB_ROWSMETHOD,
00298 NULL, NULL, NULL, NULL);
00299 if (!(SvROK(rowarrayref))) {
00300 (*r)->n = 0;
00301 (*r)->res_rows = 0;
00302 (*r)->last_row = 0;
00303 goto end;
00304 }
00305
00306 rowarray = (AV *)SvRV(rowarrayref);
00307 if (!(SvTYPE(rowarray) == SVt_PVAV)) goto error;
00308
00309 rowcount = av_len(rowarray) + 1;
00310
00311 (*r)->n = rowcount;
00312 (*r)->res_rows = rowcount;
00313 (*r)->last_row = rowcount;
00314
00315 (*r)->rows = (db_row_t *)pkg_malloc(rowcount*sizeof(db_row_t));
00316
00317 for (i = 0; i < rowcount; i++) {
00318 arowref = *av_fetch(rowarray, 0, 0);
00319 if (!SvROK(arowref)) goto error;
00320 arow = (AV *)SvRV(arowref);
00321 if (!(SvTYPE(colarray) == SVt_PVAV)) goto error;
00322 arowlen = av_len(arow) + 1;
00323
00324 (*r)->rows[i].n = arowlen;
00325 (*r)->rows[i].values =
00326 (db_val_t *)pkg_malloc(arowlen*sizeof(db_val_t));
00327
00328
00329 for (j = 0; j < arowlen; j++) {
00330 aelement = *av_fetch(arow, j, 0);
00331 #define cur_val (((*r)->rows)[i].values)[j]
00332
00333
00334 if (!(sv_isobject(aelement) &&
00335 sv_derived_from(aelement, PERL_CLASS_VALUE))) {
00336 cur_val.nul = 1;
00337 continue;
00338 }
00339 atype = SvIV(atypesv = perlvdb_perlmethod(aelement,
00340 PERL_VDB_TYPEMETHOD,
00341 NULL, NULL, NULL, NULL));
00342 aval = perlvdb_perlmethod(aelement, PERL_VDB_DATAMETHOD,
00343 NULL, NULL, NULL, NULL);
00344
00345 (*r)->rows[i].values[j].type = atype;
00346 if (!SvOK(aval)) {
00347 cur_val.nul = 1;
00348 } else {
00349 switch (atype) {
00350 case DB_INT:
00351 cur_val.val.int_val =
00352 SvIV(aval);
00353 cur_val.nul = 0;
00354 break;
00355 case DB_DOUBLE:
00356 cur_val.val.double_val =
00357 SvNV(aval);
00358 cur_val.nul = 0;
00359 break;
00360 case DB_STRING:
00361 case DB_STR:
00362
00363
00364 cur_val.type = DB_STRING;
00365 currentstring = SvPV(aval, len);
00366 charbuf = pkg_malloc(len+1);
00367 strncpy(charbuf, currentstring,
00368 len+1);
00369 cur_val.val.string_val =
00370 charbuf;
00371 cur_val.nul = 0;
00372 break;
00373 case DB_DATETIME:
00374 cur_val.val.time_val =
00375 (time_t)SvIV(aval);
00376 cur_val.nul = 0;
00377 break;
00378 case DB_BLOB:
00379 currentstring = SvPV(aval, len);
00380 charbuf = pkg_malloc(len+1);
00381 strncpy(charbuf, currentstring,
00382 len+1);
00383 cur_val.val.blob_val.s =
00384 charbuf;
00385 cur_val.val.blob_val.len = len;
00386 cur_val.nul = 0;
00387 break;
00388 case DB_BITMAP:
00389 cur_val.val.bitmap_val =
00390 SvIV(aval);
00391 cur_val.nul = 0;
00392 break;
00393 default:
00394 LM_CRIT("cannot handle this data type.\n");
00395 return -1;
00396 break;
00397 }
00398 }
00399 SvREFCNT_dec(atypesv);
00400 SvREFCNT_dec(aval);
00401 }
00402 }
00403
00404 end:
00405 av_undef(colarray);
00406 av_undef(rowarray);
00407 return retval;
00408 error:
00409 LM_CRIT("broken result set. Exiting, leaving OpenSER in unknown state.\n");
00410 return -1;
00411 }
00412
00413
00414