[couchdb-glib] Added UUIDs to API, and ways to generate them for objects that don't have it.



commit 7359a5b2819b1888440bf3276fb1cc0b9335635c
Author: Rodrigo Moya <rodrigo gnome-db org>
Date:   Wed Aug 5 16:32:15 2009 +0200

    Added UUIDs to API, and ways to generate them for objects that don't have it.
    
    Assume hostnames from clients come with the http/https part of the URI, so
    don't add it. This makes it work with per-user couchdb instance

 couchdb-glib/Makefile.am                |    3 +-
 couchdb-glib/couchdb-document-contact.c |   44 ++++++++++++++++++++++++++----
 couchdb-glib/couchdb-document-contact.h |    7 +++--
 couchdb-glib/couchdb-document.c         |   10 +++---
 couchdb-glib/couchdb-types.c            |   21 ++++++++++++++
 couchdb-glib/couchdb-types.h            |    3 ++
 couchdb-glib/couchdb.c                  |   12 ++++----
 couchdb-glib/utils.c                    |   14 ++++++++++
 couchdb-glib/utils.h                    |    6 +++-
 tests/Makefile.am                       |    4 ++-
 10 files changed, 101 insertions(+), 23 deletions(-)
---
diff --git a/couchdb-glib/Makefile.am b/couchdb-glib/Makefile.am
index a8e66dc..4b256f0 100644
--- a/couchdb-glib/Makefile.am
+++ b/couchdb-glib/Makefile.am
@@ -11,7 +11,8 @@ libcouchdb_glib_1_0_la_SOURCES =	\
 	utils.c				\
 	utils.h
 libcouchdb_glib_1_0_la_LIBADD =		\
-	$(COUCHDB_GLIB_LIBS)
+	$(COUCHDB_GLIB_LIBS)		\
+	-luuid
 
 hdir = $(includedir)/couchdb-glib-1.0
 h_DATA = 				\
diff --git a/couchdb-glib/couchdb-document-contact.c b/couchdb-glib/couchdb-document-contact.c
index 6c2076c..e0c1a54 100644
--- a/couchdb-glib/couchdb-document-contact.c
+++ b/couchdb-glib/couchdb-document-contact.c
@@ -94,6 +94,7 @@ foreach_object_cb (JsonObject *object,
 
 		sf = couchdb_struct_field_new_from_json_object (
 			json_object_ref (json_node_get_object (member_node)));
+		couchdb_struct_field_set_uuid (sf, member_name);
 		*list = g_slist_prepend (*list, sf);
 	}
 }
@@ -153,7 +154,9 @@ couchdb_document_contact_set_email_addresses (CouchDBDocument *document, GSList
 			json_object_set_string_member (this_address, "description",
 						       couchdb_document_contact_email_get_description (sf));
 
-			json_object_set_object_member (addresses_json, address_str, this_address);
+			json_object_set_object_member (addresses_json,
+						       couchdb_struct_field_get_uuid (sf),
+						       this_address);
 			/* FIXME: crashes if we _unref json_object_unref (this_address); */
 		}
 	}
@@ -206,7 +209,9 @@ couchdb_document_contact_set_phone_numbers (CouchDBDocument *document, GSList *l
 			json_object_set_int_member (this_phone, "priority",
 						    couchdb_document_contact_phone_get_priority (sf));
 
-			json_object_set_object_member (phone_numbers, number_str, this_phone);
+			json_object_set_object_member (phone_numbers,
+						       couchdb_struct_field_get_uuid (sf),
+						       this_phone);
 			/* FIXME: crashes if we _unref json_object_unref (this_phone); */
 		}
 	}
@@ -267,7 +272,9 @@ couchdb_document_contact_set_addresses (CouchDBDocument *document, GSList *list)
 			json_object_set_string_member (this_address, "description",
 						       couchdb_document_contact_address_get_description (sf));
 
-			json_object_set_object_member (addresses, street_str, this_address);
+			json_object_set_object_member (addresses,
+						       couchdb_struct_field_get_uuid (sf),
+						       this_address);
 			/* FIXME: crashes if we _unref json_object_unref (this_address); */
 		}
 	}
@@ -277,11 +284,19 @@ couchdb_document_contact_set_addresses (CouchDBDocument *document, GSList *list)
 }
 
 CouchDBStructField *
