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
00032 int bdb_set_row(db_con_t* _h, bdb_urow_p u_r, bdb_val_p _v, bdb_row_p _r)
00033 {
00034 bdb_val_p v, nv;
00035 bdb_uval_p uv;
00036 int c_idx;
00037 int found;
00038
00039
00040 for (v = _v, c_idx = 0; v != NULL; v = v->next, c_idx++) {
00041 nv = pkg_malloc(sizeof(*nv));
00042 memset(nv, 0, sizeof(*nv));
00043 bdb_push_field(_r, nv);
00044
00045 found = 0;
00046 for (uv = u_r->fields; uv != NULL; uv = uv->next) {
00047 if (uv->c_idx == c_idx) {
00048 found = 1;
00049 break;
00050 }
00051 }
00052
00053 if (found) {
00054 #ifdef BDB_EXTRA_DEBUG
00055 LOG(L_NOTICE, "BDB:bdb_set_row: need to update column #%0d\n", c_idx);
00056 #endif
00057 if (bdb_field_db2bdb(nv, &(uv->v)) < 0) {
00058 return -1;
00059 }
00060 } else {
00061 #ifdef BDB_EXTRA_DEBUG
00062 LOG(L_NOTICE, "BDB:bdb_set_row: no need to update column #%0d\n", c_idx);
00063 #endif
00064 if (bdb_field_db2bdb(nv, &(v->v)) < 0) {
00065 return -1;
00066 }
00067 }
00068
00069 bdb_push_data(_r, nv);
00070 };
00071
00072 bdb_merge_tail(_r);
00073
00074 return 0;
00075 };
00076
00077
00078 int bdb_row_db2bdb(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n, bdb_row_p *_r)
00079 {
00080 bdb_row_p r;
00081 bdb_table_p t;
00082 bdb_column_p c;
00083
00084 int found;
00085 int use_key, found_key, key_idx;
00086 int i;
00087 bdb_val_p v;
00088
00089 *_r = NULL;
00090
00091 if ((t = bdb_find_table(CON_TABLE(_h))) == NULL) {
00092 #ifdef BDB_EXTRA_DEBUG
00093 LOG(L_ERR, "BDB:bdb_row_db2bdb: table: no table in use\n");
00094 #endif
00095 return -1;
00096 };
00097
00098 key_idx = -1;
00099 use_key = -1;
00100
00101
00102 for (i = 0; i < _n; i++) {
00103 found = 0;
00104
00105 for (c = t->cols, found_key = 1; c != NULL; c = c->next, found_key = 0) {
00106 if (!strcmp(_k[i], c->name.s)) {
00107 found = 1;
00108 break;
00109 }
00110 }
00111 if (found_key == 1) {
00112 key_idx = i;
00113 use_key++;
00114 }
00115 if (!found) {
00116 LOG(L_ERR, "BDB:bdb_row_db2bdb: column '%s' does not exist\n", _k[i]);
00117 return -1;
00118 }
00119 }
00120
00121 if (use_key < 0) {
00122 #ifdef BDB_EXTRA_DEBUG
00123 LOG(L_ERR, "BDB:bdb_row_db2bdb: primary key value must be supplied\n");
00124 #endif
00125 return -1;
00126 }
00127
00128 if (use_key > 0) {
00129 #ifdef BDB_EXTRA_DEBUG
00130 LOG(L_ERR, "BDB:bdb_row_db2bdb: primary key value must be supplied only once\n");
00131 #endif
00132 return -1;
00133 }
00134
00135 r = pkg_malloc(sizeof(*r));
00136 memset(r, 0, sizeof(*r));
00137
00138
00139 for (c = t->cols; c != NULL; c = c->next) {
00140 v = pkg_malloc(sizeof(*v));
00141 memset(v, 0, sizeof(*v));
00142 VAL_NULL(&(v->v)) = 1;
00143
00144 bdb_push_field(r, v);
00145
00146 for (i = 0; i < _n; i++) {
00147 if (!strcmp(_k[i], c->name.s)) {
00148 #ifdef BDB_EXTRA_DEBUG
00149 LOG(L_NOTICE, "BDB:bdb_row_db2bdb: filling column '%.*s'\n", c->name.len, c->name.s);
00150 #endif
00151 if (bdb_field_db2bdb(v, &_v[i]) < 0) {
00152 bdb_free_row(r);
00153 return -1;
00154 };
00155
00156 if (i == key_idx) {
00157 if (bdb_set_key(r, v) < 0) {
00158 bdb_free_row(r);
00159 return -1;
00160 };
00161 }
00162
00163 break;
00164 }
00165 }
00166
00167 bdb_push_data(r, v);
00168 };
00169
00170 bdb_merge_tail(r);
00171
00172 *_r = r;
00173
00174 return 0;
00175 };
00176
00177
00178 void bdb_merge_tail(bdb_row_p _r)
00179 {
00180 if (_r->tail.len > 0) {
00181 _r->data.data = pkg_realloc(_r->data.data, _r->data.size + _r->tail.len);
00182 memcpy(_r->data.data + _r->data.size, _r->tail.s, _r->tail.len);
00183 _r->data.size += _r->tail.len;
00184 }
00185 };
00186
00187
00188 void bdb_push_data(bdb_row_p _r, bdb_val_p _v)
00189 {
00190 if (_r->data.size == 0) {
00191 _r->data.data = pkg_malloc(sizeof(*_v));
00192 } else {
00193 _r->data.data = pkg_realloc(_r->data.data, _r->data.size + sizeof(*_v));
00194 }
00195
00196 memcpy(_r->data.data + _r->data.size, _v, sizeof(*_v));
00197
00198 _r->data.size += sizeof(*_v);
00199
00200 if (!VAL_NULL(&(_v->v))) {
00201 switch (VAL_TYPE(&(_v->v))) {
00202 case DB_STRING:
00203 case DB_STR:
00204 case DB_BLOB:
00205 if (_r->tail.len == 0) {
00206 _r->tail.s = pkg_malloc(VAL_STR(&(_v->v)).len);
00207 } else {
00208 _r->tail.s = pkg_realloc(_r->tail.s, _r->tail.len + VAL_STR(&(_v->v)).len);
00209 }
00210 memcpy(_r->tail.s + _r->tail.len, VAL_STR(&(_v->v)).s, VAL_STR(&(_v->v)).len);
00211 _r->tail.len += VAL_STR(&(_v->v)).len;
00212 break;
00213 default:
00214 break;
00215 }
00216 }
00217 };
00218
00219
00220 void bdb_push_field(bdb_row_p _r, bdb_val_p _v)
00221 {
00222 bdb_val_p f;
00223
00224 if (_r->fields == NULL) {
00225 _r->fields = _v;
00226 return;
00227 }
00228 f = _r->fields;
00229 while (f->next != NULL) {
00230 f = f->next;
00231 }
00232 f->next = _v;
00233 };
00234
00235
00236 void bdb_free_field(bdb_val_p _v)
00237 {
00238 if (!VAL_NULL(&(_v->v))) {
00239 if (VAL_TYPE(&(_v->v)) == DB_STR || VAL_TYPE(&(_v->v)) == DB_STRING ||
00240 VAL_TYPE(&(_v->v)) == DB_BLOB) {
00241 pkg_free(VAL_STR(&(_v->v)).s);
00242 }
00243 }
00244 pkg_free(_v);
00245 };
00246
00247
00248 void bdb_free_field_list(bdb_val_p _v)
00249 {
00250 bdb_val_p curr, next;
00251
00252 for (curr = _v; curr != NULL;) {
00253 next = curr->next;
00254 bdb_free_field(curr);
00255 curr = next;
00256 }
00257 };
00258
00259
00260 void bdb_free_row(bdb_row_p _r)
00261 {
00262 if (_r->fields != NULL) {
00263 bdb_free_field_list(_r->fields);
00264 }
00265
00266 if (_r->data.size > 0) {
00267 pkg_free(_r->data.data);
00268 }
00269
00270 if (_r->tail.len > 0) {
00271 pkg_free(_r->tail.s);
00272 }
00273
00274 pkg_free(_r);
00275 };
00276
00277
00278 void bdb_free_row_list(bdb_row_p _r)
00279 {
00280 bdb_row_p curr, next;
00281
00282 for (curr = _r; curr != NULL;) {
00283 next = curr->next;
00284 bdb_free_row(curr);
00285 curr = next;
00286 }
00287 };
00288
00289
00290 int bdb_field_db2bdb(bdb_val_p v, db_val_t* _v)
00291 {
00292 char *s;
00293
00294 VAL_NULL(&(v->v)) = VAL_NULL(_v);
00295 VAL_TYPE(&(v->v)) = VAL_TYPE(_v);
00296
00297 if (!VAL_NULL(&(v->v))) {
00298 switch (VAL_TYPE(_v)) {
00299 case DB_INT:
00300 VAL_INT(&(v->v)) = VAL_INT(_v);
00301 break;
00302 case DB_FLOAT:
00303 VAL_FLOAT(&(v->v)) = VAL_FLOAT(_v);
00304 break;
00305 case DB_DATETIME:
00306 VAL_TIME(&(v->v)) = VAL_TIME(_v);
00307 break;
00308 case DB_BLOB:
00309 s = pkg_malloc(VAL_BLOB(_v).len);
00310 memcpy(s, VAL_BLOB(_v).s, VAL_BLOB(_v).len);
00311 VAL_BLOB(&(v->v)).s = s;
00312 VAL_BLOB(&(v->v)).len = VAL_BLOB(_v).len;
00313 break;
00314 case DB_DOUBLE:
00315 VAL_DOUBLE(&(v->v)) = VAL_DOUBLE(_v);
00316 break;
00317 case DB_STRING:
00318 VAL_STR(&(v->v)).len = strlen(VAL_STRING(_v)) + 1;
00319 s = pkg_malloc(VAL_STR(&(v->v)).len);
00320 strcpy(s, VAL_STRING(_v));
00321 VAL_STRING(&(v->v)) = s;
00322 break;
00323 case DB_STR:
00324 s = pkg_malloc(VAL_STR(_v).len);
00325 memcpy(s, VAL_STR(_v).s, VAL_STR(_v).len);
00326 VAL_STR(&(v->v)).s = s;
00327 VAL_STR(&(v->v)).len = VAL_STR(_v).len;
00328 break;
00329 case DB_BITMAP:
00330 VAL_BITMAP(&(v->v)) = VAL_BITMAP(_v);
00331 break;
00332 default:
00333 LOG(L_ERR, "BDB:bdb_field_db2bdb: unknown column type: %0X\n", VAL_TYPE(_v));
00334 return -1;
00335 break;
00336 }
00337 }
00338 return 0;
00339 };
00340
00341
00342 int bdb_get_db_row(db_con_t* _h, DBT* _data, bdb_val_p* _v)
00343 {
00344 bdb_val_p v, prev;
00345 void *p, *tail;
00346 int l;
00347
00348 if (!_data || !_data->size) {
00349 LOG(L_ERR, "BDB:bdb_get_db_row: invalid data\n");
00350 *_v = NULL;
00351 return -1;
00352 }
00353
00354 *_v = (bdb_val_p)_data->data;
00355 prev = NULL;
00356 p = _data->data;
00357 l = 0;
00358 tail = p + sizeof(*v) * BDB_CON_COL_NUM(_h);
00359
00360 while (l < sizeof(*v) * BDB_CON_COL_NUM(_h)) {
00361 v = (bdb_val_p)p;
00362 p += sizeof(*v);
00363 l += sizeof(*v);
00364 v->next = NULL;
00365 if (prev) {
00366 prev->next = v;
00367 prev = v;
00368 } else {
00369 prev = v;
00370 }
00371 if (!VAL_NULL(&(v->v))) {
00372 switch (VAL_TYPE(&(v->v))) {
00373 case DB_BLOB:
00374 case DB_STRING:
00375 case DB_STR:
00376 VAL_STR(&(v->v)).s = tail;
00377 tail += VAL_STR(&(v->v)).len;
00378 break;
00379 default:
00380 break;
00381 }
00382 }
00383 }
00384
00385 return 0;
00386 };
00387
00388 int bdb_set_key(bdb_row_p _r, bdb_val_p _v)
00389 {
00390
00391 if (VAL_NULL(&(_v->v))) {
00392 LOG(L_ERR, "BDB:bdb_set_key: NULL is not allowed for primary key\n");
00393 return -1;
00394 }
00395
00396 switch (VAL_TYPE(&(_v->v))) {
00397 case DB_INT:
00398 _r->key.data = &VAL_INT(&(_v->v));
00399 _r->key.size = sizeof(VAL_INT(&(_v->v)));
00400 break;
00401 case DB_FLOAT:
00402 _r->key.data = &VAL_FLOAT(&(_v->v));
00403 _r->key.size = sizeof(VAL_FLOAT(&(_v->v)));
00404 break;
00405 case DB_DATETIME:
00406 _r->key.data = &VAL_TIME(&(_v->v));
00407 _r->key.size = sizeof(VAL_TIME(&(_v->v)));
00408 break;
00409 case DB_BLOB:
00410 _r->key.data = VAL_BLOB(&(_v->v)).s;
00411 _r->key.size = VAL_BLOB(&(_v->v)).len;
00412 break;
00413 case DB_DOUBLE:
00414 _r->key.data = &VAL_DOUBLE(&(_v->v));
00415 _r->key.size = sizeof(VAL_DOUBLE(&(_v->v)));
00416 break;
00417 case DB_STRING:
00418 _r->key.data = (void *)VAL_STRING(&(_v->v));
00419 _r->key.size = strlen(VAL_STRING(&(_v->v))) + 1;
00420 break;
00421 case DB_STR:
00422 _r->key.data = VAL_STR(&(_v->v)).s;
00423 _r->key.size = VAL_STR(&(_v->v)).len;
00424 break;
00425 case DB_BITMAP:
00426 _r->key.data = &VAL_BITMAP(&(_v->v));
00427 _r->key.size = sizeof(VAL_BITMAP(&(_v->v)));
00428 break;
00429 default:
00430 LOG(L_ERR, "BDB:bdb_set_skey: unknown column type: %0X\n", VAL_TYPE(&(_v->v)));
00431 return -1;
00432 break;
00433 }
00434
00435 return 0;
00436 };