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
00028
00029
00030
00039 #include "pg_mod.h"
00040 #include "pg_uri.h"
00041 #include "pg_con.h"
00042 #include "pg_cmd.h"
00043 #include "pg_res.h"
00044 #include "pg_fld.h"
00045 #include "km_db_postgres.h"
00046
00047 #include "../../sr_module.h"
00048
00049 #ifdef PG_TEST
00050 #include <limits.h>
00051 #include <float.h>
00052 #endif
00053
00054 MODULE_VERSION
00055
00056 static int pg_mod_init(void);
00057 static void pg_mod_destroy(void);
00058
00059 int pg_connect_timeout = 0;
00060 int pg_retries = 2;
00061
00062
00063 int pg_lockset = 4;
00064
00065
00066
00067
00068 static cmd_export_t cmds[] = {
00069 {"db_ctx", (cmd_function)NULL, 0, 0, 0},
00070 {"db_con", (cmd_function)pg_con, 0, 0, 0},
00071 {"db_uri", (cmd_function)pg_uri, 0, 0, 0},
00072 {"db_cmd", (cmd_function)pg_cmd, 0, 0, 0},
00073 {"db_put", (cmd_function)pg_cmd_exec, 0, 0, 0},
00074 {"db_del", (cmd_function)pg_cmd_exec, 0, 0, 0},
00075 {"db_get", (cmd_function)pg_cmd_exec, 0, 0, 0},
00076 {"db_upd", (cmd_function)pg_cmd_exec, 0, 0, 0},
00077 {"db_sql", (cmd_function)pg_cmd_exec, 0, 0, 0},
00078 {"db_res", (cmd_function)pg_res, 0, 0, 0},
00079 {"db_fld", (cmd_function)pg_fld, 0, 0, 0},
00080 {"db_first", (cmd_function)pg_cmd_first, 0, 0, 0},
00081 {"db_next", (cmd_function)pg_cmd_next, 0, 0, 0},
00082 {"db_setopt", (cmd_function)pg_setopt, 0, 0, 0},
00083 {"db_getopt", (cmd_function)pg_getopt, 0, 0, 0},
00084 {"db_bind_api", (cmd_function)db_postgres_bind_api, 0, 0, 0},
00085 {0, 0, 0, 0, 0}
00086 };
00087
00088
00089
00090
00091
00092 static param_export_t params[] = {
00093 {"retries", PARAM_INT, &pg_retries },
00094 {"lockset", PARAM_INT, &pg_lockset },
00095 {0, 0, 0}
00096 };
00097
00098
00099 struct module_exports exports = {
00100 "db_postgres",
00101 cmds,
00102 0,
00103 params,
00104 pg_mod_init,
00105 0,
00106 pg_mod_destroy,
00107 0,
00108 0
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 #ifdef PG_TEST
00134 int pg_test(void)
00135 {
00136 int i, row;
00137 db_ctx_t* db;
00138 db_cmd_t* put, *del, *get;
00139 db_res_t* result;
00140 db_rec_t* rec;
00141 char* times;
00142
00143 db_fld_t int_vals[] = {
00144 {.name = "col_bool", .type = DB_INT},
00145 {.name = "col_int8", .type = DB_INT},
00146 {.name = "col_int4", .type = DB_INT},
00147 {.name = "col_inet", .type = DB_INT},
00148 {.name = "col_timestamp", .type = DB_INT},
00149 {.name = "col_timestamptz", .type = DB_INT},
00150 {.name = "col_bit", .type = DB_INT},
00151 {.name = "col_varbit", .type = DB_INT},
00152 {.name = NULL}
00153 };
00154
00155 db_fld_t datetime_vals[] = {
00156 {.name = "col_int8", .type = DB_INT},
00157 {.name = "col_int4", .type = DB_INT},
00158 {.name = "col_timestamp", .type = DB_INT},
00159 {.name = "col_timestamptz", .type = DB_INT},
00160 {.name = NULL}
00161 };
00162
00163
00164 db_fld_t bitmap_vals[] = {
00165 {.name = "col_int8", .type = DB_INT},
00166 {.name = "col_int4", .type = DB_INT},
00167 {.name = "col_bit", .type = DB_INT},
00168 {.name = "col_varbit", .type = DB_INT},
00169 {.name = NULL}
00170 };
00171
00172 db_fld_t float_vals[] = {
00173 {.name = "col_float4", .type = DB_FLOAT},
00174 {.name = "col_float8", .type = DB_FLOAT},
00175 {.name = NULL}
00176 };
00177
00178 db_fld_t double_vals[] = {
00179 {.name = "col_float8", .type = DB_DOUBLE},
00180 {.name = NULL}
00181 };
00182
00183 db_fld_t str_vals[] = {
00184 {.name = "col_varchar", .type = DB_STR},
00185 {.name = "col_bytea", .type = DB_STR},
00186 {.name = "col_text", .type = DB_STR},
00187 {.name = "col_bpchar", .type = DB_STR},
00188 {.name = "col_char", .type = DB_STR},
00189 {.name = NULL}
00190 };
00191
00192 db_fld_t cstr_vals[] = {
00193 {.name = "col_varchar", .type = DB_CSTR},
00194 {.name = "col_bytea", .type = DB_CSTR},
00195 {.name = "col_text", .type = DB_CSTR},
00196 {.name = "col_bpchar", .type = DB_CSTR},
00197 {.name = "col_char", .type = DB_CSTR},
00198 {.name = NULL}
00199 };
00200
00201 db_fld_t blob_vals[] = {
00202 {.name = "col_bytea", .type = DB_BLOB},
00203 {.name = NULL}
00204 };
00205
00206
00207 db_fld_t res[] = {
00208 {.name = "col_bool", .type = DB_INT},
00209 {.name = "col_bytea", .type = DB_BLOB},
00210 {.name = "col_char", .type = DB_STR},
00211 {.name = "col_int8", .type = DB_INT},
00212 {.name = "col_int4", .type = DB_INT},
00213 {.name = "col_int2", .type = DB_INT},
00214 {.name = "col_text", .type = DB_STR},
00215 {.name = "col_float4", .type = DB_FLOAT},
00216 {.name = "col_float8", .type = DB_DOUBLE},
00217 {.name = "col_inet", .type = DB_INT},
00218 {.name = "col_bpchar", .type = DB_STR},
00219 {.name = "col_varchar", .type = DB_STR},
00220 {.name = "col_timestamp", .type = DB_DATETIME},
00221 {.name = "col_timestamptz", .type = DB_DATETIME},
00222 {.name = "col_bit", .type = DB_BITMAP},
00223 {.name = "col_varbit", .type = DB_BITMAP},
00224 {.name = NULL}
00225 };
00226
00227
00228 db = db_ctx("postgres");
00229 if (db == NULL) {
00230 ERR("Error while initializing database layer\n");
00231 goto error;
00232 }
00233 if (db_add_db(db, "postgres://janakj:heslo@localhost/ser") < 0) goto error;
00234 if (db_connect(db) < 0) goto error;
00235
00236 del = db_cmd(DB_DEL, db, "test", NULL, NULL, NULL);
00237 if (del == NULL) {
00238 ERR("Error while building delete * query\n");
00239 goto error;
00240 }
00241
00242 put = db_cmd(DB_PUT, db, "test", NULL, NULL, int_vals);
00243 if (put == NULL) {
00244 ERR("Error while building test query\n");
00245 goto error;
00246 }
00247
00248 if (db_exec(NULL, del)) {
00249 ERR("Error while deleting rows from test table\n");
00250 goto error;
00251 }
00252
00253 put->vals[0].v.int4 = 0xffffffff;
00254 put->vals[1].v.int4 = 0xffffffff;
00255 put->vals[2].v.int4 = 0xffffffff;
00256 put->vals[3].v.int4 = 0xffffffff;
00257 put->vals[4].v.int4 = 0xffffffff;
00258 put->vals[5].v.int4 = 0xffffffff;
00259 put->vals[6].v.int4 = 0xffffffff;
00260 put->vals[7].v.int4 = 0xffffffff;
00261
00262 if (db_exec(NULL, put)) {
00263 ERR("Error while executing database command\n");
00264 goto error;
00265 }
00266
00267 put->vals[0].v.int4 = 0;
00268 put->vals[1].v.int4 = 0;
00269 put->vals[2].v.int4 = 0;
00270 put->vals[3].v.int4 = 0;
00271 put->vals[4].v.int4 = 0;
00272 put->vals[5].v.int4 = 0;
00273 put->vals[6].v.int4 = 0;
00274 put->vals[7].v.int4 = 0;
00275
00276 if (db_exec(NULL, put)) {
00277 ERR("Error while executing database command\n");
00278 goto error;
00279 }
00280
00281 db_cmd_free(put);
00282
00283 put = db_cmd(DB_PUT, db, "test", NULL, NULL, bitmap_vals);
00284 if (put == NULL) {
00285 ERR("Error while building bitmap test query\n");
00286 goto error;
00287 }
00288
00289 put->vals[0].v.int4 = 0xffffffff;
00290 put->vals[1].v.int4 = 0xffffffff;
00291 put->vals[2].v.int4 = 0xffffffff;
00292 put->vals[3].v.int4 = 0xffffffff;
00293 put->vals[4].v.int4 = 0xffffffff;
00294 if (db_exec(NULL, put)) {
00295 ERR("Error while executing database command\n");
00296 goto error;
00297 }
00298
00299 put->vals[0].v.int4 = 0;
00300 put->vals[1].v.int4 = 0;
00301 put->vals[2].v.int4 = 0;
00302 put->vals[3].v.int4 = 0;
00303 put->vals[4].v.int4 = 0;
00304 if (db_exec(NULL, put)) {
00305 ERR("Error while executing database command\n");
00306 goto error;
00307 }
00308
00309 db_cmd_free(put);
00310
00311 put = db_cmd(DB_PUT, db, "test", NULL, NULL, float_vals);
00312 if (put == NULL) {
00313 ERR("Error while building float test query\n");
00314 goto error;
00315 }
00316
00317 put->vals[0].v.flt = FLT_MAX;
00318 put->vals[1].v.flt = FLT_MAX;
00319 if (db_exec(NULL, put)) {
00320 ERR("Error while executing database command\n");
00321 goto error;
00322 }
00323
00324 put->vals[0].v.flt = FLT_MIN;
00325 put->vals[1].v.flt = FLT_MIN;
00326 if (db_exec(NULL, put)) {
00327 ERR("Error while executing database command\n");
00328 goto error;
00329 }
00330
00331 db_cmd_free(put);
00332
00333 put = db_cmd(DB_PUT, db, "test", NULL, NULL, double_vals);
00334 if (put == NULL) {
00335 ERR("Error while building double test query\n");
00336 goto error;
00337 }
00338
00339 put->vals[0].v.dbl = DBL_MAX;
00340 if (db_exec(NULL, put)) {
00341 ERR("Error while executing database command\n");
00342 goto error;
00343 }
00344
00345 put->vals[0].v.dbl = DBL_MIN;
00346 if (db_exec(NULL, put)) {
00347 ERR("Error while executing database command\n");
00348 goto error;
00349 }
00350
00351
00352 db_cmd_free(put);
00353
00354 put = db_cmd(DB_PUT, db, "test", NULL, NULL, str_vals);
00355 if (put == NULL) {
00356 ERR("Error while building str test query\n");
00357 goto error;
00358 }
00359
00360 put->vals[0].v.lstr.s = "";
00361 put->vals[0].v.lstr.len = 0;
00362 put->vals[1].v.lstr.s = "";
00363 put->vals[1].v.lstr.len = 0;
00364 put->vals[2].v.lstr.s = "";
00365 put->vals[2].v.lstr.len = 0;
00366 put->vals[3].v.lstr.s = "";
00367 put->vals[3].v.lstr.len = 0;
00368 put->vals[4].v.lstr.s = "";
00369 put->vals[4].v.lstr.len = 0;
00370 if (db_exec(NULL, put)) {
00371 ERR("Error while executing database command\n");
00372 goto error;
00373 }
00374
00375 put->vals[0].v.lstr.s = "abc should not be there";
00376 put->vals[0].v.lstr.len = 3;
00377 put->vals[1].v.lstr.s = "abc should not be there";
00378 put->vals[1].v.lstr.len = 3;
00379 put->vals[2].v.lstr.s = "abc should not be there";
00380 put->vals[2].v.lstr.len = 3;
00381 put->vals[3].v.lstr.s = "abc should not be there";
00382 put->vals[3].v.lstr.len = 3;
00383 put->vals[4].v.lstr.s = "a should not be there";
00384 put->vals[4].v.lstr.len = 1;
00385 if (db_exec(NULL, put)) {
00386 ERR("Error while executing database command\n");
00387 goto error;
00388 }
00389
00390 db_cmd_free(put);
00391
00392 put = db_cmd(DB_PUT, db, "test", NULL, NULL, cstr_vals);
00393 if (put == NULL) {
00394 ERR("Error while building cstr test query\n");
00395 goto error;
00396 }
00397
00398 put->vals[0].v.cstr = "";
00399 put->vals[1].v.cstr = "";
00400 put->vals[2].v.cstr = "";
00401 put->vals[3].v.cstr = "";
00402 put->vals[4].v.cstr = "";
00403 if (db_exec(NULL, put)) {
00404 ERR("Error while executing database command\n");
00405 goto error;
00406 }
00407
00408 put->vals[0].v.cstr = "def";
00409 put->vals[1].v.cstr = "def";
00410 put->vals[2].v.cstr = "def";
00411 put->vals[3].v.cstr = "def";
00412 put->vals[4].v.cstr = "d";
00413 if (db_exec(NULL, put)) {
00414 ERR("Error while executing database command\n");
00415 goto error;
00416 }
00417
00418 db_cmd_free(put);
00419
00420 put = db_cmd(DB_PUT, db, "test", NULL, NULL, blob_vals);
00421 if (put == NULL) {
00422 ERR("Error while building blob test query\n");
00423 goto error;
00424 }
00425
00426 put->vals[0].v.blob.s = "\0\0\0\0";
00427 put->vals[0].v.blob.len = 4;
00428 if (db_exec(NULL, put)) {
00429 ERR("Error while executing database command\n");
00430 goto error;
00431 }
00432
00433
00434 db_cmd_free(put);
00435
00436 put = db_cmd(DB_PUT, db, "test", NULL, NULL, datetime_vals);
00437 if (put == NULL) {
00438 ERR("Error while building datetime test query\n");
00439 goto error;
00440 }
00441
00442 put->vals[0].v.time = 0xffffffff;
00443 put->vals[1].v.time = 0xffffffff;
00444 put->vals[2].v.time = 0xffffffff;
00445 put->vals[3].v.time = 0xffffffff;
00446 if (db_exec(NULL, put)) {
00447 ERR("Error while executing database command\n");
00448 goto error;
00449 }
00450
00451 put->vals[0].v.time = 0;
00452 put->vals[1].v.time = 0;
00453 put->vals[2].v.time = 0;
00454 put->vals[3].v.time = 0;
00455 if (db_exec(NULL, put)) {
00456 ERR("Error while executing database command\n");
00457 goto error;
00458 }
00459
00460 if (put) db_cmd_free(put);
00461 if (del) db_cmd_free(del);
00462 put = NULL;
00463 del = NULL;
00464
00465
00466 get = db_cmd(DB_GET, db, "test", res, NULL, NULL);
00467 if (get == NULL) {
00468 ERR("Error while building select query\n");
00469 goto error;
00470 }
00471
00472 if (db_exec(&result, get)) {
00473 ERR("Error while executing select query\n");
00474 goto error;
00475 }
00476
00477 rec = db_first(result);
00478 row = 1;
00479 while(rec) {
00480 ERR("row: %d\n", row);
00481 for(i = 0; !DB_FLD_LAST(rec->fld[i]); i++) {
00482 if (rec->fld[i].flags & DB_NULL) {
00483 ERR("%s: NULL\n", rec->fld[i].name);
00484 } else {
00485 switch(rec->fld[i].type) {
00486 case DB_INT:
00487 case DB_BITMAP:
00488 ERR("%s: %d\n", rec->fld[i].name, rec->fld[i].v.int4);
00489 break;
00490
00491 case DB_DATETIME:
00492 times = ctime(&rec->fld[i].v.time);
00493 ERR("%s: %d:%.*s\n", rec->fld[i].name, rec->fld[i].v.time, strlen(times) - 1, times);
00494 break;
00495
00496 case DB_DOUBLE:
00497 ERR("%s: %f\n", rec->fld[i].name, rec->fld[i].v.dbl);
00498 break;
00499
00500 case DB_FLOAT:
00501 ERR("%s: %f\n", rec->fld[i].name, rec->fld[i].v.flt);
00502 break;
00503
00504 case DB_STR:
00505 case DB_BLOB:
00506 ERR("%s: %.*s\n", rec->fld[i].name, rec->fld[i].v.lstr.len, rec->fld[i].v.lstr.s);
00507 break;
00508
00509 case DB_CSTR:
00510 ERR("%s: %s\n", rec->fld[i].name, rec->fld[i].v.cstr);
00511 break;
00512 }
00513 }
00514 }
00515 ERR("\n");
00516 rec = db_next(result);
00517 row++;
00518 }
00519
00520 db_res_free(result);
00521
00522 db_cmd_free(get);
00523 db_disconnect(db);
00524 db_ctx_free(db);
00525 return 0;
00526
00527 error:
00528 if (get) db_cmd_free(get);
00529 if (put) db_cmd_free(put);
00530 if (del) db_cmd_free(del);
00531 db_disconnect(db);
00532 db_ctx_free(db);
00533 return -1;
00534 }
00535 #endif
00536
00537 int mod_register(char *path, int *dlflags, void *p1, void *p2)
00538 {
00539 if(db_api_init()<0)
00540 return -1;
00541 return 0;
00542 }
00543
00544 static int pg_mod_init(void)
00545 {
00546 #ifdef PG_TEST
00547 if (pg_test() == 0) {
00548 ERR("postgres: Testing successful\n");
00549 } else {
00550 ERR("postgres: Testing failed\n");
00551 }
00552 return -1;
00553 #endif
00554 if(pg_init_lock_set(pg_lockset)<0)
00555 return -1;
00556 return km_postgres_mod_init();
00557 }
00558
00559 static void pg_mod_destroy(void)
00560 {
00561 pg_destroy_lock_set();
00562 }
00563