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 #include "bdb.h"
00030
00031 #define BDB_ID "bdb://"
00032 #define BDB_ID_LEN (sizeof(BDB_ID)-1)
00033 #define BDB_PATH_LEN MAXPATHLEN
00034
00035
00036
00037
00038 db_con_t* bdb_init(const char* _sqlurl)
00039 {
00040 db_con_t* _res;
00041 char *p;
00042 char bdb_path[BDB_PATH_LEN];
00043 int ret;
00044
00045 if (!_sqlurl)
00046 {
00047 #ifdef BDB_EXTRA_DEBUG
00048 LOG(L_ERR, "BDB:bdb_init: Invalid parameter value\n");
00049 #endif
00050 return NULL;
00051 }
00052 p = (char *)_sqlurl;
00053 if(strncmp(p, BDB_ID, sizeof(BDB_ID) - 1))
00054 {
00055 LOG(L_ERR, "BDB:bdb_init: invalid database URL - should be:"
00056 " <%s[/]path/to/directory>\n", BDB_ID);
00057 return NULL;
00058 }
00059 p += BDB_ID_LEN;
00060 if(p[0] != '/')
00061 {
00062 if(sizeof(CFG_DIR) + strlen(p) + 2 > BDB_PATH_LEN)
00063 {
00064 LOG(L_ERR, "BDB:bdb_init: path to database is too long\n");
00065 return NULL;
00066 }
00067 strcpy(bdb_path, CFG_DIR);
00068 bdb_path[sizeof(CFG_DIR) - 1] = '/';
00069 strcpy(&bdb_path[sizeof(CFG_DIR)], p);
00070 p = bdb_path;
00071 }
00072 #ifdef BDB_EXTRA_DEBUG
00073 LOG(L_NOTICE, "BDB:bdb_init: bdb_path = %s\n", p);
00074 #endif
00075
00076 _res = pkg_malloc(sizeof(db_con_t) + sizeof(bdb_con_t));
00077 if (!_res)
00078 {
00079 LOG(L_ERR, "BDB:bdb_init: No memory left\n");
00080 return NULL;
00081 }
00082 memset(_res, 0, sizeof(db_con_t) + sizeof(bdb_con_t));
00083 _res->tail = (unsigned long)((char*)_res + sizeof(bdb_con_t));
00084
00085 ret = db_env_create(&BDB_CON_DBENV(_res), 0);
00086 if (ret != 0) {
00087 LOG(L_ERR, "BDB:bdb_init: unable to db_env_create(): %s\n", db_strerror(ret));
00088
00089 pkg_free(_res);
00090 return NULL;
00091 }
00092
00093 ret = BDB_CON_DBENV(_res)->open(BDB_CON_DBENV(_res), p, DB_CREATE | DB_INIT_MPOOL | DB_INIT_CDB, 0);
00094 if (ret != 0) {
00095 LOG(L_ERR, "BDB:bdb_init: unable to open environment: %s\n", db_strerror(ret));
00096
00097 pkg_free(_res);
00098 return NULL;
00099 }
00100
00101 return _res;
00102 }
00103
00104
00105
00106
00107 void bdb_close(db_con_t* _h)
00108 {
00109 if (!_h)
00110 {
00111 #ifdef DBT_EXTRA_DEBUG
00112 LOG(L_ERR, "BDB:bdb_close: Invalid parameter value\n");
00113 #endif
00114 return;
00115 }
00116
00117 if (BDB_CON_DB(_h) != NULL) {
00118 bdb_close_table(_h);
00119 }
00120
00121 if (BDB_CON_DBENV(_h) != NULL) {
00122 BDB_CON_DBENV(_h)->close(BDB_CON_DBENV(_h), 0);
00123 }
00124
00125 pkg_free(_h);
00126
00127 return;
00128 }
00129
00130
00131
00132
00133
00134 int bdb_raw_query(db_con_t* _h, char* _s, db_res_t** _r)
00135 {
00136 *_r = NULL;
00137 LOG(L_ERR, "BDB:bdb_raw_query: method is not supported.\n");
00138 return -1;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int bdb_query(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v,
00155 db_key_t* _c, int _n, int _nc, db_key_t _o, db_res_t** _r)
00156 {
00157 bdb_srow_p s_r;
00158 bdb_rrow_p r_r;
00159 int ret;
00160
00161 *_r = NULL;
00162 s_r = NULL;
00163 r_r = NULL;
00164
00165 if (_o) {
00166 LOG(L_ERR, "BDB:bdb_query: ORDER BY is not supported.\n");
00167 return -1;
00168 }
00169
00170 if ((ret = bdb_srow_db2bdb(_h, _k, _op, _v, _n, &s_r)) < 0) {
00171 return -1;
00172 };
00173
00174 if ((ret = bdb_rrow_db2bdb(_h, _c, _nc, &r_r)) < 0) {
00175 bdb_free_srow(s_r);
00176 return -1;
00177 };
00178
00179 if ((ret = bdb_query_table(_h, s_r, r_r, _nc, _r)) < 0) {
00180 bdb_free_rrow(r_r);
00181 bdb_free_srow(s_r);
00182 return -1;
00183 };
00184
00185 bdb_free_rrow(r_r);
00186 bdb_free_srow(s_r);
00187
00188 return 0;
00189 }
00190
00191
00192
00193
00194
00195 int bdb_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n)
00196 {
00197 bdb_row_p r;
00198 DBC *cursorp;
00199 int ret;
00200
00201 if ((ret = bdb_row_db2bdb(_h, _k, _v, _n, &r)) < 0) {
00202 return -1;
00203 };
00204
00205 if (r->key.size == 0) {
00206 LOG(L_ERR, "BDB:bdb_insert: no primary key specified\n");
00207 bdb_free_row(r);
00208 return -1;
00209 }
00210
00211 BDB_CON_DB(_h)->cursor(BDB_CON_DB(_h), NULL, &cursorp, DB_WRITECURSOR);
00212 ret = cursorp->c_put(cursorp, &(r->key), &(r->data), DB_KEYLAST);
00213
00214 if (ret < 0) {
00215 LOG(L_ERR, "BDB:bdb_insert: unable to insert record: %s\n", db_strerror(ret));
00216 }
00217
00218 if (cursorp != NULL) {
00219 cursorp->c_close(cursorp);
00220 }
00221
00222 bdb_free_row(r);
00223
00224 return ret;
00225 }
00226
00227
00228
00229
00230
00231 int bdb_delete(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n)
00232 {
00233 bdb_srow_p s_r;
00234 int ret;
00235
00236 s_r = NULL;
00237
00238 if ((ret = bdb_srow_db2bdb(_h, _k, _o, _v, _n, &s_r)) < 0) {
00239 return -1;
00240 };
00241
00242 if ((ret = bdb_delete_table(_h, s_r)) < 0) {
00243 bdb_free_srow(s_r);
00244 return -1;
00245 };
00246
00247 bdb_free_srow(s_r);
00248
00249 return 0;
00250 }
00251
00252
00253
00254
00255 int bdb_update(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v,
00256 db_key_t* _uk, db_val_t* _uv, int _n, int _un)
00257 {
00258 bdb_srow_p s_r;
00259 bdb_urow_p u_r;
00260 int ret;
00261
00262 s_r = NULL;
00263 u_r = NULL;
00264
00265 if ((ret = bdb_srow_db2bdb(_h, _k, _o, _v, _n, &s_r)) < 0) {
00266 return -1;
00267 };
00268
00269 if ((ret = bdb_urow_db2bdb(_h, _uk, _uv, _un, &u_r)) < 0) {
00270 bdb_free_srow(s_r);
00271 return -1;
00272 };
00273
00274 if ((ret = bdb_update_table(_h, s_r, u_r)) < 0) {
00275 bdb_free_urow(u_r);
00276 bdb_free_srow(s_r);
00277 return -1;
00278 };
00279
00280 bdb_free_urow(u_r);
00281 bdb_free_srow(s_r);
00282
00283 return 0;
00284 }
00285
00286
00287
00288
00289 int bdb_free_result(db_con_t* _h, db_res_t* _r)
00290 {
00291 db_row_t* r;
00292 db_val_t* v;
00293 int i, j;
00294
00295 if (!_r) {
00296 #ifdef BDB_EXTRA_DEBUG
00297 LOG(L_NOTICE, "BDB:bdb_free_result: NULL pointer\n");
00298 #endif
00299 return 0;
00300 }
00301
00302 for (i = 0; i < RES_ROW_N(_r); i++) {
00303 r = &(RES_ROWS(_r)[i]);
00304 for (j = 0; j < RES_COL_N(_r); j++) {
00305 v = &(ROW_VALUES(r)[j]);
00306 if (VAL_TYPE(v) == DB_STRING || VAL_TYPE(v) == DB_STR || VAL_TYPE(v) == DB_BLOB) {
00307 free(VAL_STR(v).s);
00308 }
00309 }
00310 free(ROW_VALUES(r));
00311 }
00312 free(RES_ROWS(_r));
00313
00314 for (i = 0; i < RES_COL_N(_r); i++) {
00315 pkg_free((void *)RES_NAMES(_r)[i]);
00316 }
00317 pkg_free(RES_NAMES(_r));
00318 pkg_free(RES_TYPES(_r));
00319
00320 pkg_free(_r);
00321
00322 return 0;
00323 }