OpenSync
0.22
|
00001 /* 00002 * libopensync - A synchronization framework 00003 * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 //error_free: 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; //FIXME 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