From: <dg...@su...> - 2009-01-23 10:29:28
|
Author: dgollub Date: Fri Jan 23 11:28:04 2009 New Revision: 5222 URL: http://www.opensync.org/changeset/5222 Log: Change mapping-table layout, by adding a column "objengine", which stores the name of the objengine which wrote the change. Note the difference between "objtype" and "objengine". "objtype" stores the objtype-name of the change which got written. "objengine" stores the objtype-name of the Object Engine which wrote the change. This is required due to mixed-objtype syncing, which is limited to encapuslated formats. This chance requires to drop the mapping-table. (TODO: implement table-drop function) To reuse existing groups: osyncdump $gorup --reset rm ~/.opensync/groupX/archive.db Introduced osync_engine_slowsync_for_mixed_objengines() which propagtes slow-sync to all mixed-synced object engines if required. This is done after all plugins completed connect_done(). Modified: trunk/opensync/archive/opensync_archive.c trunk/opensync/archive/opensync_archive_internals.h trunk/opensync/engine/opensync_engine.c trunk/opensync/engine/opensync_engine_internals.h trunk/opensync/engine/opensync_obj_engine.c trunk/opensync/engine/opensync_sink_engine.c trunk/tests/archive-tests/check_archive.c Modified: trunk/opensync/archive/opensync_archive.c ============================================================================== --- trunk/opensync/archive/opensync_archive.c Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/archive/opensync_archive.c Fri Jan 23 11:28:04 2009 (r5222) @@ -59,7 +59,7 @@ * enforce the entity-relationship model all queries for a single item should be: * WHERE objtype='%s' AND id=%lli */ - query = "CREATE TABLE tbl_changes (objtype VARCHAR(64) NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT, uid VARCHAR NOT NULL, memberid INTEGER NOT NULL, mappingid INTEGER NOT NULL )"; + query = "CREATE TABLE tbl_changes (objtype VARCHAR(64) NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT, uid VARCHAR NOT NULL, memberid INTEGER NOT NULL, mappingid INTEGER NOT NULL, objengine VARCHAR(64) NOT NULL )"; if (!osync_db_query(db, query, error)) { goto error; } @@ -282,30 +282,35 @@ return -1; } -long long int osync_archive_save_change(OSyncArchive *archive, long long int id, const char *uid, const char *objtype, long long int mappingid, long long int memberid, OSyncError **error) +long long int osync_archive_save_change(OSyncArchive *archive, long long int id, const char *uid, const char *objtype, long long int mappingid, long long int memberid, const char *objengine, OSyncError **error) { char *query = NULL; char *escaped_uid = NULL; char *escaped_objtype = NULL; + char *escaped_objengine = NULL; - osync_trace(TRACE_ENTRY, "%s(%p, %lli, %s, %s, %lli, %lli, %p)", __func__, archive, id, uid, objtype, mappingid, memberid, error); + osync_trace(TRACE_ENTRY, "%s(%p, %lli, %s, %s, %lli, %lli, %p, %s)", __func__, archive, id, uid, objtype, mappingid, memberid, __NULLSTR(objengine), error); osync_assert(archive); osync_assert(uid); osync_assert(objtype); + osync_assert(objengine); if (!osync_archive_create_changes(archive->db, objtype, error)) goto error; escaped_uid = osync_db_sql_escape(uid); escaped_objtype = osync_db_sql_escape(objtype); + escaped_objengine = osync_db_sql_escape(objengine); if (!id) { - query = osync_strdup_printf("INSERT INTO tbl_changes (objtype, uid, mappingid, memberid) VALUES('%s', '%s', '%lli', '%lli')", escaped_objtype, escaped_uid, mappingid, memberid); + query = osync_strdup_printf("INSERT INTO tbl_changes (objtype, uid, mappingid, memberid, objengine) VALUES('%s', '%s', '%lli', '%lli', '%s')", escaped_objtype, escaped_uid, mappingid, memberid, objengine); } else { - query = osync_strdup_printf("UPDATE tbl_changes SET uid='%s', mappingid='%lli', memberid='%lli' WHERE objtype='%s' AND id=%lli", escaped_uid, mappingid, memberid, escaped_objtype, id); + query = osync_strdup_printf("UPDATE tbl_changes SET uid='%s', mappingid='%lli', memberid='%lli', objengine='%s' WHERE objtype='%s' AND id=%lli", escaped_uid, mappingid, memberid, escaped_objengine, escaped_objtype, id); } + osync_free(escaped_objengine); osync_free(escaped_objtype); osync_free(escaped_uid); + escaped_objengine = NULL; escaped_objtype = NULL; escaped_uid = NULL; @@ -583,3 +588,43 @@ return FALSE; } +osync_bool osync_archive_get_mixed_objengines(OSyncArchive *archive, const char *objengine, OSyncList **objengines, OSyncError **error) +{ + char *query = NULL, *escaped_objengine, *objengine_name; + OSyncList *result, *row, *column; + + osync_assert(archive); + osync_assert(objengine); + osync_assert(objengines); + + escaped_objengine = osync_db_sql_escape(objengine); + + query = osync_strdup_printf("SELECT DISTINCT(b.objengine) FROM tbl_changes, tbl_changes as a, tbl_changes as b " + "WHERE a.mappingid == b.mappingid AND a.objengine == '%s';", escaped_objengine); + result = osync_db_query_table(archive->db, query, error); + osync_free(query); + + /* Check for error of osync_db_query_table() call. */ + if (osync_error_is_set(error)) + goto error; + + for (row = result; row; row = row->next) { + column = row->data; + + objengine_name = osync_list_nth_data(column, 0); + if (!objengine_name) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "Database table tbl_changes corrupt. Couldn't query for mixed object engines."); + goto error; + } + + *objengines = osync_list_append((*objengines), osync_strdup(objengine_name)); + } + + osync_db_free_list(result); + + + return TRUE; +error: + return FALSE; +} + Modified: trunk/opensync/archive/opensync_archive_internals.h ============================================================================== --- trunk/opensync/archive/opensync_archive_internals.h Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/archive/opensync_archive_internals.h Fri Jan 23 11:28:04 2009 (r5222) @@ -71,10 +71,11 @@ * @param objtype Reported object type of entry * @param mappingid Mapped ID of entry * @param memberid ID of member which reported entry + * @param objengine Object Engine which handles the change * @param error Pointer to an error struct * @return Returns number of entries in archive group database. 0 on error. */ -OSYNC_TEST_EXPORT long long int osync_archive_save_change(OSyncArchive *archive, long long int id, const char *uid, const char *objtype, long long int mappingid, long long int memberid, OSyncError **error); +OSYNC_TEST_EXPORT long long int osync_archive_save_change(OSyncArchive *archive, long long int id, const char *uid, const char *objtype, long long int mappingid, long long int memberid, const char *objengine, OSyncError **error); /** * @brief Deletes an entry from a group archive. @@ -130,6 +131,8 @@ * @return Returns TRUE on success, FALSE otherwise */ osync_bool osync_archive_flush_ignored_conflict(OSyncArchive *archive, const char *objtype, OSyncError **error); + +osync_bool osync_archive_get_mixed_objengines(OSyncArchive *archive, const char *objengine, OSyncList **objengines, OSyncError **error); /*@}*/ #endif /*OPENSYNC_ARCHIVE_INTERNALS_H_*/ Modified: trunk/opensync/engine/opensync_engine.c ============================================================================== --- trunk/opensync/engine/opensync_engine.c Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/engine/opensync_engine.c Fri Jan 23 11:28:04 2009 (r5222) @@ -828,6 +828,41 @@ return FALSE; } +osync_bool osync_engine_slowsync_for_mixed_objengines(OSyncEngine *engine, OSyncError **error) +{ + OSyncList *mixedengines = NULL, *o, *m; + const char *objengine_objtype; + + for (o = engine->object_engines; o; o = o->next) { + OSyncObjEngine *objengine = o->data; + + if (!osync_obj_engine_get_slowsync(objengine)) + continue; + + objengine_objtype = osync_obj_engine_get_objtype(objengine); + if (!osync_archive_get_mixed_objengines(engine->archive, objengine_objtype, &mixedengines, error)) + goto error; + } + + for (o = engine->object_engines; o; o = o->next) { + OSyncObjEngine *objengine = o->data; + + for (m = mixedengines; m; m = m->next) { + + if (strcmp(osync_obj_engine_get_objtype(objengine), (char*)m->data)) + continue; + + osync_obj_engine_set_slowsync(objengine, TRUE); + break; + } + + } + + return TRUE; +error: + return FALSE; +} + static void _osync_engine_generate_connect_done_event(OSyncEngine *engine) { if (osync_bitcount(engine->proxy_errors | engine->proxy_connect_done) != osync_list_length(engine->proxies)) @@ -841,6 +876,8 @@ osync_status_update_engine(engine, OSYNC_ENGINE_EVENT_ERROR, locerror); osync_engine_event(engine, OSYNC_ENGINE_EVENT_ERROR); } else { + /* TODO error handling */ + osync_engine_slowsync_for_mixed_objengines(engine, NULL); osync_status_update_engine(engine, OSYNC_ENGINE_EVENT_CONNECT_DONE, NULL); osync_engine_event(engine, OSYNC_ENGINE_EVENT_CONNECT_DONE); } Modified: trunk/opensync/engine/opensync_engine_internals.h ============================================================================== --- trunk/opensync/engine/opensync_engine_internals.h Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/engine/opensync_engine_internals.h Fri Jan 23 11:28:04 2009 (r5222) @@ -130,6 +130,20 @@ */ osync_bool osync_engine_handle_mixed_objtypes(OSyncEngine *engine, OSyncError **error); +/** @brief Trigger slow-sync for object engines which have mixed object types synced + * + * This function checks if an object engine has requested a slow-sync and if + * further function need to run a slow-sync. Due to mixed object type syncing. + * Mixed object type syncing get detected by checking the mapping table if different + * object engine have written non-native object types. + * + * @param engine Pointer to engine + * @param error Pointer to error-struct which get set on any error + * @returns TRUE on success, or FALSE on any error + * + */ +osync_bool osync_engine_slowsync_for_mixed_objengines(OSyncEngine *engine, OSyncError **error); + /*@}*/ #endif /*OPENSYNC_ENGINE_INTERNALS_H_*/ Modified: trunk/opensync/engine/opensync_obj_engine.c ============================================================================== --- trunk/opensync/engine/opensync_obj_engine.c Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/engine/opensync_obj_engine.c Fri Jan 23 11:28:04 2009 (r5222) @@ -481,8 +481,10 @@ OSyncMember *member = NULL; OSyncMappingEntry *entry = NULL; const char *objtype = NULL; + const char *objengine_objtype = NULL; long long int id = 0; + objengine_objtype = osync_obj_engine_get_objtype(engine); osync_trace(TRACE_ENTRY, "%s(%p, %p, %s, %p)", __func__, proxy, userdata, uid, error); @@ -516,7 +518,7 @@ } else { /* TODO error handling */ - osync_archive_save_change(engine->archive, id, osync_change_get_uid(entry_engine->change), objtype, osync_mapping_get_id(mapping), osync_member_get_id(member), &locerror); + osync_archive_save_change(engine->archive, id, osync_change_get_uid(entry_engine->change), objtype, osync_mapping_get_id(mapping), osync_member_get_id(member), objengine_objtype, &locerror); } } Modified: trunk/opensync/engine/opensync_sink_engine.c ============================================================================== --- trunk/opensync/engine/opensync_sink_engine.c Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/opensync/engine/opensync_sink_engine.c Fri Jan 23 11:28:04 2009 (r5222) @@ -255,7 +255,7 @@ osync_change_get_uid(entry_engine->change), osync_change_get_objtype(entry_engine->change), osync_mapping_get_id(mapping), - osync_member_get_id(member), error)) + osync_member_get_id(member), objtype, error)) goto error; } } Modified: trunk/tests/archive-tests/check_archive.c ============================================================================== --- trunk/tests/archive-tests/check_archive.c Fri Jan 23 00:51:13 2009 (r5221) +++ trunk/tests/archive-tests/check_archive.c Fri Jan 23 11:28:04 2009 (r5222) @@ -59,7 +59,7 @@ OSyncList *memberids; osync_archive_load_changes(archive, "contact", &ids, &uids, &mappingids, &memberids, &error); - long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, &error); + long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, "contact", &error); fail_unless(id != 0, NULL); fail_unless(error == NULL, NULL); @@ -84,7 +84,7 @@ OSyncList *memberids; osync_archive_load_changes(archive, "contact", &ids, &uids, &mappingids, &memberids, &error); - long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, &error); + long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, "contact", &error); fail_unless(id != 0, NULL); fail_unless(error == NULL, NULL); @@ -114,7 +114,7 @@ OSyncList *memberids; osync_archive_load_changes(archive, "contact", &ids, &uids, &mappingids, &memberids, &error); - long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, &error); + long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, "contact", &error); fail_unless(id != 0, NULL); fail_unless(error == NULL, NULL); @@ -153,7 +153,7 @@ OSyncList *memberids; osync_archive_load_changes(archive, "contact", &ids, &uids, &mappingids, &memberids, &error); - long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, &error); + long long int id = osync_archive_save_change(archive, 0, "uid", "contact", 1, 1, "contact", &error); fail_unless(id != 0, NULL); fail_unless(error == NULL, NULL); |