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
00035 #include "pg_fld.h"
00036 #include "pg_con.h"
00037 #include "pg_mod.h"
00038
00039 #include "../../lib/srdb2/db_drv.h"
00040 #include "../../mem/mem.h"
00041 #include "../../dprint.h"
00042
00043 #include <sys/types.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <stdint.h>
00047 #include <string.h>
00048
00054 #define PG_EPOCH_TIME ((int64_t)946684800)
00055
00056
00062 static void pg_fld_free(db_fld_t* fld, struct pg_fld* payload)
00063 {
00064 db_drv_free(&payload->gen);
00065 pkg_free(payload);
00066 }
00067
00068
00069 int pg_fld(db_fld_t* fld, char* table)
00070 {
00071 struct pg_fld* res;
00072
00073 res = (struct pg_fld*)pkg_malloc(sizeof(struct pg_fld));
00074 if (res == NULL) {
00075 ERR("postgres: No memory left\n");
00076 return -1;
00077 }
00078 memset(res, '\0', sizeof(struct pg_fld));
00079 if (db_drv_init(&res->gen, pg_fld_free) < 0) goto error;
00080
00081 DB_SET_PAYLOAD(fld, res);
00082 return 0;
00083
00084 error:
00085 if (res) pkg_free(res);
00086 return -1;
00087 }
00088
00089
00090 union ull {
00091 uint64_t ui64;
00092 uint32_t ui32[2];
00093 };
00094
00095 static inline uint64_t htonll(uint64_t in)
00096 {
00097 union ull* p = (union ull*)∈
00098
00099 return ((uint64_t)htonl(p->ui32[0]) << 32) + (uint64_t)htonl(p->ui32[1]);
00100 }
00101
00102
00103 static inline uint64_t ntohll(uint64_t in)
00104 {
00105 union ull* p = (union ull*)∈
00106 return ((uint64_t)ntohl(p->ui32[0]) << 32) + (uint64_t)ntohl(p->ui32[1]);
00107 }
00108
00109
00110 static inline void db_int2pg_int4(struct pg_params* dst, int i,
00111 db_fld_t* src)
00112 {
00113 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00114 pfld->v.int4[0] = htonl(src->v.int4);
00115
00116 dst->fmt[i] = 1;
00117 dst->val[i] = pfld->v.byte;
00118 dst->len[i] = 4;
00119 }
00120
00121
00122 static inline void db_int2pg_int2(struct pg_params* dst, int i,
00123 db_fld_t* src)
00124 {
00125 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00126 pfld->v.int2[0] = htons(src->v.int4);
00127
00128 dst->fmt[i] = 1;
00129 dst->val[i] = pfld->v.byte;
00130 dst->len[i] = 2;
00131 }
00132
00133
00134 static inline void db_int2pg_timestamp(struct pg_params* dst, int i,
00135 db_fld_t* src, unsigned int flags)
00136 {
00137 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00138 if (flags & PG_INT8_TIMESTAMP) {
00139 pfld->v.int8 = ((int64_t)src->v.int4 - PG_EPOCH_TIME) * 1000000;
00140 } else {
00141 pfld->v.dbl = (double)src->v.int4 - (double)PG_EPOCH_TIME;
00142 }
00143 pfld->v.int8 = htonll(pfld->v.int8);
00144
00145 dst->fmt[i] = 1;
00146 dst->val[i] = pfld->v.byte;
00147 dst->len[i] = 8;
00148 }
00149
00150
00151 static inline void db_int2pg_int8(struct pg_params* dst, int i,
00152 db_fld_t* src)
00153 {
00154 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00155 pfld->v.int4[0] = 0;
00156 pfld->v.int4[1] = htonl(src->v.int4);
00157
00158 dst->fmt[i] = 1;
00159 dst->val[i] = pfld->v.byte;
00160 dst->len[i] = 8;
00161 }
00162
00163
00164 static inline void db_int2pg_bool(struct pg_params* dst, int i, db_fld_t* src)
00165 {
00166 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00167 if (src->v.int4) pfld->v.byte[0] = 1;
00168 else pfld->v.byte[0] = 0;
00169
00170 dst->fmt[i] = 1;
00171 dst->val[i] = pfld->v.byte;
00172 dst->len[i] = 1;
00173 }
00174
00175
00176 static inline void db_int2pg_inet(struct pg_params* dst, int i, db_fld_t* src)
00177 {
00178 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00179 pfld->v.byte[0] = AF_INET;
00180 pfld->v.byte[1] = 32;
00181 pfld->v.byte[2] = 0;
00182 pfld->v.byte[3] = 4;
00183 pfld->v.int4[1] = htonl(src->v.int4);
00184
00185 dst->fmt[i] = 1;
00186 dst->val[i] = pfld->v.byte;
00187 dst->len[i] = 8;
00188 }
00189
00190
00191 static inline void db_float2pg_float4(struct pg_params* dst, int i, db_fld_t* src)
00192 {
00193 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00194 pfld->v.int4[0] = htonl(src->v.int4);
00195
00196 dst->fmt[i] = 1;
00197 dst->val[i] = pfld->v.byte;
00198 dst->len[i] = 4;
00199 }
00200
00201
00202 static inline void db_float2pg_float8(struct pg_params* dst, int i, db_fld_t* src)
00203 {
00204 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00205 pfld->v.dbl = src->v.flt;
00206 pfld->v.int8 = htonll(pfld->v.int8);
00207
00208 dst->fmt[i] = 1;
00209 dst->val[i] = pfld->v.byte;
00210 dst->len[i] = 8;
00211 }
00212
00213
00214 static inline void db_double2pg_float8(struct pg_params* dst, int i, db_fld_t* src)
00215 {
00216 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00217 pfld->v.int8 = htonll(src->v.int8);
00218
00219 dst->fmt[i] = 1;
00220 dst->val[i] = pfld->v.byte;
00221 dst->len[i] = 8;
00222 }
00223
00224
00225 static inline void db_double2pg_float4(struct pg_params* dst, int i, db_fld_t* src)
00226 {
00227 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00228 pfld->v.flt = src->v.dbl;
00229 pfld->v.int4[0] = htonl(pfld->v.int4[0]);
00230
00231 dst->fmt[i] = 1;
00232 dst->val[i] = pfld->v.byte;
00233 dst->len[i] = 4;
00234 }
00235
00236
00237 static inline void db_int2pg_bit(struct pg_params* dst, int i, db_fld_t* src)
00238 {
00239 struct pg_fld* pfld = DB_GET_PAYLOAD(src);
00240
00241 pfld->v.int4[0] = htonl(32);
00242 pfld->v.int4[1] = htonl(src->v.int4);
00243
00244 dst->fmt[i] = 1;
00245 dst->val[i] = pfld->v.byte;
00246 dst->len[i] = 8;
00247 }
00248
00249
00250 static inline void db_str2pg_string(struct pg_params* dst, int i,
00251 db_fld_t* src)
00252 {
00253 dst->fmt[i] = 1;
00254 dst->val[i] = src->v.lstr.s;
00255 dst->len[i] = src->v.lstr.len;
00256 }
00257
00258
00259 static inline void db_cstr2pg_string(struct pg_params* dst, int i,
00260 db_fld_t* src)
00261 {
00262 dst->fmt[i] = 0;
00263 dst->val[i] = src->v.cstr;
00264 }
00265
00266
00267 int pg_fld2pg(struct pg_params* dst, int off, pg_type_t* types,
00268 db_fld_t* src, unsigned int flags)
00269 {
00270 int i;
00271 struct pg_fld* pfld;
00272
00273 if (src == NULL) return 0;
00274
00275 for(i = 0; !DB_FLD_EMPTY(src) && !DB_FLD_LAST(src[i]); i++) {
00276 pfld = DB_GET_PAYLOAD(src + i);
00277
00278
00279 if (src[i].flags & DB_NULL) {
00280 dst->val[off + i] = NULL;
00281 dst->len[off + i] = 0;
00282 continue;
00283 }
00284
00285 switch(src[i].type) {
00286 case DB_INT:
00287 if (pfld->oid == types[PG_INT2].oid)
00288 db_int2pg_int2(dst, off + i, src + i);
00289 else if (pfld->oid == types[PG_INT4].oid)
00290 db_int2pg_int4(dst, off + i, src + i);
00291 else if ((pfld->oid == types[PG_TIMESTAMP].oid) ||
00292 (pfld->oid == types[PG_TIMESTAMPTZ].oid))
00293 db_int2pg_timestamp(dst, off + i, src + i, flags);
00294 else if (pfld->oid == types[PG_INT8].oid)
00295 db_int2pg_int8(dst, off + i, src + i);
00296 else if (pfld->oid == types[PG_INET].oid)
00297 db_int2pg_inet(dst, off + i, src + i);
00298 else if (pfld->oid == types[PG_BOOL].oid)
00299 db_int2pg_bool(dst, off + i, src + i);
00300 else if (pfld->oid == types[PG_BIT].oid)
00301 db_int2pg_bit(dst, off + i, src + i);
00302 else if (pfld->oid == types[PG_VARBIT].oid)
00303 db_int2pg_bit(dst, off + i, src + i);
00304 else goto bug;
00305 break;
00306
00307 case DB_BITMAP:
00308 if (pfld->oid == types[PG_INT4].oid)
00309 db_int2pg_int4(dst, off + i, src + i);
00310 else if (pfld->oid == types[PG_INT8].oid)
00311 db_int2pg_int8(dst, off + i, src + i);
00312 else if (pfld->oid == types[PG_BIT].oid)
00313 db_int2pg_bit(dst, off + i, src + i);
00314 else if (pfld->oid == types[PG_VARBIT].oid)
00315 db_int2pg_bit(dst, off + i, src + i);
00316 else goto bug;
00317 break;
00318
00319 case DB_DATETIME:
00320 if (pfld->oid == types[PG_INT4].oid)
00321 db_int2pg_int4(dst, off + i, src + i);
00322 else if ((pfld->oid == types[PG_TIMESTAMP].oid) ||
00323 (pfld->oid == types[PG_TIMESTAMPTZ].oid))
00324 db_int2pg_timestamp(dst, off + i, src + i, flags);
00325 else if (pfld->oid == types[PG_INT8].oid)
00326 db_int2pg_int8(dst, off + i, src + i);
00327 else goto bug;
00328 break;
00329
00330 case DB_FLOAT:
00331 if (pfld->oid == types[PG_FLOAT4].oid)
00332 db_float2pg_float4(dst, off + i, src + i);
00333 else if (pfld->oid == types[PG_FLOAT8].oid)
00334 db_float2pg_float8(dst, off + i, src + i);
00335 else goto bug;
00336 break;
00337
00338 case DB_DOUBLE:
00339 if (pfld->oid == types[PG_FLOAT4].oid)
00340 db_double2pg_float4(dst, off + i, src + i);
00341 else if (pfld->oid == types[PG_FLOAT8].oid)
00342 db_double2pg_float8(dst, off + i, src + i);
00343 else goto bug;
00344 break;
00345
00346 case DB_STR:
00347 if (pfld->oid == types[PG_VARCHAR].oid ||
00348 pfld->oid == types[PG_BYTE].oid ||
00349 pfld->oid == types[PG_CHAR].oid ||
00350 pfld->oid == types[PG_TEXT].oid ||
00351 pfld->oid == types[PG_BPCHAR].oid)
00352 db_str2pg_string(dst, off + i, src + i);
00353 else goto bug;
00354 break;
00355
00356 case DB_CSTR:
00357 if (pfld->oid == types[PG_VARCHAR].oid ||
00358 pfld->oid == types[PG_BYTE].oid ||
00359 pfld->oid == types[PG_CHAR].oid ||
00360 pfld->oid == types[PG_TEXT].oid ||
00361 pfld->oid == types[PG_BPCHAR].oid)
00362 db_cstr2pg_string(dst, off + i, src + i);
00363 else goto bug;
00364 break;
00365
00366 case DB_BLOB:
00367 if (pfld->oid == types[PG_BYTE].oid)
00368 db_str2pg_string(dst, off + i, src + i);
00369 else goto bug;
00370 break;
00371
00372 default:
00373 BUG("postgres: Unsupported field type %d in field %s\n",
00374 src[i].type, src[i].name);
00375 return -1;
00376 }
00377 }
00378
00379 return 0;
00380
00381 bug:
00382 BUG("postgres: Error while converting DB API type %d to Postgres Oid %d\n",
00383 src[i].type, pfld->oid);
00384 return -1;
00385
00386 }
00387
00388
00389 int pg_check_fld2pg(db_fld_t* fld, pg_type_t* types)
00390 {
00391 int i;
00392 const char* name = "UNKNOWN";
00393 struct pg_fld* pfld;
00394
00395 if (fld == NULL) return 0;
00396
00397 for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00398 pfld = DB_GET_PAYLOAD(fld + i);
00399 switch(fld[i].type) {
00400 case DB_INT:
00401 if (pfld->oid == types[PG_INT2].oid) continue;
00402 if (pfld->oid == types[PG_INT4].oid) continue;
00403 if (pfld->oid == types[PG_INT8].oid) continue;
00404 if (pfld->oid == types[PG_BOOL].oid) continue;
00405 if (pfld->oid == types[PG_INET].oid) continue;
00406 if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
00407 if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
00408 if (pfld->oid == types[PG_BIT].oid) continue;
00409 if (pfld->oid == types[PG_VARBIT].oid) continue;
00410 break;
00411
00412 case DB_BITMAP:
00413 if (pfld->oid == types[PG_INT4].oid) continue;
00414 if (pfld->oid == types[PG_INT8].oid) continue;
00415 if (pfld->oid == types[PG_BIT].oid) continue;
00416 if (pfld->oid == types[PG_VARBIT].oid) continue;
00417 break;
00418
00419 case DB_FLOAT:
00420 case DB_DOUBLE:
00421 if (pfld->oid == types[PG_FLOAT4].oid) continue;
00422 if (pfld->oid == types[PG_FLOAT8].oid) continue;
00423 break;
00424
00425 case DB_CSTR:
00426 case DB_STR:
00427 if (pfld->oid == types[PG_BYTE].oid) continue;
00428 if (pfld->oid == types[PG_CHAR].oid) continue;
00429 if (pfld->oid == types[PG_TEXT].oid) continue;
00430 if (pfld->oid == types[PG_BPCHAR].oid) continue;
00431 if (pfld->oid == types[PG_VARCHAR].oid) continue;
00432 break;
00433
00434 case DB_BLOB:
00435 if (pfld->oid == types[PG_BYTE].oid) continue;
00436 break;
00437
00438 case DB_DATETIME:
00439 if (pfld->oid == types[PG_INT4].oid) continue;
00440 if (pfld->oid == types[PG_INT8].oid) continue;
00441 if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
00442 if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
00443 break;
00444
00445 default:
00446 BUG("postgres: Unsupported field type %d, bug in postgres module\n",
00447 fld[i].type);
00448 return -1;
00449 }
00450
00451 pg_oid2name(&name, types, pfld->oid);
00452 ERR("postgres: Cannot convert column '%s' of type %s "
00453 "to PostgreSQL column type '%s'\n",
00454 fld[i].name, db_fld_str[fld[i].type], name);
00455 return -1;
00456 }
00457 return 0;
00458 }
00459
00460
00461 int pg_resolve_param_oids(db_fld_t* vals, db_fld_t* match, int n1, int n2, PGresult* types)
00462 {
00463 struct pg_fld* pfld;
00464 int i;
00465
00466 if (n1 + n2 != PQnparams(types)) {
00467 ERR("postgres: Number of command parameters do not match\n");
00468 return -1;
00469 }
00470
00471 for(i = 0; i < n1; i++) {
00472 pfld = DB_GET_PAYLOAD(vals + i);
00473 pfld->oid = PQparamtype(types, i);
00474 }
00475
00476 for(i = 0; i < n2; i++) {
00477 pfld = DB_GET_PAYLOAD(match + i);
00478 pfld->oid = PQparamtype(types, n1 + i);
00479 }
00480
00481 return 0;
00482 }
00483
00484
00485 int pg_resolve_result_oids(db_fld_t* fld, int n, PGresult* types)
00486 {
00487 struct pg_fld* pfld;
00488 int i;
00489 if (fld == NULL) return 0;
00490
00491 if (n != PQnfields(types)) {
00492 ERR("postgres: Result field numbers do not match\n");
00493 return -1;
00494 }
00495
00496 for(i = 0; i < n; i++) {
00497 pfld = DB_GET_PAYLOAD(fld + i);
00498 pfld->oid = PQftype(types, i);
00499 }
00500
00501 return 0;
00502 }
00503
00504
00505 int pg_check_pg2fld(db_fld_t* fld, pg_type_t* types)
00506 {
00507 int i;
00508 const char* name = "UNKNOWN";
00509 struct pg_fld* pfld;
00510
00511 if (fld == NULL) return 0;
00512
00513 for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00514 pfld = DB_GET_PAYLOAD(fld + i);
00515
00516 if (pfld->oid == 0) {
00517 ERR("postgres: Unknown type fields not supported\n");
00518 return -1;
00519 }
00520
00521 switch(fld[i].type) {
00522 case DB_INT:
00523 if (pfld->oid == types[PG_INT2].oid) continue;
00524 if (pfld->oid == types[PG_INT4].oid) continue;
00525 if (pfld->oid == types[PG_INT8].oid) continue;
00526 if (pfld->oid == types[PG_BOOL].oid) continue;
00527 if (pfld->oid == types[PG_INET].oid) continue;
00528 if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
00529 if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
00530 if (pfld->oid == types[PG_BIT].oid) continue;
00531 if (pfld->oid == types[PG_VARBIT].oid) continue;
00532 break;
00533
00534 case DB_BITMAP:
00535 if (pfld->oid == types[PG_INT2].oid) continue;
00536 if (pfld->oid == types[PG_INT4].oid) continue;
00537 if (pfld->oid == types[PG_INT8].oid) continue;
00538 if (pfld->oid == types[PG_BIT].oid) continue;
00539 if (pfld->oid == types[PG_VARBIT].oid) continue;
00540 break;
00541
00542 case DB_FLOAT:
00543 if (pfld->oid == types[PG_FLOAT4].oid) continue;
00544 break;
00545
00546 case DB_DOUBLE:
00547 if (pfld->oid == types[PG_FLOAT4].oid) continue;
00548 if (pfld->oid == types[PG_FLOAT8].oid) continue;
00549 break;
00550
00551 case DB_CSTR:
00552 if (pfld->oid == types[PG_CHAR].oid) continue;
00553 if (pfld->oid == types[PG_TEXT].oid) continue;
00554 if (pfld->oid == types[PG_BPCHAR].oid) continue;
00555 if (pfld->oid == types[PG_VARCHAR].oid) continue;
00556 if (pfld->oid == types[PG_INT2].oid) continue;
00557 if (pfld->oid == types[PG_INT4].oid) continue;
00558 break;
00559
00560 case DB_STR:
00561 case DB_BLOB:
00562 if (pfld->oid == types[PG_BYTE].oid) continue;
00563 if (pfld->oid == types[PG_CHAR].oid) continue;
00564 if (pfld->oid == types[PG_TEXT].oid) continue;
00565 if (pfld->oid == types[PG_BPCHAR].oid) continue;
00566 if (pfld->oid == types[PG_VARCHAR].oid) continue;
00567 if (pfld->oid == types[PG_INT2].oid) continue;
00568 if (pfld->oid == types[PG_INT4].oid) continue;
00569 break;
00570
00571 case DB_DATETIME:
00572 if (pfld->oid == types[PG_INT2].oid) continue;
00573 if (pfld->oid == types[PG_INT4].oid) continue;
00574 if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
00575 if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
00576 break;
00577
00578 default:
00579 BUG("postgres: Unsupported field type %d, bug in postgres module\n",
00580 fld[i].type);
00581 return -1;
00582 }
00583
00584 pg_oid2name(&name, types, pfld->oid);
00585 ERR("postgres: Cannot convert column '%s' of type %s "
00586 "to DB API field of type %s\n",
00587 fld[i].name, name, db_fld_str[fld[i].type]);
00588 return -1;
00589 }
00590 return 0;
00591 }
00592
00593
00594 static inline int pg_int2_2_db_cstr(db_fld_t* fld, char* val, int len)
00595 {
00596 struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
00597 int size, v;
00598
00599 v = (int16_t)ntohs(*((int16_t*)val));
00600
00601 size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
00602 if (size < 0 || size >= INT2STR_MAX_LEN) {
00603 BUG("postgres: Error while converting integer to string\n");
00604 return -1;
00605 }
00606
00607 fld->v.cstr = pfld->buf;
00608 return 0;
00609 }
00610
00611
00612 static inline int pg_int4_2_db_cstr(db_fld_t* fld, char* val, int len)
00613 {
00614 struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
00615 int size, v;
00616
00617 v = (int32_t)ntohl(*((int32_t*)val));
00618
00619 size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
00620 if (len < 0 || size >= INT2STR_MAX_LEN) {
00621 BUG("postgres: Error while converting integer to string\n");
00622 return -1;
00623 }
00624
00625 fld->v.cstr = pfld->buf;
00626 return 0;
00627 }
00628
00629
00630 static inline int pg_int2_2_db_str(db_fld_t* fld, char* val, int len)
00631 {
00632 struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
00633 int size, v;
00634
00635 v = (int16_t)ntohs(*((int16_t*)val));
00636
00637 size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
00638 if (size < 0 || size >= INT2STR_MAX_LEN) {
00639 BUG("postgres: Error while converting integer to string\n");
00640 return -1;
00641 }
00642
00643 fld->v.lstr.s = pfld->buf;
00644 fld->v.lstr.len = size;
00645 return 0;
00646 }
00647
00648
00649 static inline int pg_int4_2_db_str(db_fld_t* fld, char* val, int len)
00650 {
00651 struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
00652 int size, v;
00653
00654 v = (int32_t)ntohl(*((int32_t*)val));
00655
00656 size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
00657 if (size < 0 || size >= INT2STR_MAX_LEN) {
00658 BUG("postgres: Error while converting integer to string\n");
00659 return -1;
00660 }
00661
00662 fld->v.lstr.s = pfld->buf;
00663 fld->v.lstr.len = size;
00664 return 0;
00665 }
00666
00667
00668 static inline int pg_int2_2_db_int(db_fld_t* fld, char* val, int len)
00669 {
00670 fld->v.int4 = (int16_t)ntohs(*((int16_t*)val));
00671 return 0;
00672 }
00673
00674
00675 static inline int pg_int4_2_db_int(db_fld_t* fld, char* val, int len)
00676 {
00677 fld->v.int4 = (int32_t)ntohl(*((int32_t*)val));
00678 return 0;
00679 }
00680
00681
00682 static inline int pg_int8_2_db_int(db_fld_t* fld, char* val, int len)
00683 {
00684 fld->v.int8 = (int64_t)ntohll(*((int64_t*)val));
00685 return 0;
00686 }
00687
00688
00689 static inline int pg_bool2db_int(db_fld_t* fld, char* val, int len)
00690 {
00691 fld->v.int4 = val[0];
00692 return 0;
00693 }
00694
00695
00696 static inline int pg_inet2db_int(db_fld_t* fld, char* val, int len)
00697 {
00698 if (len != 8 || val[2] != 0) {
00699 ERR("postgres: Unsupported 'inet' format, column %s\n", fld->name);
00700 return -1;
00701 }
00702
00703 if (val[0] != AF_INET) {
00704 ERR("postgres: Unsupported address family %d in field %s\n",
00705 val[0], fld->name);
00706 return -1;
00707 }
00708
00709 if (val[1] != 32) {
00710 WARN("postgres: Netmasks shorter than 32-bits not supported, "
00711 "column %s\n", fld->name);
00712 }
00713
00714 if (val[3] != 4) {
00715 ERR("postgres: Unsupported IP address size %d in column %s\n",
00716 val[3], fld->name);
00717 return -1;
00718 }
00719
00720 fld->v.int4 = (int32_t)ntohl(((int32_t*)val)[1]);
00721 return 0;
00722 }
00723
00724
00725 static inline int pg_timestamp2db_int(db_fld_t* fld, char* val, int len,
00726 unsigned int flags)
00727 {
00728 if (flags & PG_INT8_TIMESTAMP) {
00729
00730 fld->v.int4 = (int64_t)ntohll(((int64_t*)val)[0]) / (int64_t)1000000 + PG_EPOCH_TIME;
00731 } else {
00732
00733 fld->v.int4 = PG_EPOCH_TIME + ntohll(((int64_t*)val)[0]);
00734 }
00735 return 0;
00736 }
00737
00738
00739 static inline int pg_bit2db_int(db_fld_t* fld, char* val, int len)
00740 {
00741 int size;
00742
00743 size = ntohl(*(uint32_t*)val);
00744 if (size != 32) {
00745 ERR("postgres: Unsupported bit field size (%d), column %s\n",
00746 size, fld->name);
00747 return -1;
00748 }
00749 fld->v.int4 = ntohl(((uint32_t*)val)[1]);
00750 return 0;
00751 }
00752
00753
00754 static inline int pg_float42db_float(db_fld_t* fld, char* val, int len)
00755 {
00756 fld->v.int4 = (uint32_t)ntohl(*(uint32_t*)val);
00757 return 0;
00758 }
00759
00760
00761 static inline int pg_float42db_double(db_fld_t* fld, char* val, int len)
00762 {
00763 float tmp;
00764
00765 tmp = ntohl(*(uint32_t*)val);
00766 fld->v.dbl = tmp;
00767 return 0;
00768 }
00769
00770
00771 static inline int pg_float82db_double(db_fld_t* fld, char* val, int len)
00772 {
00773 fld->v.int8 = ntohll(*(uint64_t*)val);
00774 return 0;
00775 }
00776
00777
00778 static inline int pg_string2db_cstr(db_fld_t* fld, char* val, int len)
00779 {
00780 fld->v.cstr = val;
00781 return 0;
00782 }
00783
00784
00785 static inline int pg_string2db_str(db_fld_t* fld, char* val, int len)
00786 {
00787 fld->v.lstr.s = val;
00788 fld->v.lstr.len = len;
00789 return 0;
00790 }
00791
00792
00793
00794 int pg_pg2fld(db_fld_t* dst, PGresult* src, int row,
00795 pg_type_t* types, unsigned int flags)
00796 {
00797 char* val;
00798 int i, len, ret;
00799 Oid type;
00800
00801 if (dst == NULL || src == NULL) return 0;
00802 ret = 0;
00803
00804 for(i = 0; !DB_FLD_EMPTY(dst) && !DB_FLD_LAST(dst[i]); i++) {
00805 if (PQgetisnull(src, row, i)) {
00806 dst[i].flags |= DB_NULL;
00807 continue;
00808 } else {
00809 dst[i].flags &= ~DB_NULL;
00810 }
00811
00812 type = PQftype(src, i);
00813 val = PQgetvalue(src, row, i);
00814 len = PQgetlength(src, row, i);
00815
00816 switch(dst[i].type) {
00817 case DB_INT:
00818 if (type == types[PG_INT2].oid)
00819 ret |= pg_int2_2_db_int(dst + i, val, len);
00820 else if (type == types[PG_INT4].oid)
00821 ret |= pg_int4_2_db_int(dst + i, val, len);
00822 else if (type == types[PG_INT8].oid)
00823 ret |= pg_int8_2_db_int(dst + i, val, len);
00824 else if (type == types[PG_BOOL].oid)
00825 ret |= pg_bool2db_int(dst + i, val, len);
00826 else if (type == types[PG_INET].oid)
00827 ret |= pg_inet2db_int(dst + i, val, len);
00828 else if ((type == types[PG_TIMESTAMP].oid) ||
00829 (type == types[PG_TIMESTAMPTZ].oid))
00830 ret |= pg_timestamp2db_int(dst + i, val, len, flags);
00831 else if (type == types[PG_BIT].oid)
00832 ret |= pg_bit2db_int(dst + i, val, len);
00833 else if (type == types[PG_VARBIT].oid)
00834 ret |= pg_bit2db_int(dst + i, val, len);
00835 else goto bug;
00836 break;
00837
00838 case DB_FLOAT:
00839 if (type == types[PG_FLOAT4].oid)
00840 ret |= pg_float42db_float(dst + i, val, len);
00841 else goto bug;
00842 break;
00843
00844 case DB_DOUBLE:
00845 if (type == types[PG_FLOAT4].oid)
00846 ret |= pg_float42db_double(dst + i, val, len);
00847 else if (type == types[PG_FLOAT8].oid)
00848 ret |= pg_float82db_double(dst + i, val, len);
00849 else goto bug;
00850 break;
00851
00852 case DB_DATETIME:
00853 if (type == types[PG_INT2].oid)
00854 ret |= pg_int2_2_db_int(dst + i, val, len);
00855 else if (type == types[PG_INT4].oid)
00856 ret |= pg_int4_2_db_int(dst + i, val, len);
00857 else if ((type == types[PG_TIMESTAMP].oid) ||
00858 (type == types[PG_TIMESTAMPTZ].oid))
00859 ret |= pg_timestamp2db_int(dst + i, val, len, flags);
00860 else goto bug;
00861 break;
00862
00863 case DB_CSTR:
00864 if ((type == types[PG_CHAR].oid) ||
00865 (type == types[PG_TEXT].oid) ||
00866 (type == types[PG_BPCHAR].oid) ||
00867 (type == types[PG_VARCHAR].oid))
00868 ret |= pg_string2db_cstr(dst + i, val, len);
00869 else if (type == types[PG_INT2].oid)
00870 ret |= pg_int2_2_db_cstr(dst + i, val, len);
00871 else if (type == types[PG_INT4].oid)
00872 ret |= pg_int4_2_db_cstr(dst + i, val, len);
00873 else goto bug;
00874 break;
00875
00876 case DB_STR:
00877 case DB_BLOB:
00878 if ((type == types[PG_BYTE].oid) ||
00879 (type == types[PG_CHAR].oid) ||
00880 (type == types[PG_TEXT].oid) ||
00881 (type == types[PG_BPCHAR].oid) ||
00882 (type == types[PG_VARCHAR].oid))
00883 ret |= pg_string2db_str(dst + i, val, len);
00884 else if (type == types[PG_INT2].oid)
00885 ret |= pg_int2_2_db_str(dst + i, val, len);
00886 else if (type == types[PG_INT4].oid)
00887 ret |= pg_int4_2_db_str(dst + i, val, len);
00888 else goto bug;
00889 break;
00890
00891 case DB_BITMAP:
00892 if (type == types[PG_INT2].oid)
00893 ret |= pg_int2_2_db_int(dst + i, val, len);
00894 else if (type == types[PG_INT4].oid)
00895 ret |= pg_int4_2_db_int(dst + i, val, len);
00896 else if (type == types[PG_INT8].oid)
00897 ret |= pg_int8_2_db_int(dst + i, val, len);
00898 else if (type == types[PG_BIT].oid)
00899 ret |= pg_bit2db_int(dst + i, val, len);
00900 else if (type == types[PG_VARBIT].oid)
00901 ret |= pg_bit2db_int(dst + i, val, len);
00902 else goto bug;
00903 break;
00904
00905 default:
00906 BUG("postgres: Unsupported field type %d in field %s\n",
00907 dst[i].type, dst[i].name);
00908 return -1;
00909 }
00910 }
00911 return ret;
00912
00913 bug:
00914 BUG("postgres: Error while converting Postgres Oid %d to DB API type %d\n",
00915 type, dst[i].type);
00916 return -1;
00917 }