Merge lp:~kamstrup/couchdb-glib/couchdb-glib-gtkdoc into lp:couchdb-glib

Proposed by Mikkel Kamstrup Erlandsen on 2009-10-06
Status: Merged
Approved by: Rodrigo Moya on 2009-10-07
Approved revision: 117
Merge reported by: dobey
Merged at revision: not available
Proposed branch: lp:~kamstrup/couchdb-glib/couchdb-glib-gtkdoc
Merge into: lp:couchdb-glib
Diff against target: 3027 lines
32 files modified
Makefile.am (+13/-2)
NOTES.kamstrup (+32/-0)
configure.ac (+9/-0)
couchdb-glib/Makefile.am (+17/-5)
couchdb-glib/couchdb-database-info.c (+151/-0)
couchdb-glib/couchdb-database-info.h (+59/-0)
couchdb-glib/couchdb-document-contact.c (+10/-10)
couchdb-glib/couchdb-document-contact.h (+9/-2)
couchdb-glib/couchdb-document-info.c (+107/-0)
couchdb-glib/couchdb-document-info.h (+45/-0)
couchdb-glib/couchdb-document.c (+38/-20)
couchdb-glib/couchdb-document.h (+134/-0)
couchdb-glib/couchdb-glib.h (+13/-108)
couchdb-glib/couchdb-struct-field.c (+291/-0)
couchdb-glib/couchdb-struct-field.h (+68/-0)
couchdb-glib/couchdb-types.c (+0/-466)
couchdb-glib/couchdb-types.h (+0/-89)
couchdb-glib/couchdb.c (+214/-31)
couchdb-glib/couchdb.h (+84/-0)
couchdb-glib/dbwatch.c (+7/-7)
couchdb-glib/dbwatch.h (+3/-1)
couchdb-glib/utils.c (+0/-144)
couchdb-glib/utils.h (+4/-75)
debian/control (+12/-0)
debian/libcouchdb-glib-doc.install (+1/-0)
debian/rules (+2/-0)
doc/Makefile.am (+4/-0)
doc/reference/Makefile.am (+67/-0)
doc/reference/couchdb-glib-docs.sgml (+19/-0)
doc/reference/couchdb-glib.types (+6/-0)
tests/test-couchdb-glib.c (+13/-3)
tests/test-list-databases.c (+9/-2)
To merge this branch: bzr merge lp:~kamstrup/couchdb-glib/couchdb-glib-gtkdoc
Reviewer Review Type Date Requested Status
Rodrigo Moya (community) Approve on 2009-10-07
Tim Cole (community) 2009-10-06 Approve on 2009-10-06
Review via email: mp+12917@code.launchpad.net
To post a comment you must log in.

So here's my source structure overhaul as discussed on: http://groups.google.com/group/desktop-couchdb/browse_thread/thread/7bb2fe5055370140

After manually extracting my OAUTH credentials from ~/.config/desktop-couch/desktop-couchdb.ini I was able to run the unit tests successfully.

The big picture of what I've done:

 * Enable gtk-doc for all public classes

 * Shuffle the code for all public GObjects to be in <namespace>-<type>.{h,c} files

 * Make all GObject instance struct declarations private (ie. declared in the .c file)

To facilitate this in needed some changes in the source code - on top of the massive refactoring.

In couchdb.{h,c}:
 * Don't make CouchDB struct depend on whether we are configured with OAUTH
 * Move OAUTH related functionality from util.* here
 * New method couchdb_send_message() replacing send_message_and_parse() from util.*

In couchdb-document.c:
 * Change refs to internal API of CouchDB object's ->hostname to method calls
 * Change refs to internal API of CouchDBStructField ->json_object to use method call

In couchdb-struct-field.*:
 * Add method _get_json_object()

Future plans: I have a list of items I'd like to work on in the future - they might be better of discussed on the mailing list, but I put them here FYI:
 - Silent build rules
 - Single header includes
 - ? Get rid of CouchDBStructField ?
 - Make 'make check' run unit tests
 - Rename CouchDB class to CouchDBConnection
 - Add method couchdb_send_async using a SoupSessionAsync underneath
 - A .ini parser to extract OAUTH credentials from desktop-couchdb.ini, to make OAUTH "just work", like in the desktopcouch Python module

I should also add that I also want to start writing some of the actual documentation once I start on the rest of my TODOs. Currently we just generate empty gtk-doc.

Rodrigo Moya (rodrigo-moya) wrote :

Code-wise it looks ok to me, too big a change to merge into the current tree (for karmic), so I need to make a branch on GNOME's GIT, and import that into bazaar so that that becomes the tree for karmic merge proposals.

Running now the tests...

> Code-wise it looks ok to me, too big a change to merge into the current tree
> (for karmic), so I need to make a branch on GNOME's GIT, and import that into
> bazaar so that that becomes the tree for karmic merge proposals.

Yeah, agreed. So if I understand correctly, I keep it here as a Bzr tree on LP? If you would rather have a Git branch on Gnome's Git server then I can do that too.

Rodrigo Moya (rodrigo-moya) wrote :

> > Code-wise it looks ok to me, too big a change to merge into the current tree
> > (for karmic), so I need to make a branch on GNOME's GIT, and import that
> into
> > bazaar so that that becomes the tree for karmic merge proposals.
>
> Yeah, agreed. So if I understand correctly, I keep it here as a Bzr tree on
> LP? If you would rather have a Git branch on Gnome's Git server then I can do
> that too.

well, if you can do that, that would be better. But no need to create a GIT branch, let me first find out how to import a GIT branch into LP (so that we use that for karmic merge proposals), and then, once the GIT branch has been created (doing it now), you can just commit to GIT trunk

115. By Mikkel Kamstrup Erlandsen on 2009-10-06

Update TODO

Rodrigo Moya (rodrigo-moya) wrote :

ok, so there is no way to import GIT branches into LP, so we will be doing manual code review (sending patches to an internal list) for the next few weeks from the gnome-2-28 branch I've created in GIT.

So, I'll approve your branch as soon as this other branch (https://code.edge.launchpad.net/~rodrigo-moya/couchdb-glib/no-revision-in-auth-header) gets accepted/merged. Just make sure your branch includes those 2 simple fixes, push it, so that the new diff is shown, and, as I said, I'll approve it (and push it to GNOME master branch, if you can't do so) as soon as the other branch lands in GNOME GIT.

Tim Cole (tcole) wrote :

The refcounting logic is unsafe as written; correct refcounting in the multithreaded case can be subtle and not something I would recommend attempting on your own.

(Is there a reason to use a boxed type rather than deriving from gobject, which has correct refcounting?)

The two biggest thread-related issues are with _unref; first, there is a race between the read of the refcount and acting on it, and secondly g_atomic_int_compare_and_exchange is misused here, since it can potentially fail and is supposed to be used in a retrying loop.

The requirements for refcounting here are at least a little simpler than gobject's (since I don't think you have to worry about e.g. revivification or weak/floating refs); if you were to continue with a boxed type, a correct implementation for your simple case would look something like this:

 CouchDBDatabaseInfo *
 couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo)
 {
  g_return_val_if_fail (dbinfo != NULL, NULL);
  g_return_val_if_fail (dbinfo->ref_count > 0, NULL);

  g_atomic_int_inc(&dbinfo->ref_count);

  return dbinfo;
 }

 void
 couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo)
 {
  gboolean is_zero;

  g_return_if_fail (dbinfo != NULL);
  g_return_if_fail (dbinfo->ref_count > 0);

  is_zero = g_atomic_int_dec_and_test(&dbinfo->ref_count);

  if (is_zero) {
   g_free (dbinfo->dbname);
   g_slice_free (CouchDBDatabaseInfo, dbinfo);
  }
 }

(Also, is single-space-indent acceptable from a CodingStyle point of view?)

review: Needs Fixing

> The refcounting logic is unsafe as written; correct refcounting in the
> multithreaded case can be subtle and not something I would recommend
> attempting on your own.

Note that I didn't change any of this code - I simply moved it around. I intentionally kept the branch API stable. I don't think it would be a good idea to block the merging of this branch because of this issue.

I agree however, that we could just as well use full GObjects everywhere we use custom boxed types (DatabaseInfo, DocumentInfo, and StructField as far as I recall). But we can work on this in master now that Rodrigo branched off the 0.5 series.

I have a bunch of API-breaking comments as well, but we should probably discuss such matters on the mailing list.

116. By Mikkel Kamstrup Erlandsen on 2009-10-06

More items for the todo :-)

117. By Mikkel Kamstrup Erlandsen on 2009-10-06

Port bugfix in rev. 98 of lp:~rodrigo-moya/couchdb-glib/no-revision-in-auth-header to this branch

