00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "opensync.h"
00022 #include "opensync_internals.h"
00023
00024 void osync_db_trace(void *data, const char *query)
00025 {
00026 osync_trace(TRACE_INTERNAL, "query executed: %s", query);
00027 }
00028
00029 OSyncDB *osync_db_open(char *filename, OSyncError **error)
00030 {
00031 osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, filename, error);
00032
00033 OSyncDB *db = osync_try_malloc0(sizeof(OSyncDB), error);
00034 if (!db)
00035 goto error;
00036
00037 int rc = sqlite3_open(filename, &(db->db));
00038 if (rc) {
00039 osync_error_set(error, OSYNC_ERROR_GENERIC, "Cannot open database: %s", sqlite3_errmsg(db->db));
00040 goto error_close;
00041 }
00042 sqlite3_trace(db->db, osync_db_trace, NULL);
00043
00044 osync_trace(TRACE_EXIT, "%s: %p", __func__, db);
00045 return db;
00046
00047 error_close:
00048 osync_db_close(db);
00049
00050 g_free(db);
00051 error:
00052 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00053 return NULL;
00054 }
00055
00056 void osync_db_close(OSyncDB *db)
00057 {
00058 osync_trace(TRACE_ENTRY, "%s(%p)", __func__, db);
00059
00060 int ret = sqlite3_close(db->db);
00061 if (ret != SQLITE_OK)
00062 osync_trace(TRACE_INTERNAL, "Can't close database: %s", sqlite3_errmsg(db->db));
00063
00064 osync_trace(TRACE_EXIT, "%s", __func__);
00065 }
00066
00067 int osync_db_count(OSyncDB *db, char *query)
00068 {
00069 int ret = 0;
00070
00071 sqlite3_stmt *ppStmt = NULL;
00072 if (sqlite3_prepare(db->db, query, -1, &ppStmt, NULL) != SQLITE_OK)
00073 osync_debug("OSDB", 3, "Unable prepare count! %s", sqlite3_errmsg(db->db));
00074 ret = sqlite3_step(ppStmt);
00075 if (ret != SQLITE_DONE && ret != SQLITE_ROW)
00076 osync_debug("OSDB", 3, "Unable step count! %s", sqlite3_errmsg(db->db));
00077 if (ret == SQLITE_DONE)
00078 osync_debug("OSDB", 3, "No row found!");
00079 ret = sqlite3_column_int64(ppStmt, 0);
00080 sqlite3_finalize(ppStmt);
00081 return ret;
00082 }
00083
00084 OSyncDB *_open_changelog(OSyncGroup *group, OSyncError **error)
00085 {
00086 g_assert(group);
00087 OSyncDB *log_db;
00088
00089 char *filename = g_strdup_printf("%s/changelog.db", group->configdir);
00090 if (!(log_db = osync_db_open(filename, error))) {
00091 osync_error_update(error, "Unable to load changelog: %s", osync_error_print(error));
00092 g_free(filename);
00093 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00094 return NULL;
00095 }
00096 osync_debug("OSDB", 3, "Preparing to changelog from file %s", filename);
00097 g_free(filename);
00098
00099 sqlite3 *sdb = log_db->db;
00100
00101 if (sqlite3_exec(sdb, "CREATE TABLE tbl_log (uid VARCHAR, objtype VARCHAR, memberid INTEGER, changetype INTEGER)", NULL, NULL, NULL) != SQLITE_OK)
00102 osync_debug("OSDB", 2, "Unable create log table! %s", sqlite3_errmsg(sdb));
00103 return log_db;
00104 }
00105
00106 osync_bool osync_db_open_changelog(OSyncGroup *group, char ***uids, char ***objtype, long long int **memberids, int **changetypes, OSyncError **error)
00107 {
00108 osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, group, uids, changetypes, error);
00109
00110 OSyncDB *log_db = _open_changelog(group, error);
00111 if (!log_db) {
00112 goto error;
00113 }
00114 sqlite3 *sdb = log_db->db;
00115
00116 int count = osync_db_count(log_db, "SELECT count(*) FROM tbl_log");
00117
00118 *uids = g_malloc0(sizeof(char *) * (count + 1));
00119 *objtype = g_malloc0(sizeof(char *) * (count + 1));
00120 *memberids = g_malloc0(sizeof(long long int) * (count + 1));
00121 *changetypes = g_malloc0(sizeof(int) * (count + 1));
00122
00123 sqlite3_stmt *ppStmt = NULL;
00124 sqlite3_prepare(sdb, "SELECT uid, objtype, memberid, changetype FROM tbl_log", -1, &ppStmt, NULL);
00125 int i = 0;
00126 while (sqlite3_step(ppStmt) == SQLITE_ROW) {
00127 (*uids)[i] = g_strdup((gchar*)sqlite3_column_text(ppStmt, 0));
00128 (*objtype)[i] = g_strdup((gchar*)sqlite3_column_text(ppStmt, 1));
00129 (*memberids)[i] = sqlite3_column_int64(ppStmt, 2);
00130 (*changetypes)[i] = sqlite3_column_int(ppStmt, 3);
00131 i++;
00132 }
00133 (*uids)[i] = NULL;
00134 (*objtype)[i] = NULL;
00135 (*memberids)[i] = 0;
00136 (*changetypes)[i] = 0;
00137 sqlite3_finalize(ppStmt);
00138
00139 char *query = g_strdup_printf("DELETE FROM tbl_log");
00140 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00141 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to remove all logs! %s", sqlite3_errmsg(sdb));
00142 g_free(query);
00143 goto error_db_close;
00144 }
00145 g_free(query);
00146
00147 osync_db_close(log_db);
00148 osync_trace(TRACE_EXIT, "%s", __func__);
00149 return TRUE;
00150
00151 error_db_close:
00152 osync_db_close(log_db);
00153
00154 error:
00155 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00156 return FALSE;
00157 }
00158
00159 osync_bool osync_db_save_changelog(OSyncGroup *group, OSyncChange *change, OSyncError **error)
00160 {
00161 osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, group, change, error);
00162
00163 OSyncDB *log_db = _open_changelog(group, error);
00164 if (!log_db) {
00165 goto error;
00166 }
00167 sqlite3 *sdb = log_db->db;
00168
00169 char *escaped_uid = osync_db_sql_escape(change->uid);
00170 char *query = g_strdup_printf("INSERT INTO tbl_log (uid, objtype, memberid, changetype) VALUES('%s', '%s', '%lli', '%i')", escaped_uid, osync_change_get_objtype(change)->name, change->member->id, change->changetype);
00171 g_free(escaped_uid);
00172
00173 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00174 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to insert log! %s", sqlite3_errmsg(sdb));
00175 g_free(query);
00176 goto error_db_close;
00177 }
00178 g_free(query);
00179
00180 osync_db_close(log_db);
00181 osync_trace(TRACE_EXIT, "%s", __func__);
00182 return TRUE;
00183
00184 error_db_close:
00185 osync_db_close(log_db);
00186
00187 error:
00188 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00189 return FALSE;
00190
00191 }
00192
00193 osync_bool osync_db_remove_changelog(OSyncGroup *group, OSyncChange *change, OSyncError **error)
00194 {
00195 osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, group, change, error);
00196
00197 OSyncDB *log_db = _open_changelog(group, error);
00198 if (!log_db) {
00199 goto error;
00200 }
00201 sqlite3 *sdb = log_db->db;
00202
00203 char *escaped_uid = osync_db_sql_escape(change->uid);
00204 char *query = g_strdup_printf("DELETE FROM tbl_log WHERE uid='%s' AND memberid='%lli' AND objtype='%s'",
00205 escaped_uid, change->member->id, osync_change_get_objtype(change)->name);
00206 g_free(escaped_uid);
00207
00208 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00209 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to remove log! %s", sqlite3_errmsg(sdb));
00210 g_free(query);
00211 goto error_db_close;
00212 }
00213 g_free(query);
00214
00215 osync_db_close(log_db);
00216 osync_trace(TRACE_EXIT, "%s", __func__);
00217 return TRUE;
00218
00219 error_db_close:
00220 osync_db_close(log_db);
00221
00222 error:
00223 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00224 return FALSE;
00225 }
00226
00227 osync_bool osync_db_open_changes(OSyncGroup *group, OSyncChange ***changes, OSyncError **error)
00228 {
00229 osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, group, changes, error);
00230 g_assert(group);
00231
00232 group->changes_path = g_strdup(group->configdir);
00233 char *filename = g_strdup_printf("%s/change.db", group->changes_path);
00234 if (!(group->changes_db = osync_db_open(filename, error))) {
00235 osync_error_update(error, "Unable to load changes: %s", osync_error_print(error));
00236 goto error;
00237 }
00238 osync_debug("OSDB", 3, "Preparing to load changes from file %s", filename);
00239 g_free(filename);
00240
00241 sqlite3 *sdb = group->changes_db->db;
00242
00243 if (sqlite3_exec(sdb, "CREATE TABLE tbl_changes (id INTEGER PRIMARY KEY, uid VARCHAR, objtype VARCHAR, format VARCHAR, memberid INTEGER, mappingid INTEGER)", NULL, NULL, NULL) != SQLITE_OK)
00244 osync_debug("OSDB", 2, "Unable create changes table! %s", sqlite3_errmsg(sdb));
00245
00246 int count = osync_db_count(group->changes_db, "SELECT count(*) FROM tbl_changes");
00247 *changes = g_malloc0(sizeof(OSyncChange *) * (count + 1));
00248
00249 sqlite3_stmt *ppStmt = NULL;
00250 sqlite3_prepare(sdb, "SELECT id, uid, objtype, format, memberid, mappingid FROM tbl_changes ORDER BY mappingid", -1, &ppStmt, NULL);
00251 int i = 0;
00252 while (sqlite3_step(ppStmt) == SQLITE_ROW) {
00253 OSyncChange *change = osync_change_new();
00254 change->id = sqlite3_column_int64(ppStmt, 0);
00255 change->uid = g_strdup((gchar*)sqlite3_column_text(ppStmt, 1));
00256 change->objtype_name = g_strdup((gchar*)sqlite3_column_text(ppStmt, 2));
00257 change->format_name = g_strdup((gchar*)sqlite3_column_text(ppStmt, 3));
00258 change->initial_format_name = g_strdup(change->format_name);
00259 change->mappingid = sqlite3_column_int64(ppStmt, 5);
00260 long long int memberid = sqlite3_column_int64(ppStmt, 4);
00261 change->changes_db = group->changes_db;
00262 osync_change_set_member(change, osync_member_from_id(group, memberid));
00263 osync_trace(TRACE_INTERNAL, "Loaded change with uid %s, changetype %i, data %p, size %i, objtype %s and format %s from member %lli", osync_change_get_uid(change), osync_change_get_changetype(change), osync_change_get_data(change), osync_change_get_datasize(change), osync_change_get_objtype(change) ? osync_objtype_get_name(osync_change_get_objtype(change)) : "None", osync_change_get_objformat(change) ? osync_objformat_get_name(osync_change_get_objformat(change)) : "None", memberid);
00264 (*changes)[i] = change;
00265 i++;
00266 }
00267 (*changes)[i] = NULL;
00268 sqlite3_finalize(ppStmt);
00269
00270 osync_trace(TRACE_EXIT, "%s", __func__);
00271 return TRUE;
00272
00273 error:
00274 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00275 return FALSE;
00276 }
00277
00278 osync_bool osync_db_save_change(OSyncChange *change, osync_bool save_format, OSyncError **error)
00279 {
00280 osync_trace(TRACE_ENTRY, "%s(%p, %i, %p) (Table: %p)", __func__, change, save_format, error, change->changes_db);
00281 osync_assert_msg(change, "Need to set change");
00282 osync_assert_msg(osync_change_get_objtype(change), "change->objtype was NULL while saving");
00283 osync_assert_msg(osync_change_get_objformat(change), "change->objformat was NULL while saving");
00284
00285 if (!change || !change->changes_db) {
00286 osync_error_set(error, OSYNC_ERROR_PARAMETER, "osync_db_save_change was called with wrong parameters");
00287 goto error;
00288 }
00289 sqlite3 *sdb = change->changes_db->db;
00290
00291 char *query = NULL;
00292 if (!change->id) {
00293 char *escaped_uid = osync_db_sql_escape(change->uid);
00294 query = g_strdup_printf("INSERT INTO tbl_changes (uid, objtype, format, memberid, mappingid) VALUES('%s', '%s', '%s', '%lli', '%lli')", escaped_uid, osync_change_get_objtype(change)->name, osync_change_get_objformat(change)->name, change->member->id, change->mappingid);
00295 g_free(escaped_uid);
00296
00297 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00298 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to insert change! %s", sqlite3_errmsg(sdb));
00299 g_free(query);
00300 goto error;
00301 }
00302 change->id = sqlite3_last_insert_rowid(sdb);
00303 } else {
00304 char *escaped_uid = osync_db_sql_escape(change->uid);
00305 if (save_format)
00306 query = g_strdup_printf("UPDATE tbl_changes SET uid='%s', objtype='%s', format='%s', memberid='%lli', mappingid='%lli' WHERE id=%lli", escaped_uid, osync_change_get_objtype(change)->name, osync_change_get_objformat(change)->name, change->member->id, change->mappingid, change->id);
00307 else
00308 query = g_strdup_printf("UPDATE tbl_changes SET uid='%s', memberid='%lli', mappingid='%lli' WHERE id=%lli", escaped_uid, change->member->id, change->mappingid, change->id);
00309 g_free(escaped_uid);
00310
00311 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00312 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to update change! %s", sqlite3_errmsg(sdb));
00313 g_free(query);
00314 goto error;
00315 }
00316 }
00317 g_free(query);
00318 osync_trace(TRACE_EXIT, "%s", __func__);
00319 return TRUE;
00320
00321 error:
00322 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00323 return FALSE;
00324
00325 }
00326
00327 osync_bool osync_db_delete_change(OSyncChange *change, OSyncError **error)
00328 {
00329 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error);
00330
00331 if (!change || !change->changes_db) {
00332 osync_error_set(error, OSYNC_ERROR_PARAMETER, "osync_db_delete_change was called with wrong parameters");
00333 goto error;
00334 }
00335 sqlite3 *sdb = change->changes_db->db;
00336
00337 char *query = g_strdup_printf("DELETE FROM tbl_changes WHERE id=%lli", change->id);
00338 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00339 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to delete change! %s", sqlite3_errmsg(sdb));
00340 g_free(query);
00341 goto error;
00342 }
00343 g_free(query);
00344 osync_trace(TRACE_EXIT, "%s", __func__);
00345 return TRUE;
00346
00347 error:
00348 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00349 return FALSE;
00350 }
00351
00352 osync_bool osync_db_reset_changes(OSyncGroup *group, const char *objtype, OSyncError **error)
00353 {
00354 osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, group, objtype, error);
00355
00356 if (!group || !objtype) {
00357 osync_error_set(error, OSYNC_ERROR_PARAMETER, "osync_db_reset_changes was called with wrong parameters");
00358 goto error;
00359 }
00360 sqlite3 *sdb = group->changes_db->db;
00361
00362 char *query = NULL;
00363 if (osync_conv_objtype_is_any(objtype)) {
00364 query = g_strdup_printf("DELETE FROM tbl_changes");
00365 } else {
00366 query = g_strdup_printf("DELETE FROM tbl_changes WHERE objtype='%s'", objtype);
00367 }
00368
00369 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK) {
00370 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to reset changes! %s", sqlite3_errmsg(sdb));
00371 g_free(query);
00372 goto error;
00373 }
00374
00375 g_free(query);
00376 osync_trace(TRACE_EXIT, "%s", __func__);
00377 return TRUE;
00378
00379 error:
00380 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00381 return FALSE;
00382
00383 }
00384
00385 osync_bool osync_db_reset_group(OSyncGroup *group, OSyncError **error)
00386 {
00387 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, group, error);
00388 OSyncDB *db = NULL;
00389
00390 if (!group) {
00391 osync_error_set(error, OSYNC_ERROR_PARAMETER, "osync_db_reset_group was called with wrong parameters");
00392 goto error;
00393 }
00394
00395 char *changesdb = g_strdup_printf("%s/change.db", group->configdir);
00396 if (!(db = osync_db_open(changesdb, error))) {
00397 g_free(changesdb);
00398 goto error;
00399 }
00400
00401 if (sqlite3_exec(db->db, "DELETE FROM tbl_changes", NULL, NULL, NULL) != SQLITE_OK) {
00402 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to reset changes! %s", sqlite3_errmsg(db->db));
00403 g_free(changesdb);
00404 goto error_db_close;
00405 }
00406
00407 osync_db_close(db);
00408 g_free(changesdb);
00409
00410 osync_trace(TRACE_EXIT, "%s", __func__);
00411 return TRUE;
00412
00413 error_db_close:
00414 osync_db_close(db);
00415
00416 error:
00417 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00418 return FALSE;
00419 }
00420
00421 osync_bool osync_db_reset_member(OSyncMember *member, OSyncError **error)
00422 {
00423 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, member, error);
00424 OSyncDB *db = NULL;
00425
00426 if (!member) {
00427 osync_error_set(error, OSYNC_ERROR_PARAMETER, "osync_db_reset_member was called with wrong parameters");
00428 goto error;
00429 }
00430
00431 char *hashtable = g_strdup_printf("%s/hash.db", member->configdir);
00432 if (g_file_test(hashtable, G_FILE_TEST_EXISTS)) {
00433 if (!(db = osync_db_open(hashtable, error))) {
00434 g_free(hashtable);
00435 goto error;
00436 }
00437
00438 if (sqlite3_exec(db->db, "DELETE FROM tbl_hash", NULL, NULL, NULL) != SQLITE_OK) {
00439 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to reset hashtable! %s", sqlite3_errmsg(db->db));
00440 g_free(hashtable);
00441 goto error_db_close;
00442 }
00443
00444 osync_db_close(db);
00445 }
00446 g_free(hashtable);
00447
00448 char *anchordb = g_strdup_printf("%s/anchor.db", member->configdir);
00449 if (g_file_test(anchordb, G_FILE_TEST_EXISTS)) {
00450 if (!(db = osync_db_open(anchordb, error))) {
00451 g_free(anchordb);
00452 goto error;
00453 }
00454
00455 if (sqlite3_exec(db->db, "DELETE FROM tbl_anchor", NULL, NULL, NULL) != SQLITE_OK) {
00456 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to reset anchors! %s", sqlite3_errmsg(db->db));
00457 g_free(anchordb);
00458 goto error_db_close;
00459 }
00460
00461 osync_db_close(db);
00462 }
00463 g_free(anchordb);
00464
00465 osync_trace(TRACE_EXIT, "%s", __func__);
00466 return TRUE;
00467
00468 error_db_close:
00469 osync_db_close(db);
00470
00471 error:
00472 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00473 return FALSE;
00474
00475 }
00476
00477 void osync_db_close_changes(OSyncGroup *group)
00478 {
00479 if (group->changes_db)
00480 osync_db_close(group->changes_db);
00481 }
00482
00483 OSyncDB *osync_db_open_anchor(OSyncMember *member, OSyncError **error)
00484 {
00485 g_assert(member);
00486 OSyncDB *sdb = NULL;
00487 char *filename = g_strdup_printf ("%s/anchor.db", member->configdir);
00488 if (!(sdb = osync_db_open(filename, error))) {
00489 g_free(filename);
00490 osync_error_update(error, "Unable to open anchor table: %s", (*error)->message);
00491 return NULL;
00492 }
00493 g_free(filename);
00494
00495 if (sqlite3_exec(sdb->db, "CREATE TABLE tbl_anchor (id INTEGER PRIMARY KEY, anchor VARCHAR, objtype VARCHAR UNIQUE)", NULL, NULL, NULL) != SQLITE_OK)
00496 osync_debug("OSDB", 3, "Unable create anchor table! %s", sqlite3_errmsg(sdb->db));
00497
00498 return sdb;
00499 }
00500
00501 void osync_db_close_anchor(OSyncDB *db)
00502 {
00503 osync_db_close(db);
00504 }
00505
00506 void osync_db_get_anchor(OSyncDB *sdb, const char *objtype, char **retanchor)
00507 {
00508 sqlite3_stmt *ppStmt = NULL;
00509 char *query = g_strdup_printf("SELECT anchor FROM tbl_anchor WHERE objtype='%s'", objtype);
00510 if (sqlite3_prepare(sdb->db, query, -1, &ppStmt, NULL) != SQLITE_OK)
00511 osync_debug("OSDB", 3, "Unable prepare anchor! %s", sqlite3_errmsg(sdb->db));
00512 int ret = sqlite3_step(ppStmt);
00513 if (ret != SQLITE_DONE && ret != SQLITE_ROW)
00514 osync_debug("OSDB", 3, "Unable step count! %s", sqlite3_errmsg(sdb->db));
00515 if (ret == SQLITE_DONE)
00516 osync_debug("OSDB", 3, "No row found!");
00517 *retanchor = g_strdup((gchar*)sqlite3_column_text(ppStmt, 0));
00518 sqlite3_finalize(ppStmt);
00519 g_free(query);
00520 }
00521
00522 void osync_db_put_anchor(OSyncDB *sdb, const char *objtype, const char *anchor)
00523 {
00524 char *escaped_anchor = osync_db_sql_escape(anchor);
00525 char *query = g_strdup_printf("REPLACE INTO tbl_anchor (objtype, anchor) VALUES('%s', '%s')", objtype, escaped_anchor);
00526 g_free(escaped_anchor);
00527
00528 if (sqlite3_exec(sdb->db, query, NULL, NULL, NULL) != SQLITE_OK)
00529 osync_debug("OSDB", 1, "Unable put anchor! %s", sqlite3_errmsg(sdb->db));
00530
00531 g_free(query);
00532 }
00533
00534
00535 osync_bool osync_db_open_hashtable(OSyncHashTable *table, OSyncMember *member, OSyncError **error)
00536 {
00537 g_assert(member);
00538 char *filename = g_strdup_printf ("%s/hash.db", member->configdir);
00539 if (!(table->dbhandle = osync_db_open(filename, error))) {
00540 g_free(filename);
00541 osync_error_update(error, "Unable to open hashtable: %s", (*error)->message);
00542 return FALSE;
00543 }
00544 g_free(filename);
00545
00546 sqlite3 *db = table->dbhandle->db;
00547
00548 if (sqlite3_exec(db, "CREATE TABLE tbl_hash (id INTEGER PRIMARY KEY, uid VARCHAR, hash VARCHAR, objtype VARCHAR)", NULL, NULL, NULL) != SQLITE_OK)
00549 osync_debug("OSDB", 3, "Unable create hash table! %s", sqlite3_errmsg(db));
00550
00551 return TRUE;
00552 }
00553
00554 void osync_db_close_hashtable(OSyncHashTable *table)
00555 {
00556 osync_db_close(table->dbhandle);
00557 }
00558
00559 int exists_hashtable_id(OSyncHashTable *table, const char *uid, const char *objtype)
00560 {
00561 g_assert(table->dbhandle);
00562 sqlite3 *sdb = table->dbhandle->db;
00563
00564 int id = -1;
00565
00566 char *exist = g_strdup_printf("SELECT id FROM tbl_hash WHERE uid='%s' AND objtype='%s'",uid, objtype);
00567
00568 sqlite3_stmt *ppStmt = NULL;
00569 if (sqlite3_prepare(sdb, exist, -1, &ppStmt, NULL) != SQLITE_OK)
00570 {
00571 osync_debug("OSDB", 3, "Unable prepare get id! %s", sqlite3_errmsg(sdb));
00572 return (id);
00573 }
00574 int ret = sqlite3_step(ppStmt);
00575 if (ret != SQLITE_DONE && ret != SQLITE_ROW)
00576 return (id);
00577 if (ret == SQLITE_DONE)
00578 return (id);
00579
00580 id = sqlite3_column_int64(ppStmt, 0);
00581 sqlite3_finalize(ppStmt);
00582 g_free(exist);
00583
00584 return(id);
00585 }
00586
00587 void osync_db_save_hash(OSyncHashTable *table, const char *uid, const char *hash, const char *objtype)
00588 {
00589 g_assert(table->dbhandle);
00590 sqlite3 *sdb = table->dbhandle->db;
00591
00592 char *escaped_uid = osync_db_sql_escape(uid);
00593 char *escaped_hash = osync_db_sql_escape(hash);
00594 char *escaped_objtype = osync_db_sql_escape(objtype);
00595 int id = exists_hashtable_id(table, escaped_uid, escaped_objtype);
00596 char *query = NULL;
00597 if(id < 0){
00598 query = g_strdup_printf(
00599 "REPLACE INTO tbl_hash ('uid', 'hash', 'objtype') VALUES('%s', '%s', '%s')",
00600 escaped_uid, escaped_hash, escaped_objtype);
00601 }else{
00602 query = g_strdup_printf(
00603 "REPLACE INTO tbl_hash ('id', 'uid', 'hash', 'objtype') VALUES('%i', '%s', '%s', '%s')",
00604 id, escaped_uid, escaped_hash, escaped_objtype);
00605 }
00606
00607 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK)
00608 osync_debug("OSDB", 1, "Unable to insert hash! uid = %s, hash = %s, error = %s", escaped_uid, escaped_hash, sqlite3_errmsg(sdb));
00609
00610 g_free(escaped_uid);
00611 g_free(escaped_hash);
00612 g_free(escaped_objtype);
00613 g_free(query);
00614 }
00615
00616
00617 void osync_db_delete_hash(OSyncHashTable *table, const char *uid)
00618 {
00619 g_assert(table->dbhandle);
00620 sqlite3 *sdb = table->dbhandle->db;
00621
00622 char *escaped_uid = osync_db_sql_escape(uid);
00623 char *query = g_strdup_printf("DELETE FROM tbl_hash WHERE uid='%s'", escaped_uid);
00624 g_free(escaped_uid);
00625
00626 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK)
00627 osync_debug("OSDB", 1, "Unable to delete hash! %s", sqlite3_errmsg(sdb));
00628 g_free(query);
00629 }
00630
00631 char **osync_db_get_deleted_hash(OSyncHashTable *table, const char *objtype)
00632 {
00633 g_assert(table->dbhandle);
00634 sqlite3 *sdb = table->dbhandle->db;
00635
00636 char **azResult = NULL;
00637 int numrows = 0;
00638 char *query = NULL;
00639
00640 if (osync_conv_objtype_is_any(objtype)) {
00641 query = g_strdup_printf("SELECT uid, hash FROM tbl_hash");
00642 } else {
00643 query = g_strdup_printf("SELECT uid, hash FROM tbl_hash WHERE objtype='%s'", objtype);
00644 }
00645 sqlite3_get_table(sdb, query, &azResult, &numrows, NULL, NULL);
00646 g_free(query);
00647
00648 char **ret = g_malloc0((numrows + 1) * sizeof(char *));
00649
00650 int i;
00651 int ccell = 2;
00652 int num = 0;
00653 for (i = 0; i < numrows; i++) {
00654 char *uid = azResult[ccell];
00655 ccell += 2;
00656
00657 if (!g_hash_table_lookup(table->used_entries, uid)) {
00658 ret[num] = g_strdup(uid);
00659 num++;
00660 }
00661 }
00662 sqlite3_free_table(azResult);
00663 return ret;
00664 }
00665
00666 void osync_db_get_hash(OSyncHashTable *table, const char *uid, const char *objtype, char **rethash)
00667 {
00668 sqlite3 *sdb = table->dbhandle->db;
00669 sqlite3_stmt *ppStmt = NULL;
00670 char *escaped_uid = osync_db_sql_escape(uid);
00671 char *escaped_objtype = osync_db_sql_escape(objtype);
00672 char *query = g_strdup_printf("SELECT hash FROM tbl_hash WHERE uid='%s' AND objtype='%s'", escaped_uid, escaped_objtype);
00673 g_free(escaped_uid);
00674 g_free(escaped_objtype);
00675
00676 if (sqlite3_prepare(sdb, query, -1, &ppStmt, NULL) != SQLITE_OK)
00677 osync_debug("OSDB", 3, "Unable prepare get hash! %s", sqlite3_errmsg(sdb));
00678 int ret = sqlite3_step(ppStmt);
00679 if (ret != SQLITE_DONE && ret != SQLITE_ROW)
00680 osync_debug("OSDB", 3, "Unable step get hash! %s", sqlite3_errmsg(sdb));
00681 if (ret == SQLITE_DONE)
00682 osync_debug("OSDB", 3, "No row found!");
00683 *rethash = g_strdup((gchar*)sqlite3_column_text(ppStmt, 0));
00684 sqlite3_finalize(ppStmt);
00685 g_free(query);
00686 }
00687
00688 void osync_db_reset_hash(OSyncHashTable *table, const char *objtype)
00689 {
00690 sqlite3 *sdb = table->dbhandle->db;
00691 char *query = NULL;
00692 if (osync_conv_objtype_is_any(objtype)) {
00693 query = g_strdup_printf("DELETE FROM tbl_hash");
00694 } else {
00695 query = g_strdup_printf("DELETE FROM tbl_hash WHERE objtype='%s'", objtype);
00696 }
00697 if (sqlite3_exec(sdb, query, NULL, NULL, NULL) != SQLITE_OK)
00698 osync_debug("OSDB", 1, "Unable to reset hash! %s", sqlite3_errmsg(sdb));
00699 g_free(query);
00700 }
00701
00702 char *osync_db_sql_escape(const char *s)
00703 {
00704 return osync_strreplace(s, "'", "''");
00705 }
00706