00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/adaptors/advertservice_adaptor/advertservice_database.c,v 1.9 2004/04/18 15:04:59 merzky Exp $";
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024
00025 #include <GAT.h>
00026 #include <GATUtil.h>
00027
00028 #include "regex.h"
00029 #include "advertservice_database.h"
00030
00031
00032 #if !defined(MAX_DB_NAME)
00033 #define MAX_DB_NAME 256
00034 #endif // !defined(MAX_DB_NAME)
00035
00036
00037
00038
00039 static GATResult
00040 advertservice_db_get_version(sqlite *db, GATuint32 *version, char **err_msg);
00041
00042 static GATResult
00043 advertservice_db_execute_sql_statements(sqlite *db, char const **stmts,
00044 char **err_msg);
00045
00046 static GATResult
00047 advertservice_db_begin_transaction(sqlite *db, char **err_msg);
00048
00049 static GATResult
00050 advertservice_db_commit_transaction(sqlite *db, char **err_msg);
00051
00052 static GATResult
00053 advertservice_db_find_node(sqlite *db, char const *path, int *node_id,
00054 GATBool createnode, char **err_msg);
00055
00056 static GATResult
00057 advertservice_db_write_data(sqlite *db, int node_id, char const *data,
00058 GATTable_const metadata, char **err_msg);
00059
00060 static GATResult
00061 advertservice_db_delete_node(sqlite *db, int node_id, char **err_msg);
00062
00063 static GATResult
00064 advertservice_db_get_node_metadata(sqlite *db, int node_id,
00065 GATTable *metadata, char **err_msg);
00066
00067 static GATResult
00068 advertservice_db_get_node_data(sqlite *db, int node_id,
00069 char **advert_data, char **err_msg);
00070
00071 static GATResult
00072 advertservice_db_find_pathes(sqlite *db, int nrows, char **values,
00073 GATList_String node_paths, char **err_msg);
00074
00075 static GATResult
00076 advertservice_db_construct_path(sqlite *db, char *node_id_str, char **path,
00077 char **err_msg);
00078
00079 static int
00080 advertservice_db_read_node_id(sqlite *db, char const *node_name,
00081 int parent_id, int *node_id, char **err_msg);
00082
00083 static int
00084 advertservice_db_alter_table(sqlite *db, char const **keys, char **err_msg);
00085
00086 static int
00087 advertservice_db_create_datatable(sqlite *db, char **old_fields, int count,
00088 char **new_fields, int table_number, char **err_msg);
00089
00090 static int
00091 advertservice_db_copy_datatable(sqlite *db, char **old_fields, int count,
00092 int table_number, char **err_msg);
00093
00094 static int
00095 advertservice_db_add_metadata(sqlite *db, char **new_fields, char **err_msg);
00096
00097 static int
00098 advertservice_db_get_datatable_number(sqlite *db, int *number,
00099 char **err_msg);
00100
00101 static void
00102 advertservice_db_re_match(sqlite_func *func, int argc, const char **argv);
00103
00104
00105 static int
00106 append_string(char **str, char const *to_append);
00107
00108 static unsigned int
00109 fields_count(char **fields);
00110
00111 static GATResult
00112 add_field(char ***fields, char const *key);
00113
00114 static void
00115 release_fields(char ***fields);
00116
00117
00118
00119
00120
00121 static char const *init_db_stmts[] =
00122 {
00123 "begin transaction on conflict rollback;",
00124
00125
00126 "create table main ("
00127 "id integer primary key on conflict rollback,"
00128 "key varchar(32) not null on conflict rollback,"
00129 "value varchar(128)"
00130 ");",
00131 "insert or rollback into main (key, value) values('version', '10000');",
00132 "insert or rollback into main (key, value) values('datatable', 'data1');",
00133
00134
00135 "create table nodes ("
00136 "node_id integer primary key on conflict rollback,"
00137 "node_name,"
00138 "parent_id"
00139 ");",
00140 "insert or rollback into nodes (node_name, parent_id) values('__root__', NULL);",
00141
00142
00143 "create table data1 ("
00144 "node_id unique,"
00145 "data"
00146 ");",
00147
00148
00149
00150 "create table metadata ("
00151 "metakey not null on conflict rollback"
00152 ");",
00153
00154
00155
00156 "insert or rollback into metadata (metakey) values('node_id');",
00157 "insert or rollback into metadata (metakey) values('data');",
00158
00159 "commit transaction;",
00160 0
00161 };
00162
00163
00164 static char const *begin_transaction_stmts[] =
00165 {
00166 "begin transaction on conflict rollback;",
00167 0
00168 };
00169
00170
00171 static char const *commit_transaction_stmts[] =
00172 {
00173 "commit transaction;",
00174 0
00175 };
00176
00177
00178
00179
00180
00181
00182
00183
00184 GATResult
00185 advertservice_db_init(GATContext context, sqlite **db)
00186 {
00187 GAT_USES_STATUS(context, "advertservice_db_init");
00188
00189 int result = 0;
00190 sqlite *new_db = NULL;
00191 char *err_msg = NULL;
00192
00193
00194 new_db = sqlite_open("advertservice.db", 0, &err_msg);
00195 GAT_CREATE_STATUS_IF(NULL == new_db, SQLITE_TO_GAT(SQLITE_CANTOPEN));
00196
00197
00198 if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00199 {
00200 int version = 0;
00201 GAT_CREATE_STATUS(advertservice_db_get_version(new_db, &version, &err_msg));
00202
00203
00204 if (GAT_FAILED(GAT_CURRENT_STATUS()))
00205 {
00206 GAT_CREATE_STATUS_UNCOND(advertservice_db_execute_sql_statements(new_db,
00207 init_db_stmts, &err_msg));
00208 }
00209 }
00210
00211 if (NULL == db)
00212 {
00213 GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00214 }
00215
00216
00217 if (GAT_FAILED(GAT_CURRENT_STATUS()))
00218 {
00219 if (NULL != err_msg)
00220 {
00221 GAT_STATUS_ADD_MESSAGE(err_msg);
00222 free(err_msg);
00223 }
00224 }
00225 else
00226 {
00227
00228 *db = new_db;
00229 }
00230 return GAT_RETURN_STATUS();
00231 }
00232
00233
00234
00235
00236 void
00237 advertservice_db_close(sqlite **db)
00238 {
00239 if (NULL != db && NULL != *db)
00240 {
00241 sqlite_close(*db);
00242 *db = NULL;
00243 }
00244 }
00245
00246
00247
00248
00249 GATResult
00250 advertservice_db_write_advert_data(GATContext context, sqlite *db,
00251 char const *path, char const *data, GATTable_const metadata)
00252 {
00253 GAT_USES_STATUS(context, "advertservice_db_write_advert_data");
00254 int node_id = 0;
00255 char *err_msg = NULL;
00256
00257
00258 GAT_CREATE_STATUS(advertservice_db_begin_transaction(db, &err_msg));
00259
00260
00261 GAT_CREATE_STATUS(advertservice_db_find_node(db, path, &node_id, GATTrue,
00262 &err_msg));
00263
00264
00265 GAT_CREATE_STATUS(advertservice_db_write_data(db, node_id, data, metadata,
00266 &err_msg));
00267
00268
00269 GAT_CREATE_STATUS(advertservice_db_commit_transaction(db, &err_msg));
00270
00271
00272 if (GAT_FAILED(GAT_CURRENT_STATUS()) && NULL != err_msg)
00273 {
00274 GAT_STATUS_ADD_MESSAGE(err_msg);
00275 free(err_msg);
00276 }
00277 return GAT_RETURN_STATUS();
00278 }
00279
00280
00281
00282
00283 GATResult
00284 advertservice_db_delete_advert_data(GATContext context, sqlite *db,
00285 char const *path)
00286 {
00287 GAT_USES_STATUS(context, "advertservice_db_delete_advert_data");
00288 char *err_msg = NULL;
00289 int node_id = 0;
00290
00291
00292 GAT_CREATE_STATUS(advertservice_db_begin_transaction(db, &err_msg));
00293
00294
00295 GAT_CREATE_STATUS(advertservice_db_find_node(db, path, &node_id, GATFalse,
00296 &err_msg));
00297
00298
00299 GAT_CREATE_STATUS(advertservice_db_delete_node(db, node_id, &err_msg));
00300
00301
00302 GAT_CREATE_STATUS(advertservice_db_commit_transaction(db, &err_msg));
00303
00304
00305 if (GAT_FAILED(GAT_CURRENT_STATUS()) && NULL != err_msg)
00306 {
00307 GAT_STATUS_ADD_MESSAGE(err_msg);
00308 free(err_msg);
00309 }
00310 return GAT_RETURN_STATUS();
00311 }
00312
00313
00314
00315
00316 GATResult
00317 advertservice_db_get_metadata(GATContext context, sqlite *db,
00318 char const *path, GATTable *metadata)
00319 {
00320 GAT_USES_STATUS(context, "advertservice_db_get_metadata");
00321 char *err_msg = NULL;
00322 int node_id = 0;
00323
00324
00325 GAT_CREATE_STATUS(advertservice_db_find_node(db, path, &node_id, GATFalse,
00326 &err_msg));
00327
00328
00329 GAT_CREATE_STATUS(advertservice_db_get_node_metadata(db, node_id, metadata,
00330 &err_msg));
00331
00332
00333 if (GAT_FAILED(GAT_CURRENT_STATUS()) && NULL != err_msg)
00334 {
00335 GAT_STATUS_ADD_MESSAGE(err_msg);
00336 free(err_msg);
00337 }
00338 return GAT_RETURN_STATUS();
00339 }
00340
00341
00342
00343
00344 GATResult
00345 advertservice_db_get_advert_data(GATContext context, sqlite *db,
00346 char const *path, char **data)
00347 {
00348 GAT_USES_STATUS(context, "advertservice_db_get_metadata");
00349 char *err_msg = NULL;
00350 int node_id = 0;
00351
00352
00353 GAT_CREATE_STATUS(advertservice_db_find_node(db, path, &node_id, GATFalse,
00354 &err_msg));
00355
00356
00357 GAT_CREATE_STATUS(advertservice_db_get_node_data(db, node_id, data,
00358 &err_msg));
00359
00360
00361 if (GAT_FAILED(GAT_CURRENT_STATUS()) && NULL != err_msg)
00362 {
00363 GAT_STATUS_ADD_MESSAGE(err_msg);
00364 free(err_msg);
00365 }
00366 return GAT_RETURN_STATUS();
00367 }
00368
00369
00370
00371
00372 GATResult
00373 advertservice_db_find(GATContext context, sqlite *db,
00374 GATTable_const metadata, GATList_String *paths)
00375 {
00376 GAT_USES_STATUS(context, "advertservice_db_find");
00377 char *err_msg = NULL;
00378 GATuint32 len = GATTable_Size(metadata);
00379 int result = SQLITE_OK;
00380
00381 if (0 != len)
00382 {
00383 GATuint32 i = 0;
00384
00385
00386 char buffer[256];
00387 char *sql_stmt = NULL;
00388 int table_number = 0;
00389 void **keys = GATTable_GetKeys(metadata);
00390 regex_t *regexpr = (regex_t *)malloc(len * sizeof(regex_t));
00391 GAT_CREATE_STATUS_IF(NULL == regexpr, GAT_MEMORYFAILURE);
00392
00393 for (; NULL != keys[i]; ++i)
00394 {
00395 GAT_CREATE_STATUS(GATTable_Get_String(metadata, keys[i], buffer,
00396 sizeof(buffer)));
00397
00398 GAT_CREATE_STATUS_IF(0 != regcomp(®expr[i], buffer, 0),
00399 GAT_INVALID_PARAMETER);
00400 }
00401
00402 if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00403 {
00404
00405 result = sqlite_create_function(db, "re_match", 2,
00406 advertservice_db_re_match, regexpr);
00407 GAT_CREATE_STATUS_IF(SQLITE_OK != result, SQLITE_TO_GAT(result));
00408
00409
00410 result = advertservice_db_get_datatable_number(db, &table_number, &err_msg);
00411 GAT_CREATE_STATUS_IF(SQLITE_OK != result, SQLITE_TO_GAT(result));
00412 }
00413
00414
00415 sprintf(buffer, "select node_id from data%d where ", table_number);
00416 GAT_CREATE_STATUS_IF(SQLITE_OK != (result = append_string(&sql_stmt, buffer)),
00417 SQLITE_TO_GAT(result));
00418
00419 for (i = 0; NULL != keys[i]; ++i)
00420 {
00421 sprintf(buffer, "%sre_match(%d, %s) = 1", (0 == i) ? "" : " and ", i,
00422 keys[i]);
00423 GAT_CREATE_STATUS_IF(SQLITE_OK != (result = append_string(&sql_stmt, buffer)),
00424 SQLITE_TO_GAT(result));
00425 }
00426
00427 GAT_CREATE_STATUS_IF(SQLITE_OK != (result = append_string(&sql_stmt, ";")),
00428 SQLITE_TO_GAT(result));
00429
00430
00431 {
00432 int nrows = 0;
00433 int fields = 0;
00434 char **values = NULL;
00435 GATList_String node_paths = NULL;
00436
00437 result = sqlite_get_table(db, sql_stmt, &values, &nrows, &fields, &err_msg);
00438 GAT_CREATE_STATUS_IF(SQLITE_OK != result, SQLITE_TO_GAT(result));
00439
00440 node_paths = GATList_String_Create();
00441 GAT_CREATE_STATUS_IF(NULL == node_paths, GAT_MEMORYFAILURE);
00442
00443 GAT_CREATE_STATUS(advertservice_db_find_pathes(db, nrows, &values[1],
00444 node_paths, &err_msg));
00445
00446 if (NULL != paths)
00447 {
00448 *paths = node_paths;
00449 }
00450 else
00451 {
00452 GATList_String_Destroy(&node_paths);
00453 GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00454 }
00455 sqlite_free_table(values);
00456 }
00457
00458
00459 free(sql_stmt);
00460 for (i = 0; i < len; ++i)
00461 {
00462 regfree(®expr[i]);
00463 }
00464 free(regexpr);
00465 GATTable_ReleaseKeys(metadata, &keys);
00466 }
00467 else
00468 {
00469 GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00470 }
00471
00472
00473 if (GAT_FAILED(GAT_CURRENT_STATUS()) && NULL != err_msg)
00474 {
00475 GAT_STATUS_ADD_MESSAGE(err_msg);
00476 free(err_msg);
00477 }
00478 return GAT_RETURN_STATUS();
00479 }
00480
00481
00482 static GATResult
00483 advertservice_db_get_version(sqlite *db, GATuint32 *version, char **err_msg)
00484 {
00485 int nrows = 0;
00486 int fields = 0;
00487 char **values = NULL;
00488
00489 int result = sqlite_get_table(db,
00490 "select value from main where key = 'version';",
00491 &values, &nrows, &fields, err_msg);
00492
00493 if (SQLITE_OK != result)
00494 {
00495 return SQLITE_TO_GAT(result);
00496 }
00497
00498 assert(1 == fields && 1 == nrows);
00499 result = (1 == sscanf(values[1], "%d", version)) ? SQLITE_OK : SQLITE_NOTFOUND;
00500
00501 sqlite_free_table(values);
00502 return SQLITE_TO_GAT(result);
00503 }
00504
00505
00506
00507
00508 static GATResult
00509 advertservice_db_execute_sql_statements(sqlite *db, char const **stmts,
00510 char **err_msg)
00511 {
00512 int result = SQLITE_OK;
00513 int i = 0;
00514 for(; NULL != stmts[i]; ++i)
00515 {
00516 result = sqlite_exec(db, stmts[i], 0, 0, err_msg);
00517 if (SQLITE_OK != result)
00518 {
00519 break;
00520 }
00521 }
00522 return SQLITE_TO_GAT(result);
00523 }
00524
00525
00526
00527
00528 static GATResult
00529 advertservice_db_begin_transaction(sqlite *db, char **err_msg)
00530 {
00531 return advertservice_db_execute_sql_statements(db,
00532 begin_transaction_stmts, err_msg);
00533 }
00534
00535
00536
00537
00538 static GATResult
00539 advertservice_db_commit_transaction(sqlite *db, char **err_msg)
00540 {
00541 return advertservice_db_execute_sql_statements(db,
00542 commit_transaction_stmts, err_msg);
00543 }
00544
00545
00546
00547
00548 static GATResult
00549 advertservice_db_find_node(sqlite *db, char const *pathstr, int *node_id,
00550 GATBool createnode, char **err_msg)
00551 {
00552 GATResult retval = GAT_SUCCESS;
00553 char *path = GATUtil_strdup(pathstr);
00554
00555 if (NULL != path)
00556 {
00557 if ('/' == *path)
00558 {
00559
00560 char *node_name = strtok(path + 1, "/");
00561 int parent_id = 1;
00562 int current_node_id = 0;
00563
00564 while (NULL != node_name) {
00565 if (!strcmp(node_name, "."))
00566 {
00567
00568 current_node_id = parent_id;
00569 }
00570 else if (!strcmp(node_name, ".."))
00571 {
00572
00573 int nrows = 0;
00574 int fields = 0;
00575 char **values = NULL;
00576 int result = SQLITE_OK;
00577
00578 if (1 == parent_id)
00579 {
00580 retval = GAT_INVALID_PARAMETER;
00581 break;
00582 }
00583
00584 result = sqlite_get_table_printf(db,
00585 "select parent_id from nodes where node_id = '%d';",
00586 &values, &nrows, &fields, err_msg, parent_id);
00587 if (SQLITE_OK != result)
00588 {
00589 retval = SQLITE_TO_GAT(result);
00590 break;
00591 }
00592
00593 if (1 != nrows || 1 != sscanf(values[1], "%d", ¤t_node_id))
00594 {
00595 sqlite_free_table(values);
00596 retval = SQLITE_TO_GAT(SQLITE_NOTFOUND);
00597 break;
00598 }
00599 sqlite_free_table(values);
00600 }
00601 else
00602 {
00603
00604 int result = advertservice_db_read_node_id(db, node_name, parent_id,
00605 ¤t_node_id, err_msg);
00606 if (SQLITE_OK != result || 0 == current_node_id)
00607 {
00608 if (createnode)
00609 {
00610
00611 result = sqlite_exec_printf(db,
00612 "insert or rollback into nodes "
00613 "(node_name, parent_id) values('%s', %d);",
00614 0, 0, err_msg, node_name, parent_id);
00615
00616 if (SQLITE_OK != result)
00617 {
00618 retval = SQLITE_TO_GAT(result);
00619 break;
00620 }
00621
00622
00623 result = advertservice_db_read_node_id(db, node_name, parent_id,
00624 ¤t_node_id, err_msg);
00625 if (SQLITE_OK != result || 0 == current_node_id)
00626 {
00627 retval = SQLITE_TO_GAT(result);
00628 break;
00629 }
00630 }
00631 else
00632 {
00633
00634 retval = SQLITE_TO_GAT(SQLITE_NOTFOUND);
00635 break;
00636 }
00637 }
00638 }
00639
00640
00641 node_name = strtok(NULL, "/");
00642 if (NULL != node_name)
00643 {
00644 parent_id = current_node_id;
00645 current_node_id = 0;
00646 }
00647 else
00648 {
00649 *node_id = current_node_id;
00650 break;
00651 }
00652 }
00653 }
00654 else
00655 {
00656 retval = GAT_INVALID_PARAMETER;
00657 }
00658 free(path);
00659 }
00660 else
00661 {
00662 retval = GAT_MEMORYFAILURE;
00663 }
00664
00665 return retval;
00666 }
00667
00668 static int
00669 append_string(char **str, char const *to_append)
00670 {
00671 GATBool new_string = (NULL != *str) ? GATFalse : GATTrue;
00672 unsigned int len = (NULL != *str) ? strlen(*str) + 1 : 0;
00673 char *new_str = (char *)realloc(*str, len + strlen(to_append) + 1);
00674 if (NULL == new_str)
00675 {
00676 return SQLITE_NOMEM;
00677 }
00678 if (GATTrue == new_string)
00679 {
00680 new_str[0] = '\0';
00681 }
00682 strcat(new_str, to_append);
00683 *str = new_str;
00684 return SQLITE_OK;
00685 }
00686
00687
00688
00689
00690 static GATResult
00691 advertservice_db_write_data(sqlite *db, int node_id, char const *data,
00692 GATTable_const metadata, char **err_msg)
00693 {
00694 int result = SQLITE_OK;
00695 int table_number = 0;
00696
00697 if (NULL != metadata)
00698 {
00699 void **keys = GATTable_GetKeys(metadata);
00700
00701 result = advertservice_db_alter_table(db, (char const **)keys, err_msg);
00702 GATTable_ReleaseKeys(metadata, &keys);
00703 if (SQLITE_OK != result)
00704 {
00705 return SQLITE_TO_GAT(result);
00706 }
00707 }
00708
00709
00710 result = advertservice_db_get_datatable_number(db, &table_number, err_msg);
00711 if (SQLITE_OK != result)
00712 {
00713 return SQLITE_TO_GAT(result);
00714 }
00715 result = sqlite_exec_printf(db,
00716 "insert or replace into data%d (node_id, data) values('%d', '%q');",
00717 0, 0, err_msg, table_number, node_id, data);
00718 if (SQLITE_OK != result)
00719 {
00720 return SQLITE_TO_GAT(result);
00721 }
00722
00723
00724 if (NULL != metadata)
00725 {
00726 void **keys = GATTable_GetKeys(metadata);
00727
00728 if (NULL != keys[0])
00729 {
00730 char buffer[256];
00731 int i = 0;
00732 char *sql_stmt = NULL;
00733
00734 sprintf(buffer, "update or rollback data%d set ", table_number);
00735 result = append_string(&sql_stmt, buffer);
00736 if (SQLITE_OK != result)
00737 {
00738 GATTable_ReleaseKeys(metadata, &keys);
00739 return SQLITE_TO_GAT(result);
00740 }
00741
00742 for (i = 0; NULL != keys[i]; ++i)
00743 {
00744 char value[256];
00745
00746 if (GAT_SUCCEEDED(GATTable_Get_String(metadata, keys[i], value,
00747 sizeof(value))))
00748 {
00749 sprintf(buffer, "%s%s = '%s'", (0 == i) ? "" : ", ", keys[i], value);
00750 result = append_string(&sql_stmt, buffer);
00751 if (SQLITE_OK != result)
00752 {
00753 GATTable_ReleaseKeys(metadata, &keys);
00754 return SQLITE_TO_GAT(result);
00755 }
00756 }
00757 }
00758 GATTable_ReleaseKeys(metadata, &keys);
00759
00760 sprintf(buffer, " where node_id = '%d';", node_id);
00761 result = append_string(&sql_stmt, buffer);
00762 if (SQLITE_OK != result)
00763 {
00764 return SQLITE_TO_GAT(result);
00765 }
00766
00767 result = sqlite_exec(db, sql_stmt, 0, 0, err_msg);
00768 free(sql_stmt);
00769 }
00770 else
00771 {
00772
00773 GATTable_ReleaseKeys(metadata, &keys);
00774 return GAT_INVALID_PARAMETER;
00775 }
00776 }
00777
00778 return SQLITE_TO_GAT(result);
00779 }
00780
00781
00782
00783
00784 static int
00785 advertservice_db_read_node_id(sqlite *db, char const *node_name, int parent_id,
00786 int *node_id, char **err_msg)
00787 {
00788 int result = SQLITE_OK;
00789 int nrows = 0;
00790 int fields = 0;
00791 char **values = NULL;
00792
00793 result = sqlite_get_table_printf(db,
00794 "select node_id from nodes "
00795 "where node_name = '%s' and parent_id = %d",
00796 &values, &nrows, &fields, err_msg,
00797 node_name, parent_id);
00798
00799 if (SQLITE_OK == result && 0 != nrows)
00800 {
00801 assert(1 == nrows && 1 == fields);
00802 result = (1 == sscanf(values[1], "%d", node_id)) ? SQLITE_OK : SQLITE_NOTFOUND;
00803 }
00804
00805 sqlite_free_table(values);
00806 return result;
00807 }
00808
00809 static unsigned int
00810 fields_count(char **fields)
00811 {
00812 unsigned int i = 0;
00813 if (NULL != fields)
00814 {
00815 while(NULL != fields[i])
00816 {
00817 ++i;
00818 }
00819 }
00820 return i;
00821 }
00822
00823 static GATResult
00824 add_field(char ***fields, char const *key)
00825 {
00826 unsigned int count = fields_count(*fields);
00827 char **new_fields = (char **)realloc(*fields, (count + 2) * sizeof(char *));
00828
00829 if (NULL == new_fields)
00830 {
00831 return GAT_MEMORYFAILURE;
00832 }
00833
00834 *fields = new_fields;
00835 (*fields)[count] = GATUtil_strdup(key);
00836 if (NULL == (*fields)[count])
00837 {
00838 return GAT_MEMORYFAILURE;
00839 }
00840
00841 (*fields)[count+1] = NULL;
00842 return GAT_SUCCESS;
00843 }
00844
00845 static void
00846 release_fields(char ***fields)
00847 {
00848 if (NULL != fields && NULL != *fields)
00849 {
00850 int i = 0;
00851 for (; NULL != (*fields)[i]; ++i)
00852 {
00853 free((*fields)[i]);
00854 }
00855 free(*fields);
00856 *fields = NULL;
00857 }
00858 }
00859
00860
00861
00862
00863
00864
00865
00866 static int
00867 advertservice_db_alter_table(sqlite *db, char const **keys, char **err_msg)
00868 {
00869 int result = SQLITE_OK;
00870 int old_fields_nrows = 0;
00871 int old_fields_count = 0;
00872 char **old_fields = NULL;
00873 char **new_fields = NULL;
00874 int i = 0;
00875 int j = 1;
00876 int table_number = 0;
00877
00878
00879 result = sqlite_get_table(db, "select metakey from metadata;",
00880 &old_fields, &old_fields_nrows, &old_fields_count, err_msg);
00881 if (SQLITE_OK != result || 0 == old_fields_nrows)
00882 {
00883 return result;
00884 }
00885
00886
00887 for (; NULL != keys[i] ; ++i)
00888 {
00889 GATBool found = GATFalse;
00890 for (j = 1; j < old_fields_nrows + old_fields_count; ++j)
00891 {
00892 if (!strcmp(keys[i], old_fields[j]))
00893 {
00894 found = GATTrue;
00895 break;
00896 }
00897 }
00898
00899 if (GATFalse == found)
00900 {
00901 add_field(&new_fields, keys[i]);
00902 }
00903 }
00904 if (NULL == new_fields)
00905 {
00906
00907 sqlite_free_table(old_fields);
00908 return SQLITE_OK;
00909 }
00910
00911
00912 result = advertservice_db_get_datatable_number(db, &table_number, err_msg);
00913 if (SQLITE_OK != result)
00914 {
00915 sqlite_free_table(old_fields);
00916 release_fields(&new_fields);
00917 return result;
00918 }
00919
00920
00921 result = advertservice_db_create_datatable(db, &old_fields[1],
00922 old_fields_nrows, new_fields, table_number+1, err_msg);
00923 if (SQLITE_OK != result)
00924 {
00925 sqlite_free_table(old_fields);
00926 release_fields(&new_fields);
00927 return result;
00928 }
00929
00930
00931 result = advertservice_db_copy_datatable(db, &old_fields[1],
00932 old_fields_nrows, table_number, err_msg);
00933 sqlite_free_table(old_fields);
00934 if (SQLITE_OK != result)
00935 {
00936 release_fields(&new_fields);
00937 return result;
00938 }
00939
00940
00941 result = advertservice_db_add_metadata(db, new_fields, err_msg);
00942 release_fields(&new_fields);
00943 if (SQLITE_OK != result)
00944 {
00945 return result;
00946 }
00947
00948
00949 result = sqlite_exec_printf(db, "drop table data%d;", 0, 0, err_msg,
00950 table_number);
00951 if (SQLITE_OK != result)
00952 {
00953 return result;
00954 }
00955
00956
00957 result = sqlite_exec_printf(db,
00958 "update or rollback main set value = 'data%d' where key = 'datatable';",
00959 0, 0, err_msg, table_number + 1);
00960 if (SQLITE_OK != result)
00961 {
00962 return result;
00963 }
00964
00965 return result;
00966 }
00967
00968
00969
00970
00971 static int
00972 advertservice_db_create_datatable(sqlite *db, char **old_fields, int count,
00973 char **new_fields, int table_number, char **err_msg)
00974 {
00975 int result = SQLITE_OK;
00976 char *sql_stmt = NULL;
00977 char buffer[256];
00978 int i = 0;
00979
00980
00981 sprintf(buffer, "create table data%d (", table_number);
00982 result = append_string(&sql_stmt, buffer);
00983 if (SQLITE_OK != result)
00984 {
00985 return result;
00986 }
00987
00988
00989 for (; i < count; ++i)
00990 {
00991 if (!strcmp(old_fields[i], "node_id") || !strcmp(old_fields[i], "data"))
00992 {
00993 continue;
00994 }
00995
00996 sprintf(buffer, "%s, ", old_fields[i]);
00997 result = append_string(&sql_stmt, buffer);
00998 if (SQLITE_OK != result)
00999 {
01000 free(sql_stmt);
01001 return result;
01002 }
01003 }
01004
01005
01006 for (i = 0; NULL != new_fields[i]; ++i)
01007 {
01008 sprintf(buffer, "%s, ", new_fields[i]);
01009 result = append_string(&sql_stmt, buffer);
01010 if (SQLITE_OK != result)
01011 {
01012 free(sql_stmt);
01013 return result;
01014 }
01015 }
01016
01017
01018 result = append_string(&sql_stmt, "node_id unique, data);");
01019 if (SQLITE_OK != result)
01020 {
01021 return result;
01022 }
01023
01024
01025 result = sqlite_exec(db, sql_stmt, 0, 0, err_msg);
01026 free (sql_stmt);
01027
01028 return result;
01029 }
01030
01031
01032
01033
01034 static int
01035 advertservice_db_copy_datatable(sqlite *db, char **old_fields, int count,
01036 int table_number, char **err_msg)
01037 {
01038 int result = SQLITE_OK;
01039 char buffer[256];
01040 char *sql_stmt = NULL;
01041 int i = 0;
01042
01043 sprintf(buffer, "insert or rollback into data%d (", table_number+1);
01044 result = append_string(&sql_stmt, buffer);
01045 if (SQLITE_OK != result)
01046 {
01047 return result;
01048 }
01049
01050
01051 for (; i < count; ++i)
01052 {
01053 if (!strcmp(old_fields[i], "node_id") || !strcmp(old_fields[i], "data"))
01054 {
01055 continue;
01056 }
01057 sprintf(buffer, "%s, ", old_fields[i]);
01058 result = append_string(&sql_stmt, buffer);
01059 if (SQLITE_OK != result)
01060 {
01061 free(sql_stmt);
01062 return result;
01063 }
01064 }
01065
01066 result = append_string(&sql_stmt, "node_id, data) select ");
01067 if (SQLITE_OK != result)
01068 {
01069 return result;
01070 }
01071
01072 for (i = 0; i < count; ++i)
01073 {
01074 if (!strcmp(old_fields[i], "node_id") || !strcmp(old_fields[i], "data"))
01075 {
01076 continue;
01077 }
01078 sprintf(buffer, "%s, ", old_fields[i]);
01079 result = append_string(&sql_stmt, buffer);
01080 if (SQLITE_OK != result)
01081 {
01082 free(sql_stmt);
01083 return result;
01084 }
01085 }
01086
01087 sprintf(buffer, "node_id, data from data%d;", table_number);
01088 result = append_string(&sql_stmt, buffer);
01089 if (SQLITE_OK != result)
01090 {
01091 return result;
01092 }
01093
01094
01095 result = sqlite_exec(db, sql_stmt, 0, 0, err_msg);
01096 free(sql_stmt);
01097
01098 return result;
01099 }
01100
01101
01102
01103
01104 static int
01105 advertservice_db_add_metadata(sqlite *db, char **new_fields, char **err_msg)
01106 {
01107 int result = SQLITE_OK;
01108 int i = 0;
01109
01110 for (i = 0; NULL != new_fields[i]; ++i)
01111 {
01112 result = sqlite_exec_printf(db,
01113 "insert or rollback into metadata (metakey) values('%s');",
01114 0, 0, err_msg, new_fields[i]);
01115 if (SQLITE_OK != result)
01116 {
01117 break;
01118 }
01119 }
01120 return result;
01121 }
01122
01123
01124
01125
01126 static int
01127 advertservice_db_get_datatable_number(sqlite *db, int *number, char **err_msg)
01128 {
01129 int result = SQLITE_OK;
01130 int nrows = 0;
01131 int fields = 0;
01132 char **values = NULL;
01133
01134 *number = 0;
01135
01136
01137 result = sqlite_get_table_printf(db,
01138 "select value from main where key = 'datatable';",
01139 &values, &nrows, &fields, err_msg);
01140 if (SQLITE_OK != result || 1 != nrows)
01141 {
01142 return result;
01143 }
01144 if (1 != sscanf(values[1], "data%d", number))
01145 {
01146 sqlite_free_table(values);
01147 return SQLITE_NOTFOUND;
01148 }
01149 sqlite_free_table(values);
01150
01151 return SQLITE_OK;
01152 }
01153
01154
01155
01156
01157 static GATResult
01158 advertservice_db_delete_node(sqlite *db, int node_id, char **err_msg)
01159 {
01160 int result = SQLITE_OK;
01161 int nrows = 0;
01162 int fields = 0;
01163 char **values = NULL;
01164 int table_number = 0;
01165
01166
01167 result = sqlite_get_table_printf(db,
01168 "select node_id from nodes where parent_id = '%d';",
01169 &values, &nrows, &fields, err_msg, node_id);
01170 sqlite_free_table(values);
01171 if (SQLITE_OK != result)
01172 {
01173 return SQLITE_TO_GAT(result);
01174 }
01175
01176 if (0 == nrows)
01177 {
01178
01179 result = sqlite_exec_printf(db,
01180 "delete from nodes where node_id = '%d';",
01181 0, 0, err_msg, node_id);
01182 if (SQLITE_OK != result)
01183 {
01184 return SQLITE_TO_GAT(result);
01185 }
01186
01187
01188 }
01189
01190
01191 result = advertservice_db_get_datatable_number(db, &table_number, err_msg);
01192 if (SQLITE_OK != result)
01193 {
01194 return SQLITE_TO_GAT(result);
01195 }
01196
01197
01198 result = sqlite_exec_printf(db,
01199 "delete from data%d where node_id = '%d';",
01200 0, 0, err_msg, table_number, node_id);
01201
01202
01203
01204
01205
01206 return SQLITE_TO_GAT(result);
01207 }
01208
01209
01210
01211
01212 static GATResult
01213 advertservice_db_get_node_metadata(sqlite *db, int node_id,
01214 GATTable *metadata, char **err_msg)
01215 {
01216 GATResult retval = GAT_SUCCESS;
01217 int result = SQLITE_OK;
01218 int table_number = 0;
01219 int nrows = 0;
01220 int fields = 0;
01221 char **values = NULL;
01222 GATTable table = NULL;
01223 int i = 0;
01224
01225
01226 result = advertservice_db_get_datatable_number(db, &table_number, err_msg);
01227 if (SQLITE_OK != result)
01228 {
01229 return SQLITE_TO_GAT(result);
01230 }
01231
01232
01233 result = sqlite_get_table_printf(db,
01234 "select * from data%d where node_id = '%d';",
01235 &values, &nrows, &fields, err_msg, table_number, node_id);
01236 if (SQLITE_OK != result)
01237 {
01238 return SQLITE_TO_GAT(result);
01239 }
01240
01241
01242 table = GATTable_Create();
01243 if (NULL == table)
01244 {
01245 sqlite_free_table(values);
01246 return GAT_MEMORYFAILURE;
01247 }
01248
01249
01250 for (i = 0; i < fields; ++i)
01251 {
01252
01253 if (NULL == values[i+fields] ||
01254 !strcmp(values[i], "node_id") || !strcmp(values[i], "data"))
01255 {
01256 continue;
01257 }
01258
01259 retval = GATTable_Add_String(table, values[i], values[i+fields]);
01260 if (GAT_FAILED(retval))
01261 {
01262 break;
01263 }
01264 }
01265
01266
01267 if (GAT_SUCCEEDED(retval))
01268 {
01269 if (NULL != metadata)
01270 {
01271 *metadata = table;
01272 }
01273 else
01274 {
01275 retval = GAT_INVALID_PARAMETER;
01276 GATTable_Destroy(&table);
01277 }
01278 }
01279 else
01280 {
01281 GATTable_Destroy(&table);
01282 }
01283 sqlite_free_table(values);
01284 return retval;
01285 }
01286
01287
01288
01289
01290 static GATResult
01291 advertservice_db_get_node_data(sqlite *db, int node_id,
01292 char **advert_data, char **err_msg)
01293 {
01294 GATResult retval = GAT_SUCCESS;
01295 int result = SQLITE_OK;
01296 int table_number = 0;
01297 int nrows = 0;
01298 int fields = 0;
01299 char **values = NULL;
01300 char *data = NULL;
01301
01302
01303 result = advertservice_db_get_datatable_number(db, &table_number, err_msg);
01304 if (SQLITE_OK != result)
01305 {
01306 return SQLITE_TO_GAT(result);
01307 }
01308
01309
01310 result = sqlite_get_table_printf(db,
01311 "select data from data%d where node_id = '%d';",
01312 &values, &nrows, &fields, err_msg, table_number, node_id);
01313 if (SQLITE_OK != result)
01314 {
01315 return SQLITE_TO_GAT(result);
01316 }
01317
01318
01319 data = GATUtil_strdup(values[1]);
01320 if (NULL == data)
01321 {
01322 return GAT_MEMORYFAILURE;
01323 }
01324
01325
01326 if (GAT_SUCCEEDED(retval))
01327 {
01328 if (NULL != advert_data)
01329 {
01330 *advert_data = data;
01331 }
01332 else
01333 {
01334 retval = GAT_INVALID_PARAMETER;
01335 free(data);
01336 }
01337 }
01338 else
01339 {
01340 free(data);
01341 }
01342 sqlite_free_table(values);
01343 return retval;
01344 }
01345
01346
01347
01348
01349
01350 static void
01351 advertservice_db_re_match(sqlite_func *func, int argc, const char **argv)
01352 {
01353 if (2 != argc)
01354 {
01355 sqlite_set_result_error(func, "re_match: expected exactly 2 parameters",
01356 SQLITE_MISUSE);
01357 }
01358 else
01359 {
01360 int result = REG_NOMATCH;
01361 int regexpr_num = 0;
01362 regex_t *regexpr = NULL;
01363
01364 if (1 == sscanf(argv[0], "%d", ®expr_num))
01365 {
01366 regexpr = (regex_t *)sqlite_user_data(func);
01367 result = regexec(®expr[regexpr_num], argv[1], 0, NULL, 0);
01368 if (REG_NOERROR != result && REG_NOMATCH != result)
01369 {
01370
01371 char buffer[512];
01372 char error_msg[256];
01373 GATuint32 written = 0;
01374 GATResult retval = GATSelf_ResolveErrorMessage(REGEX_TO_GAT(result),
01375 error_msg, sizeof(error_msg), &written);
01376
01377 if (GAT_SUCCEEDED(retval))
01378 {
01379 sprintf(buffer,
01380 "re_match: unexpected regular expression error: %d (%s)",
01381 result, error_msg);
01382 }
01383 else
01384 {
01385 sprintf(buffer,
01386 "re_match: unexpected regular expression error: %d (unknown error)",
01387 result);
01388 }
01389 sqlite_set_result_error(func, buffer, SQLITE_MISUSE);
01390 }
01391 else
01392 {
01393
01394 sqlite_set_result_int(func, (REG_NOERROR == result) ? 1 : 0);
01395 }
01396 }
01397 else
01398 {
01399 sqlite_set_result_error(func,
01400 "re_match: first parameter should be of integer type", SQLITE_MISUSE);
01401 }
01402 }
01403 }
01404
01405
01406
01407
01408 static GATResult
01409 advertservice_db_find_pathes(sqlite *db, int nrows, char **values,
01410 GATList_String node_paths, char **err_msg)
01411 {
01412 GATResult retval = SQLITE_TO_GAT(SQLITE_NOTFOUND);
01413 int i = 0;
01414
01415 if (0 < nrows)
01416 {
01417
01418 for (; i < nrows; ++i)
01419 {
01420 char *path = NULL;
01421
01422 retval = advertservice_db_construct_path(db, values[i], &path, err_msg);
01423 if (GAT_SUCCEEDED(retval))
01424 {
01425
01426 path[strlen(path)-1] = '\0';
01427 GATList_String_Insert(node_paths, GATList_String_End(node_paths), path);
01428 }
01429 free(path);
01430 }
01431 }
01432 return retval;
01433 }
01434
01435
01436
01437
01438 static GATResult
01439 advertservice_db_construct_path(sqlite *db, char *node_id_str, char **path,
01440 char **err_msg)
01441 {
01442 GATResult retval = GAT_SUCCESS;
01443
01444 int node_id = 0;
01445 if (1 != sscanf(node_id_str, "%d", &node_id))
01446 {
01447
01448 retval = GAT_INVALID_PARAMETER;
01449 }
01450 else if (1 == node_id)
01451 {
01452
01453 if (SQLITE_OK != append_string(path, "/"))
01454 {
01455 retval = GAT_MEMORYFAILURE;
01456 }
01457 }
01458 else
01459 {
01460
01461 int nrows = 0;
01462 int fields = 0;
01463 char **values = NULL;
01464 int result = sqlite_get_table_printf(db,
01465 "select node_name, parent_id from nodes where node_id = '%d';",
01466 &values, &nrows, &fields, err_msg, node_id);
01467
01468 if (SQLITE_OK != result)
01469 {
01470 retval = SQLITE_TO_GAT(result);
01471 }
01472 else if (1 != nrows)
01473 {
01474
01475 retval = SQLITE_TO_GAT(SQLITE_NOTFOUND);
01476 }
01477 else
01478 {
01479
01480 retval = advertservice_db_construct_path(db, values[3], path, err_msg);
01481 if (GAT_SUCCEEDED(retval))
01482 {
01483
01484 if (SQLITE_OK != append_string(path, values[2]) ||
01485 SQLITE_OK != append_string(path, "/"))
01486 {
01487 retval = GAT_MEMORYFAILURE;
01488 }
01489 }
01490 }
01491
01492
01493 sqlite_free_table(values);
01494 }
01495 return retval;
01496 }