You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
638 lines
20 KiB
638 lines
20 KiB
4 years ago
|
/*
|
||
|
* libopensync - A synchronization framework
|
||
|
* Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Lesser General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2.1 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public
|
||
|
* License along with this library; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "engine.h"
|
||
|
#include "engine_internals.h"
|
||
|
|
||
|
/**
|
||
|
* @defgroup OSEngineMappingPrivate OpenSync Mapping Internals
|
||
|
* @ingroup OSEnginePrivate
|
||
|
* @brief The internals the mappings
|
||
|
*
|
||
|
*/
|
||
|
/*@{*/
|
||
|
|
||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||
|
OSyncMappingTable *osengine_mappingtable_new(OSyncEngine *engine)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mappingtable_new(%p)", engine);
|
||
|
OSyncMappingTable *table = g_malloc0(sizeof(OSyncMappingTable));
|
||
|
table->engine = engine;
|
||
|
table->group = engine->group;
|
||
|
|
||
|
GList *c;
|
||
|
for (c = engine->clients; c; c = c->next) {
|
||
|
OSyncClient *client = c->data;
|
||
|
osengine_mappingview_new(table, client);
|
||
|
}
|
||
|
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingtable_new: %p", table);
|
||
|
return table;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingtable_reset(OSyncMappingTable *table)
|
||
|
{
|
||
|
GList *v;
|
||
|
for (v = table->views; v; v = v->next) {
|
||
|
OSyncMappingView *view = v->data;
|
||
|
osengine_mappingview_reset(view);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void osengine_mappingtable_free(OSyncMappingTable *table)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mappingtable_free(%p)", table);
|
||
|
GList *c = NULL;
|
||
|
GList *m = NULL;
|
||
|
|
||
|
GList *mappings = g_list_copy(table->mappings);
|
||
|
GList *unmapped = g_list_copy(table->unmapped);
|
||
|
GList *views = g_list_copy(table->views);
|
||
|
osync_trace(TRACE_INTERNAL, "Free mappings");
|
||
|
for (m = mappings; m; m = m->next) {
|
||
|
OSyncMapping *mapping = m->data;
|
||
|
osengine_mapping_free(mapping);
|
||
|
}
|
||
|
osync_trace(TRACE_INTERNAL, "Free unmapped");
|
||
|
for (c = unmapped; c; c = c->next) {
|
||
|
OSyncMappingEntry *entry = c->data;
|
||
|
osengine_mappingentry_free(entry);
|
||
|
}
|
||
|
for (c = views; c; c = c->next) {
|
||
|
OSyncMappingView *view = c->data;
|
||
|
osengine_mappingview_free(view);
|
||
|
}
|
||
|
g_list_free(mappings);
|
||
|
g_list_free(unmapped);
|
||
|
g_list_free(views);
|
||
|
g_free(table);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingtable_free");
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mappingtable_find_entry(OSyncMappingTable *table, const char *uid, const char *objtype, long long int memberid)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, table, uid, objtype ? objtype : "None");
|
||
|
GList *v;
|
||
|
int count_of_entries = 0; /*must not be more the one for objtype=NULL*/
|
||
|
OSyncMappingEntry *ret_entry = NULL;
|
||
|
for (v = table->views; v; v = v->next) {
|
||
|
OSyncMappingView *view = v->data;
|
||
|
GList *c;
|
||
|
|
||
|
if (memberid && memberid != osync_member_get_id(view->client->member))
|
||
|
continue;
|
||
|
|
||
|
for (c = view->changes; c; c = c->next) {
|
||
|
OSyncMappingEntry *entry = c->data;
|
||
|
g_assert(entry->change);
|
||
|
if(objtype){
|
||
|
if ( (!strcmp(
|
||
|
osync_change_get_uid(entry->change), uid)) &&
|
||
|
(!strcmp(
|
||
|
osync_objtype_get_name(
|
||
|
osync_change_get_objtype(entry->change))
|
||
|
, objtype))
|
||
|
) {
|
||
|
ret_entry = entry;
|
||
|
count_of_entries++;
|
||
|
}
|
||
|
} else { /**objtype is NULL ... try to find a entry based on uid*/
|
||
|
if (!strcmp(osync_change_get_uid(entry->change), uid)) {
|
||
|
ret_entry = entry;
|
||
|
count_of_entries++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if(count_of_entries == 1 && ret_entry){
|
||
|
osync_trace(TRACE_EXIT, "%s: %p", __func__, ret_entry);
|
||
|
return ret_entry;
|
||
|
}
|
||
|
if(count_of_entries >1){
|
||
|
if (!objtype)
|
||
|
{
|
||
|
osync_trace(TRACE_EXIT_ERROR, "%s: possible dataloss", __func__ );
|
||
|
} else {
|
||
|
osync_trace(TRACE_EXIT_ERROR, "%s: changes.db corrupted", __func__ );
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
osync_trace(TRACE_EXIT, "%s: Not Found", __func__);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mappingtable_store_change(OSyncMappingTable *table, OSyncChange *change)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mappingtable_store_change(%p, %p)", table, change);
|
||
|
OSyncMappingView *view = osengine_mappingtable_find_view(table, osync_change_get_member(change));
|
||
|
g_assert(view);
|
||
|
OSyncMappingEntry *entry = osengine_mappingview_store_change(view, change);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingtable_store_change: %p", entry);
|
||
|
return entry;
|
||
|
}
|
||
|
|
||
|
OSyncMapping *osengine_mappingtable_find_mapping(OSyncMappingTable *table, OSyncChange *change)
|
||
|
{
|
||
|
GList *m;
|
||
|
for (m = table->mappings; m; m = m->next) {
|
||
|
OSyncMapping *mapping = m->data;
|
||
|
if (osengine_mapping_find_entry(mapping, change, NULL))
|
||
|
return mapping;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
OSyncMapping *osengine_mappingtable_mapping_from_id(OSyncMappingTable *table, long long int id)
|
||
|
{
|
||
|
GList *m;
|
||
|
for (m = table->mappings; m; m = m->next) {
|
||
|
OSyncMapping *mapping = m->data;
|
||
|
if (mapping->id == id)
|
||
|
return mapping;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
OSyncMappingView *osengine_mappingtable_find_view(OSyncMappingTable *table, OSyncMember *member)
|
||
|
{
|
||
|
GList *v;
|
||
|
for (v = table->views; v; v = v->next) {
|
||
|
OSyncMappingView *view = v->data;
|
||
|
if (view->memberid == osync_member_get_id(member))
|
||
|
return view;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingtable_add_mapping(OSyncMappingTable *table, OSyncMapping *mapping)
|
||
|
{
|
||
|
table->mappings = g_list_append(table->mappings, mapping);
|
||
|
mapping->table = table;
|
||
|
}
|
||
|
|
||
|
osync_bool osengine_mappingtable_load(OSyncMappingTable *table, OSyncError **error)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mappingtable_load(%p, %p)", table, error);
|
||
|
OSyncChange **changes = NULL;
|
||
|
if (!osync_changes_load(table->group, &changes, error)) {
|
||
|
osync_trace(TRACE_EXIT_ERROR, "osengine_mappingtable_load: %s", osync_error_print(error));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
int i = 0;
|
||
|
OSyncChange *change = NULL;
|
||
|
OSyncMapping *mapping = NULL;
|
||
|
while ((change = changes[i])) {
|
||
|
OSyncMappingEntry *entry = osengine_mappingentry_new(NULL);
|
||
|
entry->change = change;
|
||
|
//entry->orig_change = change;
|
||
|
entry->client = (OSyncClient *)osync_member_get_data(osync_change_get_member(change));
|
||
|
|
||
|
if (!osync_change_get_mappingid(change)) {
|
||
|
table->unmapped = g_list_append(table->unmapped, entry);
|
||
|
} else {
|
||
|
if (!mapping || mapping->id != osync_change_get_mappingid(change)) {
|
||
|
mapping = osengine_mapping_new(table);
|
||
|
mapping->id = osync_change_get_mappingid(change);
|
||
|
}
|
||
|
osengine_mapping_add_entry(mapping, entry);
|
||
|
}
|
||
|
|
||
|
osync_flag_set(entry->fl_has_data);
|
||
|
|
||
|
OSyncMappingView *view = osengine_mappingtable_find_view(table, osync_change_get_member(change));
|
||
|
if (view)
|
||
|
osengine_mappingview_add_entry(view, entry);
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingtable_load: TRUE");
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
long long int osengine_mappingtable_get_next_id(OSyncMappingTable *table)
|
||
|
{
|
||
|
long long int new_id = 1;
|
||
|
GList *m;
|
||
|
for (m = table->mappings; m; m = m->next) {
|
||
|
OSyncMapping *mapping = m->data;
|
||
|
if (new_id <= mapping->id)
|
||
|
new_id = mapping->id + 1;
|
||
|
}
|
||
|
return new_id;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingtable_inject_changes(OSyncMappingTable *table)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "%s(%p)", __func__, table);
|
||
|
//OSyncEngine *engine = table->engine;
|
||
|
|
||
|
char **uids = NULL;
|
||
|
char **objtypes = NULL;
|
||
|
long long int *memberids = NULL;
|
||
|
int *types = NULL;
|
||
|
char *uid = NULL;
|
||
|
char *objtype = NULL;
|
||
|
int type = 0;
|
||
|
int i = 0;
|
||
|
OSyncError *error = NULL;
|
||
|
osync_group_open_changelog(table->engine->group, &uids, &objtypes, &memberids, &types, &error);
|
||
|
|
||
|
for (i = 0; (uid = uids[i]) ; i++) {
|
||
|
type = types[i];
|
||
|
objtype = objtypes[i];
|
||
|
long long int memberid = memberids[i];
|
||
|
OSyncMappingEntry *entry = osengine_mappingtable_find_entry(table, uid, objtype, memberid);
|
||
|
|
||
|
if (!entry) {
|
||
|
osync_trace(TRACE_INTERNAL, "Mappingtable and changelog inconsistent: no entry with uid %s", uid);
|
||
|
/*FIXME: We should be able to return error here. What if entry == NULL? */
|
||
|
g_assert_not_reached();
|
||
|
}
|
||
|
|
||
|
osync_change_set_changetype(entry->change, type);
|
||
|
osync_trace(TRACE_INTERNAL, "Injecting %p with changetype %i", entry, osync_change_get_changetype(entry->change));
|
||
|
osync_flag_attach(entry->fl_read, table->engine->cmb_read_all);
|
||
|
|
||
|
/* Set fl_mapped accordingly, if the entry was already mapped previously */
|
||
|
if (entry->mapping)
|
||
|
osync_flag_set(entry->fl_mapped);
|
||
|
|
||
|
//send_read_change(engine, entry);
|
||
|
}
|
||
|
|
||
|
osync_trace(TRACE_EXIT, "%s", __func__);
|
||
|
}
|
||
|
|
||
|
OSyncMappingTable *_osengine_mappingtable_load_group(OSyncGroup *group)
|
||
|
{
|
||
|
OSyncMappingTable *table = g_malloc0(sizeof(OSyncMappingTable));
|
||
|
table->group = group;
|
||
|
|
||
|
int i;
|
||
|
for (i = 0; i < osync_group_num_members(group); i++) {
|
||
|
OSyncMember *member = osync_group_nth_member(group, i);
|
||
|
OSyncMappingView *view = g_malloc0(sizeof(OSyncMappingView));
|
||
|
table->views = g_list_append(table->views, view);
|
||
|
view->table = table;
|
||
|
view->memberid = osync_member_get_id(member);
|
||
|
}
|
||
|
|
||
|
if (!osengine_mappingtable_load(table, NULL))
|
||
|
return NULL;
|
||
|
return table;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingtable_close(OSyncMappingTable *table)
|
||
|
{
|
||
|
osync_changes_close(table->group);
|
||
|
//FIXME Free the changes on the views
|
||
|
}
|
||
|
|
||
|
OSyncMapping *osengine_mapping_new(OSyncMappingTable *table)
|
||
|
{
|
||
|
g_assert(table);
|
||
|
OSyncMapping *mapping = g_malloc0(sizeof(OSyncMapping));
|
||
|
osengine_mappingtable_add_mapping(table, mapping);
|
||
|
if (table->engine) {
|
||
|
mapping->fl_solved = osync_flag_new(NULL);
|
||
|
|
||
|
mapping->fl_chkconflict = osync_flag_new(NULL);
|
||
|
osync_flag_set(mapping->fl_chkconflict);
|
||
|
|
||
|
mapping->fl_multiplied = osync_flag_new(NULL);
|
||
|
osync_flag_set(mapping->fl_multiplied);
|
||
|
|
||
|
mapping->cmb_has_data = osync_comb_flag_new(FALSE, FALSE);
|
||
|
osync_flag_set_pos_trigger(mapping->cmb_has_data, (OSyncFlagTriggerFunc)send_mapping_changed, table->engine, mapping);
|
||
|
|
||
|
mapping->cmb_has_info = osync_comb_flag_new(FALSE, FALSE);
|
||
|
|
||
|
mapping->cmb_synced = osync_comb_flag_new(FALSE, TRUE);
|
||
|
|
||
|
mapping->cmb_deleted = osync_comb_flag_new(FALSE, FALSE);
|
||
|
|
||
|
osync_flag_attach(mapping->cmb_synced, table->engine->cmb_synced);
|
||
|
osync_flag_attach(mapping->fl_multiplied, table->engine->cmb_multiplied);
|
||
|
osync_flag_attach(mapping->fl_chkconflict, table->engine->cmb_chkconflict);
|
||
|
}
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mapping_new(%p): %p", table, mapping);
|
||
|
return mapping;
|
||
|
}
|
||
|
|
||
|
void osengine_mapping_free(OSyncMapping *mapping)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mapping_free(%p)", mapping);
|
||
|
|
||
|
while (g_list_nth_data(mapping->entries, 0))
|
||
|
osengine_mappingentry_free(g_list_nth_data(mapping->entries, 0));
|
||
|
|
||
|
osync_flag_detach(mapping->cmb_synced);
|
||
|
osync_flag_detach(mapping->fl_chkconflict);
|
||
|
osync_flag_detach(mapping->fl_multiplied);
|
||
|
|
||
|
mapping->table->mappings = g_list_remove(mapping->table->mappings, mapping);
|
||
|
osync_flag_free(mapping->fl_solved);
|
||
|
osync_flag_free(mapping->cmb_has_data);
|
||
|
osync_flag_free(mapping->cmb_has_info);
|
||
|
osync_flag_free(mapping->cmb_synced);
|
||
|
osync_flag_free(mapping->fl_chkconflict);
|
||
|
osync_flag_free(mapping->cmb_deleted);
|
||
|
osync_flag_free(mapping->fl_multiplied);
|
||
|
|
||
|
g_free(mapping);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mapping_free");
|
||
|
}
|
||
|
|
||
|
void osengine_mapping_add_entry(OSyncMapping *mapping, OSyncMappingEntry *entry)
|
||
|
{
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mapping_add_entry(%p, %p)", mapping, entry);
|
||
|
g_assert(!osengine_mapping_find_entry(mapping, NULL, entry->view));
|
||
|
mapping->entries = g_list_append(mapping->entries, entry);
|
||
|
entry->mapping = mapping;
|
||
|
|
||
|
if (mapping->table->engine) {
|
||
|
osync_flag_attach(entry->fl_has_data, mapping->cmb_has_data);
|
||
|
osync_flag_attach(entry->fl_has_info, mapping->cmb_has_info);
|
||
|
osync_flag_attach(entry->fl_synced, mapping->cmb_synced);
|
||
|
osync_flag_attach(entry->fl_deleted, mapping->cmb_deleted);
|
||
|
osync_flag_set_pos_trigger(entry->fl_dirty, (OSyncFlagTriggerFunc)send_mappingentry_changed, mapping->table->engine, entry);
|
||
|
}
|
||
|
osync_change_set_mappingid(entry->change, mapping->id);
|
||
|
|
||
|
mapping->table->unmapped = g_list_remove(mapping->table->unmapped, entry);
|
||
|
mapping->table->entries = g_list_append(mapping->table->entries, entry);
|
||
|
}
|
||
|
|
||
|
void osengine_mapping_remove_entry(OSyncMapping *mapping, OSyncMappingEntry *entry)
|
||
|
{
|
||
|
mapping->entries = g_list_remove(mapping->entries, entry);
|
||
|
mapping->table->entries = g_list_remove(mapping->table->entries, entry);
|
||
|
entry->mapping = NULL;
|
||
|
|
||
|
osync_flag_detach(entry->fl_has_data);
|
||
|
osync_flag_detach(entry->fl_has_info);
|
||
|
osync_flag_detach(entry->fl_synced);
|
||
|
osync_flag_detach(entry->fl_deleted);
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mapping_find_entry(OSyncMapping *mapping, OSyncChange *change, OSyncMappingView *view)
|
||
|
{
|
||
|
GList *e;
|
||
|
for (e = mapping->entries; e; e = e->next) {
|
||
|
OSyncMappingEntry *entry = e->data;
|
||
|
if (change && entry->change == change)
|
||
|
return entry;
|
||
|
if (view && entry->view == view)
|
||
|
return entry;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mapping_nth_entry(OSyncMapping *mapping, int nth)
|
||
|
{
|
||
|
return (OSyncMappingEntry *)g_list_nth_data(mapping->entries, nth);
|
||
|
}
|
||
|
|
||
|
int osengine_mapping_num_changes(OSyncMapping *mapping)
|
||
|
{
|
||
|
return g_list_length(mapping->entries);
|
||
|
}
|
||
|
|
||
|
OSyncChange *osengine_mapping_nth_change(OSyncMapping *mapping, int nth)
|
||
|
{
|
||
|
OSyncMappingEntry *entry = g_list_nth_data(mapping->entries, nth);
|
||
|
if (!entry)
|
||
|
return NULL;
|
||
|
return entry->change;
|
||
|
}
|
||
|
|
||
|
long long osengine_mapping_get_id(OSyncMapping *mapping)
|
||
|
{
|
||
|
return mapping->id;
|
||
|
}
|
||
|
|
||
|
void osengine_mapping_reset(OSyncMapping *mapping)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mapping_reset(%p)", mapping);
|
||
|
GList *e;
|
||
|
for (e = mapping->entries; e; e = e->next) {
|
||
|
OSyncMappingEntry *entry = e->data;
|
||
|
osengine_mappingentry_reset(entry);
|
||
|
}
|
||
|
|
||
|
osync_flag_set(mapping->fl_multiplied);
|
||
|
osync_flag_set(mapping->fl_chkconflict);
|
||
|
mapping->master = NULL;
|
||
|
osync_trace(TRACE_EXIT, "osengine_mapping_reset");
|
||
|
}
|
||
|
|
||
|
void osengine_mapping_delete(OSyncMapping *mapping)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mapping_delete(%p)", mapping);
|
||
|
GList *entries = g_list_copy(mapping->entries);
|
||
|
GList *c = NULL;
|
||
|
for (c = entries; c; c = c->next) {
|
||
|
OSyncMappingEntry *entry = c->data;
|
||
|
osync_change_delete(entry->change, NULL);
|
||
|
}
|
||
|
g_list_free(entries);
|
||
|
osengine_mapping_free(mapping);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mapping_delete");
|
||
|
}
|
||
|
|
||
|
OSyncMappingView *osengine_mappingview_new(OSyncMappingTable *table, OSyncClient *client)
|
||
|
{
|
||
|
g_assert(table);
|
||
|
OSyncMappingView *view = g_malloc0(sizeof(OSyncMappingView));
|
||
|
table->views = g_list_append(table->views, view);
|
||
|
view->client = client;
|
||
|
view->table = table;
|
||
|
view->memberid = osync_member_get_id(client->member);
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mappingview_new(%p)", view);
|
||
|
return view;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingview_free(OSyncMappingView *view)
|
||
|
{
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mappingview_free(%p)", view);
|
||
|
g_list_free(view->changes);
|
||
|
view->changes = NULL;
|
||
|
g_free(view);
|
||
|
}
|
||
|
|
||
|
void osengine_mappingview_add_entry(OSyncMappingView *view, OSyncMappingEntry *entry)
|
||
|
{
|
||
|
view->changes = g_list_append(view->changes, entry);
|
||
|
entry->view = view;
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mappingview_store_change(OSyncMappingView *view, OSyncChange *change)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "osengine_mappingview_store_change(%p, %p)", view, change);
|
||
|
g_assert(change);
|
||
|
GList *c;
|
||
|
for (c = view->changes; c; c = c->next) {
|
||
|
OSyncMappingEntry *entry = c->data;
|
||
|
g_assert(entry->change);
|
||
|
|
||
|
/**
|
||
|
* not unique UID exception
|
||
|
* UID has to match and objtype has to match
|
||
|
**/
|
||
|
if (!strcmp(osync_change_get_uid(entry->change), osync_change_get_uid(change))) {
|
||
|
OSyncObjType * entry_objtype = osync_change_get_objtype(entry->change);
|
||
|
OSyncObjType * change_objtype = osync_change_get_objtype(change);
|
||
|
|
||
|
const char * entry_objtype_name = osync_objtype_get_name(entry_objtype);
|
||
|
const char * change_objtype_name = osync_objtype_get_name(change_objtype);
|
||
|
|
||
|
if (
|
||
|
(change_objtype_name == NULL) ||
|
||
|
(entry_objtype_name == NULL) ||
|
||
|
(!strcmp(change_objtype_name, entry_objtype_name)) ||
|
||
|
(!strcmp(change_objtype_name, "data")) ||
|
||
|
(!strcmp(entry_objtype_name, "data"))
|
||
|
) {
|
||
|
osengine_mappingentry_update(entry, change);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingview_store_change: %p", entry);
|
||
|
return entry;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *newentry = osengine_mappingentry_new(NULL);
|
||
|
newentry->change = change;
|
||
|
newentry->client = view->client;
|
||
|
view->table->unmapped = g_list_append(view->table->unmapped, newentry);
|
||
|
osengine_mappingview_add_entry(view, newentry);
|
||
|
osync_trace(TRACE_EXIT, "osengine_mappingview_store_change: %p (New MappingEntry)", newentry);
|
||
|
return newentry;
|
||
|
}
|
||
|
|
||
|
osync_bool osengine_mappingview_uid_is_unique(OSyncMappingView *view, OSyncMappingEntry *entry, osync_bool spare_deleted)
|
||
|
{
|
||
|
GList *e = NULL;
|
||
|
|
||
|
for (e = view->changes; e; e = e->next) {
|
||
|
OSyncMappingEntry *exentry = e->data;
|
||
|
if ((exentry != entry) && (!spare_deleted || (osync_change_get_changetype(exentry->change) != CHANGE_DELETED)) && !strcmp(osync_change_get_uid(exentry->change), osync_change_get_uid(entry->change)))
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingview_reset(OSyncMappingView *view)
|
||
|
{
|
||
|
//g_list_free(view->changes);
|
||
|
//view->changes = NULL;
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mappingentry_new(OSyncMapping *mapping)
|
||
|
{
|
||
|
OSyncMappingEntry *entry = g_malloc0(sizeof(OSyncMappingEntry));
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mappingentry_new(%p): %p", mapping, entry);
|
||
|
entry->fl_has_data = osync_flag_new(NULL);
|
||
|
entry->fl_dirty = osync_flag_new(NULL);
|
||
|
entry->fl_mapped = osync_flag_new(NULL);
|
||
|
entry->fl_has_info = osync_flag_new(NULL);
|
||
|
entry->fl_synced = osync_flag_new(NULL);
|
||
|
entry->fl_deleted = osync_flag_new(NULL);
|
||
|
entry->fl_read = osync_flag_new(NULL);
|
||
|
entry->fl_committed = osync_flag_new(NULL);
|
||
|
osync_flag_set(entry->fl_synced);
|
||
|
|
||
|
if (mapping)
|
||
|
osengine_mapping_add_entry(mapping, entry);
|
||
|
|
||
|
return entry;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingentry_free(OSyncMappingEntry *entry)
|
||
|
{
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mappingentry_free(%p)", entry);
|
||
|
|
||
|
if (entry->mapping)
|
||
|
osengine_mapping_remove_entry(entry->mapping, entry);
|
||
|
|
||
|
osync_flag_free(entry->fl_has_data);
|
||
|
osync_flag_free(entry->fl_dirty);
|
||
|
osync_flag_free(entry->fl_mapped);
|
||
|
osync_flag_free(entry->fl_has_info);
|
||
|
osync_flag_free(entry->fl_synced);
|
||
|
osync_flag_free(entry->fl_deleted);
|
||
|
osync_flag_free(entry->fl_read);
|
||
|
osync_flag_free(entry->fl_committed);
|
||
|
|
||
|
entry->view->changes = g_list_remove(entry->view->changes, entry);
|
||
|
entry->view = NULL;
|
||
|
|
||
|
g_free(entry);
|
||
|
}
|
||
|
|
||
|
void osengine_mappingentry_update(OSyncMappingEntry *entry, OSyncChange *change)
|
||
|
{
|
||
|
osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, entry, change);
|
||
|
|
||
|
OSyncObjFormat *format = osync_change_get_objformat(entry->change);
|
||
|
OSyncObjType *type = osync_change_get_objtype(entry->change);
|
||
|
|
||
|
osync_change_update(change, entry->change);
|
||
|
|
||
|
if (osync_change_get_changetype(change) == CHANGE_DELETED && format && type) {
|
||
|
osync_change_set_objformat(entry->change, format);
|
||
|
osync_change_set_objtype(entry->change, type);
|
||
|
|
||
|
osync_trace(TRACE_INTERNAL, "Change was deleted. Old objtype %s and format %s", osync_change_get_objtype(entry->change) ? osync_objtype_get_name(osync_change_get_objtype(entry->change)) : "None", osync_change_get_objformat(entry->change) ? osync_objformat_get_name(osync_change_get_objformat(entry->change)) : "None");
|
||
|
}
|
||
|
|
||
|
osync_trace(TRACE_EXIT, "%s", __func__);
|
||
|
}
|
||
|
|
||
|
OSyncMappingEntry *osengine_mappingentry_copy(OSyncMappingEntry *entry)
|
||
|
{
|
||
|
OSyncMappingEntry *newentry = osengine_mappingentry_new(NULL);
|
||
|
|
||
|
OSyncError *error = NULL;
|
||
|
newentry->change = osync_change_copy(entry->change, &error);
|
||
|
newentry->client = entry->client;
|
||
|
osengine_mappingview_add_entry(entry->view, newentry);
|
||
|
return newentry;
|
||
|
}
|
||
|
|
||
|
void osengine_mappingentry_reset(OSyncMappingEntry *entry)
|
||
|
{
|
||
|
osync_trace(TRACE_INTERNAL, "osengine_mappingentry_reset(%p)", entry);
|
||
|
|
||
|
osync_flag_set(entry->fl_has_data);
|
||
|
osync_flag_unset(entry->fl_dirty);
|
||
|
osync_flag_unset(entry->fl_has_info);
|
||
|
osync_flag_unset(entry->fl_deleted);
|
||
|
osync_flag_set(entry->fl_synced);
|
||
|
|
||
|
osync_change_reset(entry->change);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/** @} */
|