[folks] Add write support for Tracker
- From: Raul Gutierrez Segales <raulgs src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Add write support for Tracker
- Date: Thu, 31 Mar 2011 18:05:23 +0000 (UTC)
commit 8b35f9a6498d48225e31b2dd4a86fd1dc64c664e
Author: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
Date: Fri Mar 18 14:45:23 2011 +0000
Add write support for Tracker
Closes: bgo#645413
NEWS | 1 +
backends/tracker/lib/trf-persona-store.vala | 1415 ++++++++++++++++++++++++---
backends/tracker/lib/trf-persona.vala | 243 ++++--
backends/tracker/lib/trf-util.vala | 18 +
tests/tracker/Makefile.am | 96 ++
tests/tracker/add-contact.vala | 19 +-
tests/tracker/add-persona.vala | 514 ++++++++++
tests/tracker/additional-names-updates.vala | 44 +-
tests/tracker/family-name-updates.vala | 31 +-
tests/tracker/given-name-updates.vala | 19 +-
tests/tracker/name-details-interface.vala | 14 +-
tests/tracker/nickname-updates.vala | 26 +-
tests/tracker/prefix-name-updates.vala | 19 +-
tests/tracker/remove-persona.vala | 208 ++++
tests/tracker/set-alias.vala | 168 ++++
tests/tracker/set-avatar.vala | 145 +++
tests/tracker/set-birthday.vala | 154 +++
tests/tracker/set-emails.vala | 160 +++
tests/tracker/set-favourite.vala | 180 ++++
tests/tracker/set-full-name.vala | 144 +++
tests/tracker/set-gender.vala | 142 +++
tests/tracker/set-im-addresses.vala | 177 ++++
tests/tracker/set-notes.vala | 153 +++
tests/tracker/set-phones.vala | 160 +++
tests/tracker/set-postal-addresses.vala | 174 ++++
tests/tracker/set-roles.vala | 153 +++
tests/tracker/set-structured-name.vala | 156 +++
tests/tracker/set-urls.vala | 166 ++++
tests/tracker/suffix-name-updates.vala | 3 +
29 files changed, 4643 insertions(+), 259 deletions(-)
---
diff --git a/NEWS b/NEWS
index 718d6f0..d234076 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Bugs fixed:
* Bug 645475 â?? Linker warnings for Tracker backend tests
* Bug 645570 â?? Fix checks for empty and equal StructuredNames
* Bug 645989 â?? Ensure add_persona_from_details handles the basic attribute
+* Bug 645413 â?? Write support for Tracker
API changes:
* Add equal () to StructuredName
diff --git a/backends/tracker/lib/trf-persona-store.vala b/backends/tracker/lib/trf-persona-store.vala
index ce43a11..930954c 100644
--- a/backends/tracker/lib/trf-persona-store.vala
+++ b/backends/tracker/lib/trf-persona-store.vala
@@ -37,7 +37,7 @@ internal enum Trf.Fields
ADDITIONAL_NAMES,
PREFIXES,
SUFFIXES,
- NICKNAME,
+ ALIAS,
BIRTHDAY,
AVATAR_URL,
IM_ADDRESSES,
@@ -74,7 +74,8 @@ internal enum Trf.AfflInfoFields
AFFL_PHONE,
AFFL_WEBSITE,
AFFL_BLOG,
- AFFL_URL
+ AFFL_URL,
+ IM_NICKNAME
}
internal enum Trf.PostalAddressFields
@@ -111,7 +112,8 @@ internal enum Trf.IMFields
{
TRACKER_ID,
PROTO,
- ID
+ ID,
+ IM_NICKNAME
}
internal enum Trf.PhoneFields
@@ -131,6 +133,21 @@ internal enum Trf.TagFields
TRACKER_ID
}
+private enum Trf.Attrib
+{
+ EMAILS,
+ PHONES,
+ URLS,
+ IM_ADDRESSES,
+ POSTAL_ADDRESSES
+}
+
+private const char _REMOVE_ALL_ATTRIBS = 0x01;
+private const char _REMOVE_PHONES = 0x02;
+private const char _REMOVE_POSTALS = 0x04;
+private const char _REMOVE_IM_ADDRS = 0x08;
+private const char _REMOVE_EMAILS = 0x10;
+
/**
* A persona store.
* It will create { link Persona}s for each contacts on the main addressbook.
@@ -165,7 +182,8 @@ public class Trf.PersonaStore : Folks.PersonaStore
"GROUP_CONCAT ( " +
" fn:concat(tracker:id(?affl),'\t'," +
" tracker:coalesce(nco:imProtocol(?a),''), " +
- "'\t', tracker:coalesce(nco:imID(?a),'')),'\\n') " +
+ "'\t', tracker:coalesce(nco:imID(?a),''), '\t'," +
+ " tracker:coalesce(nco:imNickname(?a),'')), '\\n') " +
"WHERE { ?_contact nco:hasAffiliation ?affl. " +
" ?affl nco:hasIMAddress ?a } ) " +
@@ -248,7 +266,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
"WHERE { ?_contact nco:hasAffiliation " +
"?affl . ?affl nco:hasPostalAddress ?postal }) " +
- "{ ?_contact a nco:PersonContact . } " +
+ "{ ?_contact a nco:PersonContact . %s } " +
"ORDER BY tracker:id(?_contact) ";
@@ -268,7 +286,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
*/
public override MaybeBool can_add_personas
{
- get { return MaybeBool.FALSE; }
+ get { return MaybeBool.TRUE; }
}
/**
@@ -304,7 +322,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
*/
public override MaybeBool can_remove_personas
{
- get { return MaybeBool.FALSE; }
+ get { return MaybeBool.TRUE; }
}
/**
@@ -344,27 +362,438 @@ public class Trf.PersonaStore : Folks.PersonaStore
/**
* Add a new { link Persona} to the PersonaStore.
*
+ * Accepted keys for `details` are:
+ * - PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES)
+ * - PersonaStore.detail_key (PersonaDetail.ALIAS)
+ * - PersonaStore.detail_key (PersonaDetail.FULL_NAME)
+ * - PersonaStore.detail_key (PersonaDetail.FAVOURITE)
+ * - PersonaStore.detail_key (PersonaDetail.STRUCTURED_NAME)
+ * - PersonaStore.detail_key (PersonaDetail.AVATAR)
+ * - PersonaStore.detail_key (PersonaDetail.BIRTHDAY)
+ * - PersonaStore.detail_key (PersonaDetail.GENDER)
+ * - PersonaStore.detail_key (PersonaDetail.EMAIL_ADDRESSES)
+ * - PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES)
+ * - PersonaStore.detail_key (PersonaDetail.NOTES)
+ * - PersonaStore.detail_key (PersonaDetail.PHONE_NUMBERS)
+ * - PersonaStore.detail_key (PersonaDetail.POSTAL_ADDRESSES)
+ * - PersonaStore.detail_key (PersonaDetail.ROLES)
+ * - PersonaStore.detail_key (PersonaDetail.URL)
+ *
* See { link Folks.PersonaStore.add_persona_from_details}.
*/
public override async Folks.Persona? add_persona_from_details (
HashTable<string, Value?> details) throws Folks.PersonaStoreError
{
- throw new PersonaStoreError.READ_ONLY (
- "Personas cannot be added to this store.");
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.insert_open (null);
+ builder.subject ("_:p");
+ builder.predicate ("a");
+ builder.object ("nco:PersonContact");
+
+ foreach (var k in details.get_keys ())
+ {
+ Value? v = details.lookup (k);
+ if (k == this.detail_key (PersonaDetail.ALIAS))
+ {
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_NICKNAME);
+ builder.object_string (v.get_string ());
+ }
+ else if (k == this.detail_key (PersonaDetail.FULL_NAME))
+ {
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_FULLNAME);
+ builder.object_string (v.get_string ());
+ }
+ else if (k == this.detail_key (PersonaDetail.STRUCTURED_NAME))
+ {
+ StructuredName sname = (StructuredName) v.get_object ();
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_FAMILY);
+ builder.object_string (sname.family_name);
+ builder.predicate (Trf.OntologyDefs.NCO_GIVEN);
+ builder.object_string (sname.given_name);
+ builder.predicate (Trf.OntologyDefs.NCO_ADDITIONAL);
+ builder.object_string (sname.additional_names);
+ builder.predicate (Trf.OntologyDefs.NCO_SUFFIX);
+ builder.object_string (sname.suffixes);
+ builder.predicate (Trf.OntologyDefs.NCO_PREFIX);
+ builder.object_string (sname.prefixes);
+ }
+ else if (k == this.detail_key (PersonaDetail.FAVOURITE))
+ {
+ if (v.get_boolean ())
+ {
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NAO_TAG);
+ builder.object (Trf.OntologyDefs.NAO_FAVORITE);
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.AVATAR))
+ {
+ var avatar = (File) v.get_object ();
+ builder.subject ("_:photo");
+ builder.predicate ("a");
+ builder.object ("nfo:Image, nie:DataObject");
+ builder.predicate (Trf.OntologyDefs.NIE_URL);
+ builder.object_string (avatar.get_uri ());
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_PHOTO);
+ builder.object ("_:photo");
+ }
+ else if (k == this.detail_key (PersonaDetail.BIRTHDAY))
+ {
+ var birthday = (DateTime) v.get_boxed ();
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_BIRTHDAY);
+ TimeVal tv;
+ birthday.to_timeval (out tv);
+ builder.object_string (tv.to_iso8601 ());
+ }
+ else if (k == this.detail_key (PersonaDetail.GENDER))
+ {
+ var gender = (Gender) v.get_enum ();
+ if (gender != Gender.UNSPECIFIED)
+ {
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_GENDER);
+ if (gender == Gender.MALE)
+ builder.object (Trf.OntologyDefs.NCO_MALE);
+ else
+ builder.object (Trf.OntologyDefs.NCO_FEMALE);
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.EMAIL_ADDRESSES))
+ {
+ unowned GLib.List<FieldDetails> email_addresses =
+ (GLib.List<FieldDetails>) v.get_pointer ();
+ int email_cnt = 0;
+ foreach (var e in email_addresses)
+ {
+ var email_affl = "_:email_affl%d".printf (email_cnt);
+ var email = "_:email%d".printf (email_cnt);
+ builder.subject (email);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_EMAIL);
+ builder.predicate (Trf.OntologyDefs.NCO_EMAIL_PROP);
+ builder.object_string (e.value);
+
+ builder.subject (email_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_EMAIL);
+ builder.object (email);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (email_affl);
+
+ email_cnt++;
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.IM_ADDRESSES))
+ {
+ var im_addresses =
+ (HashTable<string, LinkedHashSet<string>>) v.get_boxed ();
+
+ int im_cnt = 0;
+ foreach (var proto in im_addresses.get_keys ())
+ {
+ var addrs_a = im_addresses.lookup (proto);
+
+ foreach (var addr in addrs_a)
+ {
+ var im_affl = "_:im_affl%d".printf (im_cnt);
+ var im = "_:im%d".printf (im_cnt);
+
+ builder.subject (im);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_IMADDRESS);
+ builder.predicate (Trf.OntologyDefs.NCO_IMID);
+ builder.object_string (addr);
+ builder.predicate (Trf.OntologyDefs.NCO_IMPROTOCOL);
+ builder.object_string (proto);
+
+ builder.subject (im_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_IMADDRESS);
+ builder.object (im);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (im_affl);
+
+ im_cnt++;
+ }
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.NOTES))
+ {
+ var notes = (Gee.HashSet<Note>) v.get_object ();
+ foreach (var n in notes)
+ {
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_NOTE);
+ builder.object_string (n.content);
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.PHONE_NUMBERS))
+ {
+ unowned GLib.List<FieldDetails> phone_numbers =
+ (GLib.List<FieldDetails>) v.get_pointer ();
+
+ int phone_cnt = 0;
+ foreach (var p in phone_numbers)
+ {
+ var phone_affl = "_:phone_affl%d".printf (phone_cnt);
+ var phone = "_:phone%d".printf (phone_cnt);
+ builder.subject (phone);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_PHONE);
+ builder.predicate (Trf.OntologyDefs.NCO_PHONE_PROP);
+ builder.object_string (p.value);
+
+ builder.subject (phone_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_PHONE);
+ builder.object (phone);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (phone_affl);
+
+ phone_cnt++;
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.ROLES))
+ {
+ var roles = (Gee.HashSet<Role>) v.get_object ();
+
+ int roles_cnt = 0;
+ foreach (var r in roles)
+ {
+ var role_affl = "_:role_affl%d".printf (roles_cnt);
+
+ builder.subject (role_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_ROLE);
+ builder.object_string (r.title);
+ builder.predicate (Trf.OntologyDefs.NCO_ORG);
+ builder.object_string (r.organisation_name);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (role_affl);
+
+ roles_cnt++;
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.POSTAL_ADDRESSES))
+ {
+ unowned GLib.List<PostalAddress> postal_addresses =
+ (GLib.List<PostalAddress>) v.get_pointer ();
+
+ int postal_cnt = 0;
+ foreach (var pa in postal_addresses)
+ {
+ var postal_affl = "_:postal_affl%d".printf (postal_cnt);
+ var postal = "_:postal%d".printf (postal_cnt);
+ builder.subject (postal);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_POSTAL_ADDRESS);
+ builder.predicate (Trf.OntologyDefs.NCO_POBOX);
+ builder.object_string (pa.po_box);
+ builder.predicate (Trf.OntologyDefs.NCO_LOCALITY);
+ builder.object_string (pa.locality);
+ builder.predicate (Trf.OntologyDefs.NCO_POSTALCODE);
+ builder.object_string (pa.postal_code);
+ builder.predicate (Trf.OntologyDefs.NCO_STREET_ADDRESS);
+ builder.object_string (pa.street);
+ builder.predicate (Trf.OntologyDefs.NCO_EXTENDED_ADDRESS);
+ builder.object_string (pa.extension);
+ builder.predicate (Trf.OntologyDefs.NCO_COUNTRY);
+ builder.object_string (pa.country);
+ builder.predicate (Trf.OntologyDefs.NCO_REGION);
+ builder.object_string (pa.region);
+
+ builder.subject (postal_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_POSTAL_ADDRESS);
+ builder.object (postal);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (postal_affl);
+
+ postal_cnt++;
+ }
+ }
+ else if (k == this.detail_key (PersonaDetail.URLS))
+ {
+ unowned GLib.List<FieldDetails> urls =
+ (GLib.List<FieldDetails>) v.get_pointer ();
+
+ int url_cnt = 0;
+ foreach (var u in urls)
+ {
+ var url_affl = "_:url_affl%d".printf (url_cnt);
+
+ builder.subject (url_affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_URL);
+ builder.object_string (u.value);
+
+ builder.subject ("_:p");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (url_affl);
+
+ url_cnt++;
+ }
+ }
+ else
+ {
+ throw new PersonaStoreError.INVALID_ARGUMENT (
+ /* Translators: the first parameter identifies the
+ * persona store and the second the unknown key
+ * that was received with the details params. */
+ _("Unrecognized paramter %s by the %s PersonaStore:\n')"),
+ this.type_id, k);
+ }
+ }
+ builder.insert_close ();
+
+ Trf.Persona ret = null;
+ lock (this._personas)
+ {
+ string? contact_urn = yield this._insert_persona (builder.result,
+ "p");
+ if (contact_urn != null)
+ {
+ string filter = " FILTER(?_contact = <%s>) ".printf (contact_urn);
+ string query = this._INITIAL_QUERY.printf (filter);
+ Queue<Persona> ret_personas;
+ ret_personas = yield this._do_add_contacts (query);
+ ret = ret_personas.pop_head ();
+ }
+ else
+ {
+ debug ("Failed to inserting the new persona into Tracker.");
+ }
+ }
+
+ return ret;
}
/**
* Remove a { link Persona} from the PersonaStore.
*
* See { link Folks.PersonaStore.remove_persona}.
+ *
*/
public override async void remove_persona (Folks.Persona persona)
throws Folks.PersonaStoreError
{
- throw new PersonaStoreError.READ_ONLY (
- "Personas cannot be removed from this store.");
+ var urn = yield this._remove_attributes_from_persona (persona,
+ _REMOVE_ALL_ATTRIBS);
+
+ /* Finally: remove literal properties */
+ var q = " DELETE { " +
+ " %s ?p ?o " +
+ "} " +
+ "WHERE { " +
+ " %s ?p ?o " +
+ "} ";
+ yield this._tracker_update (q.printf (urn, urn), "remove_persona");
+ }
+
+ private async string _remove_attributes_from_persona (Folks.Persona persona,
+ char remove_flag)
+ {
+ var urn = yield this._urn_from_persona (persona);
+ yield this._remove_attributes (urn, remove_flag);
+ return urn;
}
+ /*
+ * Garbage collecting related resources:
+ * - for each related resource we (recursively)
+ * check to if the deleted nco:Person
+ * is the only one holding a link, if so we
+ * remove the resource.
+ */
+ private async void _remove_attributes (string urn, char remove_flag)
+ {
+ Gee.HashSet<string> affiliations =
+ yield this._affiliations_from_persona (urn);
+
+ foreach (var affl in affiliations)
+ {
+ bool got_attrib = false;
+
+ if ((remove_flag & _REMOVE_ALL_ATTRIBS) ==
+ _REMOVE_ALL_ATTRIBS ||
+ (remove_flag & _REMOVE_PHONES) == _REMOVE_PHONES)
+ {
+ Gee.HashSet<string> phones =
+ yield this._phones_from_affiliation (affl);
+
+ foreach (var phone in phones)
+ {
+ got_attrib = true;
+ yield this._delete_resource (phone);
+ }
+ }
+
+ if ((remove_flag & _REMOVE_ALL_ATTRIBS) ==
+ _REMOVE_ALL_ATTRIBS ||
+ (remove_flag & _REMOVE_POSTALS) == _REMOVE_POSTALS)
+ {
+ Gee.HashSet<string> postals =
+ yield this._postals_from_affiliation (affl);
+ foreach (var postal in postals)
+ {
+ got_attrib = true;
+ yield this._delete_resource (postal);
+ }
+ }
+
+ if ((remove_flag & _REMOVE_ALL_ATTRIBS) ==
+ _REMOVE_ALL_ATTRIBS ||
+ (remove_flag & _REMOVE_IM_ADDRS) == _REMOVE_IM_ADDRS)
+ {
+ Gee.HashSet<string> im_addrs =
+ yield this._imaddrs_from_affiliation (affl);
+ foreach (var im_addr in im_addrs)
+ {
+ got_attrib = true;
+ yield this._delete_resource (im_addr);
+ }
+ }
+
+ if ((remove_flag & _REMOVE_ALL_ATTRIBS) ==
+ _REMOVE_ALL_ATTRIBS ||
+ (remove_flag & _REMOVE_EMAILS) == _REMOVE_EMAILS)
+ {
+ Gee.HashSet<string> emails =
+ yield this._emails_from_affiliation (affl);
+ foreach (var email in emails)
+ {
+ got_attrib = true;
+ yield yield this._delete_resource (email);
+ }
+ }
+
+ if (got_attrib ||
+ (remove_flag & _REMOVE_ALL_ATTRIBS) == _REMOVE_ALL_ATTRIBS)
+ yield this._delete_resource (affl);
+ }
+ }
+
/**
* Prepare the PersonaStore for use.
*
@@ -381,10 +810,11 @@ public class Trf.PersonaStore : Folks.PersonaStore
{
try
{
- this._connection = Tracker.Sparql.Connection.get ();
+ this._connection =
+ yield Tracker.Sparql.Connection.get_async ();
yield this._build_predicates_table ();
- yield this._do_add_contacts (this._INITIAL_QUERY);
+ yield this._do_add_contacts (this._INITIAL_QUERY.printf (""));
/* Don't add a match rule for all signals from Tracker but
* only for GraphUpdated with the specific class we need. We
@@ -402,6 +832,9 @@ public class Trf.PersonaStore : Folks.PersonaStore
"GraphUpdated", this._OBJECT_PATH,
Trf.OntologyDefs.PERSON_CLASS, GLib.DBusSignalFlags.NONE,
this._graph_updated_cb);
+
+ this._is_prepared = true;
+ this.notify_property ("is-prepared");
}
catch (GLib.IOError e1)
{
@@ -566,53 +999,79 @@ public class Trf.PersonaStore : Folks.PersonaStore
return;
}
- var removed_personas = new Queue<Persona> ();
- var added_personas = new Queue<Persona> ();
+ this._handle_events ((owned) iter_del, (owned) iter_ins);
+ }
+
+ private async void _handle_events
+ (owned VariantIter iter_del, owned VariantIter iter_ins)
+ {
+ yield this._handle_delete_events ((owned) iter_del);
+ yield this._handle_insert_events ((owned) iter_ins);
+ }
+ private async void _handle_delete_events (owned VariantIter iter_del)
+ {
+ var removed_personas = new Queue<Persona> ();
var nco_person_id =
this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_PERSON);
var rdf_type_id = this._prefix_tracker_id.get (Trf.OntologyDefs.RDF_TYPE);
-
Event e = Event ();
while (iter_del.next
("(iiii)", &e.graph_id, &e.subject_id, &e.pred_id, &e.object_id))
{
var p_id = Trf.Persona.build_iid (this.id, e.subject_id.to_string ());
- var persona = this._personas.lookup (p_id);
- if (persona != null)
+ if (e.pred_id == rdf_type_id &&
+ e.object_id == nco_person_id)
{
- if (e.pred_id == rdf_type_id &&
- e.object_id == nco_person_id)
+ lock (this._personas)
{
- removed_personas.push_tail (persona);
- _personas.remove (persona.iid);
+ var removed_p = this._personas.lookup (p_id);
+ if (removed_p != null)
+ {
+ removed_personas.push_tail (removed_p);
+ _personas.remove (removed_p.iid);
+ }
}
- else
+ }
+ else
+ {
+ var persona = this._personas.lookup (p_id);
+ if (persona != null)
{
- this._do_update (persona, e, false);
+ yield this._do_update (persona, e, false);
}
}
}
+ if (removed_personas.length > 0)
+ {
+ this.personas_changed (null, removed_personas.head, null, null, 0);
+ }
+ }
+
+ private async void _handle_insert_events (owned VariantIter iter_ins)
+ {
+ var added_personas = new Queue<Persona> ();
+ Event e = Event ();
+
while (iter_ins.next
("(iiii)", &e.graph_id, &e.subject_id, &e.pred_id, &e.object_id))
{
var subject_tracker_id = e.subject_id.to_string ();
var p_id = Trf.Persona.build_iid (this.id, subject_tracker_id);
- var persona = this._personas.lookup (p_id);
- if (persona == null)
+ Trf.Persona persona;
+ lock (this._personas)
{
- persona = new Trf.Persona (this, subject_tracker_id);
- this._personas.insert (persona.iid, persona);
- added_personas.push_tail (persona);
+ persona = this._personas.lookup (p_id);
+ if (persona == null)
+ {
+ persona = new Trf.Persona (this, subject_tracker_id);
+ this._personas.insert (persona.iid, persona);
+ added_personas.push_tail (persona);
+ }
}
- this._do_update (persona, e);
- }
-
- if (removed_personas.length > 0)
- {
- this.personas_changed (null, removed_personas.head, null, null, 0);
+ yield this._do_update (persona, e);
}
if (added_personas.length > 0)
@@ -621,10 +1080,11 @@ public class Trf.PersonaStore : Folks.PersonaStore
}
}
- private async void _do_add_contacts (string query)
+ private async Queue<Persona> _do_add_contacts (string query)
{
- try {
- var added_personas = new Queue<Persona> ();
+ var added_personas = new Queue<Persona> ();
+
+ try {
Sparql.Cursor cursor = yield this._connection.query_async (query);
while (cursor.next ())
@@ -647,9 +1107,11 @@ public class Trf.PersonaStore : Folks.PersonaStore
} catch (GLib.Error e) {
warning ("Couldn't perform queries: %s %s", query, e.message);
}
+
+ return added_personas;
}
- private void _do_update (Persona p, Event e, bool adding = true)
+ private async void _do_update (Persona p, Event e, bool adding = true)
{
if (e.pred_id ==
this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_FULLNAME))
@@ -658,21 +1120,22 @@ public class Trf.PersonaStore : Folks.PersonaStore
if (adding)
{
fullname =
- this._get_property (e.subject_id, Trf.OntologyDefs.NCO_FULLNAME);
+ yield this._get_property (e.subject_id,
+ Trf.OntologyDefs.NCO_FULLNAME);
}
p._update_full_name (fullname);
}
else if (e.pred_id ==
this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_NICKNAME))
{
- string nickname = "";
+ string alias = "";
if (adding)
{
- nickname =
- this._get_property (
- e.subject_id, Trf.OntologyDefs.NCO_NICKNAME);
+ alias =
+ yield this._get_property (
+ e.subject_id, Trf.OntologyDefs.NCO_NICKNAME);
}
- p._update_nickname (nickname);
+ p._update_alias (alias);
}
else if (e.pred_id ==
this._prefix_tracker_id.get (Trf.OntologyDefs.NCO_FAMILY))
@@ -680,8 +1143,8 @@ public class Trf.PersonaStore : Folks.PersonaStore
string family_name = "";
if (adding)
{
- family_name = this._get_property
- (e.subject_id, Trf.OntologyDefs.NCO_FAMILY);
+ family_name = yield this._get_property (e.subject_id,
+ Trf.OntologyDefs.NCO_FAMILY);
}
p._update_family_name (family_name);
}
@@ -691,7 +1154,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
string given_name = "";
if (adding)
{
- given_name = this._get_property (
+ given_name = yield this._get_property (
e.subject_id, Trf.OntologyDefs.NCO_GIVEN);
}
p._update_given_name (given_name);
@@ -702,7 +1165,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
string additional_name = "";
if (adding)
{
- additional_name = this._get_property
+ additional_name = yield this._get_property
(e.subject_id, Trf.OntologyDefs.NCO_ADDITIONAL);
}
p._update_additional_names (additional_name);
@@ -713,7 +1176,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
string suffix_name = "";
if (adding)
{
- suffix_name = this._get_property
+ suffix_name = yield this._get_property
(e.subject_id, Trf.OntologyDefs.NCO_SUFFIX);
}
p._update_suffixes (suffix_name);
@@ -724,23 +1187,23 @@ public class Trf.PersonaStore : Folks.PersonaStore
string prefix_name = "";
if (adding)
{
- prefix_name = this._get_property
+ prefix_name = yield this._get_property
(e.subject_id, Trf.OntologyDefs.NCO_PREFIX);
}
p._update_prefixes (prefix_name);
}
else if (e.pred_id == this._prefix_tracker_id.get
- ("nao:hasTag"))
+ (Trf.OntologyDefs.NAO_TAG))
{
if (e.object_id == this.get_favorite_id ())
{
if (adding)
{
- p.is_favourite = true;
+ p._set_favourite (true);
}
else
{
- p.is_favourite = false;
+ p._set_favourite (false);
}
}
}
@@ -749,7 +1212,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
{
if (adding)
{
- var email = this._get_property (
+ var email = yield this._get_property (
e.object_id,
Trf.OntologyDefs.NCO_EMAIL_PROP,
Trf.OntologyDefs.NCO_EMAIL);
@@ -765,7 +1228,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
{
if (adding)
{
- var phone = this._get_property (
+ var phone = yield this._get_property (
e.object_id, Trf.OntologyDefs.NCO_PHONE_PROP,
Trf.OntologyDefs.NCO_PHONE);
p._add_phone (phone, e.object_id.to_string ());
@@ -780,15 +1243,18 @@ public class Trf.PersonaStore : Folks.PersonaStore
{
if (adding)
{
- var affl_info = this._get_affl_info (e.subject_id.to_string (),
+ var affl_info =
+ yield this._get_affl_info (e.subject_id.to_string (),
e.object_id.to_string ());
debug ("affl_info : %s", affl_info.to_string ());
if (affl_info.im_tracker_id != null)
{
- p._add_im_address (affl_info.affl_tracker_id,
- affl_info.im_proto, affl_info.im_account_id);
+ p._update_nickname (affl_info.im_nickname);
+ if (affl_info.im_proto != null)
+ p._add_im_address (affl_info.affl_tracker_id,
+ affl_info.im_proto, affl_info.im_account_id);
}
if (affl_info.affl_tracker_id != null)
@@ -838,7 +1304,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
string bday = "";
if (adding)
{
- bday = this._get_property (
+ bday = yield this._get_property (
e.subject_id, Trf.OntologyDefs.NCO_BIRTHDAY);
}
p._set_birthday (bday);
@@ -849,7 +1315,7 @@ public class Trf.PersonaStore : Folks.PersonaStore
string note = "";
if (adding)
{
- note = this._get_property (
+ note = yield this._get_property (
e.subject_id, Trf.OntologyDefs.NCO_NOTE);
}
p._set_note (note);
@@ -872,18 +1338,17 @@ public class Trf.PersonaStore : Folks.PersonaStore
string avatar_url = "";
if (adding)
{
- avatar_url = this._get_property (e.object_id,
+ avatar_url = yield this._get_property (e.object_id,
Trf.OntologyDefs.NIE_URL, Trf.OntologyDefs.NFO_IMAGE);
}
p._set_avatar (avatar_url);
}
}
- private string _get_property
+ private async string _get_property
(int subject_tracker_id, string property,
string subject_type = Trf.OntologyDefs.NCO_PERSON)
{
- string ret = "";
const string query_template =
"SELECT ?property WHERE" +
" { ?p a %s ; " +
@@ -892,66 +1357,48 @@ public class Trf.PersonaStore : Folks.PersonaStore
string query = query_template.printf (subject_type,
property, subject_tracker_id);
-
- try
- {
- Sparql.Cursor cursor = this._connection.query (query);
- while (cursor.next ())
- {
- var prop = cursor.get_string (0);
- if (prop != null)
- {
- ret = prop.dup ();
- }
- }
- }
- catch (Tracker.Sparql.Error e1)
- {
- warning ("Couldn't fetch propery: %s %s", query, e1.message);
- }
- catch (GLib.Error e2)
- {
- warning ("Couldn't fetch property: %s %s", query, e2.message);
- }
-
- return ret;
+ return yield this._single_value_query (query);
}
/*
* This should be kept in sync with Trf.AfflInfoFields
*/
- private Trf.AfflInfo _get_affl_info (
+ private async Trf.AfflInfo _get_affl_info (
string person_id, string affiliation_id)
{
Trf.AfflInfo affl_info = new Trf.AfflInfo ();
const string query_template =
"SELECT " +
"tracker:id(?i) " +
- "nco:imProtocol(?i) " +
- "nco:imID(?i) " +
+ Trf.OntologyDefs.NCO_IMPROTOCOL + "(?i) " +
+ Trf.OntologyDefs.NCO_IMID + "(?i) " +
"tracker:id(?a) " +
- "nco:role(?a) " +
- "nco:org(?a) " +
- "nco:pobox(?postal) " +
- "nco:district(?postal) " +
- "nco:county(?postal) " +
- "nco:locality(?postal) " +
- "nco:postalcode(?postal) " +
- "nco:streetAddress(?postal) " +
- "nco:addressLocation(?postal) " +
- "nco:extendedAddress(?postal) " +
- "nco:country(?postal) " +
- "nco:region(?postal) " +
- "nco:emailAddress(?e) " +
- "nco:phoneNumber(?number) " +
- "nco:websiteUrl(?a) " +
- "nco:blogUrl(?a) " +
- "nco:url(?a) " +
- " WHERE { ?p a nco:PersonContact ; nco:hasAffiliation ?a . " +
- " OPTIONAL { ?a nco:hasIMAddress ?i } . " +
- " OPTIONAL { ?a nco:hasPostalAddress ?postal } . " +
- " OPTIONAL { ?a nco:hasEmailAddress ?e } . " +
- " OPTIONAL { ?a nco:hasPhoneNumber ?number } " +
+ Trf.OntologyDefs.NCO_ROLE + "(?a) " +
+ Trf.OntologyDefs.NCO_ORG + "(?a) " +
+ Trf.OntologyDefs.NCO_POBOX + "(?postal) " +
+ Trf.OntologyDefs.NCO_DISTRICT + "(?postal) " +
+ Trf.OntologyDefs.NCO_COUNTY + "(?postal) " +
+ Trf.OntologyDefs.NCO_LOCALITY + "(?postal) " +
+ Trf.OntologyDefs.NCO_POSTALCODE + "(?postal) " +
+ Trf.OntologyDefs.NCO_STREET_ADDRESS + "(?postal) " +
+ Trf.OntologyDefs.NCO_ADDRESS_LOCATION + "(?postal) " +
+ Trf.OntologyDefs.NCO_EXTENDED_ADDRESS + "(?postal) " +
+ Trf.OntologyDefs.NCO_COUNTRY + "(?postal) " +
+ Trf.OntologyDefs.NCO_REGION + "(?postal) " +
+ Trf.OntologyDefs.NCO_EMAIL_PROP + "(?e) " +
+ Trf.OntologyDefs.NCO_PHONE_PROP + "(?number) " +
+ Trf.OntologyDefs.NCO_WEBSITE + "(?a) " +
+ Trf.OntologyDefs.NCO_BLOG + "(?a) " +
+ Trf.OntologyDefs.NCO_URL + "(?a) " +
+ Trf.OntologyDefs.NCO_IM_NICKNAME + "(?i) " +
+ "WHERE { "+
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " ; " +
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION + " ?a . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_HAS_IMADDRESS + " ?i } . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_HAS_POSTAL_ADDRESS +
+ " ?postal } . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_HAS_EMAIL + " ?e } . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_HAS_PHONE + " ?number } " +
" FILTER(tracker:id(?p) = %s" +
" && tracker:id(?a) = %s" +
" ) } ";
@@ -962,8 +1409,8 @@ public class Trf.PersonaStore : Folks.PersonaStore
try
{
- Sparql.Cursor cursor = this._connection.query (query);
- while (cursor.next ())
+ Sparql.Cursor cursor = yield this._connection.query_async (query);
+ while (yield cursor.next_async ())
{
affl_info.im_tracker_id = cursor.get_string
(Trf.AfflInfoFields.IM_TRACKER_ID).dup ();
@@ -971,6 +1418,9 @@ public class Trf.PersonaStore : Folks.PersonaStore
(Trf.AfflInfoFields.IM_PROTOCOL).dup ();
affl_info.im_account_id = cursor.get_string
(Trf.AfflInfoFields.IM_ACCOUNT_ID).dup ();
+ affl_info.im_nickname = cursor.get_string
+ (Trf.AfflInfoFields.IM_NICKNAME).dup ();
+
affl_info.affl_tracker_id = cursor.get_string
(Trf.AfflInfoFields.AFFL_TRACKER_ID).dup ();
affl_info.title = cursor.get_string
@@ -1025,4 +1475,741 @@ public class Trf.PersonaStore : Folks.PersonaStore
return affl_info;
}
+
+ private async string? _insert_persona (string query, string persona_var)
+ {
+ GLib.Variant variant;
+ string contact_urn = null;
+
+ try
+ {
+ debug ("_insert_persona: %s", query);
+ variant = yield this._connection.update_blank_async (query);
+
+ VariantIter iter1, iter2, iter3;
+ string anon_var = null;
+ iter1 = variant.iterator ();
+
+ while (iter1.next ("aa{ss}", out iter2))
+ {
+ if (iter2 == null)
+ continue;
+
+ while (iter2.next ("a{ss}", out iter3))
+ {
+ if (iter3 == null)
+ continue;
+
+ while (iter3.next ("{ss}", out anon_var, out contact_urn))
+ {
+ /* The dictionary mapping blank node names to
+ * IRIs doesn't have a fixed order so we need
+ * check for the anon var corresponding to
+ * nco:PersonContact.
+ */
+ if (anon_var == persona_var)
+ return contact_urn;
+ }
+ }
+ }
+ }
+ catch (GLib.Error e)
+ {
+ contact_urn = null;
+ warning ("Couldn't insert nco:PersonContact: %s", e.message);
+ }
+
+ return null;
+ }
+
+ private async string _single_value_query (string query)
+ {
+ Gee.HashSet<string> rows = yield this._multi_value_query (query);
+ foreach (var r in rows)
+ {
+ return r;
+ }
+ return "";
+ }
+
+ private async Gee.HashSet<string> _multi_value_query (string query)
+ {
+ Gee.HashSet<string> ret = new Gee.HashSet<string> ();
+
+ try
+ {
+ Sparql.Cursor cursor = yield this._connection.query_async (query);
+ while (cursor.next ())
+ {
+ var prop = cursor.get_string (0);
+ if (prop != null)
+ ret.add (prop);
+ }
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ warning ("Couldn't run query: %s %s", query, e1.message);
+ }
+ catch (GLib.Error e2)
+ {
+ warning ("Couldn't run query: %s %s", query, e2.message);
+ }
+
+ return ret;
+ }
+
+ private async string _urn_from_tracker_id (string tracker_id)
+ {
+ const string query = "SELECT fn:concat('<', tracker:uri(%s), '>') " +
+ "WHERE {}";
+ return yield this._single_value_query (query.printf (tracker_id));
+ }
+
+ internal async void _set_alias (Trf.Persona persona, string alias)
+ {
+ const string query_t = "DELETE { "+
+ " ?p " + Trf.OntologyDefs.NCO_NICKNAME + " ?n " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " ; " +
+ Trf.OntologyDefs.NCO_NICKNAME + " ?n . " +
+ " FILTER(tracker:id(?p) = %s) " +
+ "} " +
+ "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NCO_NICKNAME + " '%s' " +
+ "} " +
+ "WHERE { "+
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ "FILTER (tracker:id(?p) = %s) " +
+ "} ";
+
+ string query = query_t.printf (persona.tracker_id (), alias,
+ persona.tracker_id ());
+
+ yield this._tracker_update (query, "change_alias");
+ }
+
+ internal async void _set_is_favourite (Folks.Persona persona,
+ bool is_favourite)
+ {
+ const string ins_q = "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NAO_TAG + " " +
+ Trf.OntologyDefs.NAO_FAVORITE +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+ const string del_q = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NAO_TAG + " " +
+ Trf.OntologyDefs.NAO_FAVORITE + " " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+ string query;
+
+ if (is_favourite)
+ {
+ query = ins_q.printf (((Trf.Persona) persona).tracker_id ());
+ }
+ else
+ {
+ query = del_q.printf (((Trf.Persona) persona).tracker_id ());
+ }
+
+ yield this._tracker_update (query, "change_is_favourite");
+ }
+
+ internal async void _set_phones (Folks.Persona persona,
+ owned GLib.List<FieldDetails> phone_numbers)
+ {
+ yield this._set_attrib (persona, (owned) phone_numbers,
+ Trf.Attrib.PHONES);
+ }
+
+ internal async void _set_emails (Folks.Persona persona,
+ owned GLib.List<FieldDetails> emails)
+ {
+ yield this._set_attrib (persona, (owned) emails,
+ Trf.Attrib.EMAILS);
+ }
+
+ internal async void _set_urls (Folks.Persona persona,
+ owned GLib.List<FieldDetails> urls)
+ {
+ yield this._set_attrib (persona, (owned) urls,
+ Trf.Attrib.URLS);
+ }
+
+ internal async void _set_im_addresses (Folks.Persona persona,
+ owned HashTable<string, LinkedHashSet<string>> im_addresses)
+ {
+ /* FIXME:
+ * - this conversion should go away once we've switched to use the
+ * same data structure for each property that is a list of something.
+ * See: https://bugzilla.gnome.org/show_bug.cgi?id=646079 */
+ GLib.List <FieldDetails> ims = new GLib.List <FieldDetails> ();
+ foreach (var proto in im_addresses.get_keys ())
+ {
+ var addrs = im_addresses.lookup (proto);
+ foreach (var a in addrs)
+ {
+ var fd = new FieldDetails (a);
+ fd.set_parameter ("proto", proto);
+ ims.prepend ((owned) fd);
+ }
+ }
+
+ yield this._set_attrib (persona, (owned) ims,
+ Trf.Attrib.IM_ADDRESSES);
+ }
+
+ internal async void _set_postal_addresses (Folks.Persona persona,
+ owned GLib.List<PostalAddress> postal_addresses)
+ {
+ yield this._set_attrib (persona, (owned) postal_addresses,
+ Trf.Attrib.POSTAL_ADDRESSES);
+ }
+
+ internal async void _set_roles (Folks.Persona persona,
+ owned Gee.HashSet<Role> roles)
+ {
+ const string del_t = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NCO_HAS_AFFILIATION + " ?a " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + "; " +
+ " " + Trf.OntologyDefs.NCO_HAS_AFFILIATION + " ?a . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_ORG + " ?o } . " +
+ " OPTIONAL { ?a " + Trf.OntologyDefs.NCO_ROLE + " ?r } . " +
+ " FILTER(tracker:id(?p) = %s) " +
+ "} ";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ string del_q = del_t.printf (p_id);
+
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.insert_open (null);
+
+ int i = 0;
+ foreach (var r in roles)
+ {
+ string affl = "_:a%d".printf (i);
+
+ builder.subject (affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (Trf.OntologyDefs.NCO_ROLE);
+ builder.object_string (r.title);
+ builder.predicate (Trf.OntologyDefs.NCO_ORG);
+ builder.object_string (r.organisation_name);
+ builder.subject ("?contact");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (affl);
+ }
+
+ builder.insert_close ();
+ builder.where_open ();
+ builder.subject ("?contact");
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_PERSON);
+ string filter = " FILTER(tracker:id(?contact) = %s) ".printf (p_id);
+ builder.append (filter);
+ builder.where_close ();
+
+ yield this._tracker_update (del_q + builder.result, "_set_roles");
+ }
+
+ internal async void _set_notes (Folks.Persona persona,
+ owned Gee.HashSet<Note> notes)
+ {
+ const string del_t = "DELETE { " +
+ "?p " + Trf.OntologyDefs.NCO_NOTE + " ?n " +
+ "} " +
+ "WHERE {" +
+ " ?p a nco:PersonContact ; " +
+ Trf.OntologyDefs.NCO_NOTE + " ?n . " +
+ " FILTER(tracker:id(?p) = %s)" +
+ "}";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ string del_q = del_t.printf (p_id);
+
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.insert_open (null);
+
+ foreach (var n in notes)
+ {
+ builder.subject ("?contact");
+ builder.predicate (Trf.OntologyDefs.NCO_NOTE);
+ builder.object_string (n.content);
+ }
+
+ builder.insert_close ();
+ builder.where_open ();
+ builder.subject ("?contact");
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_PERSON);
+ string filter = " FILTER(tracker:id(?contact) = %s) ".printf (p_id);
+ builder.append (filter);
+ builder.where_close ();
+
+ yield this._tracker_update (del_q + builder.result, "_set_notes");
+ }
+
+ internal async void _set_birthday (Folks.Persona persona,
+ owned DateTime bday)
+ {
+ const string q_t = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NCO_BIRTHDAY + " ?b " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + "; " +
+ Trf.OntologyDefs.NCO_BIRTHDAY + " ?b . " +
+ " FILTER (tracker:id(?p) = %s ) " +
+ "} " +
+ "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NCO_BIRTHDAY + " '%s' " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ TimeVal tv;
+ bday.to_timeval (out tv);
+ string query = q_t.printf (p_id, tv.to_iso8601 (), p_id);
+
+ yield this._tracker_update (query, "_set_birthday");
+ }
+
+ internal async void _set_gender (Folks.Persona persona,
+ owned Gender gender)
+ {
+ const string del_t = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NCO_GENDER + " ?g " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " ; " +
+ Trf.OntologyDefs.NCO_GENDER + " ?g . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+ const string ins_t = "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NCO_GENDER + " %s " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ string query;
+
+ if (gender == Gender.UNSPECIFIED)
+ {
+ query = del_t.printf (p_id);
+ }
+ else
+ {
+ string gender_urn;
+
+ if (gender == Gender.MALE)
+ gender_urn = Trf.OntologyDefs.NCO_URL_PREFIX + "nco#gender-male>";
+ else
+ gender_urn = Trf.OntologyDefs.NCO_URL_PREFIX + "nco#gender-female>";
+
+ query = del_t.printf (p_id) + ins_t.printf (gender_urn, p_id);
+ }
+
+ yield this._tracker_update (query, "_set_gender");
+ }
+
+ internal async void _set_avatar (Folks.Persona persona,
+ File avatar)
+ {
+ const string query_t = "DELETE {" +
+ " ?c " + Trf.OntologyDefs.NCO_PHOTO + " ?p " +
+ " } " +
+ "WHERE { " +
+ " ?c a " + Trf.OntologyDefs.NCO_PERSON + " ; " +
+ Trf.OntologyDefs.NCO_PHOTO + " ?p . " +
+ " FILTER(tracker:id(?c) = %s) " +
+ "} " +
+ "INSERT { " +
+ " _:i a " + Trf.OntologyDefs.NFO_IMAGE + ", " +
+ Trf.OntologyDefs.NIE_DATAOBJECT + " ; " +
+ Trf.OntologyDefs.NIE_URL + " '%s' . " +
+ " ?c " + Trf.OntologyDefs.NCO_PHOTO + " _:i " +
+ "} " +
+ "WHERE { " +
+ " ?c a nco:PersonContact . " +
+ " FILTER(tracker:id(?c) = %s) " +
+ "}";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+
+ var image_urn = yield this._get_property (int.parse (p_id),
+ Trf.OntologyDefs.NCO_PHOTO);
+ if (image_urn != "")
+ this._delete_resource ("<%s>".printf (image_urn));
+
+ string query = query_t.printf (p_id, avatar.get_uri (), p_id);
+ yield this._tracker_update (query, "_set_avatar");
+ }
+
+ internal async void _set_structured_name (Folks.Persona persona,
+ StructuredName sname)
+ {
+ const string query_t = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NCO_FAMILY + " ?family . " +
+ " ?p " + Trf.OntologyDefs.NCO_GIVEN + " ?given . " +
+ " ?p " + Trf.OntologyDefs.NCO_ADDITIONAL + " ?adi . " +
+ " ?p " + Trf.OntologyDefs.NCO_PREFIX + " ?prefix . " +
+ " ?p " + Trf.OntologyDefs.NCO_SUFFIX + " ?suffix " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_FAMILY + " ?family } . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_GIVEN + " ?given } . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_ADDITIONAL + " ?adi } . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_PREFIX + " ?prefix } . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_SUFFIX + " ?suffix } . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} " +
+ "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NCO_FAMILY + " '%s'; " +
+ " " + Trf.OntologyDefs.NCO_GIVEN + " '%s'; " +
+ " " + Trf.OntologyDefs.NCO_ADDITIONAL + " '%s'; " +
+ " " + Trf.OntologyDefs.NCO_PREFIX + " '%s'; " +
+ " " + Trf.OntologyDefs.NCO_SUFFIX + " '%s' " +
+ " } " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ string query = query_t.printf (p_id, sname.family_name, sname.given_name,
+ sname.additional_names, sname.prefixes, sname.suffixes, p_id);
+ yield this._tracker_update (query, "_set_structured_name");
+ }
+
+ internal async void _set_full_name (Folks.Persona persona,
+ string full_name)
+ {
+ const string query_t = "DELETE { " +
+ " ?p " + Trf.OntologyDefs.NCO_FULLNAME + " ?fn " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " OPTIONAL { ?p " + Trf.OntologyDefs.NCO_FULLNAME + " ?fn } . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} " +
+ "INSERT { " +
+ " ?p " + Trf.OntologyDefs.NCO_FULLNAME + " '%s' " +
+ "} " +
+ "WHERE { " +
+ " ?p a " + Trf.OntologyDefs.NCO_PERSON + " . " +
+ " FILTER (tracker:id(?p) = %s) " +
+ "} ";
+
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+ string query = query_t.printf (p_id, full_name, p_id);
+ yield this._tracker_update (query, "_set_full_name");
+ }
+
+ /* NOTE:
+ * - first we nuke old attribs
+ * - we create new affls with the new attribs
+ */
+ private async void _set_attrib (Folks.Persona persona,
+ owned GLib.List<Object> attribs, Trf.Attrib what)
+ {
+ var p_id = ((Trf.Persona) persona).tracker_id ();
+
+ unowned string? related_attrib = null;
+ unowned string? related_prop = null;
+ unowned string? related_prop_2 = null;
+ unowned string? related_connection = null;
+
+ switch (what)
+ {
+ case Trf.Attrib.PHONES:
+ related_attrib = Trf.OntologyDefs.NCO_PHONE;
+ related_prop = Trf.OntologyDefs.NCO_PHONE_PROP;
+ related_connection = Trf.OntologyDefs.NCO_HAS_PHONE;
+ yield this._remove_attributes_from_persona (persona,
+ _REMOVE_PHONES);
+ break;
+ case Trf.Attrib.EMAILS:
+ related_attrib = Trf.OntologyDefs.NCO_EMAIL;
+ related_prop = Trf.OntologyDefs.NCO_EMAIL_PROP;
+ related_connection = Trf.OntologyDefs.NCO_HAS_EMAIL;
+ yield this._remove_attributes_from_persona (persona,
+ _REMOVE_EMAILS);
+ break;
+ case Trf.Attrib.URLS:
+ related_attrib = Trf.OntologyDefs.NCO_URL;
+ related_connection = Trf.OntologyDefs.NCO_URL;
+ break;
+ case Trf.Attrib.IM_ADDRESSES:
+ related_attrib = Trf.OntologyDefs.NCO_IMADDRESS;
+ related_prop = Trf.OntologyDefs.NCO_IMID;
+ related_prop_2 = Trf.OntologyDefs.NCO_IMPROTOCOL;
+ related_connection = Trf.OntologyDefs.NCO_HAS_IMADDRESS;
+ yield this._remove_attributes_from_persona (persona,
+ _REMOVE_IM_ADDRS);
+ break;
+ case Trf.Attrib.POSTAL_ADDRESSES:
+ related_attrib = Trf.OntologyDefs.NCO_POSTAL_ADDRESS;
+ related_connection = Trf.OntologyDefs.NCO_HAS_POSTAL_ADDRESS;
+ yield this._remove_attributes_from_persona (persona,
+ _REMOVE_POSTALS);
+ break;
+ }
+
+ var builder = new Tracker.Sparql.Builder.update ();
+ builder.insert_open (null);
+ int i = 0;
+ foreach (var p in attribs)
+ {
+ FieldDetails fd = null;
+ PostalAddress pa = null;
+
+ string affl = "_:a%d".printf (i);
+ string attr;
+
+ if (what == Trf.Attrib.POSTAL_ADDRESSES)
+ {
+ pa = (PostalAddress) p;
+ attr = "_:p%d".printf (i);
+ builder.subject (attr);
+ builder.predicate ("a");
+ builder.object (related_attrib);
+ builder.predicate (Trf.OntologyDefs.NCO_POBOX);
+ builder.object_string (pa.po_box);
+ builder.predicate (Trf.OntologyDefs.NCO_LOCALITY);
+ builder.object_string (pa.locality);
+ builder.predicate (Trf.OntologyDefs.NCO_POSTALCODE);
+ builder.object_string (pa.postal_code);
+ builder.predicate (Trf.OntologyDefs.NCO_STREET_ADDRESS);
+ builder.object_string (pa.street);
+ builder.predicate (Trf.OntologyDefs.NCO_EXTENDED_ADDRESS);
+ builder.object_string (pa.extension);
+ builder.predicate (Trf.OntologyDefs.NCO_COUNTRY);
+ builder.object_string (pa.country);
+ builder.predicate (Trf.OntologyDefs.NCO_REGION);
+ builder.object_string (pa.region);
+ }
+ else if (what == Trf.Attrib.URLS)
+ {
+ fd = (FieldDetails) p;
+ unowned List<string> type_p = fd.get_parameter_values ("type");
+ if (type_p.length () > 0)
+ {
+ if (type_p.nth_data (0) == "blog")
+ {
+ related_connection = Trf.OntologyDefs.NCO_BLOG;
+ }
+ else if (type_p.nth_data (0) == "website")
+ {
+ related_connection = Trf.OntologyDefs.NCO_WEBSITE;
+ }
+ }
+ attr = "'%s'".printf (fd.value);
+ }
+ else
+ {
+ fd = (FieldDetails) p;
+ attr = "_:p%d".printf (i);
+ builder.subject (attr);
+ builder.predicate ("a");
+ builder.object (related_attrib);
+ builder.predicate (related_prop);
+ builder.object_string (fd.value);
+
+ if (what == Trf.Attrib.IM_ADDRESSES)
+ {
+ builder.predicate (related_prop_2);
+ unowned List<string> im_params =
+ fd.get_parameter_values ("proto");
+ builder.object_string (im_params.nth_data (0));
+ }
+ }
+
+ builder.subject (affl);
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_AFFILIATION);
+ builder.predicate (related_connection);
+ builder.object (attr);
+ builder.subject ("?contact");
+ builder.predicate (Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ builder.object (affl);
+
+ i++;
+ }
+ builder.insert_close ();
+ builder.where_open ();
+ builder.subject ("?contact");
+ builder.predicate ("a");
+ builder.object (Trf.OntologyDefs.NCO_PERSON);
+ string filter = " FILTER(tracker:id(?contact) = %s) ".printf (p_id);
+ builder.append (filter);
+ builder.where_close ();
+
+ yield this._tracker_update (builder.result, "set_attrib");
+ }
+
+ private async bool _tracker_update (string query, string caller)
+ {
+ bool ret = false;
+
+ debug ("%s: %s", caller, query);
+
+ try
+ {
+ yield this._connection.update_async (query);
+ ret = true;
+ }
+ catch (Tracker.Sparql.Error e1)
+ {
+ warning ("[%s] SPARQL syntax error: %s. Query: %s",
+ caller, e1.message, query);
+ }
+ catch (GLib.IOError e2)
+ {
+ warning ("[%s] IO error: %s",
+ caller, e2.message);
+ }
+ catch (GLib.DBusError e3)
+ {
+ warning ("[%s] DBus error: %s",
+ caller, e3.message);
+ }
+
+ return ret;
+ }
+
+ private async Gee.HashSet<string> _affiliations_from_persona (string urn)
+ {
+ return yield this._linked_resources (urn, Trf.OntologyDefs.NCO_PERSON,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION);
+ }
+
+ private async Gee.HashSet<string> _phones_from_affiliation (string affl)
+ {
+ return yield this._linked_resources (affl,
+ Trf.OntologyDefs.NCO_AFFILIATION,
+ Trf.OntologyDefs.NCO_HAS_PHONE);
+ }
+
+ private async Gee.HashSet<string> _postals_from_affiliation (string affl)
+ {
+ return yield this._linked_resources (affl,
+ Trf.OntologyDefs.NCO_AFFILIATION,
+ Trf.OntologyDefs.NCO_HAS_POSTAL_ADDRESS);
+ }
+
+ private async Gee.HashSet<string> _imaddrs_from_affiliation (string affl)
+ {
+ return yield this._linked_resources (affl,
+ Trf.OntologyDefs.NCO_AFFILIATION,
+ Trf.OntologyDefs.NCO_HAS_IMADDRESS);
+ }
+
+ private async Gee.HashSet<string> _emails_from_affiliation (string affl)
+ {
+ return yield this._linked_resources (affl,
+ Trf.OntologyDefs.NCO_AFFILIATION,
+ Trf.OntologyDefs.NCO_HAS_EMAIL);
+ }
+
+ /**
+ * Retrieve the list of linked resources of a given subject
+ *
+ * @param resource the urn of the resource in <urn> format
+ * @return number of resources linking to this resource
+ */
+ private async int _resource_usage_count (string resource)
+ {
+ const string query_t = "SELECT " +
+ " count(?s) " +
+ "WHERE { " +
+ " %s a rdfs:Resource . " +
+ " ?s ?p %s } ";
+
+ var query = query_t.printf (resource, resource);
+ var result = yield this._single_value_query (query);
+ return int.parse (result);
+ }
+
+ /*
+ * NOTE:
+ *
+ * We asume that the caller is holding a link to the resource,
+ * so if _resource_usage_count () == 1 it means no one else
+ * (beside the caller) is linking to the resource.
+ *
+ * This means that _delete_resource shold be called before
+ * removing the resources that hold a link to it (which also
+ * makes sense from the signaling perspective).
+ */
+ private async bool _delete_resource (string resource_urn,
+ bool check_count = true)
+ {
+ bool deleted = false;
+ var query_t = " DELETE { " +
+ " %s a rdfs:Resource " +
+ "} " +
+ "WHERE { " +
+ " %s a rdfs:Resource " +
+ "} ";
+
+ var query = query_t.printf (resource_urn, resource_urn);
+ if (check_count)
+ {
+ int count = yield this._resource_usage_count (resource_urn);
+ if (count == 1)
+ {
+ deleted = yield this._tracker_update (query, "_delete_resource");
+ }
+ }
+ else
+ {
+ deleted = yield this._tracker_update (query, "_delete_resource");
+ }
+
+ return deleted;
+ }
+
+ /**
+ * Retrieve the list of linked resources of a given subject
+ *
+ * @param urn the urn of the subject in <urn> format
+ * @param subject_type i.e: nco:Person, nco:Affiliation, etc
+ * @param linking_predicate i.e.: nco:hasAffiliation
+ * @return a list of linked resources (in <urn> format)
+ */
+ private async Gee.HashSet<string> _linked_resources (string urn,
+ string subject_type, string linking_predicate)
+ {
+ string query_t = "SELECT " +
+ " fn:concat('<',?linkedr,'>') " +
+ "WHERE { " +
+ " %s a %s; " +
+ " %s ?linkedr " +
+ "} ";
+
+ var query = query_t.printf (urn, subject_type, linking_predicate);
+ return yield this._multi_value_query (query);
+ }
+
+ private async string _urn_from_persona (Folks.Persona persona)
+ {
+ var id = ((Trf.Persona) persona).tracker_id ();
+ return yield this._urn_from_tracker_id (id);
+ }
}
diff --git a/backends/tracker/lib/trf-persona.vala b/backends/tracker/lib/trf-persona.vala
index 47b5a2d..29effd8 100644
--- a/backends/tracker/lib/trf-persona.vala
+++ b/backends/tracker/lib/trf-persona.vala
@@ -30,6 +30,7 @@ using Tracker.Sparql;
* A persona subclass which represents a single nco:Contact.
*/
public class Trf.Persona : Folks.Persona,
+ AliasDetails,
AvatarDetails,
BirthdayDetails,
EmailDetails,
@@ -43,6 +44,8 @@ public class Trf.Persona : Folks.Persona,
RoleDetails,
UrlDetails
{
+ private string _alias;
+ private bool _is_favourite;
private const string[] _linkable_properties =
{"im-addresses", "email-addresses"};
private GLib.List<FieldDetails> _phone_numbers;
@@ -51,19 +54,41 @@ public class Trf.Persona : Folks.Persona,
private string _tracker_id;
/**
+ * An alias for the Persona.
+ *
+ * See { link Folks.AliasDetails.alias}.
+ */
+ public string alias
+ {
+ get { return this._alias; }
+
+ set
+ {
+ if (this._alias == value)
+ return;
+ this._alias = value;
+ this.notify_property ("alias");
+ ((Trf.PersonaStore) this.store)._set_alias (this, value);
+ }
+ }
+
+ /**
* { inheritDoc}
*/
public GLib.List<FieldDetails> phone_numbers
{
get { return this._phone_numbers; }
- private set
+ public set
{
- this._phone_numbers = new GLib.List<FieldDetails> ();
- foreach (unowned FieldDetails ps in value)
+ var _temp = new GLib.List<FieldDetails> ();
+ foreach (unowned FieldDetails e in value)
{
- this._phone_numbers.prepend (ps);
+ _temp.prepend (e);
}
- this._phone_numbers.reverse ();
+ _temp.reverse ();
+
+ ((Trf.PersonaStore) this.store)._set_phones (this,
+ (owned) _temp);
}
}
@@ -73,14 +98,17 @@ public class Trf.Persona : Folks.Persona,
public GLib.List<FieldDetails> email_addresses
{
get { return this._email_addresses; }
- private set
+ public set
{
- this._email_addresses = new GLib.List<FieldDetails> ();
+ var _temp = new GLib.List<FieldDetails> ();
foreach (unowned FieldDetails e in value)
{
- this._email_addresses.prepend (e);
+ _temp.prepend (e);
}
- this._email_addresses.reverse ();
+ _temp.reverse ();
+
+ ((Trf.PersonaStore) this.store)._set_emails (this,
+ (owned) _temp);
}
}
@@ -92,22 +120,46 @@ public class Trf.Persona : Folks.Persona,
get { return this._linkable_properties; }
}
+ private File _avatar;
/**
* An avatar for the Persona.
*
* See { link Folks.Avatar.avatar}.
*/
- public File avatar { get; set; }
+ public File avatar
+ {
+ get { return this._avatar; }
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_avatar (this, value);
+ }
+ }
+ private StructuredName _structured_name;
/**
* { inheritDoc}
*/
- public StructuredName structured_name { get; private set; }
+ public StructuredName structured_name
+ {
+ get { return this._structured_name; }
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_structured_name (this, value);
+ }
+ }
+ private string _full_name;
/**
* { inheritDoc}
*/
- public string full_name { get; private set; }
+ public string full_name
+ {
+ get { return this._full_name; }
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_full_name (this, value);
+ }
+ }
private string _nickname;
/**
@@ -115,16 +167,36 @@ public class Trf.Persona : Folks.Persona,
*/
public string nickname { get { return this._nickname; } }
+ private Gender _gender;
/**
* { inheritDoc}
*/
- public Gender gender { get; private set; }
+ public Gender gender
+ {
+ get { return this._gender; }
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_gender (this, value);
+ }
+ }
private HashSet<Role> _roles =
new HashSet<Role> ((GLib.HashFunc) Role.hash,
(GLib.EqualFunc) Role.equal);
- public DateTime birthday { get; set; }
+
+ private DateTime _birthday;
+ /**
+ * { inheritDoc}
+ */
+ public DateTime birthday
+ {
+ get { return this._birthday; }
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_birthday (this, value);
+ }
+ }
public string calendar_event_id { get; set; }
@@ -134,10 +206,9 @@ public class Trf.Persona : Folks.Persona,
public HashSet<Role> roles
{
get { return this._roles; }
- private set
+ public set
{
- this._roles = value;
- this.notify_property ("roles");
+ ((Trf.PersonaStore) this.store)._set_roles (this, value);
}
}
@@ -153,8 +224,7 @@ public class Trf.Persona : Folks.Persona,
get { return this._notes; }
private set
{
- this._notes = notes;
- this.notify_property ("notes");
+ ((Trf.PersonaStore) this.store)._set_notes (this, value);
}
}
@@ -165,12 +235,15 @@ public class Trf.Persona : Folks.Persona,
public GLib.List<FieldDetails> urls
{
get { return this._urls; }
- private set
+ public set
{
- this._urls = new GLib.List<FieldDetails> ();
- foreach (unowned FieldDetails ps in value)
- this._urls.prepend (ps);
- this._urls.reverse ();
+ var _temp = new GLib.List<FieldDetails> ();
+ foreach (unowned FieldDetails e in value)
+ _temp.prepend (e);
+ _temp.reverse ();
+
+ ((Trf.PersonaStore) this.store)._set_urls (this,
+ (owned) _temp);
}
}
@@ -184,11 +257,11 @@ public class Trf.Persona : Folks.Persona,
get { return this._postal_addresses; }
private set
{
- this._postal_addresses = new GLib.List<PostalAddress> ();
- foreach (PostalAddress pa in value)
- this._postal_addresses.prepend (pa);
- this._postal_addresses.reverse ();
- this.notify_property ("postal-addresses");
+ var _temp = new GLib.List<PostalAddress> ();
+ foreach (unowned PostalAddress e in value)
+ _temp.prepend (e);
+ ((Trf.PersonaStore) this.store)._set_postal_addresses (this,
+ (owned) _temp);
}
}
@@ -203,13 +276,32 @@ public class Trf.Persona : Folks.Persona,
public HashTable<string, LinkedHashSet<string>> im_addresses
{
get { return this._im_addresses; }
- private set {}
+ public set
+ {
+ ((Trf.PersonaStore) this.store)._set_im_addresses (this,
+ value);
+ }
}
/**
* Whether this contact is a user-defined favourite.
*/
- public bool is_favourite { get; set; }
+ public bool is_favourite
+ {
+ get { return this._is_favourite; }
+
+ set
+ {
+ if (this._is_favourite == value)
+ return;
+
+ /* Note:
+ * this property will be set (and notified)
+ * once we receive a notification event from Tracker
+ */
+ ((Trf.PersonaStore) this.store)._set_is_favourite (this, value);
+ }
+ }
/**
* Build a IID.
@@ -249,18 +341,18 @@ public class Trf.Persona : Folks.Persona,
}
}
- debug ("Creating new Trf.Persona with id '%s'", fullname);
+ debug ("Creating new Trf.Persona with iid '%s'", iid);
Object (display_id: fullname,
uid: uid,
iid: iid,
store: store,
- gender: Gender.UNSPECIFIED,
is_user: is_user);
- this.full_name = fullname;
+ this._gender = Gender.UNSPECIFIED;
+ this._full_name = fullname;
this._tracker_id = tracker_id;
- this.structured_name = new StructuredName (null, null, null, null, null);
+ this._structured_name = new StructuredName (null, null, null, null, null);
if (cursor != null)
{
@@ -269,6 +361,11 @@ public class Trf.Persona : Folks.Persona,
}
}
+ internal string tracker_id ()
+ {
+ return this._tracker_id;
+ }
+
~Persona ()
{
debug ("Destroying Trf.Persona '%s': %p", this.uid, this);
@@ -278,7 +375,8 @@ public class Trf.Persona : Folks.Persona,
{
if (fn != null && this.full_name != fn)
{
- this.full_name = fn;
+ this._full_name = fn;
+ this.notify_property ("full-name");
}
}
@@ -291,11 +389,21 @@ public class Trf.Persona : Folks.Persona,
}
}
+ internal void _update_alias (string? alias)
+ {
+ if (alias != null && this._alias != alias)
+ {
+ this._alias = alias;
+ this.notify_property ("alias");
+ }
+ }
+
internal void _update_family_name (string? family_name)
{
if (family_name != null)
{
- this.structured_name.family_name = family_name;
+ this._structured_name.family_name = family_name;
+ this.notify_property ("structured-name");
}
}
@@ -303,7 +411,8 @@ public class Trf.Persona : Folks.Persona,
{
if (given_name != null)
{
- this.structured_name.given_name = given_name;
+ this._structured_name.given_name = given_name;
+ this.notify_property ("structured-name");
}
}
@@ -311,7 +420,8 @@ public class Trf.Persona : Folks.Persona,
{
if (additional_names != null)
{
- this.structured_name.additional_names = additional_names;
+ this._structured_name.additional_names = additional_names;
+ this.notify_property ("structured-name");
}
}
@@ -319,7 +429,8 @@ public class Trf.Persona : Folks.Persona,
{
if (prefixes != null)
{
- this.structured_name.prefixes = prefixes;
+ this._structured_name.prefixes = prefixes;
+ this.notify_property ("structured-name");
}
}
@@ -327,7 +438,8 @@ public class Trf.Persona : Folks.Persona,
{
if (suffixes != null)
{
- this.structured_name.suffixes = suffixes;
+ this._structured_name.suffixes = suffixes;
+ this.notify_property ("structured-name");
}
}
@@ -394,7 +506,7 @@ public class Trf.Persona : Folks.Persona,
}
postal_addresses.reverse ();
- this.postal_addresses = (owned) postal_addresses;
+ this._postal_addresses = (owned) postal_addresses;
}
internal bool _add_postal_address (PostalAddress postal_address)
@@ -443,7 +555,7 @@ public class Trf.Persona : Folks.Persona,
{
if (gender_id == 0)
{
- this.gender = Gender.UNSPECIFIED;
+ this._gender = Gender.UNSPECIFIED;
}
else
{
@@ -451,13 +563,15 @@ public class Trf.Persona : Folks.Persona,
if (gender_id == trf_store.get_gender_male_id ())
{
- this.gender = Gender.MALE;
+ this._gender = Gender.MALE;
}
else if (gender_id == trf_store.get_gender_female_id ())
{
- this.gender = Gender.FEMALE;
+ this._gender = Gender.FEMALE;
}
}
+
+ this.notify_property ("gender");
}
private void _update_note ()
@@ -492,13 +606,15 @@ public class Trf.Persona : Folks.Persona,
{
TimeVal t = TimeVal ();
t.from_iso8601 (birthday);
- this.birthday = new DateTime.from_timeval_utc (t);
+ this._birthday = new DateTime.from_timeval_utc (t);
+ this.notify_property ("birthday");
}
else
{
- if (this.birthday != null)
+ if (this._birthday != null)
{
- this.birthday = null;
+ this._birthday = null;
+ this.notify_property ("birthday");
}
}
}
@@ -564,8 +680,8 @@ public class Trf.Persona : Folks.Persona,
string fullname = this._cursor.get_string (Trf.Fields.FULL_NAME).dup ();
this._update_full_name (fullname);
- string nickname = this._cursor.get_string (Trf.Fields.NICKNAME).dup ();
- this._update_nickname (nickname);
+ string alias = this._cursor.get_string (Trf.Fields.ALIAS).dup ();
+ this._update_alias (alias);
string family_name = this._cursor.get_string (
Trf.Fields.FAMILY_NAME).dup ();
@@ -600,7 +716,8 @@ public class Trf.Persona : Folks.Persona,
{
_avatar = File.new_for_uri (avatar_url);
}
- this.avatar = _avatar;
+ this._avatar = _avatar;
+ this.notify_property ("avatar");
return true;
}
@@ -624,7 +741,9 @@ public class Trf.Persona : Folks.Persona,
var tracker_id = addr_info[Trf.IMFields.TRACKER_ID];
var proto = addr_info[Trf.IMFields.PROTO];
var account_id = addr_info[Trf.IMFields.ID];
+ var nickname = addr_info[Trf.IMFields.IM_NICKNAME];
+ this._update_nickname (nickname);
this._add_im_address (tracker_id, proto, account_id, false);
}
@@ -737,7 +856,7 @@ public class Trf.Persona : Folks.Persona,
}
phones.reverse ();
- this.phone_numbers = phones;
+ this._phone_numbers = (owned) phones;
}
internal bool _add_phone (string phone, string tracker_id)
@@ -865,7 +984,7 @@ public class Trf.Persona : Folks.Persona,
}
email_addresses.reverse ();
- this.email_addresses = email_addresses;
+ this._email_addresses = (owned) email_addresses;
}
private void _update_urls ()
@@ -910,7 +1029,7 @@ public class Trf.Persona : Folks.Persona,
}
urls.reverse ();
- this.urls = urls;
+ this._urls = (owned) urls;
}
internal bool _add_url (string url, string tracker_id, string type = "")
@@ -964,7 +1083,7 @@ public class Trf.Persona : Folks.Persona,
{
var favourite = this._cursor.get_string (Trf.Fields.FAVOURITE).dup ();
- this.is_favourite = false;
+ this._is_favourite = false;
if (favourite != null)
{
@@ -974,9 +1093,21 @@ public class Trf.Persona : Folks.Persona,
{
if (int.parse (tag) == favorite_tracker_id)
{
- this.is_favourite = true;
+ this._is_favourite = true;
}
}
}
}
+
+ /**
+ * This method sets the is_favourite attribute internally.
+ * That is, it should be used as a result of an event fired by
+ * Tracker since this method doesn't propagate changes back
+ * to Tracker again.
+ */
+ internal void _set_favourite (bool is_fav)
+ {
+ this._is_favourite = is_fav;
+ this.notify_property ("is-favourite");
+ }
}
diff --git a/backends/tracker/lib/trf-util.vala b/backends/tracker/lib/trf-util.vala
index 5e93687..f000231 100644
--- a/backends/tracker/lib/trf-util.vala
+++ b/backends/tracker/lib/trf-util.vala
@@ -46,6 +46,8 @@ internal class Trf.AfflInfo : Object
public string im_account_id { get; set; }
+ public string im_nickname { get; set; }
+
public string affl_tracker_id { get; set; }
public string title { get; set; }
@@ -105,6 +107,7 @@ public class Trf.OntologyDefs : Object
public static const string NCO_NICKNAME = "nco:nickname";
public static const string RDF_TYPE = "ns:type";
public static const string NCO_PERSON = "nco:PersonContact";
+ public static const string NCO_URL = "nco:url";
public static const string NCO_WEBSITE = "nco:websiteUrl";
public static const string NCO_BLOG = "nco:blogUrl";
public static const string NAO_FAVORITE = "nao:predefined-tag-favorite";
@@ -125,11 +128,26 @@ public class Trf.OntologyDefs : Object
public static const string NCO_PHOTO = "nco:photo";
public static const string NIE_URL = "nie:url";
public static const string NFO_IMAGE = "nfo:Image";
+ public static const string NIE_DATAOBJECT = "nie:DataObject";
public static const string NCO_IMADDRESS = "nco:IMAddress";
public static const string NCO_HAS_IMADDRESS = "nco:hasIMAddress";
public static const string NCO_IMPROTOCOL = "nco:imProtocol";
public static const string NCO_IMID = "nco:imID";
+ public static const string NCO_IM_NICKNAME = "nco:imNickname";
public static const string NCO_POSTAL_ADDRESS = "nco:PostalAddress";
+ public static const string NCO_HAS_POSTAL_ADDRESS = "nco:hasPostalAddress";
+ public static const string NCO_POBOX = "nco:pobox";
+ public static const string NCO_DISTRICT = "nco:district";
+ public static const string NCO_COUNTY = "nco:county";
+ public static const string NCO_LOCALITY = "nco:locality";
+ public static const string NCO_POSTALCODE = "nco:postalcode";
+ public static const string NCO_STREET_ADDRESS = "nco:streetAddress";
+ public static const string NCO_ADDRESS_LOCATION = "nco:addressLocation";
+ public static const string NCO_EXTENDED_ADDRESS = "nco:extendedAddress";
+ public static const string NCO_COUNTRY = "nco:country";
+ public static const string NCO_REGION = "nco:region";
+ public static const string NCO_ROLE = "nco:role";
+ public static const string NCO_ORG = "nco:org";
public static const string NCO_URL_PREFIX =
"<http://www.semanticdesktop.org/ontologies/2007/03/22/";
public static const string NAO_URL_PREFIX =
diff --git a/tests/tracker/Makefile.am b/tests/tracker/Makefile.am
index 5793a8d..5d11af8 100644
--- a/tests/tracker/Makefile.am
+++ b/tests/tracker/Makefile.am
@@ -70,6 +70,22 @@ noinst_PROGRAMS = \
gender-details-interface \
postal-address-details-interface \
avatar-updates \
+ add-persona \
+ remove-persona \
+ set-alias \
+ set-favourite \
+ set-phones \
+ set-emails \
+ set-avatar \
+ set-structured-name \
+ set-full-name \
+ set-urls \
+ set-im-addresses \
+ set-postal-addresses \
+ set-roles \
+ set-notes \
+ set-birthday \
+ set-gender \
$(NULL)
backend_store_key_file=$(srcdir)/data/backend-tracker-only.ini
@@ -204,6 +220,70 @@ avatar_updates_SOURCES = \
avatar-updates.vala \
$(NULL)
+add_persona_SOURCES = \
+ add-persona.vala \
+ $(NULL)
+
+remove_persona_SOURCES = \
+ remove-persona.vala \
+ $(NULL)
+
+set_alias_SOURCES = \
+ set-alias.vala \
+ $(NULL)
+
+set_favourite_SOURCES = \
+ set-favourite.vala \
+ $(NULL)
+
+set_phones_SOURCES = \
+ set-phones.vala \
+ $(NULL)
+
+set_emails_SOURCES = \
+ set-emails.vala \
+ $(NULL)
+
+set_avatar_SOURCES = \
+ set-avatar.vala \
+ $(NULL)
+
+set_structured_name_SOURCES = \
+ set-structured-name.vala \
+ $(NULL)
+
+set_full_name_SOURCES = \
+ set-full-name.vala \
+ $(NULL)
+
+set_urls_SOURCES = \
+ set-urls.vala \
+ $(NULL)
+
+set_im_addresses_SOURCES = \
+ set-im-addresses.vala \
+ $(NULL)
+
+set_postal_addresses_SOURCES = \
+ set-postal-addresses.vala \
+ $(NULL)
+
+set_roles_SOURCES = \
+ set-roles.vala \
+ $(NULL)
+
+set_notes_SOURCES = \
+ set-notes.vala \
+ $(NULL)
+
+set_birthday_SOURCES = \
+ set-birthday.vala \
+ $(NULL)
+
+set_gender_SOURCES = \
+ set-gender.vala \
+ $(NULL)
+
CLEANFILES = \
*.pid \
*.address \
@@ -242,6 +322,22 @@ MAINTAINERCLEANFILES = \
gender_details_interface_vala.stamp \
postal_address_details_interface_vala.stamp \
avatar_updates_vala.stamp \
+ add_persona_vala.stamp \
+ remove_persona_vala.stamp \
+ set_alias_vala.stamp \
+ set_favourite_vala.stamp \
+ set_phones_vala.stamp \
+ set_emails_vala.stamp \
+ set_avatar_vala.stamp \
+ set_structured_name_vala.stamp \
+ set_full_name_vala.stamp \
+ set_urls_vala.stamp \
+ set_im_addresses_vala.stamp \
+ set_postal_addresses_vala.stamp \
+ set_roles_vala.stamp \
+ set_notes_vala.stamp \
+ set_birthday_vala.stamp \
+ set_gender_vala.stamp \
$(NULL)
EXTRA_DIST = \
diff --git a/tests/tracker/add-contact.vala b/tests/tracker/add-contact.vala
index 79ed324..7ce6c87 100644
--- a/tests/tracker/add-contact.vala
+++ b/tests/tracker/add-contact.vala
@@ -54,12 +54,12 @@ public class AddContactTests : Folks.TestCase
this._persona_fullname = "persona #1";
this._contact_added = false;
- var store = BackendStore.dup ();
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+ this._tracker_backend.set_up ();
- this._test_add_contact_async (store, (o, r) =>
- {
- this._test_add_contact_async.end (r);
- });
+ this._test_add_contact_async ();
Timeout.add_seconds (5, () =>
{
@@ -72,10 +72,10 @@ public class AddContactTests : Folks.TestCase
this._tracker_backend.tear_down ();
}
- private async void _test_add_contact_async (BackendStore store)
+ private async void _test_add_contact_async ()
{
+ var store = BackendStore.dup ();
yield store.prepare ();
-
this._aggregator = new IndividualAggregator ();
this._aggregator.individuals_changed.connect
(this._individuals_changed_cb);
@@ -83,11 +83,6 @@ public class AddContactTests : Folks.TestCase
try
{
yield this._aggregator.prepare ();
-
- Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
- c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
- this._tracker_backend.add_contact (c1);
- this._tracker_backend.set_up ();
}
catch (GLib.Error e)
{
diff --git a/tests/tracker/add-persona.vala b/tests/tracker/add-persona.vala
new file mode 100644
index 0000000..1606f37
--- /dev/null
+++ b/tests/tracker/add-persona.vala
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class AddPersonaTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private string _persona_alias;
+ private string _family_name;
+ private string _given_name;
+ private HashTable<string, bool> _properties_found;
+ private string _persona_iid;
+ private string _file_uri;
+ private string _birthday;
+ private DateTime _bday;
+ private string _email_1;
+ private string _email_2;
+ private string _im_addr_1;
+ private string _im_addr_2;
+ private string _note_1;
+ private string _phone_1;
+ private string _phone_2;
+ private string _title_1;
+ private string _organisation_1;
+ private PostalAddress _address;
+ private string _po_box = "12345";
+ private string _locality = "locality";
+ private string _postal_code = "code";
+ private string _street = "some street";
+ private string _extension = "some extension";
+ private string _country = "some country";
+ private string _region = "some region";
+ private string _url_1 = "http://www-1.example.org";
+ private string _url_2 = "http://www-1.example.org";
+ private Trf.PersonaStore _pstore;
+ private bool _added_persona = false;
+
+ public AddPersonaTests ()
+ {
+ base ("AddPersonaTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test adding personas to Tracker ", this.test_add_persona);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_add_persona ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._persona_fullname = "persona #1";
+ this._persona_alias = "alias";
+ this._family_name = "family";
+ this._given_name = "given";
+ this._persona_iid = "";
+ this._file_uri = "file:///tmp/some-avatar.jpg";
+ this._birthday = "2001-10-26T20:32:52Z";
+ this._email_1 = "someone-1 example org";
+ this._email_2 = "someone-2 example org";
+ this._im_addr_1 = "someone-1 jabber example org";
+ this._im_addr_2 = "someone-2 jabber example org";
+ this._note_1 = "this is a note";
+ this._phone_1 = "12345";
+ this._phone_2 = "54321";
+ this._title_1 = "CFO";
+ this._organisation_1 = "Example Inc.";
+
+ GLib.List<string> types = new GLib.List<string> ();
+ this._address = new PostalAddress (this._po_box,
+ this._extension, this._street, this._locality, this._region,
+ this._postal_code, this._country, null, types, null);
+
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (this._birthday);
+ this._bday = new DateTime.from_timeval_utc (t);
+
+ this._properties_found = new HashTable<string, bool>
+ (str_hash, str_equal);
+ this._properties_found.insert ("full_name", false);
+ this._properties_found.insert ("alias", false);
+ this._properties_found.insert ("is_favourite", false);
+ this._properties_found.insert ("structured_name", false);
+ this._properties_found.insert ("avatar", false);
+ this._properties_found.insert ("birthday", false);
+ this._properties_found.insert ("gender", false);
+ this._properties_found.insert ("email-1", false);
+ this._properties_found.insert ("email-2", false);
+ this._properties_found.insert ("im-addr-1", false);
+ this._properties_found.insert ("im-addr-2", false);
+ this._properties_found.insert ("note-1", false);
+ this._properties_found.insert ("phone-1", false);
+ this._properties_found.insert ("phone-2", false);
+ this._properties_found.insert ("role-1", false);
+ this._properties_found.insert ("postal-address-1", false);
+ this._properties_found.insert ("url-1", false);
+ this._properties_found.insert ("url-2", false);
+
+ this._test_add_persona_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ foreach (var k in this._properties_found.get_values ())
+ {
+ assert (k);
+ }
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_add_persona_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+
+ this._pstore = null;
+ foreach (var backend in store.enabled_backends)
+ {
+ this._pstore =
+ (Trf.PersonaStore) backend.persona_stores.lookup ("tracker");
+ if (this._pstore != null)
+ break;
+ }
+ assert (this._pstore != null);
+ this._pstore.notify["is-prepared"].connect (this._notify_pstore_cb);
+ this._try_to_add ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private async void _add_persona ()
+ {
+ HashTable<string, Value?> details = new HashTable<string, Value?>
+ (str_hash, str_equal);
+
+ Value? v1 = Value (typeof (string));
+ v1.set_string (this._persona_fullname);
+ details.insert (this._pstore.detail_key (PersonaDetail.FULL_NAME),
+ (owned)v1);
+
+ Value? v2 = Value (typeof (string));
+ v2.set_string (this._persona_alias);
+ details.insert (this._pstore.detail_key (PersonaDetail.ALIAS), (owned)v2);
+
+ Value? v3 = Value (typeof (bool));
+ v3.set_boolean (true);
+ details.insert (this._pstore.detail_key (PersonaDetail.FAVOURITE),
+ (owned) v3);
+
+ Value? v4 = Value (typeof (StructuredName));
+ StructuredName sname = new StructuredName (this._family_name,
+ this._given_name, null, null, null);
+ v4.set_object (sname);
+ details.insert (this._pstore.detail_key (PersonaDetail.STRUCTURED_NAME),
+ (owned) v4);
+
+ Value? v5 = Value (typeof (File));
+ File avatar = File.new_for_uri (this._file_uri);
+ v5.set_object (avatar);
+ details.insert (this._pstore.detail_key (PersonaDetail.AVATAR),
+ (owned) v5);
+
+ Value? v6 = Value (typeof (DateTime));
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (this._birthday);
+ DateTime dobj = new DateTime.from_timeval_utc (t);
+ v6.set_boxed (dobj);
+ details.insert (this._pstore.detail_key (PersonaDetail.BIRTHDAY),
+ (owned) v6);
+
+ Value? v7 = Value (typeof (Folks.Gender));
+ v7.set_enum (Folks.Gender.MALE);
+ details.insert (this._pstore.detail_key (PersonaDetail.GENDER),
+ (owned) v7);
+
+ Value? v8 = Value (typeof (GLib.List<FieldDetails>));
+ GLib.List<FieldDetails> emails =
+ new GLib.List<FieldDetails> ();
+ var email_1 = new FieldDetails (this._email_1);
+ emails.prepend ((owned) email_1);
+ var email_2 = new FieldDetails (this._email_2);
+ emails.prepend ((owned) email_2);
+ v8.set_pointer (emails);
+ details.insert (this._pstore.detail_key (PersonaDetail.EMAIL_ADDRESSES),
+ (owned) v8);
+
+ Value? v9 = Value (typeof (HashTable<string, LinkedHashSet<string>>));
+ HashTable<string, LinkedHashSet<string>> im_addrs =
+ new HashTable<string, LinkedHashSet<string>> (null, null);
+ LinkedHashSet<string> proto1 = new LinkedHashSet<string> ();
+ proto1.add (this._im_addr_1);
+ im_addrs.insert ("jabber", proto1);
+ LinkedHashSet<string> proto2 = new LinkedHashSet<string> ();
+ proto2.add (this._im_addr_2);
+ im_addrs.insert ("yahoo", proto2);
+ v9.set_boxed (im_addrs);
+ details.insert (this._pstore.detail_key (PersonaDetail.IM_ADDRESSES), v9);
+
+ Value? v10 = Value (typeof (Gee.HashSet<Note>));
+ Gee.HashSet<Note> notes = new Gee.HashSet<Note> ();
+ Note n1 = new Note (this._note_1);
+ notes.add (n1);
+ v10.set_object (notes);
+ details.insert (this._pstore.detail_key (PersonaDetail.NOTES),
+ (owned) v10);
+
+ Value? v11 = Value (typeof (GLib.List<FieldDetails>));
+ GLib.List<FieldDetails> phones =
+ new GLib.List<FieldDetails> ();
+ var phone_1 = new FieldDetails (this._phone_1);
+ phones.prepend ((owned) phone_1);
+ var phone_2 = new FieldDetails (this._phone_2);
+ phones.prepend ((owned) phone_2);
+ v11.set_pointer (phones);
+ details.insert (this._pstore.detail_key (PersonaDetail.PHONE_NUMBERS),
+ (owned) v11);
+
+ Value? v12 = Value (typeof (Gee.HashSet<Role>));
+ Gee.HashSet<Role> roles = new Gee.HashSet<Role> ();
+ Role r1 = new Role (this._title_1, this._organisation_1);
+ roles.add (r1);
+ v12.set_object (roles);
+ details.insert (this._pstore.detail_key (PersonaDetail.ROLES),
+ (owned) v12);
+
+ Value? v13 = Value (typeof (GLib.List<PostalAddress>));
+ GLib.List<PostalAddress> postal_addresses =
+ new GLib.List<PostalAddress> ();
+
+ GLib.List<string> types = new GLib.List<string> ();
+ PostalAddress postal_a = new PostalAddress (this._po_box,
+ this._extension, this._street, this._locality, this._region,
+ this._postal_code, this._country, null, types, null);
+ postal_addresses.prepend ((owned) postal_a);
+ v13.set_pointer (postal_addresses);
+ details.insert (this._pstore.detail_key (PersonaDetail.POSTAL_ADDRESSES),
+ (owned) v13);
+
+ Value? v14 = Value (typeof (GLib.List<FieldDetails>));
+ GLib.List<FieldDetails> urls =
+ new GLib.List<FieldDetails> ();
+ var url_1 = new FieldDetails (this._url_1);
+ urls.prepend ((owned) url_1);
+ var url_2 = new FieldDetails (this._url_2);
+ urls.prepend ((owned) url_2);
+ v14.set_pointer (urls);
+ details.insert (this._pstore.detail_key (PersonaDetail.URLS), (owned)v14);
+
+ try
+ {
+ Trf.Persona persona = (Trf. Persona)
+ yield this._aggregator.add_persona_from_details
+ (null, this._pstore, details);
+ this._persona_iid = persona.iid;
+ }
+ catch (Folks.IndividualAggregatorError e)
+ {
+ GLib.warning ("[AddPersonaError] add_persona_from_details: %s\n",
+ e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.is_user == false)
+ {
+ /* NOTE:
+ * we also listen to the Trf.Persona's structured-name
+ * because if only one of its property is updated
+ * Individual won't fire a notification.
+ */
+ unowned Trf.Persona p = (Trf.Persona) i.personas.nth_data (0);
+ if (p.structured_name != null)
+ {
+ p.notify["structured-name"].connect
+ (this._notify_persona_sname);
+ }
+
+ i.notify["full-name"].connect (this._notify_cb);
+ i.notify["alias"].connect (this._notify_cb);
+ i.notify["avatar"].connect (this._notify_cb);
+ i.notify["is-favourite"].connect (this._notify_cb);
+ i.notify["structured-name"].connect (this._notify_cb);
+ i.notify["family-name"].connect (this._notify_cb);
+ i.notify["given-name"].connect (this._notify_cb);
+ i.notify["avatar"].connect (this._notify_cb);
+ i.notify["birthday"].connect (this._notify_cb);
+ i.notify["gender"].connect (this._notify_cb);
+ i.notify["email-addresses"].connect (this._notify_cb);
+ i.notify["im-addresses"].connect (this._notify_cb);
+ i.notify["notes"].connect (this._notify_cb);
+ i.notify["phone-numbers"].connect (this._notify_cb);
+ i.notify["roles"].connect (this._notify_cb);
+ i.notify["postal-addresses"].connect (this._notify_cb);
+ i.notify["urls"].connect (this._notify_cb);
+
+ this._check_properties (i);
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ this._check_properties (i);
+ }
+
+ private void _notify_persona_sname (Object persona_p, ParamSpec ps)
+ {
+ Trf.Persona persona = (Trf.Persona) persona_p;
+ this._check_sname (persona.structured_name);
+ this._exit_if_all_properties_found ();
+ }
+
+ private void _notify_pstore_cb (Object _pstore, ParamSpec ps)
+ {
+ this._try_to_add ();
+ }
+
+ private void _try_to_add ()
+ {
+ lock (this._added_persona)
+ {
+ if (this._pstore.is_prepared &&
+ this._added_persona == false)
+ {
+ this._added_persona = true;
+ this._add_persona ();
+ }
+ }
+ }
+
+ private void _check_properties (Individual i)
+ {
+ if (i.full_name == this._persona_fullname)
+ this._properties_found.replace ("full_name", true);
+
+ if (i.alias == this._persona_alias)
+ this._properties_found.replace ("alias", true);
+
+ if (i.is_favourite)
+ this._properties_found.replace ("is_favourite", true);
+
+ if (i.structured_name != null)
+ {
+ this._check_sname (i.structured_name);
+ }
+
+ if (i.avatar != null &&
+ i.avatar.get_uri () == this._file_uri)
+ this._properties_found.replace ("avatar", true);
+
+ if (i.birthday != null &&
+ i.birthday.compare (this._bday) == 0)
+ this._properties_found.replace ("birthday", true);
+
+ if (i.gender == Gender.MALE)
+ this._properties_found.replace ("gender", true);
+
+ foreach (unowned FieldDetails e in i.email_addresses)
+ {
+ if (e.value == this._email_1)
+ {
+ this._properties_found.replace ("email-1", true);
+ }
+ else if (e.value == this._email_2)
+ {
+ this._properties_found.replace ("email-2", true);
+ }
+ }
+
+ foreach (var proto in i.im_addresses.get_keys ())
+ {
+ var addrs = i.im_addresses.lookup (proto);
+ foreach (var a in addrs)
+ {
+ if (a == this._im_addr_1)
+ this._properties_found.replace ("im-addr-1", true);
+ else if (a == this._im_addr_2)
+ this._properties_found.replace ("im-addr-2", true);
+ }
+ }
+
+ foreach (var n in i.notes)
+ {
+ if (n.content == this._note_1)
+ {
+ this._properties_found.replace ("note-1", true);
+ }
+ }
+
+ foreach (unowned FieldDetails e in i.phone_numbers)
+ {
+ if (e.value == this._phone_1)
+ {
+ this._properties_found.replace ("phone-1", true);
+ }
+ else if (e.value == this._phone_2)
+ {
+ this._properties_found.replace ("phone-2", true);
+ }
+ }
+
+ foreach (var r in i.roles)
+ {
+ if (r.title == this._title_1 &&
+ r.organisation_name == this._organisation_1)
+ {
+ this._properties_found.replace ("role-1", true);
+ }
+ }
+
+ foreach (var pa in i.postal_addresses)
+ {
+ this._address.uid = pa.uid;
+ if (pa.equal (this._address))
+ this._properties_found.replace ("postal-address-1", true);
+ }
+
+ foreach (var u in i.urls)
+ {
+ if (u.value == this._url_1)
+ this._properties_found.replace ("url-1", true);
+ if (u.value == this._url_2)
+ this._properties_found.replace ("url-2", true);
+ }
+
+ this._exit_if_all_properties_found ();
+ }
+
+ private void _exit_if_all_properties_found ()
+ {
+ foreach (var k in this._properties_found.get_keys ())
+ {
+ var v = this._properties_found.lookup (k);
+ if (v == false)
+ return;
+ }
+ this._main_loop.quit ();
+ }
+
+ private void _check_sname (StructuredName sname)
+ {
+ if (sname.family_name == this._family_name &&
+ sname.given_name == this._given_name)
+ this._properties_found.replace ("structured_name", true);
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new AddPersonaTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/additional-names-updates.vala b/tests/tracker/additional-names-updates.vala
index 8a0ac9a..fa28286 100644
--- a/tests/tracker/additional-names-updates.vala
+++ b/tests/tracker/additional-names-updates.vala
@@ -34,6 +34,7 @@ public class AdditionalNamesUpdatesTests : Folks.TestCase
private bool _initial_additional_names_found;
private string _contact_urn;
private string _initial_additional_names;
+ private string _initial_fullname;
public AdditionalNamesUpdatesTests ()
{
@@ -58,13 +59,13 @@ public class AdditionalNamesUpdatesTests : Folks.TestCase
{
this._main_loop = new GLib.MainLoop (null, false);
Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
- string initial_fullname = "persona #1";
+ this._initial_fullname = "persona #1";
this._initial_additional_names = "additional name #1";
this._updated_additional_names = "updated additional name #1";
this._contact_urn = "<urn:contact001>";
c1.set (TrackerTest.Backend.URN, this._contact_urn);
- c1.set (Trf.OntologyDefs.NCO_FULLNAME, initial_fullname);
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
c1.set (Trf.OntologyDefs.NCO_ADDITIONAL,
this._initial_additional_names);
this._tracker_backend.add_contact (c1);
@@ -116,31 +117,30 @@ public class AdditionalNamesUpdatesTests : Folks.TestCase
GroupDetails.ChangeReason reason)
{
foreach (unowned Individual i in added)
- {
- i.structured_name.notify["additional-names"].connect
- (this._notify_additional_names_cb);
- var additional_names = i.structured_name.additional_names;
- if (additional_names == this._initial_additional_names)
- {
- this._individual_id = i.id;
- this._initial_additional_names_found = true;
- this._tracker_backend.update_contact (this._contact_urn,
- Trf.OntologyDefs.NCO_ADDITIONAL,
- this._updated_additional_names);
- }
- }
+ {
+ if (this._initial_fullname == i.full_name)
+ {
+ var additional_names = i.structured_name.additional_names;
+ if (additional_names == this._initial_additional_names)
+ {
+ i.structured_name.notify["additional-names"].connect
+ (this._notify_additional_names_cb);
+ this._individual_id = i.id;
+ this._initial_additional_names_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_ADDITIONAL,
+ this._updated_additional_names);
+ }
+ }
+ }
assert (removed == null);
}
- private void _notify_additional_names_cb ()
+ private void _notify_additional_names_cb (Object sname_obj, ParamSpec ps)
{
- var i = this._aggregator.individuals.lookup (this._individual_id);
-
- if (i == null)
- return;
-
- var additional_names = i.structured_name.additional_names;
+ Folks.StructuredName sname = (Folks.StructuredName) sname_obj;
+ var additional_names = sname.additional_names;
if (additional_names == this._updated_additional_names)
{
diff --git a/tests/tracker/family-name-updates.vala b/tests/tracker/family-name-updates.vala
index dbcb7ee..9801863 100644
--- a/tests/tracker/family-name-updates.vala
+++ b/tests/tracker/family-name-updates.vala
@@ -117,28 +117,27 @@ public class FamilyNameUpdatesTests : Folks.TestCase
{
foreach (unowned Individual i in added)
{
- i.structured_name.notify["family-name"].connect
- (this._notify_family_name_cb);
- var family_name = i.structured_name.family_name;
- if (family_name == this._initial_family_name)
+ if (this._initial_fullname == i.full_name)
{
- this._individual_id = i.id;
- this._initial_family_name_found = true;
- this._tracker_backend.update_contact (this._contact_urn,
- Trf.OntologyDefs.NCO_FAMILY, this._updated_family_name);
+ i.structured_name.notify["family-name"].connect
+ (this._notify_family_name_cb);
+ var family_name = i.structured_name.family_name;
+ if (family_name == this._initial_family_name)
+ {
+ this._individual_id = i.id;
+ this._initial_family_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_FAMILY, this._updated_family_name);
+ }
}
}
-
- assert (removed == null);
+ assert (removed == null);
}
- private void _notify_family_name_cb ()
+ private void _notify_family_name_cb (Object individual_obj, ParamSpec ps)
{
- var i = this._aggregator.individuals.lookup (this._individual_id);
- if (i == null)
- return;
-
- var family_name = i.structured_name.family_name;
+ Folks.StructuredName sname = (Folks.StructuredName) individual_obj;
+ var family_name = sname.family_name;
if (family_name == this._updated_family_name)
{
this._updated_family_name_found = true;
diff --git a/tests/tracker/given-name-updates.vala b/tests/tracker/given-name-updates.vala
index 463fb0d..9ed9d27 100644
--- a/tests/tracker/given-name-updates.vala
+++ b/tests/tracker/given-name-updates.vala
@@ -116,15 +116,18 @@ public class GivenNameUpdatesTests : Folks.TestCase
{
foreach (unowned Individual i in added)
{
- i.structured_name.notify["given-name"].connect
- (this._notify_given_name_cb);
- var given_name = i.structured_name.given_name;
- if (given_name == this._initial_given_name)
+ if (this._initial_fullname == i.full_name)
{
- this._individual_id = i.id;
- this._initial_given_name_found = true;
- this._tracker_backend.update_contact (this._contact_urn,
- Trf.OntologyDefs.NCO_GIVEN, this._updated_given_name);
+ i.structured_name.notify["given-name"].connect
+ (this._notify_given_name_cb);
+ var given_name = i.structured_name.given_name;
+ if (given_name == this._initial_given_name)
+ {
+ this._individual_id = i.id;
+ this._initial_given_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_GIVEN, this._updated_given_name);
+ }
}
}
diff --git a/tests/tracker/name-details-interface.vala b/tests/tracker/name-details-interface.vala
index 0aa6eb5..54d2530 100644
--- a/tests/tracker/name-details-interface.vala
+++ b/tests/tracker/name-details-interface.vala
@@ -56,7 +56,6 @@ public class NameDetailsInterfaceTests : Folks.TestCase
this._c2 = new Gee.HashMap<string, string> ();
this._c1.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #1");
- this._c1.set (Trf.OntologyDefs.NCO_NICKNAME, "p #1");
this._c1.set (Trf.OntologyDefs.NCO_FAMILY, "p #1 Family");
this._c1.set (Trf.OntologyDefs.NCO_GIVEN, "p #1 Given");
this._c1.set (Trf.OntologyDefs.NCO_ADDITIONAL, "p #1 Additional");
@@ -65,7 +64,6 @@ public class NameDetailsInterfaceTests : Folks.TestCase
this._tracker_backend.add_contact (this._c1);
this._c2.set (Trf.OntologyDefs.NCO_FULLNAME, "persona #2");
- this._c2.set (Trf.OntologyDefs.NCO_NICKNAME, "p #2");
this._tracker_backend.add_contact (this._c2);
this._tracker_backend.set_up ();
@@ -122,11 +120,6 @@ public class NameDetailsInterfaceTests : Folks.TestCase
{
this._c1.unset (Trf.OntologyDefs.NCO_FULLNAME);
- string nickname = ((Folks.NameDetails) i).nickname;
- assert (this._c1.get (Trf.OntologyDefs.NCO_NICKNAME) ==
- nickname);
- this._c1.unset (Trf.OntologyDefs.NCO_NICKNAME);
-
string family = sname.family_name ;
assert (this._c1.get (Trf.OntologyDefs.NCO_FAMILY) ==
family);
@@ -157,12 +150,7 @@ public class NameDetailsInterfaceTests : Folks.TestCase
{
this._c2.unset (Trf.OntologyDefs.NCO_FULLNAME);
- string nickname = ((Folks.NameDetails) i).nickname;
- assert (this._c2.get (Trf.OntologyDefs.NCO_NICKNAME) ==
- nickname);
- this._c2.unset (Trf.OntologyDefs.NCO_NICKNAME);
-
- assert (sname.is_empty () == true);
+ assert (sname == null || sname.is_empty () == true);
}
}
}
diff --git a/tests/tracker/nickname-updates.vala b/tests/tracker/nickname-updates.vala
index e3e39d4..deaafa9 100644
--- a/tests/tracker/nickname-updates.vala
+++ b/tests/tracker/nickname-updates.vala
@@ -28,12 +28,10 @@ public class NicknameUpdatesTests : Folks.TestCase
private TrackerTest.Backend _tracker_backend;
private IndividualAggregator _aggregator;
private bool _updated_nickname_found;
- private bool _initial_nickname_found = false;
private string _updated_nickname;
private string _individual_id;
private GLib.MainLoop _main_loop;
private string _initial_fullname;
- private string _initial_nickname;
private string _contact_urn;
public NicknameUpdatesTests ()
@@ -59,18 +57,15 @@ public class NicknameUpdatesTests : Folks.TestCase
this._main_loop = new GLib.MainLoop (null, false);
Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
this._initial_fullname = "persona #1";
- this._initial_nickname = "nickname #1";
this._updated_nickname = "updated nickname #1";
this._contact_urn = "<urn:contact001>";
c1.set (TrackerTest.Backend.URN, this._contact_urn);
c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname);
- c1.set (Trf.OntologyDefs.NCO_NICKNAME, this._initial_nickname);
this._tracker_backend.add_contact (c1);
this._tracker_backend.set_up ();
- this._initial_nickname_found = false;
this._updated_nickname_found = false;
this._individual_id = "";
@@ -84,7 +79,6 @@ public class NicknameUpdatesTests : Folks.TestCase
this._main_loop.run ();
- assert (this._initial_nickname_found == true);
assert (this._updated_nickname_found == true);
this._tracker_backend.tear_down ();
@@ -116,13 +110,25 @@ public class NicknameUpdatesTests : Folks.TestCase
{
foreach (unowned Individual i in added)
{
- if (i.nickname == this._initial_nickname)
+ if (i.full_name == this._initial_fullname)
{
i.notify["nickname"].connect (this._notify_nickname_cb);
this._individual_id = i.id;
- this._initial_nickname_found = true;
- this._tracker_backend.update_contact (this._contact_urn,
- Trf.OntologyDefs.NCO_NICKNAME, this._updated_nickname);
+
+ var im_addr = "<urn:im-address>";
+ this._tracker_backend.insert_triplet (im_addr,
+ "a", Trf.OntologyDefs.NCO_IMADDRESS,
+ Trf.OntologyDefs.NCO_IM_NICKNAME, this._updated_nickname);
+
+ var affl = "<urn:im-affl>";
+ this._tracker_backend.insert_triplet (affl,
+ "a", Trf.OntologyDefs.NCO_AFFILIATION);
+
+ this._tracker_backend.insert_triplet (affl,
+ Trf.OntologyDefs.NCO_HAS_IMADDRESS, im_addr);
+
+ this._tracker_backend.insert_triplet (this._contact_urn,
+ Trf.OntologyDefs.NCO_HAS_AFFILIATION, affl);
}
}
diff --git a/tests/tracker/prefix-name-updates.vala b/tests/tracker/prefix-name-updates.vala
index c547c94..82e655a 100644
--- a/tests/tracker/prefix-name-updates.vala
+++ b/tests/tracker/prefix-name-updates.vala
@@ -116,15 +116,18 @@ public class PrefixNameUpdatesTests : Folks.TestCase
{
foreach (unowned Individual i in added)
{
- var prefix_name = i.structured_name.prefixes;
- if (prefix_name == this._initial_prefix_name)
+ if (this._initial_fullname == i.full_name)
{
- i.structured_name.notify["prefixes"].connect
- (this._notify_prefix_name_cb);
- this._individual_id = i.id;
- this._initial_prefix_name_found = true;
- this._tracker_backend.update_contact (this._contact_urn,
- Trf.OntologyDefs.NCO_PREFIX, this._updated_prefix_name);
+ var prefix_name = i.structured_name.prefixes;
+ if (prefix_name == this._initial_prefix_name)
+ {
+ i.structured_name.notify["prefixes"].connect
+ (this._notify_prefix_name_cb);
+ this._individual_id = i.id;
+ this._initial_prefix_name_found = true;
+ this._tracker_backend.update_contact (this._contact_urn,
+ Trf.OntologyDefs.NCO_PREFIX, this._updated_prefix_name);
+ }
}
}
assert (removed == null);
diff --git a/tests/tracker/remove-persona.vala b/tests/tracker/remove-persona.vala
new file mode 100644
index 0000000..e83d0fd
--- /dev/null
+++ b/tests/tracker/remove-persona.vala
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class RemovePersonaTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _persona_removed;
+ private bool _individual_removed;
+ private string _individual_id;
+ private PersonaStore _pstore;
+ private string _persona_id;
+ private Individual _individual;
+ private bool _added_persona = false;
+
+ public RemovePersonaTests ()
+ {
+ base ("RemovePersonaTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test adding personas to Tracker ", this.test_remove_persona);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_remove_persona ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ this._persona_fullname = "persona #1";
+
+ this._persona_removed = false;
+ this._individual_removed = false;
+
+ this._test_remove_persona_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._persona_removed == true);
+ assert (this._individual_removed == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_remove_persona_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+
+ this._pstore = null;
+ foreach (var backend in store.enabled_backends)
+ {
+ this._pstore = backend.persona_stores.lookup ("tracker");
+ if (this._pstore != null)
+ break;
+ }
+ assert (this._pstore != null);
+
+ this._pstore.notify["is-prepared"].connect (this._notify_pstore_cb);
+ this._try_to_add ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _notify_pstore_cb (Object _pstore, ParamSpec ps)
+ {
+ this._try_to_add ();
+ }
+
+ private void _try_to_add ()
+ {
+ if (this._pstore.is_prepared &&
+ this._added_persona == false)
+ {
+ this._added_persona = true;
+ this._add_persona ();
+ }
+ }
+
+ private async void _add_persona ()
+ {
+ HashTable<string, Value?> details = new HashTable<string, Value?>
+ (str_hash, str_equal);
+ Value? v1 = Value (typeof (string));
+ v1.set_string (this._persona_fullname);
+ details.insert (this._pstore.detail_key (PersonaDetail.FULL_NAME),
+ (owned) v1);
+
+ Value? v2 = Value (typeof (GLib.List<FieldDetails>));
+ GLib.List<FieldDetails> emails =
+ new GLib.List<FieldDetails> ();
+ var email_1 = new FieldDetails ("test-1 example org");
+ emails.prepend ((owned) email_1);
+ var email_2 = new FieldDetails ("test-2 example org");
+ emails.prepend ((owned) email_2);
+ v2.set_pointer (emails);
+ details.insert (this._pstore.detail_key (PersonaDetail.EMAIL_ADDRESSES),
+ (owned) v2);
+
+ try
+ {
+ yield this._aggregator.add_persona_from_details
+ (null, this._pstore, details);
+ }
+ catch (Folks.IndividualAggregatorError e)
+ {
+ GLib.warning ("[RemovePersonaError] add_persona_from_details: %s\n",
+ e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ this._individual_id = i.id;
+ this._persona_id = i.personas.nth_data (0).iid;
+ this._individual = i;
+ if (this._pstore.personas.lookup (this._persona_id) != null)
+ {
+ this._pstore.personas_changed.connect (this._personas_cb);
+ this._aggregator.remove_individual (this._individual);
+ }
+ }
+ }
+
+ foreach (unowned Individual i in removed)
+ {
+ if (i.id == this._individual_id)
+ {
+ this._individual_removed = true;
+ }
+ }
+ }
+
+ private void _personas_cb ()
+ {
+ if (this._pstore.personas.lookup (this._persona_id) == null)
+ {
+ this._persona_removed = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new RemovePersonaTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-alias.vala b/tests/tracker/set-alias.vala
new file mode 100644
index 0000000..a7bb252
--- /dev/null
+++ b/tests/tracker/set-alias.vala
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetAliasTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private string _initial_alias;
+ private string _modified_alias;
+ private bool _initial_alias_found;
+ private bool _modified_alias_found;
+
+ public SetAliasTests ()
+ {
+ base ("SetAliasTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting alias ", this.test_set_alias);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_alias ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._initial_alias = "initial alias";
+ this._modified_alias = "modified alias";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+
+ /* Note:
+ *
+ * we treat the nco:nickname associated to an nco:PersonContact
+ * as the alias, and the nco:nickname(s) associated to IM accounts
+ * as possible nicknames. */
+ c1.set (Trf.OntologyDefs.NCO_NICKNAME, this._initial_alias);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._initial_alias_found = false;
+ this._modified_alias_found = false;
+
+ this._test_set_alias_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._initial_alias_found == true);
+ assert (this._modified_alias_found == true);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_alias_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ if (i.alias == this._initial_alias)
+ {
+ this._initial_alias_found = true;
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+
+ /*
+ * We connect to the Persona's handler because
+ * Individual won't forward the notification to us
+ * unless it comes from a writeable store.
+ */
+ p.notify["alias"].connect (this._notify_alias_cb);
+
+ /* FIXME:
+ * it would be nice if we could just do:
+ * i.alias = "foobar"
+ * but we depend on:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=645441 */
+ p.alias = this._modified_alias;
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_alias_cb (Object persona, ParamSpec ps)
+ {
+ Trf.Persona p = (Trf.Persona) persona;
+ if (p.alias == this._modified_alias)
+ {
+ this._modified_alias_found = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetAliasTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-avatar.vala b/tests/tracker/set-avatar.vala
new file mode 100644
index 0000000..3cac3c3
--- /dev/null
+++ b/tests/tracker/set-avatar.vala
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetAvatarTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private string _avatar_uri;
+ private File _avatar;
+ private bool _avatar_found;
+
+ public SetAvatarTests ()
+ {
+ base ("SetAvatarTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting avatar ", this.test_set_avatar);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_avatar ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._avatar_uri = "file:///tmp/some-avatar.jpg";
+ this._avatar = File.new_for_uri (this._avatar_uri);
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._avatar_found = false;
+
+ this._test_set_avatar_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._avatar_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_avatar_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["avatar"].connect (this._notify_avatar_cb);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.avatar = this._avatar;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_avatar_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ if (i.avatar.get_uri () == this._avatar_uri)
+ {
+ this._avatar_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetAvatarTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-birthday.vala b/tests/tracker/set-birthday.vala
new file mode 100644
index 0000000..5e8332e
--- /dev/null
+++ b/tests/tracker/set-birthday.vala
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetBirthdayTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _bday_found;
+ private DateTime _bday;
+ private string _birthday;
+
+ public SetBirthdayTests ()
+ {
+ base ("SetBirthdayTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting bithday ",
+ this.test_set_bday);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_bday ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._birthday = "2001-10-26T20:32:52Z";
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (this._birthday);
+ this._bday = new DateTime.from_timeval_utc (t);
+
+ this._tracker_backend.set_up ();
+
+ this._bday_found = false;
+
+ this._test_set_bday_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._bday_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_bday_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["birthday"].connect (this._notify_bday_cb);
+
+ TimeVal t = TimeVal ();
+ t.from_iso8601 (this._birthday);
+ DateTime bday = new DateTime.from_timeval_utc (t);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.birthday = (owned) bday;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_bday_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ if (i.birthday != null &&
+ i.birthday.compare (this._bday) == 0)
+ {
+ this._bday_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetBirthdayTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-emails.vala b/tests/tracker/set-emails.vala
new file mode 100644
index 0000000..2275f38
--- /dev/null
+++ b/tests/tracker/set-emails.vala
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetEmailsTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private string _email_1;
+ private string _email_2;
+ private bool _email_1_found;
+ private bool _email_2_found;
+
+ public SetEmailsTests ()
+ {
+ base ("SetEmailsTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting emails ", this.test_set_emails);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_emails ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._email_1 = "email-1 example org";
+ this._email_2 = "email-2 example org";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._email_1_found = false;
+ this._email_2_found = false;
+
+ this._test_set_emails_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._email_1_found);
+ assert (this._email_2_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_emails_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["email-addresses"].connect (this._notify_emails_cb);
+
+ GLib.List<FieldDetails> emails = new GLib.List<FieldDetails> ();
+ var p1 = new FieldDetails (this._email_1);
+ emails.prepend ((owned) p1);
+ var p2 = new FieldDetails (this._email_2);
+ emails.prepend ((owned) p2);
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.email_addresses = (owned) emails;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_emails_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (unowned FieldDetails p in i.email_addresses)
+ {
+ if (p.value == this._email_1)
+ this._email_1_found = true;
+ else if (p.value == this._email_2)
+ this._email_2_found = true;
+ }
+ }
+
+ if (this._email_1_found && this._email_2_found)
+ {
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetEmailsTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-favourite.vala b/tests/tracker/set-favourite.vala
new file mode 100644
index 0000000..4ded8ba
--- /dev/null
+++ b/tests/tracker/set-favourite.vala
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetFavouriteTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _initial_fullname_1 = "persona #1";
+ private string _initial_fullname_2 = "persona #2";
+ private bool _c1_initially_not_favourite;
+ private bool _c1_finally_favourite;
+ private bool _c2_initially_favourite;
+ private bool _c2_finally_not_favourite;
+
+ public SetFavouriteTests ()
+ {
+ base ("SetFavouriteTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting favourite ", this.test_set_alias);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_alias ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ Gee.HashMap<string, string> c2 = new Gee.HashMap<string, string> ();
+ this._initial_fullname_1 = "persona #1";
+ this._initial_fullname_2 = "persona #2";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_1);
+ this._tracker_backend.add_contact (c1);
+
+ c2.set (Trf.OntologyDefs.NCO_FULLNAME, this._initial_fullname_2);
+ c2.set (Trf.OntologyDefs.NAO_TAG, "");
+ this._tracker_backend.add_contact (c2);
+
+ this._tracker_backend.set_up ();
+
+ this._c1_initially_not_favourite = false;
+ this._c1_finally_favourite = false;
+ this._c2_initially_favourite = false;
+ this._c2_finally_not_favourite = false;
+
+ this._test_set_alias_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ /* Note:
+ * the is-favourite property is notified as a
+ * consequence of a value changed event fired by
+ * Tracker
+ */
+ assert (this._c1_initially_not_favourite);
+ assert (this._c1_finally_favourite);
+ assert (this._c2_initially_favourite);
+ assert (this._c2_finally_not_favourite);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_alias_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ i.notify["is-favourite"].connect (this._notify_favourite_cb);
+ if (i.full_name == this._initial_fullname_1)
+ {
+ if (i.is_favourite == false)
+ {
+ this._c1_initially_not_favourite = true;
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.is_favourite = true;
+ }
+ }
+ else if (i.full_name == this._initial_fullname_2)
+ {
+ if (i.is_favourite == true)
+ {
+ this._c2_initially_favourite = true;
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.is_favourite = false;
+ }
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_favourite_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._initial_fullname_1)
+ {
+ if (i.is_favourite == true)
+ this._c1_finally_favourite = true;
+ }
+ else if (i.full_name == this._initial_fullname_2)
+ {
+ if (i.is_favourite == false)
+ this._c2_finally_not_favourite = true;
+ }
+
+ if (this._c1_finally_favourite &&
+ this._c2_finally_not_favourite)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetFavouriteTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-full-name.vala b/tests/tracker/set-full-name.vala
new file mode 100644
index 0000000..40c954f
--- /dev/null
+++ b/tests/tracker/set-full-name.vala
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetFullNameTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _found_changed_full_name ;
+ private string _individual_id;
+ private string _modified_fullname;
+
+ public SetFullNameTests ()
+ {
+ base ("SetFullNameTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting structured name ",
+ this.test_set_full_name);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_full_name ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._individual_id = "";
+ this._modified_fullname = "modified - persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._found_changed_full_name = false;
+
+ this._test_set_full_name_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_changed_full_name);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_full_name_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ this._individual_id = i.id;
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ i.notify["full-name"].connect (this._notify_full_name_cb);
+ p.full_name = this._modified_fullname;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_full_name_cb (Object individual, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual;
+ if (i.id == this._individual_id &&
+ i.full_name == this._modified_fullname)
+ {
+ this._found_changed_full_name = true;
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetFullNameTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-gender.vala b/tests/tracker/set-gender.vala
new file mode 100644
index 0000000..268baf9
--- /dev/null
+++ b/tests/tracker/set-gender.vala
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetGenderTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _gender_found;
+
+ public SetGenderTests ()
+ {
+ base ("SetGenderTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting gender ",
+ this.test_set_gender);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_gender ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._gender_found = false;
+
+ this._test_set_gender_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._gender_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_gender_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["gender"].connect (this._notify_gender_cb);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.gender = Gender.MALE;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_gender_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ if (i.gender == Gender.MALE)
+ {
+ this._gender_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetGenderTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-im-addresses.vala b/tests/tracker/set-im-addresses.vala
new file mode 100644
index 0000000..1f13a4f
--- /dev/null
+++ b/tests/tracker/set-im-addresses.vala
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetIMAddressesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private GLib.List<string> _addresses =
+ new GLib.List<string> ();
+
+ public SetIMAddressesTests ()
+ {
+ base ("SetIMAddressesTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting im_addresses ", this.test_set_im_addresses);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_im_addresses ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 =
+ new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._addresses.prepend ("one example org");
+ this._addresses.prepend ("two example org");
+ this._addresses.prepend ("three example org");
+ this._addresses.prepend ("four example org");
+
+ this._tracker_backend.set_up ();
+
+ this._test_set_im_addresses_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._addresses.length () == 0);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_im_addresses_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["im-addresses"].connect (this._notify_im_addresses_cb);
+
+ HashTable<string, LinkedHashSet<string>> im_addresses =
+ new HashTable<string, LinkedHashSet<string>>
+ (str_hash, str_equal);
+
+ var addrs_1 = new LinkedHashSet<string> ();
+ addrs_1.add ("one example org");
+ addrs_1.add ("two example org");
+ im_addresses.insert ("aim",
+ (owned) addrs_1);
+
+ var addrs_2 = new LinkedHashSet<string> ();
+ addrs_2.add ("three example org");
+ addrs_2.add ("four example org");
+ im_addresses.insert ("yahoo",
+ (owned) addrs_2);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.im_addresses = (owned) im_addresses;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_im_addresses_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (var proto in i.im_addresses.get_keys ())
+ {
+ var addrs = i.im_addresses.lookup (proto);
+ foreach (var a in addrs)
+ {
+ foreach (unowned string my_a in this._addresses)
+ {
+ if (my_a == a)
+ {
+ this._addresses.remove (my_a);
+ break;
+ }
+ }
+ }
+ }
+
+ if (this._addresses.length () == 0)
+ {
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetIMAddressesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-notes.vala b/tests/tracker/set-notes.vala
new file mode 100644
index 0000000..7ff3667
--- /dev/null
+++ b/tests/tracker/set-notes.vala
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetNotesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _note_found;
+ private Note _note;
+
+ public SetNotesTests ()
+ {
+ base ("SetNotesTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting notes ",
+ this.test_set_notes);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_notes ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._note = new Note ("some note");
+
+ this._tracker_backend.set_up ();
+
+ this._note_found = false;
+
+ this._test_set_notes_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._note_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_notes_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["notes"].connect (this._notify_notes_cb);
+
+ Gee.HashSet<Note> notes = new HashSet<Note>
+ ((GLib.HashFunc) Note.hash, (GLib.EqualFunc) Note.equal);
+ var n = new Note ("some note");
+ notes.add ((owned) n);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.notes = (owned) notes;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_notes_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (var n in i.notes)
+ {
+ if (Note.equal (n, this._note))
+ {
+ this._note_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetNotesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-phones.vala b/tests/tracker/set-phones.vala
new file mode 100644
index 0000000..00409d8
--- /dev/null
+++ b/tests/tracker/set-phones.vala
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetPhonesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private string _phone_1;
+ private string _phone_2;
+ private bool _phone_1_found;
+ private bool _phone_2_found;
+
+ public SetPhonesTests ()
+ {
+ base ("SetPhonesTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting phones ", this.test_set_phones);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_phones ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._phone_1 = "12345";
+ this._phone_2 = "54321";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._phone_1_found = false;
+ this._phone_2_found = false;
+
+ this._test_set_phones_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._phone_1_found);
+ assert (this._phone_2_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_phones_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["phone-numbers"].connect (this._notify_phones_cb);
+
+ GLib.List<FieldDetails> phones = new GLib.List<FieldDetails> ();
+ var p1 = new FieldDetails (this._phone_1);
+ phones.prepend ((owned) p1);
+ var p2 = new FieldDetails (this._phone_2);
+ phones.prepend ((owned) p2);
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.phone_numbers = (owned) phones;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_phones_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (unowned FieldDetails p in i.phone_numbers)
+ {
+ if (p.value == this._phone_1)
+ this._phone_1_found = true;
+ else if (p.value == this._phone_2)
+ this._phone_2_found = true;
+ }
+ }
+
+ if (this._phone_1_found && this._phone_2_found)
+ {
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetPhonesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-postal-addresses.vala b/tests/tracker/set-postal-addresses.vala
new file mode 100644
index 0000000..f887b1a
--- /dev/null
+++ b/tests/tracker/set-postal-addresses.vala
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetPostalAddressesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _postal_address_found;
+ private PostalAddress _address;
+
+ public SetPostalAddressesTests ()
+ {
+ base ("SetPostalAddressesTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting postal addresses ",
+ this.test_set_postal_addresses);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_postal_addresses ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ GLib.List<string> types = new GLib.List<string> ();
+ this._address = new PostalAddress (null, null, null, null, null,
+ null, null, null, types, null);
+ this._address.po_box = "12345";
+ this._address.locality = "locality";
+ this._address.postal_code = "code";
+ this._address.street = "some street";
+ this._address.extension = "some extension";
+ this._address.country = "some country";
+ this._address.region = "some region";
+
+ this._tracker_backend.set_up ();
+
+ this._postal_address_found = false;
+
+ this._test_set_postal_addresses_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._postal_address_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_postal_addresses_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["postal-addresses"].connect (this._notify_postal_cb);
+
+ GLib.List<string> types = new GLib.List<string> ();
+ GLib.List<PostalAddress> addresses =
+ new GLib.List<PostalAddress> ();
+ var pa = new Folks.PostalAddress (null, null, null, null, null,
+ null, null, null, types, null);
+ pa.po_box = this._address.po_box;
+ pa.locality = this._address.locality;
+ pa.postal_code =this._address.postal_code;
+ pa.street = this._address.street;
+ pa.extension = this._address.extension;
+ pa.country = this._address.country;
+ pa.region = this._address.region;
+
+ addresses.prepend ((owned) pa);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.postal_addresses = (owned) addresses;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_postal_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (unowned PostalAddress p in i.postal_addresses)
+ {
+ /* we don't care if UIDs differ for this test */
+ this._address.uid = p.uid;
+ if (p.equal (this._address))
+ {
+ this._postal_address_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetPostalAddressesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-roles.vala b/tests/tracker/set-roles.vala
new file mode 100644
index 0000000..3924de2
--- /dev/null
+++ b/tests/tracker/set-roles.vala
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetRolesTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _role_found;
+ private Role _role;
+
+ public SetRolesTests ()
+ {
+ base ("SetRolesTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting roles ",
+ this.test_set_roles);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_roles ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._role = new Role ("some title", "some organisation");
+
+ this._tracker_backend.set_up ();
+
+ this._role_found = false;
+
+ this._test_set_roles_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._role_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_roles_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["roles"].connect (this._notify_roles_cb);
+
+ Gee.HashSet<Role> roles = new HashSet<Role>
+ ((GLib.HashFunc) Role.hash, (GLib.EqualFunc) Role.equal);
+ var r = new Role ("some title", "some organisation");
+ roles.add ((owned) r);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.roles = (owned) roles;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_roles_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (var r in i.roles)
+ {
+ if (Role.equal (r, this._role))
+ {
+ this._role_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetRolesTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-structured-name.vala b/tests/tracker/set-structured-name.vala
new file mode 100644
index 0000000..b2a3d30
--- /dev/null
+++ b/tests/tracker/set-structured-name.vala
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetStructuredNameTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ private bool _sname_found;
+ private StructuredName _sname;
+ private string _family_name;
+ private string _given_name;
+ private string _additional_names;
+ private string _prefixes;
+ private string _suffixes;
+
+ public SetStructuredNameTests ()
+ {
+ base ("SetStructuredNameTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting structured name ",
+ this.test_set_structured_name);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_structured_name ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._family_name = "family name";
+ this._given_name = "given name";
+ this._additional_names = "additional name";
+ this._prefixes = "prefixes";
+ this._suffixes = "suffixes";
+
+ this._sname = new StructuredName (this._family_name, this._given_name,
+ this._additional_names, this._prefixes, this._suffixes);
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._sname_found = false;
+
+ this._test_set_structured_name_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._sname_found);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_structured_name_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.notify["structured-name"].connect (this._notify_sname_cb);
+ p.structured_name = this._sname;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_sname_cb (Object persona, ParamSpec ps)
+ {
+ Trf.Persona p = (Trf.Persona) persona;
+ if (p.full_name == this._persona_fullname)
+ {
+ if (p.structured_name.is_empty () == false &&
+ p.structured_name.equal (this._sname) == true)
+ {
+ this._sname_found = true;
+ this._main_loop.quit ();
+ }
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetStructuredNameTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/set-urls.vala b/tests/tracker/set-urls.vala
new file mode 100644
index 0000000..d7e56e7
--- /dev/null
+++ b/tests/tracker/set-urls.vala
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using Tracker.Sparql;
+using TrackerTest;
+using Folks;
+using Gee;
+
+public class SetURLsTests : Folks.TestCase
+{
+ private GLib.MainLoop _main_loop;
+ private TrackerTest.Backend _tracker_backend;
+ private IndividualAggregator _aggregator;
+ private string _persona_fullname;
+ Gee.HashMap<string, string> _urls;
+
+ public SetURLsTests ()
+ {
+ base ("SetURLsTests");
+
+ this._tracker_backend = new TrackerTest.Backend ();
+
+ this.add_test ("test setting urls ", this.test_set_urls);
+ }
+
+ public override void set_up ()
+ {
+ }
+
+ public override void tear_down ()
+ {
+ }
+
+ public void test_set_urls ()
+ {
+ this._main_loop = new GLib.MainLoop (null, false);
+ Gee.HashMap<string, string> c1 = new Gee.HashMap<string, string> ();
+ this._persona_fullname = "persona #1";
+ this._urls = new Gee.HashMap<string, string> ();
+ this._urls.set ("blog", "http://one.example.org");
+ this._urls.set ("website", "http://two.example.org");
+ this._urls.set ("url", "http://three.example.org");
+
+ c1.set (Trf.OntologyDefs.NCO_FULLNAME, this._persona_fullname);
+ this._tracker_backend.add_contact (c1);
+
+ this._tracker_backend.set_up ();
+
+ this._test_set_urls_async ();
+
+ Timeout.add_seconds (5, () =>
+ {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._urls.size == 0);
+
+ this._tracker_backend.tear_down ();
+ }
+
+ private async void _test_set_urls_async ()
+ {
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.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
+ (GLib.List<Individual>? added,
+ GLib.List<Individual>? removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ foreach (unowned Individual i in added)
+ {
+ if (i.full_name == this._persona_fullname)
+ {
+ i.notify["urls"].connect (this._notify_urls_cb);
+
+ GLib.List<FieldDetails> urls = new GLib.List<FieldDetails> ();
+ var p1 = new FieldDetails (this._urls.get ("blog"));
+ p1.set_parameter ("type", "blog");
+ urls.prepend ((owned) p1);
+ var p2 = new FieldDetails (this._urls.get ("website"));
+ p2.set_parameter ("type", "website");
+ urls.prepend ((owned) p2);
+ var p3 = new FieldDetails (this._urls.get ("url"));
+ p3.set_parameter ("type", "url");
+ urls.prepend ((owned) p3);
+
+ Trf.Persona p = (Trf.Persona)i.personas.nth_data (0);
+ p.urls = (owned) urls;
+ }
+ }
+
+ assert (removed == null);
+ }
+
+ private void _notify_urls_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ if (i.full_name == this._persona_fullname)
+ {
+ foreach (unowned FieldDetails p in i.urls)
+ {
+ unowned GLib.List<string> type_p =
+ p.get_parameter_values ("type");
+ string type = type_p.nth_data (0);
+
+ if (type == "blog" && p.value == this._urls.get ("blog"))
+ this._urls.unset ("blog");
+ else if (type == "website" &&
+ p.value == this._urls.get ("website"))
+ this._urls.unset ("website");
+ else if (type == "url" && p.value == this._urls.get ("url"))
+ this._urls.unset ("url");
+ }
+ }
+
+ if (this._urls.size == 0)
+ this._main_loop.quit ();
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetURLsTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
diff --git a/tests/tracker/suffix-name-updates.vala b/tests/tracker/suffix-name-updates.vala
index 0696567..aded7bb 100644
--- a/tests/tracker/suffix-name-updates.vala
+++ b/tests/tracker/suffix-name-updates.vala
@@ -118,6 +118,8 @@ public class SuffixNameUpdatesTests : Folks.TestCase
{
foreach (unowned Individual i in added)
{
+ if (this._initial_fullname == i.full_name)
+ {
var suffix_name = i.structured_name.suffixes;
if (suffix_name == this._initial_suffix_name)
{
@@ -128,6 +130,7 @@ public class SuffixNameUpdatesTests : Folks.TestCase
this._tracker_backend.update_contact (this._contact_urn,
Trf.OntologyDefs.NCO_SUFFIX, this._updated_suffix_name);
}
+ }
}
assert (removed == null);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]