[folks/wip/arbitrary-field-interface: 9/9] eds: Implement ExtendedInfo interface



commit 699bf9a70f2ba7b80e20e16820b04db21c62a79b
Author: Rodrigo Moya <rodrigo gnome-db org>
Date:   Tue Jan 20 12:36:35 2015 +0000

    eds: Implement ExtendedInfo interface
    
    Store extended info fields as arbitrary vCard properties.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=641211

 backends/eds/lib/edsf-persona-store.vala |   64 ++++++++++++++
 backends/eds/lib/edsf-persona.vala       |   32 +++++++
 tests/eds/Makefile.am                    |    5 +
 tests/eds/extended-info.vala             |  136 ++++++++++++++++++++++++++++++
 tests/lib/eds/backend.vala               |   13 +++-
 5 files changed, 249 insertions(+), 1 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 9f9a400..58862f6 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -875,6 +875,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                       PersonaDetail.IS_FAVOURITE));
                   prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.ANTI_LINKS));
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
+                      PersonaDetail.EXTENDED_INFO));
 
                   foreach (unowned string field in fields)
                     {
@@ -1597,6 +1599,68 @@ public class Edsf.PersonaStore : Folks.PersonaStore
       yield this._commit_modified_property (persona, "email-addresses");
     }
 
