• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List

opensync/opensync_hashtable.c

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 

Generated on Fri Sep 17 2010 for OpenSync by  doxygen 1.7.1