> ok, so there is no way to import GIT branches into LP, so we will be doing
> manual code review (sending patches to an internal list) for the next few
> weeks from the gnome-2-28 branch I've created in GIT.
>
> So, I'll approve your branch as soon as this other branch
> (https://code.edge.launchpad.net/~rodrigo-moya/couchdb-glib/no-revision-in-
> auth-header) gets accepted/merged. Just make sure your branch includes those 2
> simple fixes, push it, so that the new diff is shown, and, as I said, I'll
> approve it (and push it to GNOME master branch, if you can't do so) as soon as
> the other branch lands in GNOME GIT.

I've ported you fixes to my branch in rev. 117: http://bazaar.launchpad.net/~kamstrup/couchdb-glib/couchdb-glib-gtkdoc/revision/117. I've have SSH keys for Gnome so I can merge it to master myself.

Tim Cole (tcole) wrote :

Hmm.. okay....

I'd still really like to see the refcounting fixed per my example though. That shouldn't cause any ABI/API incompatibilities.

review: Approve
Rodrigo Moya (rodrigo-moya) wrote :

Well, AFAICS boxed types are used everywhere in GNOME for structs, so that's why I used them. I wouldn't mind using GObject's, but since they won't have any signal, property, or any other GObject-related feature, I think we can live with implementing the refcounting ourselves. Of course, it makes sense to use the g_atomic_* calls Tim suggests, although, yes, let's fix that once the branch has landed.

So Mikkel, please commit to GIT master

review: Approve

> So Mikkel, please commit to GIT master

Done.

(I hope I did not mess something up too badly with my bzr->git transition (using the bzr fast-import plugin)).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2009-07-20 11:27:33 +0000
3+++ Makefile.am 2009-10-06 18:10:22 +0000
4@@ -1,4 +1,6 @@
5-SUBDIRS = couchdb-glib tests
6+SUBDIRS = couchdb-glib tests doc
7+
8+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
9
10 pcfiles = couchdb-glib-1.0.pc
11
12@@ -8,7 +10,16 @@
13 pkgconfig_DATA = $(pcfiles)
14 pkgconfigdir = $(libdir)/pkgconfig
15
16-EXTRA_DIST = couchdb-glib.pc.in LICENSE
17+couchdbdocdir = ${datadir}/doc/couchdb-glib
18+couchdbdoc_DATA = \
19+ README \
20+ LICENSE \
21+ couchdb-glib.doap \
22+ NEWS
23+
24+EXTRA_DIST = \
25+ couchdb-glib.pc.in \
26+ $(couchdbdoc_DATA)
27
28 dist-hook:
29 git log --stat > ChangeLog.in && \
30
31=== added file 'NOTES.kamstrup'
32--- NOTES.kamstrup 1970-01-01 00:00:00 +0000
33+++ NOTES.kamstrup 2009-10-06 18:10:22 +0000
34@@ -0,0 +1,32 @@
35+TODO:
36+-----
37+Silent build rules
38+Single header includes
39+? Get rid of CouchDBStructField ?
40+Make 'make check' run unit tests
41+Rename CouchDB class to CouchDBConnection
42+Add method couchdb_send_async using a SoupSessionAsync underneath
43+A .ini parser to extract OAUTH credentials from desktop-couchdb.ini
44+Move couchdb_document_put() to couchdb_put(doc) in order to separate responsibilities and make CouchDB sub-classable
45+Class struct padding for future ABI stability
46+Ref counting in custom boxed types vs. full GObjects
47+Abstract out OAUTH, in favour of custom message filters in couchdb_send_message
48+
49+DONE:
50+-----
51+
52+In couchdb.*:
53+ * Don't make API depend on whether we are configured with OAUTH
54+ * Move OAUTH related functionality from util.* here
55+ * New method couchdb_send_message() replacing send_message_and_parse() from util.*
56+
57+In couchdb-document.c:
58+ * Change refs to internal API of CouchDB object's ->hostname to method calls
59+ * Change refs to internal API of CouchDBStructField ->json_object to use method call
60+
61+In couchdb-struct-field.*:
62+ * Add method _get_json_object()
63+
64+THOUGHTS:
65+ * CouchDBStructField seems to be a superfluous wrapper of JSonObject
66+ * Rename CouchDB object to CouchDBConnection
67
68=== modified file 'configure.ac'
69--- configure.ac 2009-09-29 12:19:40 +0000
70+++ configure.ac 2009-10-06 18:10:22 +0000
71@@ -43,11 +43,20 @@
72 AC_SUBST(LIBCOUCHDBGLIB_REVISION)
73 AC_SUBST(LIBCOUCHDBGLIB_AGE)
74
75+##################################################
76+# Check for gtk-doc.
77+##################################################
78+GTK_DOC_CHECK(1.0)
79+DISTCHECK_CONFIGURE_FLAGS="--enable-gtk-doc"
80+AC_SUBST(DISTCHECK_CONFIGURE_FLAGS)
81+
82 AC_OUTPUT([
83 Makefile
84 couchdb-glib.pc
85 couchdb-glib/Makefile
86 tests/Makefile
87+doc/Makefile
88+doc/reference/Makefile
89 ])
90
91 AC_MSG_NOTICE([
92
93=== modified file 'couchdb-glib/Makefile.am'
94--- couchdb-glib/Makefile.am 2009-09-09 15:09:10 +0000
95+++ couchdb-glib/Makefile.am 2009-10-06 18:10:22 +0000
96@@ -22,21 +22,33 @@
97 couchdb-marshal.c: couchdb-marshal.list $(GLIB_GENMARSHAL)
98 $(GLIB_GENMARSHAL) $< --body --prefix=_couchdb_marshal > $@
99
100-libcouchdb_glib_1_0_la_SOURCES = \
101- $(MARSHAL_GENERATED) \
102+libcouchdb_glib_1_0_la_SOURCES = \
103 couchdb.c \
104+ couchdb.h \
105+ couchdb-database-info.c \
106+ couchdb-database-info.h \
107 couchdb-document.c \
108+ couchdb-document.h \
109 couchdb-document-contact.c \
110- couchdb-types.c \
111+ couchdb-document-contact.h \
112+ couchdb-document-info.c \
113+ couchdb-document-info.h \
114+ couchdb-glib.h \
115+ couchdb-struct-field.c \
116+ couchdb-struct-field.h \
117+ couchdb-types.h \
118 dbwatch.c \
119 dbwatch.h \
120- $(OAUTH_SOURCES) \
121 utils.c \
122- utils.h
123+ utils.h \
124+ $(MARSHAL_GENERATED) \
125+ $(OAUTH_SOURCES)
126+
127 libcouchdb_glib_1_0_la_LIBADD = \
128 $(COUCHDB_GLIB_LIBS) \
129 $(OAUTH_LIBS) \
130 -luuid
131+
132 libcouchdb_glib_1_0_la_LDFLAGS = \
133 -version-info $(LIBCOUCHDBGLIB_CURRENT):$(LIBCOUCHDBGLIB_REVISION):$(LIBCOUCHDBGLIB_AGE)
134
135
136=== added file 'couchdb-glib/couchdb-database-info.c'
137--- couchdb-glib/couchdb-database-info.c 1970-01-01 00:00:00 +0000
138+++ couchdb-glib/couchdb-database-info.c 2009-10-06 18:10:22 +0000
139@@ -0,0 +1,151 @@
140+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
141+/*
142+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
143+ * 2009 Mikkel Kamstrup Erlandsen
144+ *
145+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
146+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
147+ *
148+ * This library is free software; you can redistribute it and/or
149+ * modify it under the terms of version 2 of the GNU Lesser General Public
150+ * License as published by the Free Software Foundation.
151+ *
152+ * This program is distributed in the hope that it will be useful,
153+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
154+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
155+ * General Public License for more details.
156+ *
157+ * You should have received a copy of the GNU Lesser General Public
158+ * License along with this library; if not, write to the
159+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
160+ * Boston, MA 02110-1301, USA.
161+ */
162+
163+#include "couchdb-database-info.h"
164+
165+struct _CouchDBDatabaseInfo {
166+ gint ref_count;
167+
168+ char *dbname;
169+ gint doc_count;
170+ gint doc_del_count;
171+ gint update_seq;
172+ gboolean compact_running;
173+ gint disk_size;
174+};
175+
176+/*
177+ * CouchDBDatabaseInfo object
178+ */
179+
180+GType
181+couchdb_database_info_get_type (void)
182+{
183+ static GType object_type = 0;
184+
185+ if (G_UNLIKELY (!object_type))
186+ object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDatabaseInfo"),
187+ (GBoxedCopyFunc) couchdb_database_info_ref,
188+ (GBoxedFreeFunc) couchdb_database_info_unref);
189+
190+ return object_type;
191+}
192+
193+CouchDBDatabaseInfo *
194+couchdb_database_info_new (const char *dbname,
195+ gint doc_count,
196+ gint doc_del_count,
197+ gint update_seq,
198+ gboolean compact_running,
199+ gint disk_size)
200+{
201+ CouchDBDatabaseInfo *dbinfo;
202+
203+ dbinfo = g_slice_new (CouchDBDatabaseInfo);
204+ dbinfo->ref_count = 1;
205+ dbinfo->dbname = g_strdup (dbname);
206+ dbinfo->doc_count = doc_count;
207+ dbinfo->doc_del_count = doc_del_count;
208+ dbinfo->update_seq = update_seq;
209+ dbinfo->compact_running = compact_running;
210+ dbinfo->disk_size = disk_size;
211+
212+ return dbinfo;
213+}
214+
215+CouchDBDatabaseInfo *
216+couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo)
217+{
218+ g_return_val_if_fail (dbinfo != NULL, NULL);
219+ g_return_val_if_fail (dbinfo->ref_count > 0, NULL);
220+
221+ g_atomic_int_exchange_and_add (&dbinfo->ref_count, 1);
222+
223+ return dbinfo;
224+}
225+
226+void
227+couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo)
228+{
229+ gint old_ref;
230+
231+ g_return_if_fail (dbinfo != NULL);
232+ g_return_if_fail (dbinfo->ref_count > 0);
233+
234+ old_ref = g_atomic_int_get (&dbinfo->ref_count);
235+ if (old_ref > 1)
236+ g_atomic_int_compare_and_exchange (&dbinfo->ref_count, old_ref, old_ref - 1);
237+ else {
238+ g_free (dbinfo->dbname);
239+ g_slice_free (CouchDBDatabaseInfo, dbinfo);
240+ }
241+}
242+
243+const char *
244+couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo)
245+{
246+ g_return_val_if_fail (dbinfo != NULL, NULL);
247+
248+ return (const char *) dbinfo->dbname;
249+}
250+
251+gint
252+couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo)
253+{
254+ g_return_val_if_fail (dbinfo != NULL, 0);
255+
256+ return dbinfo->doc_count;
257+}
258+
259+gint
260+couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo)
261+{
262+ g_return_val_if_fail (dbinfo != NULL, 0);
263+
264+ return dbinfo->doc_del_count;
265+}
266+
267+gint
268+couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo)
269+{
270+ g_return_val_if_fail (dbinfo != NULL, 0);
271+
272+ return dbinfo->update_seq;
273+}
274+
275+gboolean
276+couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo)
277+{
278+ g_return_val_if_fail (dbinfo != NULL, FALSE);
279+
280+ return dbinfo->compact_running;
281+}
282+
283+gint
284+couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo)
285+{
286+ g_return_val_if_fail (dbinfo != NULL, 0);
287+
288+ return dbinfo->disk_size;
289+}
290+
291
292=== added file 'couchdb-glib/couchdb-database-info.h'
293--- couchdb-glib/couchdb-database-info.h 1970-01-01 00:00:00 +0000
294+++ couchdb-glib/couchdb-database-info.h 2009-10-06 18:10:22 +0000
295@@ -0,0 +1,59 @@
296+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
297+/*
298+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
299+ * 2009 Mikkel Kamstrup Erlandsen
300+ *
301+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
302+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
303+ *
304+ * This library is free software; you can redistribute it and/or
305+ * modify it under the terms of version 2 of the GNU Lesser General Public
306+ * License as published by the Free Software Foundation.
307+ *
308+ * This program is distributed in the hope that it will be useful,
309+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
310+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
311+ * General Public License for more details.
312+ *
313+ * You should have received a copy of the GNU Lesser General Public
314+ * License along with this library; if not, write to the
315+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
316+ * Boston, MA 02110-1301, USA.
317+ */
318+
319+#ifndef __COUCHDB_DATABASE_INFO_H__
320+#define __COUCHDB_DATABASE_INFO_H__
321+
322+#include <glib.h>
323+#include <glib-object.h>
324+#include "couchdb-types.h"
325+
326+G_BEGIN_DECLS
327+
328+#define COUCHDB_TYPE_DATABASE_INFO (couchdb_database_info_get_type ())
329+
330+/*
331+ * CouchDBDatabaseInfo
332+ */
333+
334+GType couchdb_database_info_get_type (void);
335+CouchDBDatabaseInfo *couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo);
336+void couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo);
337+
338+const char *couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo);
339+gint couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo);
340+gint couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo);
341+gint couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo);
342+gboolean couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo);
343+gint couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo);
344+
345+CouchDBDatabaseInfo* couchdb_database_info_new (const char *dbname,
346+ gint doc_count,
347+ gint doc_del_count,
348+ gint update_seq,
349+ gboolean compact_running,
350+ gint disk_size);
351+
352+G_END_DECLS
353+
354+#endif /* __COUCHDB_DATABASE_INFO_H__ */
355
356=== modified file 'couchdb-glib/couchdb-document-contact.c'
357--- couchdb-glib/couchdb-document-contact.c 2009-09-22 12:38:41 +0000
358+++ couchdb-glib/couchdb-document-contact.c 2009-10-06 18:10:22 +0000
359@@ -337,7 +337,7 @@
360 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
361
362 addresses_json = json_object_get_object_member (
363- json_node_get_object (document->root_node), "email_addresses");;
364+ couchdb_document_get_json_object (document), "email_addresses");;
365 if (addresses_json) {
366 json_object_foreach_member (addresses_json,
367 (JsonObjectForeach) foreach_object_cb,
368@@ -375,7 +375,7 @@
369 }
370 }
371
372- json_object_set_object_member (json_node_get_object (document->root_node), "email_addresses", addresses_json);
373+ json_object_set_object_member (couchdb_document_get_json_object (document), "email_addresses", addresses_json);
374 }
375
376 GSList *
377@@ -388,7 +388,7 @@
378 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
379
380 phone_numbers = json_object_get_object_member (
381- json_node_get_object (document->root_node), "phone_numbers");
382+ couchdb_document_get_json_object (document), "phone_numbers");
383 if (phone_numbers) {
384 json_object_foreach_member (phone_numbers,
385 (JsonObjectForeach) foreach_object_cb,
386@@ -428,7 +428,7 @@
387 }
388 }
389
390- json_object_set_object_member (json_node_get_object (document->root_node), "phone_numbers", phone_numbers);
391+ json_object_set_object_member (couchdb_document_get_json_object (document), "phone_numbers", phone_numbers);
392 }
393
394 GSList *
395@@ -441,7 +441,7 @@
396 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
397
398 addresses = json_object_get_object_member (
399- json_node_get_object (document->root_node), "addresses");
400+ couchdb_document_get_json_object (document), "addresses");
401 if (addresses) {
402 json_object_foreach_member (addresses,
403 (JsonObjectForeach) foreach_object_cb,
404@@ -489,7 +489,7 @@
405 }
406 }
407
408- json_object_set_object_member (json_node_get_object (document->root_node), "addresses", addresses);
409+ json_object_set_object_member (couchdb_document_get_json_object (document), "addresses", addresses);
410 }
411
412 GSList *
413@@ -502,7 +502,7 @@
414 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
415
416 im_addresses = json_object_get_object_member (
417- json_node_get_object (document->root_node), "im_addresses");
418+ couchdb_document_get_json_object (document), "im_addresses");
419 if (im_addresses != NULL) {
420 json_object_foreach_member (im_addresses,
421 (JsonObjectForeach) foreach_object_cb,
422@@ -542,7 +542,7 @@
423 }
424 }
425
426- json_object_set_object_member (json_node_get_object (document->root_node), "im_addresses", im_addresses_json);
427+ json_object_set_object_member (couchdb_document_get_json_object (document), "im_addresses", im_addresses_json);
428 }
429
430 GSList *
431@@ -555,7 +555,7 @@
432 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
433
434 urls = json_object_get_object_member (
435- json_node_get_object (document->root_node), "urls");
436+ couchdb_document_get_json_object (document), "urls");
437 if (urls) {
438 json_object_foreach_member (urls,
439 (JsonObjectForeach) foreach_object_cb,
440@@ -593,7 +593,7 @@
441 }
442 }
443
444- json_object_set_object_member (json_node_get_object (document->root_node), "urls", urls_json);
445+ json_object_set_object_member (couchdb_document_get_json_object (document), "urls", urls_json);
446 }
447
448 const char *
449
450=== modified file 'couchdb-glib/couchdb-document-contact.h'
451--- couchdb-glib/couchdb-document-contact.h 2009-09-21 22:34:18 +0000
452+++ couchdb-glib/couchdb-document-contact.h 2009-10-06 18:10:22 +0000
453@@ -22,7 +22,11 @@
454 #ifndef __COUCHDB_DOCUMENT_CONTACT_H__
455 #define __COUCHDB_DOCUMENT_CONTACT_H__
456
457-#include <couchdb-glib.h>
458+#include <glib.h>
459+#include "couchdb-document.h"
460+#include "couchdb-struct-field.h"
461+
462+G_BEGIN_DECLS
463
464 #define COUCHDB_RECORD_TYPE_CONTACT "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact"
465
466@@ -191,4 +195,7 @@
467
468 const char *couchdb_document_contact_url_get_description (CouchDBStructField *sf);
469 void couchdb_document_contact_url_set_description (CouchDBStructField *sf, const char *description);
470-#endif
471+
472+G_END_DECLS
473+
474+#endif /* __COUCHDB_DOCUMENT_CONTACT_H__ */
475
476=== added file 'couchdb-glib/couchdb-document-info.c'
477--- couchdb-glib/couchdb-document-info.c 1970-01-01 00:00:00 +0000
478+++ couchdb-glib/couchdb-document-info.c 2009-10-06 18:10:22 +0000
479@@ -0,0 +1,107 @@
480+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
481+/*
482+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
483+ * 2009 Mikkel Kamstrup Erlandsen
484+ *
485+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
486+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
487+ *
488+ * This library is free software; you can redistribute it and/or
489+ * modify it under the terms of version 2 of the GNU Lesser General Public
490+ * License as published by the Free Software Foundation.
491+ *
492+ * This program is distributed in the hope that it will be useful,
493+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
494+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
495+ * General Public License for more details.
496+ *
497+ * You should have received a copy of the GNU Lesser General Public
498+ * License along with this library; if not, write to the
499+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
500+ * Boston, MA 02110-1301, USA.
501+ */
502+
503+#include "couchdb-document-info.h"
504+
505+struct _CouchDBDocumentInfo {
506+ gint ref_count;
507+
508+ char *docid;
509+ char *revision;
510+};
511+
512+/*
513+ * CouchDBDocumentInfo object
514+ */
515+
516+GType
517+couchdb_document_info_get_type (void)
518+{
519+ static GType object_type = 0;
520+
521+ if (G_UNLIKELY (!object_type))
522+ object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDocumentInfo"),
523+ (GBoxedCopyFunc) couchdb_document_info_ref,
524+ (GBoxedFreeFunc) couchdb_document_info_unref);
525+
526+ return object_type;
527+}
528+
529+CouchDBDocumentInfo *
530+couchdb_document_info_new (const char *docid, const char *revision)
531+{
532+ CouchDBDocumentInfo *doc_info;
533+
534+ doc_info = g_slice_new (CouchDBDocumentInfo);
535+ doc_info->ref_count = 1;
536+ doc_info->docid = g_strdup (docid);
537+ doc_info->revision = g_strdup (revision);
538+
539+ return doc_info;
540+}
541+
542+CouchDBDocumentInfo *
543+couchdb_document_info_ref (CouchDBDocumentInfo *doc_info)
544+{
545+ g_return_val_if_fail (doc_info != NULL, NULL);
546+ g_return_val_if_fail (doc_info->ref_count > 0, NULL);
547+
548+ g_atomic_int_exchange_and_add (&doc_info->ref_count, 1);
549+
550+ return doc_info;
551+}
552+
553+void
554+couchdb_document_info_unref (CouchDBDocumentInfo *doc_info)
555+{
556+ gint old_ref;
557+
558+ g_return_if_fail (doc_info != NULL);
559+ g_return_if_fail (doc_info->ref_count > 0);
560+
561+ old_ref = g_atomic_int_get (&doc_info->ref_count);
562+ if (old_ref > 1)
563+ g_atomic_int_compare_and_exchange (&doc_info->ref_count, old_ref, old_ref - 1);
564+ else {
565+ g_free (doc_info->docid);
566+ g_free (doc_info->revision);
567+ g_slice_free (CouchDBDocumentInfo, doc_info);
568+ }
569+}
570+
571+const char *
572+couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info)
573+{
574+ g_return_val_if_fail (doc_info != NULL, NULL);
575+
576+ return (const char *) doc_info->docid;
577+}
578+
579+const char *
580+couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info)
581+{
582+ g_return_val_if_fail (doc_info != NULL, NULL);
583+
584+ return (const char *) doc_info->revision;
585+}
586+
587
588=== added file 'couchdb-glib/couchdb-document-info.h'
589--- couchdb-glib/couchdb-document-info.h 1970-01-01 00:00:00 +0000
590+++ couchdb-glib/couchdb-document-info.h 2009-10-06 18:10:22 +0000
591@@ -0,0 +1,45 @@
592+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
593+/*
594+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
595+ * 2009 Mikkel Kamstrup Erlandsen
596+ *
597+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
598+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
599+ *
600+ * This library is free software; you can redistribute it and/or
601+ * modify it under the terms of version 2 of the GNU Lesser General Public
602+ * License as published by the Free Software Foundation.
603+ *
604+ * This program is distributed in the hope that it will be useful,
605+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
606+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
607+ * General Public License for more details.
608+ *
609+ * You should have received a copy of the GNU Lesser General Public
610+ * License along with this library; if not, write to the
611+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
612+ * Boston, MA 02110-1301, USA.
613+ */
614+
615+#ifndef __COUCHDB_DOCUMENT_INFO_H__
616+#define __COUCHDB_DOCUMENT_INFO_H__
617+
618+#include <glib.h>
619+#include <glib-object.h>
620+#include "couchdb-types.h"
621+
622+G_BEGIN_DECLS
623+
624+#define COUCHDB_TYPE_DOCUMENT_INFO (couchdb_document_info_get_type ())
625+
626+GType couchdb_document_info_get_type (void);
627+CouchDBDocumentInfo *couchdb_document_info_new (const char *docid, const char *revision);
628+CouchDBDocumentInfo *couchdb_document_info_ref (CouchDBDocumentInfo *dbinfo);
629+void couchdb_document_info_unref (CouchDBDocumentInfo *dbinfo);
630+
631+const char *couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info);
632+const char *couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info);
633+
634+G_END_DECLS
635+
636+#endif /* __COUCHDB_DOCUMENT_INFO_H__ */
637
638=== modified file 'couchdb-glib/couchdb-document.c'
639--- couchdb-glib/couchdb-document.c 2009-09-09 12:30:29 +0000
640+++ couchdb-glib/couchdb-document.c 2009-10-06 18:10:22 +0000
641@@ -1,8 +1,10 @@
642 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
643 /*
644 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
645+ * 2009 Mikkel Kamstrup Erlandsen
646 *
647 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
648+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
649 *
650 * This library is free software; you can redistribute it and/or
651 * modify it under the terms of version 2 of the GNU Lesser General Public
652@@ -23,9 +25,17 @@
653 #include <libsoup/soup-session-async.h>
654 #include <libsoup/soup-gnome.h>
655 #include <json-glib/json-glib.h>
656-#include "couchdb-glib.h"
657+#include "couchdb-document.h"
658 #include "utils.h"
659
660+struct _CouchDBDocument {
661+ GObject parent;
662+
663+ CouchDB *couchdb;
664+ char *dbname;
665+ JsonNode *root_node;
666+};
667+
668 G_DEFINE_TYPE(CouchDBDocument, couchdb_document, G_TYPE_OBJECT);
669
670 static void
671@@ -85,17 +95,16 @@
672 g_return_val_if_fail (docid != NULL, NULL);
673
674 encoded_docid = soup_uri_encode (docid, NULL);
675- url = g_strdup_printf ("%s/%s/%s", couchdb->hostname, dbname, encoded_docid);
676- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
677- if (parser) {
678+ url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (couchdb), dbname, encoded_docid);
679+ parser = json_parser_new ();
680+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
681 document = g_object_new (COUCHDB_TYPE_DOCUMENT, NULL);
682 document->couchdb = couchdb;
683 document->dbname = g_strdup (dbname);
684
685- document->root_node = json_node_copy (json_parser_get_root (parser));
686- g_object_unref (G_OBJECT (parser));
687+ document->root_node = json_node_copy (json_parser_get_root (parser));
688 }
689-
690+ g_object_unref (G_OBJECT (parser));
691 g_free (encoded_docid);
692 g_free (url);
693
694@@ -111,34 +120,34 @@
695 const char *id;
696 JsonParser *parser;
697 gboolean result = FALSE;
698+ gboolean send_ok;;
699
700 g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);
701 g_return_val_if_fail (dbname != NULL, FALSE);
702
703 id = couchdb_document_get_id (document);
704 body = couchdb_document_to_string (document);
705+ parser = json_parser_new ();
706 if (id) {
707 char *encoded_docid;
708
709 encoded_docid = soup_uri_encode (id, NULL);
710- url = g_strdup_printf ("%s/%s/%s", document->couchdb->hostname, dbname, encoded_docid);
711- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_PUT, url, body, error);
712+ url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (document->couchdb), dbname, encoded_docid);
713+ send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_PUT, url, body, parser, error);
714
715 g_free (encoded_docid);
716 } else {
717- url = g_strdup_printf ("%s/%s/", document->couchdb->hostname, dbname);
718- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_POST, url, body, error);
719+ url = g_strdup_printf ("%s/%s/", couchdb_get_hostname (document->couchdb), dbname);
720+ send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_POST, url, body, parser, error);
721 }
722
723- if (parser) {
724+ if (send_ok) {
725 JsonObject *object;
726
727 object = json_node_get_object (json_parser_get_root (parser));
728 couchdb_document_set_id (document, json_object_get_string_member (object, "id"));
729 couchdb_document_set_revision (document, json_object_get_string_member (object, "rev"));
730
731- g_object_unref (G_OBJECT (parser));
732-
733 if (document->dbname) {
734 g_free (document->dbname);
735 document->dbname = g_strdup (dbname);
736@@ -155,6 +164,7 @@
737 /* free memory */
738 g_free (url);
739 g_free (body);
740+ g_object_unref (G_OBJECT (parser));
741
742 return result;
743 }
744@@ -174,11 +184,11 @@
745 if (!id || !revision) /* we can't remove a document without an ID and/or a REVISION */
746 return FALSE;
747
748- url = g_strdup_printf ("%s/%s/%s?rev=%s", document->couchdb->hostname, document->dbname, id, revision);
749- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_DELETE, url, NULL, error);
750- if (parser) {
751- g_object_unref (G_OBJECT (parser));
752-
753+ url = g_strdup_printf ("%s/%s/%s?rev=%s", couchdb_get_hostname (document->couchdb), document->dbname, id, revision);
754+
755+ /* We don't parse the http response, therefore the parser arg is NULL */
756+ if (couchdb_send_message (document->couchdb, SOUP_METHOD_DELETE, url, NULL, NULL, error)) {
757+ result = TRUE;
758 g_signal_emit_by_name (document->couchdb, "document_deleted", document->dbname, id);
759 }
760
761@@ -410,7 +420,7 @@
762
763 json_object_set_object_member (json_node_get_object (document->root_node),
764 field,
765- json_object_ref (value->json_object));
766+ json_object_ref (couchdb_struct_field_get_json_object (value)));
767 }
768
769 CouchDBStructField *
770@@ -450,3 +460,11 @@
771
772 return NULL;
773 }
774+
775+JsonObject *
776+couchdb_document_get_json_object (CouchDBDocument *document)
777+{
778+ g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), NULL);
779+
780+ return json_node_get_object (document->root_node);
781+}
782
783=== added file 'couchdb-glib/couchdb-document.h'
784--- couchdb-glib/couchdb-document.h 1970-01-01 00:00:00 +0000
785+++ couchdb-glib/couchdb-document.h 2009-10-06 18:10:22 +0000
786@@ -0,0 +1,134 @@
787+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
788+/*
789+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
790+ * 2009 Mikkel Kamstrup Erlandsen
791+ *
792+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
793+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
794+ *
795+ * This library is free software; you can redistribute it and/or
796+ * modify it under the terms of version 2 of the GNU Lesser General Public
797+ * License as published by the Free Software Foundation.
798+ *
799+ * This program is distributed in the hope that it will be useful,
800+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
801+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
802+ * General Public License for more details.
803+ *
804+ * You should have received a copy of the GNU Lesser General Public
805+ * License along with this library; if not, write to the
806+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
807+ * Boston, MA 02110-1301, USA.
808+ */
809+
810+#ifndef __COUCHDB_DOCUMENT_H__
811+#define __COUCHDB_DOCUMENT_H__
812+
813+#include <glib.h>
814+#include <glib-object.h>
815+#include <json-glib/json-glib.h>
816+#include "couchdb-types.h"
817+#include "couchdb-struct-field.h"
818+
819+G_BEGIN_DECLS
820+
821+#define COUCHDB_TYPE_DOCUMENT (couchdb_document_get_type ())
822+#define COUCHDB_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocument))
823+#define COUCHDB_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE_DOCUMENT))
824+#define COUCHDB_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
825+#define COUCHDB_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE_DOCUMENT))
826+#define COUCHDB_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
827+
828+typedef struct {
829+ GObjectClass parent_class;
830+} CouchDBDocumentClass;
831+
832+
833+GType couchdb_document_get_type (void);
834+
835+CouchDBDocument *couchdb_document_new (CouchDB *couchdb);
836+
837+CouchDBDocument *couchdb_document_get (CouchDB *couchdb,
838+ const char *dbname,
839+ const char *docid,
840+ GError **error);
841+
842+gboolean couchdb_document_put (CouchDBDocument *document,
843+ const char *dbname,
844+ GError **error);
845+
846+gboolean couchdb_document_delete (CouchDBDocument *document,
847+ GError **error);
848+
849+const char *couchdb_document_get_id (CouchDBDocument *document);
850+
851+void couchdb_document_set_id (CouchDBDocument *document,
852+ const char *id);
853+
854+const char *couchdb_document_get_revision (CouchDBDocument *document);
855+void couchdb_document_set_revision (CouchDBDocument *document,
856+ const char *revision);
857+
858+const char *couchdb_document_get_record_type (CouchDBDocument *document);
859+
860+void couchdb_document_set_record_type (CouchDBDocument *document,
861+
862+ const char *record_type);
863+
864+gboolean couchdb_document_has_field (CouchDBDocument *document,
865+ const char *field);
866+
867+void couchdb_document_remove_field (CouchDBDocument *document,
868+ const char *field);
869+
870+gboolean couchdb_document_get_boolean_field (CouchDBDocument *document,
871+ const char *field);
872+
873+void couchdb_document_set_boolean_field (CouchDBDocument *document,
874+ const char *field,
875+ gboolean value);
876+
877+gint couchdb_document_get_int_field (CouchDBDocument *document,
878+ const char *field);
879+
880+void couchdb_document_set_int_field (CouchDBDocument *document,
881+ const char *field,
882+ gint value);
883+
884+gdouble couchdb_document_get_double_field (CouchDBDocument *document,
885+ const char *field);
886+
887+void couchdb_document_set_double_field (CouchDBDocument *document,
888+ const char *field,
889+ gdouble value);
890+
891+const char *couchdb_document_get_string_field (CouchDBDocument *document,
892+ const char *field);
893+
894+void couchdb_document_set_string_field (CouchDBDocument *document,
895+ const char *field,
896+ const char *value);
897+
898+CouchDBStructField*
899+ couchdb_document_get_struct_field (CouchDBDocument *document,
900+ const char *field);
901+
902+void couchdb_document_set_struct_field (CouchDBDocument *document,
903+ const char *field,
904+ CouchDBStructField *value);
905+
906+CouchDBStructField*
907+ couchdb_document_get_application_annotations
908+ (CouchDBDocument *document);
909+
910+void couchdb_document_set_application_annotations
911+ (CouchDBDocument *document,
912+ CouchDBStructField *annotations);
913+
914+char* couchdb_document_to_string (CouchDBDocument *document);
915+
916+JsonObject* couchdb_document_get_json_object (CouchDBDocument *document);
917+
918+G_END_DECLS
919+
920+#endif /* __COUCHDB_DOCUMENT_H__ */
921
922=== modified file 'couchdb-glib/couchdb-glib.h'
923--- couchdb-glib/couchdb-glib.h 2009-09-09 14:53:00 +0000
924+++ couchdb-glib/couchdb-glib.h 2009-10-06 18:10:22 +0000
925@@ -1,8 +1,10 @@
926 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
927 /*
928 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
929+ * 2009 Mikkel Kamstrup Erlandsen
930 *
931 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
932+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
933 *
934 * This library is free software; you can redistribute it and/or
935 * modify it under the terms of version 2 of the GNU Lesser General Public
936@@ -18,115 +20,18 @@
937 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
938 * Boston, MA 02110-1301, USA.
939 */
940-
941+
942 #ifndef __COUCHDB_GLIB_H__
943 #define __COUCHDB_GLIB_H__
944
945 #include <couchdb-types.h>
946-
947-#define COUCHDB_TYPE (couchdb_get_type ())
948-#define COUCHDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE, CouchDB))
949-#define COUCHDB_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE))
950-#define COUCHDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE, CouchDBClass))
951-#define COUCHDB_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE))
952-#define COUCHDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE, CouchDBClass))
953-
954-typedef struct _CouchDBDocument CouchDBDocument;
955-
956-typedef struct _CouchDB CouchDB;
957-typedef struct {
958- GObjectClass parent_class;
959-
960- void (* database_created) (CouchDB *couchdb, const char *dbname);
961- void (* database_deleted) (CouchDB *couchdb, const char *dbname);
962-
963- void (* document_created) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
964- void (* document_updated) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
965- void (* document_deleted) (CouchDB *couchdb, const char *dbname, const char *docid);
966-} CouchDBClass;
967-
968-GType couchdb_get_type (void);
969-CouchDB *couchdb_new (const char *hostname);
970-
971-const char *couchdb_get_hostname (CouchDB *couchdb);
972-
973-/*
974- * Databases API
975- */
976-
977-GSList *couchdb_list_databases (CouchDB *couchdb, GError **error);
978-void couchdb_free_database_list (GSList *dblist);
979-
980-CouchDBDatabaseInfo *couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error);
981-
982-gboolean couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error);
983-gboolean couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error);
984-
985-void couchdb_listen_for_changes (CouchDB *couchdb, const char *dbname);
986-
987-gboolean couchdb_enable_oauth (CouchDB *couchdb,
988- const char *consumer_key,
989- const char *consumer_secret,
990- const char *token_key,
991- const char *token_secret);
992-void couchdb_disable_oauth (CouchDB *couchdb);
993-
994-/*
995- * Documents API
996- */
997-
998-#define COUCHDB_TYPE_DOCUMENT (couchdb_document_get_type ())
999-#define COUCHDB_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocument))
1000-#define COUCHDB_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE_DOCUMENT))
1001-#define COUCHDB_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
1002-#define COUCHDB_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE_DOCUMENT))
1003-#define COUCHDB_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
1004-
1005-typedef struct {
1006- GObjectClass parent_class;
1007-} CouchDBDocumentClass;
1008-
1009-GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error);
1010-void couchdb_free_document_list (GSList *doclist);
1011-
1012-GType couchdb_document_get_type (void);
1013-CouchDBDocument *couchdb_document_new (CouchDB *couchdb);
1014-CouchDBDocument *couchdb_document_get (CouchDB *couchdb,
1015- const char *dbname,
1016- const char *docid,
1017- GError **error);
1018-gboolean couchdb_document_put (CouchDBDocument *document,
1019- const char *dbname,
1020- GError **error);
1021-gboolean couchdb_document_delete (CouchDBDocument *document, GError **error);
1022-
1023-const char *couchdb_document_get_id (CouchDBDocument *document);
1024-void couchdb_document_set_id (CouchDBDocument *document, const char *id);
1025-const char *couchdb_document_get_revision (CouchDBDocument *document);
1026-void couchdb_document_set_revision (CouchDBDocument *document, const char *revision);
1027-const char *couchdb_document_get_record_type (CouchDBDocument *document);
1028-void couchdb_document_set_record_type (CouchDBDocument *document, const char *record_type);
1029-
1030-gboolean couchdb_document_has_field (CouchDBDocument *document, const char *field);
1031-void couchdb_document_remove_field (CouchDBDocument *document, const char *field);
1032-
1033-gboolean couchdb_document_get_boolean_field (CouchDBDocument *document, const char *field);
1034-void couchdb_document_set_boolean_field (CouchDBDocument *document, const char *field, gboolean value);
1035-gint couchdb_document_get_int_field (CouchDBDocument *document, const char *field);
1036-void couchdb_document_set_int_field (CouchDBDocument *document, const char *field, gint value);
1037-gdouble couchdb_document_get_double_field (CouchDBDocument *document, const char *field);
1038-void couchdb_document_set_double_field (CouchDBDocument *document, const char *field, gdouble value);
1039-const char *couchdb_document_get_string_field (CouchDBDocument *document, const char *field);
1040-void couchdb_document_set_string_field (CouchDBDocument *document, const char *field, const char *value);
1041-CouchDBStructField *couchdb_document_get_struct_field (CouchDBDocument *document, const char *field);
1042-void couchdb_document_set_struct_field (CouchDBDocument *document,
1043- const char *field,
1044- CouchDBStructField *value);
1045-
1046-CouchDBStructField *couchdb_document_get_application_annotations (CouchDBDocument *document);
1047-void couchdb_document_set_application_annotations (CouchDBDocument *document, CouchDBStructField *annotations);
1048-
1049-char *couchdb_document_to_string (CouchDBDocument *document);
1050-
1051-
1052-#endif
1053+#include <couchdb.h>
1054+#include <couchdb-database-info.h>
1055+#include <couchdb-document.h>
1056+#include <couchdb-document-contact.h>
1057+#include <couchdb-document-info.h>
1058+#include <couchdb-struct-field.h>
1059+
1060+#endif /* __COUCHDB_GLIB_H__ */
1061+
1062+
1063
1064=== added file 'couchdb-glib/couchdb-struct-field.c'
1065--- couchdb-glib/couchdb-struct-field.c 1970-01-01 00:00:00 +0000
1066+++ couchdb-glib/couchdb-struct-field.c 2009-10-06 18:10:22 +0000
1067@@ -0,0 +1,291 @@
1068+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1069+/*
1070+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1071+ * 2009 Mikkel Kamstrup Erlandsen
1072+ *
1073+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1074+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
1075+ *
1076+ * This library is free software; you can redistribute it and/or
1077+ * modify it under the terms of version 2 of the GNU Lesser General Public
1078+ * License as published by the Free Software Foundation.
1079+ *
1080+ * This program is distributed in the hope that it will be useful,
1081+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1082+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1083+ * General Public License for more details.
1084+ *
1085+ * You should have received a copy of the GNU Lesser General Public
1086+ * License along with this library; if not, write to the
1087+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1088+ * Boston, MA 02110-1301, USA.
1089+ */
1090+
1091+#include "couchdb-struct-field.h"
1092+
1093+struct _CouchDBStructField {
1094+ gint ref_count;
1095+ JsonObject *json_object;
1096+
1097+ /* Extra data needed for some specific StructField's */
1098+ char *uuid; /* the UUID of this item */
1099+};
1100+
1101+GType
1102+couchdb_struct_field_get_type (void)
1103+{
1104+ static GType object_type = 0;
1105+
1106+ if (G_UNLIKELY (!object_type))
1107+ object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBStructField"),
1108+ (GBoxedCopyFunc) couchdb_struct_field_ref,
1109+ (GBoxedFreeFunc) couchdb_struct_field_unref);
1110+
1111+ return object_type;
1112+}
1113+
1114+CouchDBStructField *
1115+couchdb_struct_field_new (void)
1116+{
1117+ CouchDBStructField *sf;
1118+
1119+ sf = g_slice_new (CouchDBStructField);
1120+ sf->ref_count = 1;
1121+ sf->json_object = json_object_new ();
1122+ sf->uuid = NULL;
1123+
1124+ return sf;
1125+}
1126+
1127+CouchDBStructField *
1128+couchdb_struct_field_new_from_string (const char *str)
1129+{
1130+ JsonParser *parser;
1131+ GError *error = NULL;
1132+ CouchDBStructField *sf = NULL;
1133+
1134+ g_return_val_if_fail (str != NULL, NULL);
1135+
1136+ parser = json_parser_new ();
1137+ if (json_parser_load_from_data (parser, str, strlen (str), &error)) {
1138+ JsonNode *node = json_parser_get_root (parser);
1139+
1140+ if (json_node_get_node_type (node) == JSON_NODE_OBJECT)
1141+ sf = couchdb_struct_field_new_from_json_object (json_node_get_object (node));
1142+ } else {
1143+ g_warning ("Could not parse string: %s", error->message);
1144+ g_error_free (error);
1145+ }
1146+
1147+ g_object_unref (G_OBJECT (parser));
1148+
1149+ return sf;
1150+}
1151+
1152+CouchDBStructField *
1153+couchdb_struct_field_new_from_json_object (JsonObject *json_object)
1154+{
1155+ CouchDBStructField *sf;
1156+
1157+ sf = g_slice_new (CouchDBStructField);
1158+ sf->ref_count = 1;
1159+ sf->json_object = json_object_ref (json_object);
1160+ sf->uuid = NULL;
1161+
1162+ return sf;
1163+}
1164+
1165+CouchDBStructField *
1166+couchdb_struct_field_ref (CouchDBStructField *sf)
1167+{
1168+ g_return_val_if_fail (sf != NULL, NULL);
1169+ g_return_val_if_fail (sf->ref_count > 0, NULL);
1170+
1171+ g_atomic_int_exchange_and_add (&sf->ref_count, 1);
1172+
1173+ return sf;
1174+}
1175+
1176+void
1177+couchdb_struct_field_unref (CouchDBStructField *sf)
1178+{
1179+ gint old_ref;
1180+
1181+ g_return_if_fail (sf != NULL);
1182+ g_return_if_fail (sf->ref_count > 0);
1183+
1184+ old_ref = g_atomic_int_get (&sf->ref_count);
1185+ if (old_ref > 1)
1186+ g_atomic_int_compare_and_exchange (&sf->ref_count, old_ref, old_ref - 1);
1187+ else {
1188+ json_object_unref (sf->json_object);
1189+ g_slice_free (CouchDBStructField, sf);
1190+ }
1191+}
1192+
1193+gboolean
1194+couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field)
1195+{
1196+ g_return_val_if_fail (sf != NULL, FALSE);
1197+ g_return_val_if_fail (field != NULL, FALSE);
1198+
1199+ return json_object_has_member (sf->json_object, field);
1200+}
1201+
1202+void
1203+couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field)
1204+{
1205+ g_return_if_fail (sf != NULL);
1206+ g_return_if_fail (field != NULL);
1207+
1208+ json_object_remove_member (sf->json_object, field);
1209+}
1210+
1211+gboolean
1212+couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field)
1213+{
1214+ g_return_val_if_fail (sf != NULL, 0);
1215+ g_return_val_if_fail (field != NULL, 0);
1216+
1217+ return json_object_get_boolean_member (sf->json_object, field);
1218+}
1219+
1220+void
1221+couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value)
1222+{
1223+ g_return_if_fail (sf != NULL);
1224+ g_return_if_fail (field != NULL);
1225+
1226+ json_object_set_boolean_member (sf->json_object, field, value);
1227+}
1228+
1229+gdouble
1230+couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field)
1231+{
1232+ g_return_val_if_fail (sf != NULL, 0);
1233+ g_return_val_if_fail (field != NULL, 0);
1234+
1235+ return json_object_get_double_member (sf->json_object, field);
1236+}
1237+
1238+void
1239+couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value)
1240+{
1241+ g_return_if_fail (sf != NULL);
1242+ g_return_if_fail (field != NULL);
1243+
1244+ json_object_set_double_member (sf->json_object, field, value);
1245+}
1246+
1247+gint
1248+couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field)
1249+{
1250+ g_return_val_if_fail (sf != NULL, 0);
1251+ g_return_val_if_fail (field != NULL, 0);
1252+
1253+ return json_object_get_int_member (sf->json_object, field);
1254+}
1255+
1256+void
1257+couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value)
1258+{
1259+ g_return_if_fail (sf != NULL);
1260+ g_return_if_fail (field != NULL);
1261+
1262+ json_object_set_int_member (sf->json_object, field, value);
1263+}
1264+
1265+const char *
1266+couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field)
1267+{
1268+ g_return_val_if_fail (sf != NULL, NULL);
1269+ g_return_val_if_fail (field != NULL, NULL);
1270+
1271+ return json_object_get_string_member (sf->json_object, field);
1272+}
1273+
1274+void
1275+couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value)
1276+{
1277+ g_return_if_fail (sf != NULL);
1278+ g_return_if_fail (field != NULL);
1279+
1280+ if (value)
1281+ json_object_set_string_member (sf->json_object, field, value);
1282+ else {
1283+ /* Remove the field if the value is NULL */
1284+ couchdb_struct_field_remove_field (sf, field);
1285+ }
1286+}
1287+
1288+CouchDBStructField *
1289+couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field)
1290+{
1291+ g_return_val_if_fail (sf != NULL, NULL);
1292+ g_return_val_if_fail (field != NULL, NULL);
1293+
1294+ return couchdb_struct_field_new_from_json_object (
1295+ json_object_get_object_member (sf->json_object, field));
1296+}
1297+
1298+void
1299+couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value)
1300+{
1301+ g_return_if_fail (sf != NULL);
1302+ g_return_if_fail (field != NULL);
1303+ g_return_if_fail (value != NULL);
1304+
1305+ json_object_set_object_member (sf->json_object, field, json_object_ref (value->json_object));
1306+}
1307+
1308+const char *
1309+couchdb_struct_field_get_uuid (CouchDBStructField *sf)
1310+{
1311+ g_return_val_if_fail (sf != NULL, NULL);
1312+
1313+ return (const char *) sf->uuid;
1314+}
1315+
1316+void
1317+couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid)
1318+{
1319+ g_return_if_fail (sf != NULL);
1320+
1321+ if (sf->uuid)
1322+ g_free (sf->uuid);
1323+
1324+ sf->uuid = g_strdup (uuid);
1325+}
1326+
1327+char *
1328+couchdb_struct_field_to_string (CouchDBStructField *sf)
1329+{
1330+ JsonNode *node;
1331+ JsonGenerator *generator;
1332+ gsize size;
1333+ char *str = NULL;
1334+
1335+ g_return_val_if_fail (sf != NULL, NULL);
1336+
1337+ node = json_node_new (JSON_NODE_OBJECT);
1338+ json_node_set_object (node, sf->json_object);
1339+
1340+ generator = json_generator_new ();
1341+ json_generator_set_root (generator, node);
1342+
1343+ str = json_generator_to_data (generator, &size);
1344+ g_object_unref (G_OBJECT (generator));
1345+
1346+ json_node_free (node);
1347+
1348+ return str;
1349+}
1350+
1351+JsonObject *
1352+couchdb_struct_field_get_json_object (CouchDBStructField *sf)
1353+{
1354+ g_return_val_if_fail (sf != NULL, NULL);
1355+
1356+ return sf->json_object;
1357+}
1358+
1359
1360=== added file 'couchdb-glib/couchdb-struct-field.h'
1361--- couchdb-glib/couchdb-struct-field.h 1970-01-01 00:00:00 +0000
1362+++ couchdb-glib/couchdb-struct-field.h 2009-10-06 18:10:22 +0000
1363@@ -0,0 +1,68 @@
1364+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1365+/*
1366+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1367+ * 2009 Mikkel Kamstrup Erlandsen
1368+ *
1369+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1370+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
1371+ *
1372+ * This library is free software; you can redistribute it and/or
1373+ * modify it under the terms of version 2 of the GNU Lesser General Public
1374+ * License as published by the Free Software Foundation.
1375+ *
1376+ * This program is distributed in the hope that it will be useful,
1377+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1378+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1379+ * General Public License for more details.
1380+ *
1381+ * You should have received a copy of the GNU Lesser General Public
1382+ * License along with this library; if not, write to the
1383+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1384+ * Boston, MA 02110-1301, USA.
1385+ */
1386+
1387+#ifndef __COUCHDB_STRUCT_FIELD_H__
1388+#define __COUCHDB_STRUCT_FIELD_H__
1389+
1390+#include <glib.h>
1391+#include <glib-object.h>
1392+#include <json-glib/json-glib.h>
1393+#include "couchdb.h"
1394+#include "couchdb-types.h"
1395+
1396+G_BEGIN_DECLS
1397+
1398+#define COUCHDB_TYPE_STRUCT_FIELD (couchdb_struct_field_get_type ())
1399+
1400+GType couchdb_struct_field_get_type (void);
1401+CouchDBStructField *couchdb_struct_field_new (void);
1402+CouchDBStructField *couchdb_struct_field_new_from_string (const char *str);
1403+CouchDBStructField *couchdb_struct_field_ref (CouchDBStructField *sf);
1404+void couchdb_struct_field_unref (CouchDBStructField *sf);
1405+
1406+gboolean couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field);
1407+void couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field);
1408+
1409+gboolean couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field);
1410+void couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value);
1411+gdouble couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field);
1412+void couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value);
1413+gint couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field);
1414+void couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value);
1415+const char *couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field);
1416+void couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value);
1417+CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
1418+void couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value);
1419+
1420+const char *couchdb_struct_field_get_uuid (CouchDBStructField *sf);
1421+void couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid);
1422+
1423+char *couchdb_struct_field_to_string (CouchDBStructField *sf);
1424+
1425+CouchDBStructField *couchdb_struct_field_new_from_json_object (JsonObject *json_object);
1426+
1427+JsonObject *couchdb_struct_field_get_json_object (CouchDBStructField *sf);
1428+
1429+G_END_DECLS
1430+
1431+#endif /* __COUCHDB_STRUCT_FIELD__ */
1432
1433=== removed file 'couchdb-glib/couchdb-types.c'
1434--- couchdb-glib/couchdb-types.c 2009-08-19 16:43:24 +0000
1435+++ couchdb-glib/couchdb-types.c 1970-01-01 00:00:00 +0000
1436@@ -1,466 +0,0 @@
1437-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1438-/*
1439- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1440- *
1441- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1442- *
1443- * This library is free software; you can redistribute it and/or
1444- * modify it under the terms of version 2 of the GNU Lesser General Public
1445- * License as published by the Free Software Foundation.
1446- *
1447- * This program is distributed in the hope that it will be useful,
1448- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1449- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1450- * General Public License for more details.
1451- *
1452- * You should have received a copy of the GNU Lesser General Public
1453- * License along with this library; if not, write to the
1454- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1455- * Boston, MA 02110-1301, USA.
1456- */
1457-
1458-#include "couchdb-glib.h"
1459-#include "utils.h"
1460-
1461-/*
1462- * CouchDBDatabaseInfo object
1463- */
1464-
1465-GType
1466-couchdb_database_info_get_type (void)
1467-{
1468- static GType object_type = 0;
1469-
1470- if (G_UNLIKELY (!object_type))
1471- object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDatabaseInfo"),
1472- (GBoxedCopyFunc) couchdb_database_info_ref,
1473- (GBoxedFreeFunc) couchdb_database_info_unref);
1474-
1475- return object_type;
1476-}
1477-
1478-CouchDBDatabaseInfo *
1479-couchdb_database_info_new (const char *dbname,
1480- gint doc_count,
1481- gint doc_del_count,
1482- gint update_seq,
1483- gboolean compact_running,
1484- gint disk_size)
1485-{
1486- CouchDBDatabaseInfo *dbinfo;
1487-
1488- dbinfo = g_slice_new (CouchDBDatabaseInfo);
1489- dbinfo->ref_count = 1;
1490- dbinfo->dbname = g_strdup (dbname);
1491- dbinfo->doc_count = doc_count;
1492- dbinfo->doc_del_count = doc_del_count;
1493- dbinfo->update_seq = update_seq;
1494- dbinfo->compact_running = compact_running;
1495- dbinfo->disk_size = disk_size;
1496-
1497- return dbinfo;
1498-}
1499-
1500-CouchDBDatabaseInfo *
1501-couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo)
1502-{
1503- g_return_val_if_fail (dbinfo != NULL, NULL);
1504- g_return_val_if_fail (dbinfo->ref_count > 0, NULL);
1505-
1506- g_atomic_int_exchange_and_add (&dbinfo->ref_count, 1);
1507-
1508- return dbinfo;
1509-}
1510-
1511-void
1512-couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo)
1513-{
1514- gint old_ref;
1515-
1516- g_return_if_fail (dbinfo != NULL);
1517- g_return_if_fail (dbinfo->ref_count > 0);
1518-
1519- old_ref = g_atomic_int_get (&dbinfo->ref_count);
1520- if (old_ref > 1)
1521- g_atomic_int_compare_and_exchange (&dbinfo->ref_count, old_ref, old_ref - 1);
1522- else {
1523- g_free (dbinfo->dbname);
1524- g_slice_free (CouchDBDatabaseInfo, dbinfo);
1525- }
1526-}
1527-
1528-const char *
1529-couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo)
1530-{
1531- g_return_val_if_fail (dbinfo != NULL, NULL);
1532-
1533- return (const char *) dbinfo->dbname;
1534-}
1535-
1536-gint
1537-couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo)
1538-{
1539- g_return_val_if_fail (dbinfo != NULL, 0);
1540-
1541- return dbinfo->doc_count;
1542-}
1543-
1544-gint
1545-couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo)
1546-{
1547- g_return_val_if_fail (dbinfo != NULL, 0);
1548-
1549- return dbinfo->doc_del_count;
1550-}
1551-
1552-gint
1553-couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo)
1554-{
1555- g_return_val_if_fail (dbinfo != NULL, 0);
1556-
1557- return dbinfo->update_seq;
1558-}
1559-
1560-gboolean
1561-couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo)
1562-{
1563- g_return_val_if_fail (dbinfo != NULL, FALSE);
1564-
1565- return dbinfo->compact_running;
1566-}
1567-
1568-gint
1569-couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo)
1570-{
1571- g_return_val_if_fail (dbinfo != NULL, 0);
1572-
1573- return dbinfo->disk_size;
1574-}
1575-
1576-/*
1577- * CouchDBDocumentInfo object
1578- */
1579-
1580-GType
1581-couchdb_document_info_get_type (void)
1582-{
1583- static GType object_type = 0;
1584-
1585- if (G_UNLIKELY (!object_type))
1586- object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDocumentInfo"),
1587- (GBoxedCopyFunc) couchdb_document_info_ref,
1588- (GBoxedFreeFunc) couchdb_document_info_unref);
1589-
1590- return object_type;
1591-}
1592-
1593-CouchDBDocumentInfo *
1594-couchdb_document_info_new (const char *docid, const char *revision)
1595-{
1596- CouchDBDocumentInfo *doc_info;
1597-
1598- doc_info = g_slice_new (CouchDBDocumentInfo);
1599- doc_info->ref_count = 1;
1600- doc_info->docid = g_strdup (docid);
1601- doc_info->revision = g_strdup (revision);
1602-
1603- return doc_info;
1604-}
1605-
1606-CouchDBDocumentInfo *
1607-couchdb_document_info_ref (CouchDBDocumentInfo *doc_info)
1608-{
1609- g_return_val_if_fail (doc_info != NULL, NULL);
1610- g_return_val_if_fail (doc_info->ref_count > 0, NULL);
1611-
1612- g_atomic_int_exchange_and_add (&doc_info->ref_count, 1);
1613-
1614- return doc_info;
1615-}
1616-
1617-void
1618-couchdb_document_info_unref (CouchDBDocumentInfo *doc_info)
1619-{
1620- gint old_ref;
1621-
1622- g_return_if_fail (doc_info != NULL);
1623- g_return_if_fail (doc_info->ref_count > 0);
1624-
1625- old_ref = g_atomic_int_get (&doc_info->ref_count);
1626- if (old_ref > 1)
1627- g_atomic_int_compare_and_exchange (&doc_info->ref_count, old_ref, old_ref - 1);
1628- else {
1629- g_free (doc_info->docid);
1630- g_free (doc_info->revision);
1631- g_slice_free (CouchDBDocumentInfo, doc_info);
1632- }
1633-}
1634-
1635-const char *
1636-couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info)
1637-{
1638- g_return_val_if_fail (doc_info != NULL, NULL);
1639-
1640- return (const char *) doc_info->docid;
1641-}
1642-
1643-const char *
1644-couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info)
1645-{
1646- g_return_val_if_fail (doc_info != NULL, NULL);
1647-
1648- return (const char *) doc_info->revision;
1649-}
1650-
1651-/*
1652- * CouchDBStructField
1653- */
1654-GType
1655-couchdb_struct_field_get_type (void)
1656-{
1657- static GType object_type = 0;
1658-
1659- if (G_UNLIKELY (!object_type))
1660- object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBStructField"),
1661- (GBoxedCopyFunc) couchdb_struct_field_ref,
1662- (GBoxedFreeFunc) couchdb_struct_field_unref);
1663-
1664- return object_type;
1665-}
1666-
1667-CouchDBStructField *
1668-couchdb_struct_field_new (void)
1669-{
1670- CouchDBStructField *sf;
1671-
1672- sf = g_slice_new (CouchDBStructField);
1673- sf->ref_count = 1;
1674- sf->json_object = json_object_new ();
1675- sf->uuid = NULL;
1676-
1677- return sf;
1678-}
1679-
1680-CouchDBStructField *
1681-couchdb_struct_field_new_from_string (const char *str)
1682-{
1683- JsonParser *parser;
1684- GError *error = NULL;
1685- CouchDBStructField *sf = NULL;
1686-
1687- g_return_val_if_fail (str != NULL, NULL);
1688-
1689- parser = json_parser_new ();
1690- if (json_parser_load_from_data (parser, str, strlen (str), &error)) {
1691- JsonNode *node = json_parser_get_root (parser);
1692-
1693- if (json_node_get_node_type (node) == JSON_NODE_OBJECT)
1694- sf = couchdb_struct_field_new_from_json_object (json_node_get_object (node));
1695- } else {
1696- g_warning ("Could not parse string: %s", error->message);
1697- g_error_free (error);
1698- }
1699-
1700- g_object_unref (G_OBJECT (parser));
1701-
1702- return sf;
1703-}
1704-
1705-CouchDBStructField *
1706-couchdb_struct_field_new_from_json_object (JsonObject *json_object)
1707-{
1708- CouchDBStructField *sf;
1709-
1710- sf = g_slice_new (CouchDBStructField);
1711- sf->ref_count = 1;
1712- sf->json_object = json_object_ref (json_object);
1713- sf->uuid = NULL;
1714-
1715- return sf;
1716-}
1717-
1718-CouchDBStructField *
1719-couchdb_struct_field_ref (CouchDBStructField *sf)
1720-{
1721- g_return_val_if_fail (sf != NULL, NULL);
1722- g_return_val_if_fail (sf->ref_count > 0, NULL);
1723-
1724- g_atomic_int_exchange_and_add (&sf->ref_count, 1);
1725-
1726- return sf;
1727-}
1728-
1729-void
1730-couchdb_struct_field_unref (CouchDBStructField *sf)
1731-{
1732- gint old_ref;
1733-
1734- g_return_if_fail (sf != NULL);
1735- g_return_if_fail (sf->ref_count > 0);
1736-
1737- old_ref = g_atomic_int_get (&sf->ref_count);
1738- if (old_ref > 1)
1739- g_atomic_int_compare_and_exchange (&sf->ref_count, old_ref, old_ref - 1);
1740- else {
1741- json_object_unref (sf->json_object);
1742- g_slice_free (CouchDBStructField, sf);
1743- }
1744-}
1745-
1746-gboolean
1747-couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field)
1748-{
1749- g_return_val_if_fail (sf != NULL, FALSE);
1750- g_return_val_if_fail (field != NULL, FALSE);
1751-
1752- return json_object_has_member (sf->json_object, field);
1753-}
1754-
1755-void
1756-couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field)
1757-{
1758- g_return_if_fail (sf != NULL);
1759- g_return_if_fail (field != NULL);
1760-
1761- json_object_remove_member (sf->json_object, field);
1762-}
1763-
1764-gboolean
1765-couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field)
1766-{
1767- g_return_val_if_fail (sf != NULL, 0);
1768- g_return_val_if_fail (field != NULL, 0);
1769-
1770- return json_object_get_boolean_member (sf->json_object, field);
1771-}
1772-
1773-void
1774-couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value)
1775-{
1776- g_return_if_fail (sf != NULL);
1777- g_return_if_fail (field != NULL);
1778-
1779- json_object_set_boolean_member (sf->json_object, field, value);
1780-}
1781-
1782-gdouble
1783-couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field)
1784-{
1785- g_return_val_if_fail (sf != NULL, 0);
1786- g_return_val_if_fail (field != NULL, 0);
1787-
1788- return json_object_get_double_member (sf->json_object, field);
1789-}
1790-
1791-void
1792-couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value)
1793-{
1794- g_return_if_fail (sf != NULL);
1795- g_return_if_fail (field != NULL);
1796-
1797- json_object_set_double_member (sf->json_object, field, value);
1798-}
1799-
1800-gint
1801-couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field)
1802-{
1803- g_return_val_if_fail (sf != NULL, 0);
1804- g_return_val_if_fail (field != NULL, 0);
1805-
1806- return json_object_get_int_member (sf->json_object, field);
1807-}
1808-
1809-void
1810-couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value)
1811-{
1812- g_return_if_fail (sf != NULL);
1813- g_return_if_fail (field != NULL);
1814-
1815- json_object_set_int_member (sf->json_object, field, value);
1816-}
1817-
1818-const char *
1819-couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field)
1820-{
1821- g_return_val_if_fail (sf != NULL, NULL);
1822- g_return_val_if_fail (field != NULL, NULL);
1823-
1824- return json_object_get_string_member (sf->json_object, field);
1825-}
1826-
1827-void
1828-couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value)
1829-{
1830- g_return_if_fail (sf != NULL);
1831- g_return_if_fail (field != NULL);
1832-
1833- if (value)
1834- json_object_set_string_member (sf->json_object, field, value);
1835- else {
1836- /* Remove the field if the value is NULL */
1837- couchdb_struct_field_remove_field (sf, field);
1838- }
1839-}
1840-
1841-CouchDBStructField *
1842-couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field)
1843-{
1844- g_return_val_if_fail (sf != NULL, NULL);
1845- g_return_val_if_fail (field != NULL, NULL);
1846-
1847- return couchdb_struct_field_new_from_json_object (
1848- json_object_get_object_member (sf->json_object, field));
1849-}
1850-
1851-void
1852-couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value)
1853-{
1854- g_return_if_fail (sf != NULL);
1855- g_return_if_fail (field != NULL);
1856- g_return_if_fail (value != NULL);
1857-
1858- json_object_set_object_member (sf->json_object, field, json_object_ref (value->json_object));
1859-}
1860-
1861-const char *
1862-couchdb_struct_field_get_uuid (CouchDBStructField *sf)
1863-{
1864- g_return_val_if_fail (sf != NULL, NULL);
1865-
1866- return (const char *) sf->uuid;
1867-}
1868-
1869-void
1870-couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid)
1871-{
1872- g_return_if_fail (sf != NULL);
1873-
1874- if (sf->uuid)
1875- g_free (sf->uuid);
1876-
1877- sf->uuid = g_strdup (uuid);
1878-}
1879-
1880-char *
1881-couchdb_struct_field_to_string (CouchDBStructField *sf)
1882-{
1883- JsonNode *node;
1884- JsonGenerator *generator;
1885- gsize size;
1886- char *str = NULL;
1887-
1888- g_return_val_if_fail (sf != NULL, NULL);
1889-
1890- node = json_node_new (JSON_NODE_OBJECT);
1891- json_node_set_object (node, sf->json_object);
1892-
1893- generator = json_generator_new ();
1894- json_generator_set_root (generator, node);
1895-
1896- str = json_generator_to_data (generator, &size);
1897- g_object_unref (G_OBJECT (generator));
1898-
1899- json_node_free (node);
1900-
1901- return str;
1902-}
1903
1904=== added file 'couchdb-glib/couchdb-types.h'
1905--- couchdb-glib/couchdb-types.h 1970-01-01 00:00:00 +0000
1906+++ couchdb-glib/couchdb-types.h 2009-10-06 18:10:22 +0000
1907@@ -0,0 +1,39 @@
1908+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1909+/*
1910+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1911+ * 2009 Mikkel Kamstrup Erlandsen
1912+ *
1913+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1914+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
1915+ *
1916+ * This library is free software; you can redistribute it and/or
1917+ * modify it under the terms of version 2 of the GNU Lesser General Public
1918+ * License as published by the Free Software Foundation.
1919+ *
1920+ * This program is distributed in the hope that it will be useful,
1921+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1922+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1923+ * General Public License for more details.
1924+ *
1925+ * You should have received a copy of the GNU Lesser General Public
1926+ * License along with this library; if not, write to the
1927+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1928+ * Boston, MA 02110-1301, USA.
1929+ */
1930+
1931+#ifndef __COUCHDB_TYPES_H__
1932+#define __COUCHDB_TYPES_H__
1933+
1934+#include <glib.h>
1935+
1936+G_BEGIN_DECLS
1937+
1938+typedef struct _CouchDBDocument CouchDBDocument;
1939+typedef struct _CouchDB CouchDB;
1940+typedef struct _CouchDBDatabaseInfo CouchDBDatabaseInfo;
1941+typedef struct _CouchDBDocumentInfo CouchDBDocumentInfo;
1942+typedef struct _CouchDBStructField CouchDBStructField;
1943+
1944+G_END_DECLS
1945+
1946+#endif /* __COUCHDB_TYPES_H__ */
1947
1948=== removed file 'couchdb-glib/couchdb-types.h'
1949--- couchdb-glib/couchdb-types.h 2009-08-19 16:43:24 +0000
1950+++ couchdb-glib/couchdb-types.h 1970-01-01 00:00:00 +0000
1951@@ -1,89 +0,0 @@
1952-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1953-/*
1954- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1955- *
1956- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1957- *
1958- * This library is free software; you can redistribute it and/or
1959- * modify it under the terms of version 2 of the GNU Lesser General Public
1960- * License as published by the Free Software Foundation.
1961- *
1962- * This program is distributed in the hope that it will be useful,
1963- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1964- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1965- * General Public License for more details.
1966- *
1967- * You should have received a copy of the GNU Lesser General Public
1968- * License along with this library; if not, write to the
1969- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1970- * Boston, MA 02110-1301, USA.
1971- */
1972-
1973-#ifndef __COUCHDB_TYPES_H__
1974-#define __COUCHDB_TYPES_H__
1975-
1976-#include <glib-object.h>
1977-
1978-#define COUCHDB_TYPE_DATABASE_INFO (couchdb_database_info_get_type ())
1979-#define COUCHDB_TYPE_DOCUMENT_INFO (couchdb_document_info_get_type ())
1980-#define COUCHDB_TYPE_STRUCT_FIELD (couchdb_struct_field_get_type ())
1981-
1982-/*
1983- * CouchDBDatabaseInfo
1984- */
1985-typedef struct _CouchDBDatabaseInfo CouchDBDatabaseInfo;
1986-
1987-GType couchdb_database_info_get_type (void);
1988-CouchDBDatabaseInfo *couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo);
1989-void couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo);
1990-
1991-const char *couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo);
1992-gint couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo);
1993-gint couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo);
1994-gint couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo);
1995-gboolean couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo);
1996-gint couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo);
1997-
1998-/*
1999- * CouchDBDocumentInfo
2000- */
2001-typedef struct _CouchDBDocumentInfo CouchDBDocumentInfo;
2002-
2003-GType couchdb_document_info_get_type (void);
2004-CouchDBDocumentInfo *couchdb_document_info_ref (CouchDBDocumentInfo *doc_info);
2005-void couchdb_document_info_unref (CouchDBDocumentInfo *doc_info);
2006-
2007-const char *couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info);
2008-const char *couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info);
2009-
2010-/*
2011- * CouchDBStructField
2012- */
2013-typedef struct _CouchDBStructField CouchDBStructField;
2014-
2015-GType couchdb_struct_field_get_type (void);
2016-CouchDBStructField *couchdb_struct_field_new (void);
2017-CouchDBStructField *couchdb_struct_field_new_from_string (const char *str);
2018-CouchDBStructField *couchdb_struct_field_ref (CouchDBStructField *sf);
2019-void couchdb_struct_field_unref (CouchDBStructField *sf);
2020-
2021-gboolean couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field);
2022-void couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field);
2023-
2024-gboolean couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field);
2025-void couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value);
2026-gdouble couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field);
2027-void couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value);
2028-gint couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field);
2029-void couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value);
2030-const char *couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field);
2031-void couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value);
2032-CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
2033-void couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value);
2034-
2035-const char *couchdb_struct_field_get_uuid (CouchDBStructField *sf);
2036-void couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid);
2037-
2038-char *couchdb_struct_field_to_string (CouchDBStructField *sf);
2039-
2040-#endif
2041
2042=== modified file 'couchdb-glib/couchdb.c'
2043--- couchdb-glib/couchdb.c 2009-09-21 22:34:56 +0000
2044+++ couchdb-glib/couchdb.c 2009-10-06 18:10:22 +0000
2045@@ -1,8 +1,10 @@
2046 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2047 /*
2048 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
2049+ * 2009 Mikkel Kamstrup Erlandsen
2050 *
2051 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
2052+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
2053 *
2054 * This library is free software; you can redistribute it and/or
2055 * modify it under the terms of version 2 of the GNU Lesser General Public
2056@@ -21,11 +23,32 @@
2057
2058 #include <libsoup/soup-logger.h>
2059 #include <libsoup/soup-gnome.h>
2060-#include <json-glib/json-glib.h>
2061-#include "couchdb-glib.h"
2062+#include <libsoup/soup-message.h>
2063+#include "couchdb.h"
2064+#include "couchdb-document-info.h"
2065 #include "couchdb-marshal.h"
2066 #include "dbwatch.h"
2067 #include "utils.h"
2068+#include <string.h>
2069+#ifdef HAVE_OAUTH
2070+#include <time.h>
2071+#include "oauth.h"
2072+#endif
2073+
2074+struct _CouchDB {
2075+ GObject parent;
2076+
2077+ char *hostname;
2078+ SoupSession *http_session;
2079+
2080+ GHashTable *db_watchlist;
2081+
2082+ gboolean oauth_enabled;
2083+ char *oauth_consumer_key;
2084+ char *oauth_consumer_secret;
2085+ char *oauth_token_key;
2086+ char *oauth_token_secret;
2087+};
2088
2089 G_DEFINE_TYPE(CouchDB, couchdb, G_TYPE_OBJECT)
2090
2091@@ -49,12 +72,14 @@
2092 g_free (couchdb->hostname);
2093 g_object_unref (couchdb->http_session);
2094
2095-#ifdef HAVE_OAUTH
2096- g_free (couchdb->oauth_consumer_key);
2097- g_free (couchdb->oauth_consumer_secret);
2098- g_free (couchdb->oauth_token_key);
2099- g_free (couchdb->oauth_token_secret);
2100-#endif
2101+ if (couchdb->oauth_consumer_key)
2102+ g_free (couchdb->oauth_consumer_key);
2103+ if (couchdb->oauth_consumer_secret)
2104+ g_free (couchdb->oauth_consumer_secret);
2105+ if (couchdb->oauth_token_key)
2106+ g_free (couchdb->oauth_token_key);
2107+ if (couchdb->oauth_token_secret)
2108+ g_free (couchdb->oauth_token_secret);
2109
2110 G_OBJECT_CLASS (couchdb_parent_class)->finalize (object);
2111 }
2112@@ -135,6 +160,13 @@
2113 couchdb->http_session = soup_session_sync_new_with_options (
2114 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
2115 NULL);
2116+
2117+ couchdb->oauth_consumer_key = NULL;
2118+ couchdb->oauth_consumer_secret = NULL;
2119+ couchdb->oauth_token_key = NULL;
2120+ couchdb->oauth_token_secret = NULL;
2121+ couchdb->oauth_enabled = FALSE;
2122+
2123 soup_session_add_feature_by_type (couchdb->http_session, SOUP_TYPE_LOGGER);
2124
2125 return couchdb;
2126@@ -159,8 +191,8 @@
2127
2128 /* Prepare request */
2129 url = g_strdup_printf ("%s/_all_dbs", couchdb->hostname);
2130- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
2131- if (parser) {
2132+ parser = json_parser_new ();
2133+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
2134 JsonNode *root_node;
2135
2136 root_node = json_parser_get_root (parser);
2137@@ -173,10 +205,9 @@
2138 dblist,
2139 g_strdup (json_node_get_string ((JsonNode *) sl->data)));
2140 }
2141- }
2142-
2143- g_object_unref (G_OBJECT (parser));
2144+ }
2145 }
2146+ g_object_unref (G_OBJECT (parser));
2147
2148 /* Free memory */
2149 g_free (url);
2150@@ -195,8 +226,8 @@
2151 g_return_val_if_fail (dbname != NULL, NULL);
2152
2153 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
2154- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
2155- if (parser) {
2156+ parser = json_parser_new ();
2157+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
2158 JsonNode *root_node;
2159
2160 root_node = json_parser_get_root (parser);
2161@@ -210,9 +241,8 @@
2162 json_object_get_boolean_member (object, "compact_running"),
2163 json_object_get_int_member (object, "disk_size"));
2164 }
2165-
2166- g_object_unref (G_OBJECT (parser));
2167 }
2168+ g_object_unref (G_OBJECT (parser));
2169
2170 return result;
2171 }
2172@@ -228,18 +258,17 @@
2173 g_return_val_if_fail (dbname != NULL, FALSE);
2174
2175 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
2176- parser = send_message_and_parse (couchdb, SOUP_METHOD_PUT, url, NULL, error);
2177- if (parser) {
2178+ parser = json_parser_new ();
2179+ if (couchdb_send_message (couchdb, SOUP_METHOD_PUT, url, NULL, parser, error)) {
2180 JsonNode *root_node;
2181
2182 root_node = json_parser_get_root (parser);
2183 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
2184 result = json_object_get_boolean_member (
2185- json_node_get_object (root_node), "ok");
2186-
2187- g_object_unref (G_OBJECT (parser));
2188+ json_node_get_object (root_node), "ok");
2189 }
2190-
2191+
2192+ g_object_unref (G_OBJECT (parser));
2193 g_free (url);
2194
2195 if (result)
2196@@ -259,17 +288,16 @@
2197 g_return_val_if_fail (dbname != NULL, FALSE);
2198
2199 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
2200- parser = send_message_and_parse (couchdb, SOUP_METHOD_DELETE, url, NULL, error);
2201- if (parser) {
2202+ parser = json_parser_new ();
2203+ if (couchdb_send_message (couchdb, SOUP_METHOD_DELETE, url, NULL, parser, error)) {
2204 JsonNode *root_node;
2205
2206 root_node = json_parser_get_root (parser);
2207 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
2208 result = json_object_get_boolean_member (
2209- json_node_get_object (root_node), "ok");
2210-
2211- g_object_unref (G_OBJECT (parser));
2212+ json_node_get_object (root_node), "ok");
2213 }
2214+ g_object_unref (G_OBJECT (parser));
2215
2216 g_free (url);
2217
2218@@ -304,8 +332,8 @@
2219 g_return_val_if_fail (dbname != NULL, NULL);
2220
2221 url = g_strdup_printf ("%s/%s/_all_docs", couchdb->hostname, dbname);
2222- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
2223- if (parser) {
2224+ parser = json_parser_new ();
2225+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
2226 JsonNode *root_node;
2227
2228 root_node = json_parser_get_root (parser);
2229@@ -332,7 +360,7 @@
2230 }
2231 }
2232 }
2233-
2234+ g_object_unref (G_OBJECT (parser));
2235 g_free (url);
2236
2237 return doclist;
2238@@ -423,3 +451,158 @@
2239 return FALSE;
2240 #endif
2241 }
2242+
2243+gboolean
2244+couchdb_is_oauth_enabled (CouchDB *couchdb)
2245+{
2246+ g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
2247+
2248+ return couchdb->oauth_enabled;
2249+}
2250+
2251+
2252+static void
2253+couchdb_add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
2254+{
2255+ /* This method is a no-op if we are configured without OAUTH */
2256+#ifdef HAVE_OAUTH
2257+ char *signed_url;
2258+
2259+ signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
2260+ couchdb->oauth_consumer_key,
2261+ couchdb->oauth_consumer_secret,
2262+ couchdb->oauth_token_key,
2263+ couchdb->oauth_token_secret);
2264+ if (signed_url != NULL) {
2265+ char **parsed_url;
2266+ GString *header = NULL;
2267+
2268+ /* Get the OAuth signature from the signed URL */
2269+ parsed_url = g_strsplit (signed_url, "?", 2);
2270+ if (parsed_url != NULL) {
2271+ gchar **params;
2272+ int i;
2273+
2274+ params = g_strsplit (parsed_url[1], "&", 0);
2275+#ifdef DEBUG_OAUTH
2276+ g_debug ("Parsing %s", parsed_url[1]);
2277+#endif
2278+ for (i = 0; params[i] != NULL; i++) {
2279+ gchar **url_param;
2280+
2281+ /* Don't include non-OAuth URL parameters in OAuth header */
2282+ if (!g_str_has_prefix (params[i], "oauth_"))
2283+ continue;
2284+
2285+#ifdef DEBUG_OAUTH
2286+ g_debug ("%s\n", params[i]);
2287+#endif
2288+ url_param = g_strsplit (params[i], "=", 2);
2289+ if (url_param == NULL)
2290+ continue;
2291+
2292+ if (header != NULL)
2293+ header = g_string_append (header, ", ");
2294+ else
2295+ header = g_string_new ("OAuth ");
2296+
2297+ header = g_string_append (header, url_param[0]);
2298+ header = g_string_append (header, "=\"");
2299+ header = g_string_append (header, url_param[1]);
2300+ header = g_string_append (header, "\"");
2301+
2302+ g_strfreev (url_param);
2303+ }
2304+
2305+ if (params)
2306+ g_strfreev (params);
2307+
2308+ g_strfreev (parsed_url);
2309+ }
2310+
2311+ if (header != NULL) {
2312+ soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
2313+
2314+ g_string_free (header, TRUE);
2315+ }
2316+
2317+ free (signed_url);
2318+ }
2319+#endif /* HAVE_OAUTH */
2320+}
2321+
2322+static gboolean
2323+parse_json_response (CouchDB *couchdb, JsonParser *json_parser, SoupMessage *http_message, GError **error)
2324+{
2325+ SoupBuffer *buffer;
2326+ GString *str = NULL;
2327+ goffset offset = 0;
2328+ gboolean success = TRUE;
2329+
2330+ while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
2331+ if (!str)
2332+ str = g_string_new ("");
2333+ g_string_append_len (str, buffer->data, buffer->length);
2334+
2335+ offset += buffer->length;
2336+ soup_buffer_free (buffer);
2337+ }
2338+
2339+ if (str && str->len > 0) {
2340+ g_debug ("Response body: %s", str->str);
2341+ if (!json_parser_load_from_data (json_parser,
2342+ (const gchar *) str->str,
2343+ str->len,
2344+ error)) {
2345+ g_object_unref (G_OBJECT (json_parser));
2346+ g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
2347+ success = FALSE;
2348+ }
2349+
2350+ g_string_free (str, TRUE);
2351+ }
2352+
2353+ return success;
2354+}
2355+
2356+static void
2357+debug_print_headers (const char *name, const char *value, gpointer user_data)
2358+{
2359+ g_print ("\t%s: %s\n", name, value);
2360+}
2361+
2362+gboolean
2363+couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error)
2364+{
2365+ SoupMessage *http_message;
2366+ guint status;
2367+
2368+ g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
2369+ g_return_val_if_fail (method != NULL, FALSE);
2370+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2371+
2372+ http_message = soup_message_new (method, url);
2373+ if (body != NULL) {
2374+ soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
2375+ body, strlen (body));
2376+ }
2377+
2378+ if (couchdb_is_oauth_enabled (couchdb))
2379+ couchdb_add_oauth_signature (couchdb, http_message, method, url);
2380+
2381+
2382+ g_debug ("Sending %s to %s... with headers\n: ", method, url);
2383+ soup_message_headers_foreach (http_message->request_headers,
2384+ (SoupMessageHeadersForeachFunc) debug_print_headers,
2385+ NULL);
2386+
2387+ status = soup_session_send_message (couchdb->http_session, http_message);
2388+ if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
2389+ if (parser != NULL)
2390+ parse_json_response (couchdb, parser, http_message, error);
2391+ return TRUE;
2392+ } else {
2393+ g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
2394+ return FALSE;
2395+ }
2396+}
2397
2398=== added file 'couchdb-glib/couchdb.h'
2399--- couchdb-glib/couchdb.h 1970-01-01 00:00:00 +0000
2400+++ couchdb-glib/couchdb.h 2009-10-06 18:10:22 +0000
2401@@ -0,0 +1,84 @@
2402+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2403+/*
2404+ * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
2405+ * 2009 Mikkel Kamstrup Erlandsen
2406+ *
2407+ * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
2408+ * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
2409+ *
2410+ * This library is free software; you can redistribute it and/or
2411+ * modify it under the terms of version 2 of the GNU Lesser General Public
2412+ * License as published by the Free Software Foundation.
2413+ *
2414+ * This program is distributed in the hope that it will be useful,
2415+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2416+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2417+ * General Public License for more details.
2418+ *
2419+ * You should have received a copy of the GNU Lesser General Public
2420+ * License along with this library; if not, write to the
2421+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2422+ * Boston, MA 02110-1301, USA.
2423+ */
2424+
2425+#ifndef __COUCHDB_H__
2426+#define __COUCHDB_H__
2427+
2428+#include <glib.h>
2429+#include <glib-object.h>
2430+#include <json-glib/json-glib.h>
2431+#include "couchdb-types.h"
2432+#include "couchdb-database-info.h"
2433+
2434+G_BEGIN_DECLS
2435+
2436+#define COUCHDB_TYPE (couchdb_get_type ())
2437+#define COUCHDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE, CouchDB))
2438+#define COUCHDB_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE))
2439+#define COUCHDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE, CouchDBClass))
2440+#define COUCHDB_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE))
2441+#define COUCHDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE, CouchDBClass))
2442+
2443+typedef struct {
2444+ GObjectClass parent_class;
2445+
2446+ void (* database_created) (CouchDB *couchdb, const char *dbname);
2447+ void (* database_deleted) (CouchDB *couchdb, const char *dbname);
2448+
2449+ void (* document_created) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
2450+ void (* document_updated) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
2451+ void (* document_deleted) (CouchDB *couchdb, const char *dbname, const char *docid);
2452+} CouchDBClass;
2453+
2454+GType couchdb_get_type (void);
2455+CouchDB *couchdb_new (const char *hostname);
2456+
2457+const char *couchdb_get_hostname (CouchDB *couchdb);
2458+
2459+GSList *couchdb_list_databases (CouchDB *couchdb, GError **error);
2460+void couchdb_free_database_list (GSList *dblist);
2461+
2462+CouchDBDatabaseInfo *couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error);
2463+
2464+gboolean couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error);
2465+gboolean couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error);
2466+
2467+void couchdb_listen_for_changes (CouchDB *couchdb, const char *dbname);
2468+
2469+gboolean couchdb_enable_oauth (CouchDB *couchdb,
2470+ const char *consumer_key,
2471+ const char *consumer_secret,
2472+ const char *token_key,
2473+ const char *token_secret);
2474+void couchdb_disable_oauth (CouchDB *couchdb);
2475+
2476+gboolean couchdb_is_oauth_enabled (CouchDB *couchdb);
2477+
2478+gboolean couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error);
2479+
2480+GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error);
2481+void couchdb_free_document_list (GSList *doclist);
2482+
2483+G_END_DECLS
2484+
2485+#endif /* __COUCHDB_H__ */
2486
2487=== modified file 'couchdb-glib/dbwatch.c'
2488--- couchdb-glib/dbwatch.c 2009-08-31 15:48:46 +0000
2489+++ couchdb-glib/dbwatch.c 2009-10-06 18:10:22 +0000
2490@@ -19,7 +19,8 @@
2491 * Boston, MA 02110-1301, USA.
2492 */
2493
2494-#include "couchdb-glib.h"
2495+#include <libsoup/soup-method.h>
2496+#include "couchdb-document.h"
2497 #include "dbwatch.h"
2498 #include "utils.h"
2499
2500@@ -78,11 +79,11 @@
2501 DBWatch *watch = (DBWatch *) user_data;
2502
2503 url = g_strdup_printf ("%s/%s/_changes?since=%d",
2504- watch->couchdb->hostname,
2505+ couchdb_get_hostname (watch->couchdb),
2506 watch->dbname,
2507 watch->last_update_seq);
2508- parser = send_message_and_parse (watch->couchdb, SOUP_METHOD_GET, url, NULL, &error);
2509- if (parser != NULL) {
2510+ parser = json_parser_new ();
2511+ if (couchdb_send_message (watch->couchdb, SOUP_METHOD_GET, url, NULL, parser, &error)) {
2512 JsonNode *root_node;
2513
2514 root_node = json_parser_get_root (parser);
2515@@ -102,12 +103,11 @@
2516
2517 if (json_object_has_member (root_object, "last_seq"))
2518 watch->last_update_seq = json_object_get_int_member (root_object, "last_seq");
2519- }
2520-
2521- g_object_unref (G_OBJECT (parser));
2522+ }
2523 }
2524
2525 /* Free memory */
2526+ g_object_unref (G_OBJECT (parser));
2527 g_free (url);
2528 }
2529
2530
2531=== modified file 'couchdb-glib/dbwatch.h'
2532--- couchdb-glib/dbwatch.h 2009-08-31 15:48:46 +0000
2533+++ couchdb-glib/dbwatch.h 2009-10-06 18:10:22 +0000
2534@@ -22,6 +22,8 @@
2535 #ifndef __DBWATCH_H__
2536 #define __DBWATCH_H__
2537
2538+#include <glib.h>
2539+#include "couchdb.h"
2540 #include "utils.h"
2541
2542 typedef struct {
2543@@ -34,4 +36,4 @@
2544 DBWatch *dbwatch_new (CouchDB *couchdb, const gchar *dbname, gint update_seq);
2545 void dbwatch_free (DBWatch *watch);
2546
2547-#endif
2548+#endif /* __DBWATCH_H__ */
2549
2550=== modified file 'couchdb-glib/utils.c'
2551--- couchdb-glib/utils.c 2009-09-09 14:53:00 +0000
2552+++ couchdb-glib/utils.c 2009-10-06 18:10:22 +0000
2553@@ -24,46 +24,6 @@
2554 #include <libsoup/soup-session-async.h>
2555 #include "couchdb-glib.h"
2556 #include "utils.h"
2557-#ifdef HAVE_OAUTH
2558-#include <time.h>
2559-#include "oauth.h"
2560-#endif
2561-
2562-static JsonParser *
2563-parse_json_response (SoupMessage *http_message, GError **error)
2564-{
2565- SoupBuffer *buffer;
2566- GString *str = NULL;
2567- goffset offset = 0;
2568- JsonParser *json_parser = NULL;
2569-
2570- while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
2571- if (!str)
2572- str = g_string_new ("");
2573- g_string_append_len (str, buffer->data, buffer->length);
2574-
2575- offset += buffer->length;
2576- soup_buffer_free (buffer);
2577- }
2578-
2579- if (str && str->len > 0) {
2580- g_debug ("Response body: %s", str->str);
2581- json_parser = json_parser_new ();
2582- if (!json_parser_load_from_data (json_parser,
2583- (const gchar *) str->str,
2584- str->len,
2585- error)) {
2586- g_object_unref (G_OBJECT (json_parser));
2587- json_parser = NULL;
2588-
2589- g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
2590- }
2591-
2592- g_string_free (str, TRUE);
2593- }
2594-
2595- return json_parser;
2596-}
2597
2598 GQuark
2599 couchdb_error_quark (void)
2600@@ -76,110 +36,6 @@
2601 return error;
2602 }
2603
2604-#ifdef HAVE_OAUTH
2605-static void
2606-add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
2607-{
2608- char *signed_url;
2609-
2610- signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
2611- couchdb->oauth_consumer_key,
2612- couchdb->oauth_consumer_secret,
2613- couchdb->oauth_token_key,
2614- couchdb->oauth_token_secret);
2615- if (signed_url != NULL) {
2616- char **parsed_url;
2617- GString *header = NULL;
2618-
2619- /* Get the OAuth signature from the signed URL */
2620- parsed_url = g_strsplit (signed_url, "?", 2);
2621- if (parsed_url != NULL) {
2622- gchar **params;
2623- int i;
2624-
2625- params = g_strsplit (parsed_url[1], "&", 0);
2626-#ifdef DEBUG_OAUTH
2627- g_debug ("Parsing %s", parsed_url[1]);
2628-#endif
2629- for (i = 0; params[i] != NULL; i++) {
2630- gchar **url_param;
2631-
2632-#ifdef DEBUG_OAUTH
2633- g_debug ("%s\n", params[i]);
2634-#endif
2635- url_param = g_strsplit (params[i], "=", 2);
2636- if (url_param == NULL)
2637- continue;
2638-
2639- if (header != NULL)
2640- header = g_string_append (header, ", ");
2641- else
2642- header = g_string_new ("OAuth ");
2643-
2644- header = g_string_append (header, url_param[0]);
2645- header = g_string_append (header, "=\"");
2646- header = g_string_append (header, url_param[1]);
2647- header = g_string_append (header, "\"");
2648-
2649- g_strfreev (url_param);
2650- }
2651-
2652- if (params)
2653- g_strfreev (params);
2654-
2655- g_strfreev (parsed_url);
2656- }
2657-
2658- if (header != NULL) {
2659- soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
2660-
2661- g_string_free (header, TRUE);
2662- }
2663-
2664- free (signed_url);
2665- }
2666-}
2667-#endif
2668-
2669-static void
2670-debug_print_headers (const char *name, const char *value, gpointer user_data)
2671-{
2672- g_print ("\t%s: %s\n", name, value);
2673-}
2674-
2675-JsonParser *
2676-send_message_and_parse (CouchDB *couchdb, const char *method, const char *url, const char *body, GError **error)
2677-{
2678- SoupMessage *http_message;
2679- guint status;
2680- JsonParser *parser = NULL;
2681-
2682- http_message = soup_message_new (method, url);
2683- if (body != NULL) {
2684- soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
2685- body, strlen (body));
2686- }
2687-
2688-#ifdef HAVE_OAUTH
2689- if (couchdb->oauth_enabled)
2690- add_oauth_signature (couchdb, http_message, method, url);
2691-#endif
2692-
2693- g_debug ("Sending %s to %s... with headers\n: ", method, url);
2694- soup_message_headers_foreach (http_message->request_headers,
2695- (SoupMessageHeadersForeachFunc) debug_print_headers,
2696- NULL);
2697-
2698- status = soup_session_send_message (couchdb->http_session, http_message);
2699- if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
2700- parser = parse_json_response (http_message, error);
2701- } else {
2702- g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
2703- }
2704-
2705- return parser;
2706-}
2707-
2708 char *
2709 generate_uuid (void)
2710 {
2711
2712=== modified file 'couchdb-glib/utils.h'
2713--- couchdb-glib/utils.h 2009-09-09 14:53:00 +0000
2714+++ couchdb-glib/utils.h 2009-10-06 18:10:22 +0000
2715@@ -22,85 +22,14 @@
2716 #ifndef __UTILS_H__
2717 #define __UTILS_H__
2718
2719+#include <glib.h>
2720+#include <json-glib/json-glib.h>
2721 #include "config.h"
2722-#include <libsoup/soup-session-async.h>
2723-#include <json-glib/json-glib.h>
2724-
2725-struct _CouchDB {
2726- GObject parent;
2727-
2728- char *hostname;
2729- SoupSession *http_session;
2730-
2731- GHashTable *db_watchlist;
2732-
2733-#ifdef HAVE_OAUTH
2734- gboolean oauth_enabled;
2735- char *oauth_consumer_key;
2736- char *oauth_consumer_secret;
2737- char *oauth_token_key;
2738- char *oauth_token_secret;
2739-#endif
2740-};
2741-
2742-struct _CouchDBDocument {
2743- GObject parent;
2744-
2745- CouchDB *couchdb;
2746- char *dbname;
2747- JsonNode *root_node;
2748-};
2749-
2750-struct _CouchDBDatabaseInfo {
2751- gint ref_count;
2752-
2753- char *dbname;
2754- gint doc_count;
2755- gint doc_del_count;
2756- gint update_seq;
2757- gboolean compact_running;
2758- gint disk_size;
2759-};
2760-
2761-CouchDBDatabaseInfo *couchdb_database_info_new (const char *dbname,
2762- gint doc_count,
2763- gint doc_del_count,
2764- gint update_seq,
2765- gboolean compact_running,
2766- gint disk_size);
2767-
2768-struct _CouchDBDocumentInfo {
2769- gint ref_count;
2770-
2771- char *docid;
2772- char *revision;
2773-};
2774-
2775-CouchDBDocumentInfo *couchdb_document_info_new (const char *docid, const char *revision);
2776-
2777-struct _CouchDBStructField {
2778- gint ref_count;
2779- JsonObject *json_object;
2780-
2781- /* Extra data needed for some specific StructField's */
2782- char *uuid; /* the UUID of this item */
2783-};
2784-
2785-CouchDBStructField *couchdb_struct_field_new_from_json_object (JsonObject *json_object);
2786-
2787-/*
2788- * Utility functions
2789- */
2790+#include "couchdb.h"
2791
2792 #define COUCHDB_ERROR couchdb_error_quark()
2793 GQuark couchdb_error_quark (void);
2794
2795-JsonParser *send_message_and_parse (CouchDB *couchdb,
2796- const char *method,
2797- const char *url,
2798- const char *body,
2799- GError **error);
2800-
2801-char *generate_uuid (void);
2802+char* generate_uuid (void);
2803
2804 #endif
2805
2806=== modified file 'debian/control'
2807--- debian/control 2009-08-11 15:04:39 +0000
2808+++ debian/control 2009-10-06 18:10:22 +0000
2809@@ -27,3 +27,15 @@
2810 Ubuntu One.
2811 .
2812 This package contains the development files.
2813+
2814+Package: libcouchdb-glib-doc
2815+Section: doc
2816+Architecture: any
2817+Depends: ${misc:Depends}
2818+Description: API documentation for GLib-based API for CouchDB
2819+ CouchDB-GLib is a GLib-based API to access CouchDB servers
2820+ (http://couchdb.apache.org), a replication/synchronization
2821+ database of JSON documents, used in online services like
2822+ Ubuntu One.
2823+ .
2824+ This package contains the API documentation for the couchdb-glib library
2825
2826=== added file 'debian/libcouchdb-glib-doc.install'
2827--- debian/libcouchdb-glib-doc.install 1970-01-01 00:00:00 +0000
2828+++ debian/libcouchdb-glib-doc.install 2009-10-06 18:10:22 +0000
2829@@ -0,0 +1,1 @@
2830+debian/tmp/usr/share/gtk-doc
2831
2832=== modified file 'debian/rules'
2833--- debian/rules 2009-07-20 12:11:54 +0000
2834+++ debian/rules 2009-10-06 18:10:22 +0000
2835@@ -2,3 +2,5 @@
2836
2837 include /usr/share/cdbs/1/rules/debhelper.mk
2838 include /usr/share/cdbs/1/class/gnome.mk
2839+include /usr/share/cdbs/1/rules/utils.mk
2840+
2841
2842=== added directory 'doc'
2843=== added file 'doc/Makefile.am'
2844--- doc/Makefile.am 1970-01-01 00:00:00 +0000
2845+++ doc/Makefile.am 2009-10-06 18:10:22 +0000
2846@@ -0,0 +1,4 @@
2847+# Include to make 'make check' work with GTest
2848+#include $(top_srcdir)/Makefile.decl
2849+
2850+SUBDIRS = reference
2851
2852=== added directory 'doc/reference'
2853=== added file 'doc/reference/Makefile.am'
2854--- doc/reference/Makefile.am 1970-01-01 00:00:00 +0000
2855+++ doc/reference/Makefile.am 2009-10-06 18:10:22 +0000
2856@@ -0,0 +1,67 @@
2857+## Process this file with automake to produce Makefile.in
2858+
2859+# Dummy targets we need to make distcheck and check pass
2860+test test-report perf-report full-report:
2861+ ## Ignore
2862+
2863+# automake requirements
2864+AUTOMAKE_OPTIONS = 1.7
2865+
2866+# The name of the module
2867+DOC_MODULE=couchdb-glib
2868+
2869+# The top-level SGML file. You can change this if you want to.
2870+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
2871+
2872+# The directory containing the source code. Relative to $(srcdir).
2873+DOC_SOURCE_DIR=../..
2874+
2875+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
2876+SCANGOBJ_OPTIONS=
2877+
2878+# Extra options to supply to gtkdoc-scan.
2879+# Fx --rebuild-types --rebuild-sections
2880+SCAN_OPTIONS=
2881+
2882+# Extra options to supply to gtkdoc-mkdb.
2883+MKDB_OPTIONS=--sgml-mode --output-format=xml --ignore-files=trio
2884+
2885+# Extra options to supply to gtkdoc-fixref. Not normally needed.
2886+FIXXREF_OPTIONS=
2887+
2888+# Used for dependencies. The docs will be rebuilt if any of these change.
2889+HFILE_GLOB=$(top_srcdir)/couchdb-glib/couchdb*.h
2890+CFILE_GLOB=$(top_srcdir)/couchdb-glib/couchdb*.c
2891+
2892+# Header files to ignore when scanning.
2893+IGNORE_HFILES= \
2894+ xmalloc.h \
2895+ dbwatch.h \
2896+ oauth.h \
2897+ utils.h \
2898+ xmalloc.h \
2899+ config.h
2900+
2901+# Images to copy into HTML directory.
2902+HTML_IMAGES=
2903+
2904+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
2905+content_files =
2906+
2907+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
2908+INCLUDES=-I$(top_srcdir)/couchdb-glib \
2909+ $(COUCHDB_GLIB_CFLAGS)
2910+
2911+GTKDOC_LIBS=$(COUCHDB_GLIB_LIBS) \
2912+ $(top_builddir)/couchdb-glib/libcouchdb-glib-1.0.la
2913+
2914+# This includes the standard gtk-doc make rules, copied by gtkdocize.
2915+include $(top_srcdir)/gtk-doc.make
2916+
2917+# Other files to distribute
2918+# e.g. EXTRA_DIST += version.xml.in
2919+EXTRA_DIST += \
2920+ couchdb-glib.types \
2921+ couchdb-glib-docs.sgml
2922+# couchdb-glib-sections.txt
2923+
2924
2925=== added file 'doc/reference/couchdb-glib-docs.sgml'
2926--- doc/reference/couchdb-glib-docs.sgml 1970-01-01 00:00:00 +0000
2927+++ doc/reference/couchdb-glib-docs.sgml 2009-10-06 18:10:22 +0000
2928@@ -0,0 +1,19 @@
2929+<?xml version="1.0"?>
2930+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
2931+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
2932+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
2933+ <bookinfo>
2934+ <title>Reference Manual for CouchDB GLib Bindings</title>
2935+ </bookinfo>
2936+
2937+ <chapter>
2938+ <title>Core API</title>
2939+ <xi:include href="xml/couchdb.xml"/>
2940+ <xi:include href="xml/couchdb-document.xml"/>
2941+ <xi:include href="xml/couchdb-document-contact.xml"/>
2942+ <xi:include href="xml/couchdb-document-info.xml"/>
2943+ <xi:include href="xml/couchdb-database-info.xml"/>
2944+ <xi:include href="xml/couchdb-struct-field.xml"/>
2945+ </chapter>
2946+
2947+</book>
2948
2949=== added file 'doc/reference/couchdb-glib.types'
2950--- doc/reference/couchdb-glib.types 1970-01-01 00:00:00 +0000
2951+++ doc/reference/couchdb-glib.types 2009-10-06 18:10:22 +0000
2952@@ -0,0 +1,6 @@
2953+couchdb_get_type
2954+couchdb_database_info_get_type
2955+couchdb_document_get_type
2956+couchdb_document_info_get_type
2957+couchdb_struct_field_get_type
2958+
2959
2960=== modified file 'tests/test-couchdb-glib.c'
2961--- tests/test-couchdb-glib.c 2009-08-31 15:48:46 +0000
2962+++ tests/test-couchdb-glib.c 2009-10-06 18:10:22 +0000
2963@@ -31,7 +31,12 @@
2964 GSList *dblist;
2965
2966 dblist = couchdb_list_databases (couchdb, &error);
2967- g_assert (error == NULL);
2968+ if (error != NULL) {
2969+ /* A critical will abort the test case */
2970+ g_critical ("Error listing databases: %s", error->message);
2971+ g_error_free (error);
2972+ error = NULL;
2973+ }
2974
2975 while (dblist != NULL) {
2976 CouchDBDatabaseInfo *dbinfo;
2977@@ -112,7 +117,10 @@
2978
2979 /* Create database */
2980 couchdb_create_database (couchdb, dbname, &error);
2981- g_assert (error == NULL);
2982+ if (error) {
2983+ g_critical ("Error creating database '%s': %s", dbname, error->message);
2984+ g_error_free (error);
2985+ }
2986
2987 couchdb_listen_for_changes (couchdb, dbname);
2988
2989@@ -184,7 +192,9 @@
2990 g_test_init (&argc, &argv, NULL);
2991
2992 /* Initialize data needed for all tests */
2993- couchdb = couchdb_new (NULL);
2994+ couchdb = argc > 1 ? couchdb_new (argv[1]) : couchdb_new (NULL);
2995+ g_printf ("Connecting to CouchDB at %s\n", couchdb_get_hostname (couchdb));
2996+
2997 if (!couchdb) {
2998 g_print ("Could not create CouchDB object\n");
2999 return -1;
3000
3001=== modified file 'tests/test-list-databases.c'
3002--- tests/test-list-databases.c 2009-07-27 21:52:04 +0000
3003+++ tests/test-list-databases.c 2009-10-06 18:10:22 +0000
3004@@ -32,14 +32,21 @@
3005 g_type_init ();
3006 g_thread_init (NULL);
3007
3008- /* initialize CouchDB */
3009- couchdb = couchdb_new (NULL);
3010+ /* Initialize CouchDB */
3011+ couchdb = argc > 1 ? couchdb_new (argv[1]) : couchdb_new (NULL);
3012+ g_printf ("Connecting to CouchDB at %s\n", couchdb_get_hostname (couchdb));
3013+
3014 if (!couchdb) {
3015 g_print ("Could not create CouchDB object\n");
3016 return -1;
3017 }
3018
3019 dblist = couchdb_list_databases (couchdb, &error);
3020+ if (error != NULL) {
3021+ g_critical ("Error listing databases: %s", error->message);
3022+ g_error_free (error);
3023+ }
3024+
3025 for (sl = dblist; sl != NULL; sl = sl->next) {
3026 CouchDBDatabaseInfo *dbinfo;
3027 GSList *doclist;

Subscribers

People subscribed via source and target branches