desktop-data-model r7253 - in trunk: ddm engine



Author: otaylor
Date: Fri Feb 15 19:40:07 2008
New Revision: 7253
URL: http://svn.gnome.org/viewvc/desktop-data-model?rev=7253&view=rev

Log:
Use <resource deleted="true"> notifications from the server to
  clear out rule-based properties that reference those resources.
  (This is needed to get contact deletion working properly.)


Modified:
   trunk/ddm/ddm-data-model-internal.h
   trunk/ddm/ddm-data-model.c
   trunk/ddm/ddm-data-resource.c
   trunk/ddm/ddm-data-resource.h
   trunk/engine/hippo-connection.c

Modified: trunk/ddm/ddm-data-model-internal.h
==============================================================================
--- trunk/ddm/ddm-data-model-internal.h	(original)
+++ trunk/ddm/ddm-data-model-internal.h	Fri Feb 15 19:40:07 2008
@@ -11,6 +11,8 @@
 
 void _ddm_data_model_mark_changed   (DDMDataModel    *model,
                                      DDMDataResource *resource);
+void _ddm_data_model_remove         (DDMDataModel    *model,
+                                     DDMDataResource *resource);
 void _ddm_data_model_add_work_item  (DDMDataModel    *model,
                                      DDMWorkItem     *item);
 void _ddm_data_model_query_answered (DDMDataModel    *model,

Modified: trunk/ddm/ddm-data-model.c
==============================================================================
--- trunk/ddm/ddm-data-model.c	(original)
+++ trunk/ddm/ddm-data-model.c	Fri Feb 15 19:40:07 2008
@@ -617,6 +617,15 @@
     ddm_data_model_schedule_flush(model);
 }
 
+void
+_ddm_data_model_remove (DDMDataModel    *model,
+                        DDMDataResource *resource)
+{
+    _ddm_data_model_mark_changed(model, resource);
+    g_hash_table_remove(model->resources,
+                        ddm_data_resource_get_resource_id(resource));
+}
+
 static gboolean
 do_flush(gpointer data)
 {
@@ -741,7 +750,7 @@
     if (g_hash_table_size(model->changed_resources) == 0)
         return;
 
-    /* We need to snapshot the changed resources, since the set of changd resources
+    /* We need to snapshot the changed resources, since the set of changed resources
      * may be extended as we process rules.
      */
     resources_to_process = hash_table_get_values(model->changed_resources);

Modified: trunk/ddm/ddm-data-resource.c
==============================================================================
--- trunk/ddm/ddm-data-resource.c	(original)
+++ trunk/ddm/ddm-data-resource.c	Fri Feb 15 19:40:07 2008
@@ -65,7 +65,8 @@
     DDMDataModel *model;
     char *resource_id;
     char *class_id;
-    gboolean local;
+    guint local : 1;
+    guint removed : 1;
 
     /* Properties that reference this resource as the source of a rule */
     GSList *referencing_rule_properties;
@@ -338,6 +339,44 @@
     }
 }
 
+/* Separate from the public function, because in the _ddm_data_resource_reset() case,
+ * we don't want to call _ddm_data_model_remove()
+ */
+static void
+resource_remove_internal (DDMDataResource *resource)
+{
+    GSList *l;
+
+    resource->removed = TRUE;
+
+    /* This is called when a resource belongs to a previous generation, or is
+     * deleted on the server; the resource might still be referenced by a client
+     * but we  unlinking it from properties that reference it and that it references.
+     */
+    for (l = resource->properties; l; l = l->next) {
+        DDMDataProperty *property = l->data;
+        GSList *ll;
+        
+        for (ll = property->rule_sources; ll; ll = ll->next) {
+            DDMDataResource *source = ll->data;
+            
+            source->referencing_rule_properties = g_slist_remove(source->referencing_rule_properties, property);
+        }
+    }
+    
+    while (resource->referencing_rule_properties) {
+        DDMDataProperty *property = resource->referencing_rule_properties->data;
+        property_remove_rule_source(property, resource);
+    }
+}
+
+void
+ddm_data_resource_remove (DDMDataResource *resource)
+{
+    resource_remove_internal(resource);
+    _ddm_data_model_remove(resource->model, resource);
+}
+
 gboolean
 _ddm_data_resource_reset (DDMDataResource *resource)
 {
@@ -368,25 +407,8 @@
         /* For a remote resource, we remove the resource entirely from the resource table.
          * after unlinking it from properties that reference it and that it references.
          */
-        
-        GSList *l;
-
-        for (l = resource->properties; l; l = l->next) {
-            DDMDataProperty *property = l->data;
-            GSList *ll;
-
-            for (ll = property->rule_sources; ll; ll = ll->next) {
-                DDMDataResource *source = ll->data;
-
-                source->referencing_rule_properties = g_slist_remove(source->referencing_rule_properties, property);
-            }
-        }
+        resource_remove_internal(resource);
 
-        while (resource->referencing_rule_properties) {
-            DDMDataProperty *property = resource->referencing_rule_properties->data;
-            property_remove_rule_source(property, resource);
-        }
-        
         return TRUE;
     }
 }