-couchdb_document_contact_email_new (const char *address, const char *description)
+couchdb_document_contact_email_new (const char *uuid, const char *address, const char *description)
 {
 	CouchDBStructField *sf;
 
 	sf = couchdb_struct_field_new_from_json_object (json_object_new ());
+	if (uuid != NULL)
+		couchdb_struct_field_set_uuid (sf, uuid);
+	else {
+		char *new_uuid = generate_uuid ();
+		couchdb_struct_field_set_uuid (sf, new_uuid);
+		g_free (new_uuid);
+	}
+
 	if (address)
 		couchdb_document_contact_email_set_address (sf, address);
 	if (description)
@@ -324,11 +339,19 @@ couchdb_document_contact_email_set_description (CouchDBStructField *sf, const ch
 }
 
 CouchDBStructField *
-couchdb_document_contact_phone_new (const char *number, const char *description, gint priority)
+couchdb_document_contact_phone_new (const char *uuid, const char *number, const char *description, gint priority)
 {
 	CouchDBStructField *sf;
 
 	sf = couchdb_struct_field_new_from_json_object (json_object_new ());
+	if (uuid != NULL)
+		couchdb_struct_field_set_uuid (sf, uuid);
+	else {
+		char *new_uuid = generate_uuid ();
+		couchdb_struct_field_set_uuid (sf, new_uuid);
+		g_free (new_uuid);
+	}
+
 	if (number)
 		couchdb_document_contact_phone_set_number (sf, number);
 	if (description)
@@ -388,7 +411,8 @@ couchdb_document_contact_phone_set_description (CouchDBStructField *sf, const ch
 }
 
 CouchDBStructField *
-couchdb_document_contact_address_new (const char *street,
+couchdb_document_contact_address_new (const char *uuid,
+				      const char *street,
 				      const char *city,
 				      const char *state,
 				      const char *country,
@@ -399,6 +423,14 @@ couchdb_document_contact_address_new (const char *street,
 	CouchDBStructField *sf;
 
 	sf = couchdb_struct_field_new_from_json_object (json_object_new ());
+	if (uuid != NULL)
+		couchdb_struct_field_set_uuid (sf, uuid);
+	else {
+		char *new_uuid = generate_uuid ();
+		couchdb_struct_field_set_uuid (sf, new_uuid);
+		g_free (new_uuid);
+	}
+
 	if (street)
 		couchdb_document_contact_address_set_street (sf, street);
 	if (city)
diff --git a/couchdb-glib/couchdb-document-contact.h b/couchdb-glib/couchdb-document-contact.h
index e1224bf..2fd786a 100644
--- a/couchdb-glib/couchdb-document-contact.h
+++ b/couchdb-glib/couchdb-document-contact.h
@@ -48,7 +48,7 @@ void        couchdb_document_contact_set_addresses (CouchDBDocument *document, G
  * Utility functions to manipulate email addresses fields
  */
 
-CouchDBStructField *couchdb_document_contact_email_new (const char *address, const char *description);
+CouchDBStructField *couchdb_document_contact_email_new (const char *uuid, const char *address, const char *description);
 const char         *couchdb_document_contact_email_get_address (CouchDBStructField *sf);
 void                couchdb_document_contact_email_set_address (CouchDBStructField *sf, const char *email);
 const char         *couchdb_document_contact_email_get_description (CouchDBStructField *sf);
@@ -58,7 +58,7 @@ void                couchdb_document_contact_email_set_description (CouchDBStruc
  * Utility functions to manipulate phone numbers
  */
 
-CouchDBStructField *couchdb_document_contact_phone_new (const char *number, const char *description, gint priority);
+CouchDBStructField *couchdb_document_contact_phone_new (const char *uuid, const char *number, const char *description, gint priority);
 gint                couchdb_document_contact_phone_get_priority (CouchDBStructField *sf);
 void                couchdb_document_contact_phone_set_priority (CouchDBStructField *sf, gint priority);
 const char         *couchdb_document_contact_phone_get_number (CouchDBStructField *sf);
@@ -69,7 +69,8 @@ void                couchdb_document_contact_phone_set_description (CouchDBStruc
 /*
  * Utility functions to manipulate addresses
  */
-CouchDBStructField *couchdb_document_contact_address_new (const char *street,
+CouchDBStructField *couchdb_document_contact_address_new (const char *uuid,
+							  const char *street,
 							  const char *city,
 							  const char *state,
 							  const char *country,
diff --git a/couchdb-glib/couchdb-document.c b/couchdb-glib/couchdb-document.c
index a45cd2c..ce32582 100644
--- a/couchdb-glib/couchdb-document.c
+++ b/couchdb-glib/couchdb-document.c
@@ -85,7 +85,7 @@ couchdb_document_get (CouchDB *couchdb,
 	g_return_val_if_fail (dbname != NULL, NULL);
 	g_return_val_if_fail (docid != NULL, NULL);
 
-	url = g_strdup_printf ("http://%s/%s/%s";, couchdb->hostname, dbname, docid);
+	url = g_strdup_printf ("%s/%s/%s", couchdb->hostname, dbname, docid);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
 	if (parser) {
 		document = g_object_new (COUCHDB_TYPE_DOCUMENT, NULL);
@@ -117,10 +117,10 @@ couchdb_document_put (CouchDBDocument *document,
 	id = couchdb_document_get_id (document);
 	body = couchdb_document_to_string (document);
 	if (id) {
-		url = g_strdup_printf ("http://%s/%s/%s";, document->couchdb->hostname, dbname, id);
+		url = g_strdup_printf ("%s/%s/%s", document->couchdb->hostname, dbname, id);
 		parser = send_message_and_parse (document->couchdb, SOUP_METHOD_PUT, url, body, error);
 	} else {
-		url = g_strdup_printf ("http://%s/%s/";, document->couchdb->hostname, dbname);
+		url = g_strdup_printf ("%s/%s/", document->couchdb->hostname, dbname);
 		parser = send_message_and_parse (document->couchdb, SOUP_METHOD_POST, url, body, error);
 	}
 
@@ -163,7 +163,7 @@ couchdb_document_delete (CouchDBDocument *document, GError **error)
 	if (!id || !revision) /* we can't remove a document without an ID and/or a REVISION */
 		return FALSE;
 
-	url = g_strdup_printf ("http://%s/%s/%s?rev=%s";, document->couchdb->hostname, document->dbname, id, revision);
+	url = g_strdup_printf ("%s/%s/%s?rev=%s", document->couchdb->hostname, document->dbname, id, revision);
 	parser = send_message_and_parse (document->couchdb, SOUP_METHOD_DELETE, url, NULL, error);
 	if (parser) {
 		g_object_unref (G_OBJECT (parser));
@@ -235,7 +235,7 @@ couchdb_document_is_contact (CouchDBDocument *document)
 
 	return !g_ascii_strcasecmp (json_object_get_string_member (json_node_get_object (document->root_node),
 								   "record_type"),
-				    "http://example.com/contact-record";);
+				    "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact";);
 }
 
 gboolean
diff --git a/couchdb-glib/couchdb-types.c b/couchdb-glib/couchdb-types.c
index c043457..8ddc8aa 100644
--- a/couchdb-glib/couchdb-types.c
+++ b/couchdb-glib/couchdb-types.c
@@ -236,6 +236,7 @@ couchdb_struct_field_new (void)
 	sf = g_slice_new (CouchDBStructField);
 	sf->ref_count = 1;
 	sf->json_object = json_object_new ();
+	sf->uuid = NULL;
 
 	return sf;
 }
@@ -248,6 +249,7 @@ couchdb_struct_field_new_from_json_object (JsonObject *json_object)
 	sf = g_slice_new (CouchDBStructField);
 	sf->ref_count = 1;
 	sf->json_object = json_object_ref (json_object);
+	sf->uuid = NULL;
 
 	return sf;
 }
@@ -394,3 +396,22 @@ couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field
 
 	json_object_set_object_member (sf->json_object, field, json_object_ref (value->json_object));
 }
+
+const char *
+couchdb_struct_field_get_uuid (CouchDBStructField *sf)
+{
+	g_return_val_if_fail (sf != NULL, NULL);
+
+	return (const char *) sf->uuid;
+}
+
+void
+couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid)
+{
+	g_return_if_fail (sf != NULL);
+
+	if (sf->uuid)
+		g_free (sf->uuid);
+
+	sf->uuid = g_strdup (uuid);
+}
diff --git a/couchdb-glib/couchdb-types.h b/couchdb-glib/couchdb-types.h
index daf243e..3daf537 100644
--- a/couchdb-glib/couchdb-types.h
+++ b/couchdb-glib/couchdb-types.h
@@ -80,4 +80,7 @@ void                couchdb_struct_field_set_string_field (CouchDBStructField *s
 CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
 void                couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value);
 
+const char         *couchdb_struct_field_get_uuid (CouchDBStructField *sf);
+void                couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid);
+
 #endif
diff --git a/couchdb-glib/couchdb.c b/couchdb-glib/couchdb.c
index cb0c159..19193ef 100644
--- a/couchdb-glib/couchdb.c
+++ b/couchdb-glib/couchdb.c
@@ -57,7 +57,7 @@ couchdb_new (const char *hostname)
 	CouchDB *couchdb;
 
 	couchdb = g_object_new (COUCHDB_TYPE, NULL);
-	couchdb->hostname = hostname ? g_strdup (hostname) : g_strdup ("localhost:5984");
+	couchdb->hostname = hostname ? g_strdup (hostname) : g_strdup ("http://localhost:5984";);
 	couchdb->http_session = soup_session_sync_new_with_options (
 		SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
                 NULL);
@@ -84,7 +84,7 @@ couchdb_list_databases (CouchDB *couchdb, GError **error)
 	g_return_val_if_fail (COUCHDB_IS (couchdb), NULL);
 
 	/* Prepare request */
-	url = g_strdup_printf ("http://%s/_all_dbs";, couchdb->hostname);
+	url = g_strdup_printf ("%s/_all_dbs", couchdb->hostname);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
 	if (parser) {
 		JsonNode *root_node;
@@ -120,7 +120,7 @@ couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error)
 	g_return_val_if_fail (COUCHDB_IS (couchdb), NULL);
 	g_return_val_if_fail (dbname != NULL, NULL);
 
-	url = g_strdup_printf ("http://%s/%s/";, couchdb->hostname, dbname);
+	url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
 	if (parser) {
 		JsonNode *root_node;
@@ -153,7 +153,7 @@ couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error)
 	g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
 	g_return_val_if_fail (dbname != NULL, FALSE);
 
-	url = g_strdup_printf ("http://%s/%s/";, couchdb->hostname, dbname);
+	url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_PUT, url, NULL, error);
 	if (parser) {
 		JsonNode *root_node;
@@ -181,7 +181,7 @@ couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error)
 	g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
 	g_return_val_if_fail (dbname != NULL, FALSE);
 
-	url = g_strdup_printf ("http://%s/%s/";, couchdb->hostname, dbname);
+	url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_DELETE, url, NULL, error);
 	if (parser) {
 		JsonNode *root_node;
@@ -218,7 +218,7 @@ couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error)
 	g_return_val_if_fail (COUCHDB_IS (couchdb), NULL);
 	g_return_val_if_fail (dbname != NULL, NULL);
 
-	url = g_strdup_printf ("http://%s/%s/_all_docs";, couchdb->hostname, dbname);
+	url = g_strdup_printf ("%s/%s/_all_docs", couchdb->hostname, dbname);
 	parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
 	if (parser) {
 		JsonNode *root_node;
diff --git a/couchdb-glib/utils.c b/couchdb-glib/utils.c
index 83c5473..2b4f20d 100644
--- a/couchdb-glib/utils.c
+++ b/couchdb-glib/utils.c
@@ -19,6 +19,7 @@
  * Boston, MA 02110-1301, USA.
  */
 
+#include <uuid/uuid.h>
 #include <string.h>
 #include <libsoup/soup-session-async.h>
 #include "couchdb-glib.h"
@@ -86,3 +87,16 @@ send_message_and_parse (CouchDB *couchdb, const char *method, const char *url, c
 
 	return parser;
 }
+
+char *
+generate_uuid (void)
+{
+	uuid_t uuid;
+	char uuid_string[37];
+
+	uuid_generate_random (uuid);
+	uuid_unparse (uuid, uuid_string);
+
+	g_print ("Generated %s uuid", uuid_string);
+	return g_strdup (uuid_string);
+}
diff --git a/couchdb-glib/utils.h b/couchdb-glib/utils.h
index cc5b0ba..88cab7c 100644
--- a/couchdb-glib/utils.h
+++ b/couchdb-glib/utils.h
@@ -69,8 +69,10 @@ CouchDBDocumentInfo *couchdb_document_info_new (const char *docid, const char *r
 
 struct _CouchDBStructField {
 	gint ref_count;
-
 	JsonObject *json_object;
+
+	/* Extra data needed for some specific StructField's */
+	char *uuid; /* the UUID of this item */
 };
 
 CouchDBStructField *couchdb_struct_field_new_from_json_object (JsonObject *json_object);
@@ -85,4 +87,6 @@ JsonParser *send_message_and_parse (CouchDB *couchdb,
 				    const char *body,
 				    GError **error);
 
+char *generate_uuid (void);
+
 #endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 447a188..1d657aa 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -9,11 +9,13 @@ noinst_PROGRAMS = 		\
 test_list_databases_SOURCES = test-list-databases.c
 test_list_databases_LDADD = 	\
 	$(COUCHDB_GLIB_LIBS)	\
+	-luuid			\
 	$(top_builddir)/couchdb-glib/libcouchdb-glib-1.0.la
 
 test_couchdb_glib_SOURCES = test-couchdb-glib.c
 test_couchdb_glib_LDADD = 	\
 	$(COUCHDB_GLIB_LIBS)	\
+	-luuid			\
 	$(top_builddir)/couchdb-glib/libcouchdb-glib-1.0.la
 
 EXTRA_DIST = createCouchContacts.py
@@ -21,4 +23,4 @@ EXTRA_DIST = createCouchContacts.py
 check_PROGRAMS = test-couchdb-glib
 
 test: $(check_PROGRAMS)
-	$(top_srcdir)/tests/test-couchdb-glib
\ No newline at end of file
+	$(top_srcdir)/tests/test-couchdb-glib



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