+  internal ExtendedFieldDetails? _get_extended_field (Edsf.Persona persona,
+      string name)
+    {
+      unowned VCardAttribute? attr = persona.contact.get_attribute (name);
+      if (attr == null)
+        {
+          return null;
+        }
+
+      var details = new ExtendedFieldDetails (attr.get_value (), null);
+
+      foreach (unowned E.VCardAttributeParam param in attr.get_params ())
+        {
+          unowned string param_name = param.get_name ();
+          foreach (unowned string param_value in param.get_values ())
+            {
+              details.add_parameter (param_name, param_value);
+            }
+        }
+
+      return details;
+    }
+
+  internal async void _change_extended_field (Edsf.Persona persona,
+      string name, ExtendedFieldDetails details) throws PropertyError
+    {
+      var vcard = (E.VCard) persona.contact;
+      unowned E.VCardAttribute? prev_attr = vcard.get_attribute (name);
+
+      if (prev_attr != null)
+          vcard.remove_attribute (prev_attr);
+
+      E.VCardAttribute new_attr = new E.VCardAttribute ("", name);
+      new_attr.add_value (details.value);
+
+      vcard.add_attribute (new_attr);
+
+      try
+        {
+          yield ((!) this._addressbook).modify_contact (persona.contact, null);
+        }
+      catch (GLib.Error e)
+        {
+          throw this.e_client_error_to_property_error (name, e);
+        }
+    }
+
+  internal async void _remove_extended_field (Edsf.Persona persona,
+      string name) throws PropertyError
+    {
+      persona.contact.remove_attributes ("", name);
+
+      try
+        {
+          yield ((!) this._addressbook).modify_contact (persona.contact, null);
+        }
+      catch (GLib.Error e)
+        {
+          throw this.e_client_error_to_property_error (name, e);
+        }
+    }
+
   internal async void _set_phones (Edsf.Persona persona,
       Set<PhoneFieldDetails> phones) throws PropertyError
     {
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index 4a8d505..aa715b0 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -40,6 +40,7 @@ public class Edsf.Persona : Folks.Persona,
     AvatarDetails,
     BirthdayDetails,
     EmailDetails,
+    ExtendedInfo,
     FavouriteDetails,
     GenderDetails,
     GroupDetails,
@@ -362,6 +363,37 @@ public class Edsf.Persona : Folks.Persona,
           email_addresses);
     }
 
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public ExtendedFieldDetails? get_extended_field (string name)
+    {
+      return ((Edsf.PersonaStore) this.store)._get_extended_field (this, name);
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_extended_field (
+      string name, ExtendedFieldDetails value) throws PropertyError
+    {
+      yield ((Edsf.PersonaStore) this.store)._change_extended_field (this, name, value);
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void remove_extended_field (string name) throws PropertyError
+    {
+      yield ((Edsf.PersonaStore) this.store)._remove_extended_field (this, name);
+    }
+
   private SmallSet<NoteFieldDetails>? _notes = null;
   private Set<NoteFieldDetails>? _notes_ro = null;
 
diff --git a/tests/eds/Makefile.am b/tests/eds/Makefile.am
index 1f2d346..fcafa97 100644
--- a/tests/eds/Makefile.am
+++ b/tests/eds/Makefile.am
@@ -76,6 +76,7 @@ TESTS = \
        enable-disable-stores \
        set-is-favourite \
        perf \
+       extended-info \
        $(NULL)
 
 noinst_PROGRAMS = \
@@ -225,6 +226,10 @@ perf_SOURCES = \
        perf.vala \
        $(NULL)
 
+extended_info_SOURCES = \
+       extended-info.vala
+       $(NULL)
+
 helper_create_many_contacts_SOURCES = \
        helper-create-many-contacts.vala \
        $(NULL)
diff --git a/tests/eds/extended-info.vala b/tests/eds/extended-info.vala
new file mode 100644
index 0000000..3586b62
--- /dev/null
+++ b/tests/eds/extended-info.vala
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2013 Collabora Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Rodrigo Moya <rodrigo moya collabora co uk>
+ *
+ */
+
+using EdsTest;
+using Folks;
+using Gee;
+
+public class ExtendedInfoTests : EdsTest.TestCase
+{
+  private GLib.MainLoop _main_loop;
+  private IndividualAggregator _aggregator;
+  private string _full_name;
+  private bool _found_field_1;
+  private bool _found_field_2;
+
+  public ExtendedInfoTests ()
+    {
+      base ("ExtendedInfo");
+
+      this.add_test ("extended info interface", this.test_extended_info);
+    }
+
+  public void test_extended_info ()
+    {
+      this._main_loop = new GLib.MainLoop (null, false);
+      this._full_name = "persona #1";
+      Gee.HashMap<string, Value?> c1 = new Gee.HashMap<string, Value?> ();
+      Value? v;
+
+      this.eds_backend.reset ();
+
+      v = Value (typeof (string));
+      v.set_string (this._full_name);
+      c1.set ("full_name", (owned) v);
+      v = Value (typeof (string));
+      v.set_string ("value1");
+      c1.set ("X-FIELD-1", (owned) v);
+      v = Value (typeof (string));
+      v.set_string ("value2");
+      c1.set ("X-FIELD-2", (owned) v);
+
+      this.eds_backend.add_contact (c1);
+
+      this._found_field_1 = false;
+      this._found_field_2 = false;
+
+      this._test_extended_info_async.begin ();
+
+      TestUtils.loop_run_with_timeout (this._main_loop);
+
+      assert (this._found_field_1 == true);
+      assert (this._found_field_2 == true);
+    }
+
+  private async void _test_extended_info_async ()
+    {
+      yield this.eds_backend.commit_contacts_to_addressbook ();
+
+      var store = BackendStore.dup ();
+      yield store.prepare ();
+      this._aggregator = new IndividualAggregator ();
+      this._aggregator.individuals_changed_detailed.connect
+          (this._individuals_changed_cb);
+      try
+        {
+          yield this._aggregator.prepare ();
+        }
+      catch (GLib.Error e)
+        {
+          GLib.warning ("Error when calling prepare: %s\n", e.message);
+        }
+    }
+
+  private void _individuals_changed_cb (
+       MultiMap<Individual?, Individual?> changes)
+    {
+      var added = changes.get_values ();
+      var removed = changes.get_keys ();
+
+      foreach (var i in added)
+        {
+          assert (i != null);
+
+          string full_name = i.full_name;
+          if (full_name == this._full_name)
+            {
+              if (i.get_extended_field ("X-FIELD-1") != null)
+                  this._found_field_1 = true;
+              if (i.get_extended_field ("X-FIELD-2") != null)
+                  this._found_field_2 = true;
+            }
+        }
+
+      assert (removed.size == 1);
+
+      foreach (var i in removed)
+        {
+          assert (i == null);
+        }
+
+      if (this._found_field_1 == true &&
+          this._found_field_2 == true)
+        {
+          this._main_loop.quit ();
+        }
+    }
+}
+
+public int main (string[] args)
+{
+  Test.init (ref args);
+
+  var tests = new ExtendedInfoTests ();
+  tests.register ();
+  Test.run ();
+  tests.final_tear_down ();
+
+  return 0;
+}
diff --git a/tests/lib/eds/backend.vala b/tests/lib/eds/backend.vala
index 5a371e2..b6194c2 100644
--- a/tests/lib/eds/backend.vala
+++ b/tests/lib/eds/backend.vala
@@ -317,8 +317,19 @@ public class EdsTest.Backend
            }
           else
             {
+              var field_id = E.Contact.field_id (k);
               var v = c.get (k).get_string ();
-              contact.set (E.Contact.field_id (k), v);
+
+              if (field_id != 0)
+                {
+                  contact.set (field_id, v);
+                }
+              else
+                {
+                  var vcard = (E.VCard) contact;
+                  var attr = new E.VCardAttribute (null, k);
+                  vcard.append_attribute_with_value (attr, v);
+                }
             }
         }
       if (added_contact_name)


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