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 00033 00034 static void osync_hashtable_assert_loaded(OSyncHashTable *table) 00035 { 00036 osync_assert_msg(table, "You have to pass a valid hashtable to the call!"); 00037 osync_assert_msg(table->dbhandle, "Hashtable not loaded yet. You have to load the hashtable first using osync_hashtable_load!"); 00038 } 00039 00084 00093 OSyncHashTable *osync_hashtable_new(void) 00094 { 00095 OSyncHashTable *table = g_malloc0(sizeof(OSyncHashTable)); 00096 g_assert(table); 00097 table->used_entries = g_hash_table_new(g_str_hash, g_str_equal); 00098 return table; 00099 } 00100 00107 void osync_hashtable_free(OSyncHashTable *table) 00108 { 00109 g_hash_table_destroy(table->used_entries); 00110 g_free(table); 00111 } 00112 00124 void osync_hashtable_forget(OSyncHashTable *table) 00125 { 00126 g_hash_table_destroy(table->used_entries); 00127 table->used_entries = g_hash_table_new(g_str_hash, g_str_equal); 00128 } 00129 00138 osync_bool osync_hashtable_load(OSyncHashTable *table, OSyncMember *member, OSyncError **error) 00139 { 00140 return osync_db_open_hashtable(table, member, error); 00141 } 00142 00150 void osync_hashtable_close(OSyncHashTable *table) 00151 { 00152 osync_hashtable_assert_loaded(table); 00153 00154 osync_hashtable_forget(table); 00155 osync_db_close(table->dbhandle); 00156 } 00157 00164 int osync_hashtable_num_entries(OSyncHashTable *table) 00165 { 00166 osync_hashtable_assert_loaded(table); 00167 00168 return osync_db_count(table->dbhandle, "SELECT count(*) FROM tbl_hash"); 00169 } 00170 00182 osync_bool osync_hashtable_nth_entry(OSyncHashTable *table, int i, char **uid, char **hash) 00183 { 00184 osync_hashtable_assert_loaded(table); 00185 00186 sqlite3 *sdb = table->dbhandle->db; 00187 00188 sqlite3_stmt *ppStmt = NULL; 00189 char *query = g_strdup_printf("SELECT uid, hash FROM tbl_hash LIMIT 1 OFFSET %i", i); 00190 sqlite3_prepare(sdb, query, -1, &ppStmt, NULL); 00191 sqlite3_step(ppStmt); 00192 *uid = g_strdup((gchar*)sqlite3_column_text(ppStmt, 0)); 00193 *hash = g_strdup((gchar*)sqlite3_column_text(ppStmt, 1)); 00194 sqlite3_finalize(ppStmt); 00195 g_free(query); 00196 return TRUE; 00197 } 00198 00208 void osync_hashtable_update_hash(OSyncHashTable *table, OSyncChange *change) 00209 { 00210 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, table, change); 00211 osync_hashtable_assert_loaded(table); 00212 osync_assert_msg(change, "Change was NULL. Bug in a plugin"); 00213 osync_assert_msg(change->uid, "No uid was set on change. Bug in a plugin"); 00214 00215 osync_trace(TRACE_INTERNAL, "Updating hashtable with hash \"%s\" and changetype %i", 00216 change->hash, osync_change_get_changetype(change)); 00217 00218 switch (osync_change_get_changetype(change)) { 00219 case CHANGE_MODIFIED: 00220 case CHANGE_ADDED: 00221 osync_db_save_hash(table, change->uid, change->hash, 00222 osync_change_get_objtype(change) ? osync_change_get_objtype(change)->name : NULL); 00223 break; 00224 case CHANGE_DELETED: 00225 osync_db_delete_hash(table, change->uid); 00226 break; 00227 default: 00228 g_assert_not_reached(); 00229 } 00230 00231 osync_trace(TRACE_EXIT, "%s", __func__); 00232 } 00233 00244 void osync_hashtable_report(OSyncHashTable *table, const char *uid) 00245 { 00246 osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, table, uid); 00247 osync_hashtable_assert_loaded(table); 00248 00249 g_hash_table_insert(table->used_entries, g_strdup(uid), GINT_TO_POINTER(1)); 00250 00251 osync_trace(TRACE_EXIT, "%s", __func__); 00252 } 00253 00261 void osync_hashtable_report_deleted(OSyncHashTable *table, OSyncContext *context, const char *objtype) 00262 { 00263 osync_trace(TRACE_ENTRY, "%s(%p, %p, %s)", __func__, table, context, objtype); 00264 osync_hashtable_assert_loaded(table); 00265 00266 char **uidarr = osync_db_get_deleted_hash(table, objtype); 00267 int i = 0; 00268 for (i = 0; uidarr[i]; i++) { 00269 char *uid = uidarr[i]; 00270 OSyncChange *change = osync_change_new(); 00271 change->changetype = CHANGE_DELETED; 00272 osync_change_set_objtype_string(change, objtype); 00273 osync_change_set_uid(change, uid); 00274 osync_context_report_change(context, change); 00275 osync_hashtable_update_hash(table, change); 00276 g_free(uid); 00277 } 00278 g_free(uidarr); 00279 00280 osync_trace(TRACE_EXIT, "%s", __func__); 00281 } 00282 00290 char **osync_hashtable_get_deleted(OSyncHashTable *table, const char *objtype) 00291 { 00292 osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, table, objtype); 00293 osync_hashtable_assert_loaded(table); 00294 00295 char **retarr = osync_db_get_deleted_hash(table, objtype); 00296 osync_trace(TRACE_EXIT, "%s: %p", __func__, retarr); 00297 return retarr; 00298 } 00299 00303 void osync_hashtable_get_hash(OSyncHashTable *table, OSyncChange *chg) 00304 { 00305 char *orighash = NULL; 00306 osync_db_get_hash(table, chg->uid, osync_change_get_objtype(chg)->name, &orighash); 00307 osync_change_set_hash(chg, orighash); 00308 g_free(orighash); 00309 } 00310 00323 OSyncChangeType osync_hashtable_get_changetype(OSyncHashTable *table, const char *uid, const char *objtype, const char *hash) 00324 { 00325 osync_trace(TRACE_ENTRY, "%s(%p, %s, %s, %s)", __func__, table, uid, objtype, hash); 00326 osync_hashtable_assert_loaded(table); 00327 OSyncChangeType retval = CHANGE_UNMODIFIED; 00328 00329 char *orighash = NULL; 00330 osync_db_get_hash(table, uid, objtype, &orighash); 00331 osync_trace(TRACE_INTERNAL, "Comparing %s with %s", hash, orighash); 00332 00333 if (orighash) { 00334 if (strcmp(hash, orighash) == 0) 00335 retval = CHANGE_UNMODIFIED; 00336 else 00337 retval = CHANGE_MODIFIED; 00338 } else 00339 retval = CHANGE_ADDED; 00340 00341 osync_trace(TRACE_EXIT, "%s: %s", __func__, retval ? "TRUE" : "FALSE"); 00342 return retval; 00343 } 00344 00354 osync_bool osync_hashtable_detect_change(OSyncHashTable *table, OSyncChange *change) 00355 { 00356 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, table, change); 00357 osync_bool retval = FALSE; 00358 00359 change->changetype = osync_hashtable_get_changetype(table, change->uid, osync_objtype_get_name(osync_change_get_objtype(change)), change->hash); 00360 if (change->changetype != CHANGE_UNMODIFIED) 00361 retval = TRUE; 00362 00363 g_hash_table_insert(table->used_entries, g_strdup(change->uid), GINT_TO_POINTER(1)); 00364 osync_trace(TRACE_EXIT, "%s: %s", __func__, retval ? "TRUE" : "FALSE"); 00365 return retval; 00366 } 00367 00373 void osync_hashtable_set_slow_sync(OSyncHashTable *table, const char *objtype) 00374 { 00375 osync_hashtable_assert_loaded(table); 00376 00377 osync_db_reset_hash(table, objtype); 00378 } 00379