@@ -2239,8 +2261,17 @@
                                           DDMClientNotificationSet *notification_set)
 {
     GSList *l;
-    
-    
+
+    /* We probably should pass along the removal to clients, but since the resource
+     * has been delinked from both server side properties and rule-based local
+     * properties, clients should naturally drop their references in any case.
+     *
+     * If we start sending real evictions of non-deleted resources, then those have to
+     * be passed along so that the clients have the chance to re-request notification.
+     */
+    if (resource->removed)
+        return;
+
     for (l = resource->clients; l; l = l->next) {
         DataClient *data_client = l->data;
 

Modified: trunk/ddm/ddm-data-resource.h
==============================================================================
--- trunk/ddm/ddm-data-resource.h	(original)
+++ trunk/ddm/ddm-data-resource.h	Fri Feb 15 19:40:07 2008
@@ -148,9 +148,11 @@
                                                             gboolean            default_include,
                                                             const char         *default_children,
                                                             DDMDataValue       *value);
+void               ddm_data_resource_remove                (DDMDataResource    *resource);
 /* Add the given fetch to the received fetch for a particular resource */
 void               ddm_data_resource_fetch_received        (DDMDataResource    *resource,
                                                             DDMDataFetch       *received_fetch);
+
 /* Add the given fetch to the received fetch for a particular resource, and recurse into children
  * and add the appropriate fetches for them as well. If mark_remote_resources is FALSE, then
  * we only do the marking for resources that are local and skip marking any resources in the

Modified: trunk/engine/hippo-connection.c
==============================================================================
--- trunk/engine/hippo-connection.c	(original)
+++ trunk/engine/hippo-connection.c	Fri Feb 15 19:40:07 2008
@@ -3052,6 +3052,27 @@
     }
 }
 
+static gboolean
+dm_context_get_system_attribute_boolean(DMContext  *context,
+                                        const char *name,
+                                        gboolean   *result)
+{
+    const char *value = dm_context_get_system_attribute(context, name);
+    if (value == NULL) {
+        return FALSE;
+    } else {
+        char *str_stripped;
+        
+        str_stripped = g_strdup(value);
+        g_strstrip(str_stripped);
+        
+        *result = g_ascii_strcasecmp(value, "true") == 0;
+
+        g_free(str_stripped);
+        return TRUE;
+    }
+}
+
 static void
 dm_context_push_node(DMContext     *context,
                      LmMessageNode *node)
@@ -3140,11 +3161,21 @@
 static gboolean
 dm_context_get_indirect(DMContext *context)
 {
-    const char *indirect_attr = dm_context_get_system_attribute(context, "indirect");
-    if (indirect_attr != NULL)
-        return g_ascii_strcasecmp(indirect_attr, "true") == 0;
-    else
-        return FALSE;
+    gboolean indirect = FALSE;
+
+    dm_context_get_system_attribute_boolean(context, "indirect", &indirect);
+    
+    return indirect;
+}
+
+static gboolean
+dm_context_get_deleted(DMContext *context)
+{
+    gboolean deleted = FALSE;
+
+    dm_context_get_system_attribute_boolean(context, "deleted", &deleted);
+    
+    return deleted;
 }
 
 static DDMDataFetch *
@@ -3624,7 +3655,18 @@
         
         for (resource_node = child->children; resource_node; resource_node = resource_node->next) {
             dm_context_push_node(&context, resource_node);
-            update_resource(&context, broadcast_notifications, save_notifications, TRUE);
+
+            if (dm_context_get_deleted(&context)) {
+                const char *resource_id = dm_context_get_resource_id(&context);
+                if (resource_id) {
+                    DDMDataResource *resource = ddm_data_model_lookup_resource (context.model, resource_id);
+                    if (resource)
+                        ddm_data_resource_remove(resource);
+                }
+            } else {
+                update_resource(&context, broadcast_notifications, save_notifications, TRUE);
+            }
+                    
             dm_context_pop_node(&context);
         }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]