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
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