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

Proposed by Mikkel Kamstrup Erlandsen
Status: Merged
Approved by: Rodrigo Moya
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
Tim Cole (community) Approve
Review via email: mp+12917@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

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

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

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.

Revision history for this message
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...

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) 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.

Revision history for this message
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

Update TODO

Revision history for this message
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.

Revision history for this message
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
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) 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.

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

More items for the todo :-)

117. By Mikkel Kamstrup Erlandsen

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

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) 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.

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.

Revision history for this message
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
Revision history for this message
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
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

> 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
=== modified file 'Makefile.am'
--- Makefile.am 2009-07-20 11:27:33 +0000
+++ Makefile.am 2009-10-06 18:10:22 +0000
@@ -1,4 +1,6 @@
1SUBDIRS = couchdb-glib tests1SUBDIRS = couchdb-glib tests doc
2
3DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
24
3pcfiles = couchdb-glib-1.0.pc5pcfiles = couchdb-glib-1.0.pc
46
@@ -8,7 +10,16 @@
8pkgconfig_DATA = $(pcfiles)10pkgconfig_DATA = $(pcfiles)
9pkgconfigdir = $(libdir)/pkgconfig11pkgconfigdir = $(libdir)/pkgconfig
1012
11EXTRA_DIST = couchdb-glib.pc.in LICENSE13couchdbdocdir = ${datadir}/doc/couchdb-glib
14couchdbdoc_DATA = \
15 README \
16 LICENSE \
17 couchdb-glib.doap \
18 NEWS
19
20EXTRA_DIST = \
21 couchdb-glib.pc.in \
22 $(couchdbdoc_DATA)
1223
13dist-hook:24dist-hook:
14 git log --stat > ChangeLog.in && \25 git log --stat > ChangeLog.in && \
1526
=== added file 'NOTES.kamstrup'
--- NOTES.kamstrup 1970-01-01 00:00:00 +0000
+++ NOTES.kamstrup 2009-10-06 18:10:22 +0000
@@ -0,0 +1,32 @@
1TODO:
2-----
3Silent build rules
4Single header includes
5? Get rid of CouchDBStructField ?
6Make 'make check' run unit tests
7Rename CouchDB class to CouchDBConnection
8Add method couchdb_send_async using a SoupSessionAsync underneath
9A .ini parser to extract OAUTH credentials from desktop-couchdb.ini
10Move couchdb_document_put() to couchdb_put(doc) in order to separate responsibilities and make CouchDB sub-classable
11Class struct padding for future ABI stability
12Ref counting in custom boxed types vs. full GObjects
13Abstract out OAUTH, in favour of custom message filters in couchdb_send_message
14
15DONE:
16-----
17
18In couchdb.*:
19 * Don't make API depend on whether we are configured with OAUTH
20 * Move OAUTH related functionality from util.* here
21 * New method couchdb_send_message() replacing send_message_and_parse() from util.*
22
23In couchdb-document.c:
24 * Change refs to internal API of CouchDB object's ->hostname to method calls
25 * Change refs to internal API of CouchDBStructField ->json_object to use method call
26
27In couchdb-struct-field.*:
28 * Add method _get_json_object()
29
30THOUGHTS:
31 * CouchDBStructField seems to be a superfluous wrapper of JSonObject
32 * Rename CouchDB object to CouchDBConnection
033
=== modified file 'configure.ac'
--- configure.ac 2009-09-29 12:19:40 +0000
+++ configure.ac 2009-10-06 18:10:22 +0000
@@ -43,11 +43,20 @@
43AC_SUBST(LIBCOUCHDBGLIB_REVISION)43AC_SUBST(LIBCOUCHDBGLIB_REVISION)
44AC_SUBST(LIBCOUCHDBGLIB_AGE)44AC_SUBST(LIBCOUCHDBGLIB_AGE)
4545
46##################################################
47# Check for gtk-doc.
48##################################################
49GTK_DOC_CHECK(1.0)
50DISTCHECK_CONFIGURE_FLAGS="--enable-gtk-doc"
51AC_SUBST(DISTCHECK_CONFIGURE_FLAGS)
52
46AC_OUTPUT([53AC_OUTPUT([
47Makefile54Makefile
48couchdb-glib.pc55couchdb-glib.pc
49couchdb-glib/Makefile56couchdb-glib/Makefile
50tests/Makefile57tests/Makefile
58doc/Makefile
59doc/reference/Makefile
51])60])
5261
53AC_MSG_NOTICE([62AC_MSG_NOTICE([
5463
=== modified file 'couchdb-glib/Makefile.am'
--- couchdb-glib/Makefile.am 2009-09-09 15:09:10 +0000
+++ couchdb-glib/Makefile.am 2009-10-06 18:10:22 +0000
@@ -22,21 +22,33 @@
22couchdb-marshal.c: couchdb-marshal.list $(GLIB_GENMARSHAL)22couchdb-marshal.c: couchdb-marshal.list $(GLIB_GENMARSHAL)
23 $(GLIB_GENMARSHAL) $< --body --prefix=_couchdb_marshal > $@23 $(GLIB_GENMARSHAL) $< --body --prefix=_couchdb_marshal > $@
2424
25libcouchdb_glib_1_0_la_SOURCES = \25libcouchdb_glib_1_0_la_SOURCES = \
26 $(MARSHAL_GENERATED) \
27 couchdb.c \26 couchdb.c \
27 couchdb.h \
28 couchdb-database-info.c \
29 couchdb-database-info.h \
28 couchdb-document.c \30 couchdb-document.c \
31 couchdb-document.h \
29 couchdb-document-contact.c \32 couchdb-document-contact.c \
30 couchdb-types.c \33 couchdb-document-contact.h \
34 couchdb-document-info.c \
35 couchdb-document-info.h \
36 couchdb-glib.h \
37 couchdb-struct-field.c \
38 couchdb-struct-field.h \
39 couchdb-types.h \
31 dbwatch.c \40 dbwatch.c \
32 dbwatch.h \41 dbwatch.h \
33 $(OAUTH_SOURCES) \
34 utils.c \42 utils.c \
35 utils.h43 utils.h \
44 $(MARSHAL_GENERATED) \
45 $(OAUTH_SOURCES)
46
36libcouchdb_glib_1_0_la_LIBADD = \47libcouchdb_glib_1_0_la_LIBADD = \
37 $(COUCHDB_GLIB_LIBS) \48 $(COUCHDB_GLIB_LIBS) \
38 $(OAUTH_LIBS) \49 $(OAUTH_LIBS) \
39 -luuid50 -luuid
51
40libcouchdb_glib_1_0_la_LDFLAGS = \52libcouchdb_glib_1_0_la_LDFLAGS = \
41 -version-info $(LIBCOUCHDBGLIB_CURRENT):$(LIBCOUCHDBGLIB_REVISION):$(LIBCOUCHDBGLIB_AGE)53 -version-info $(LIBCOUCHDBGLIB_CURRENT):$(LIBCOUCHDBGLIB_REVISION):$(LIBCOUCHDBGLIB_AGE)
4254
4355
=== added file 'couchdb-glib/couchdb-database-info.c'
--- couchdb-glib/couchdb-database-info.c 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-database-info.c 2009-10-06 18:10:22 +0000
@@ -0,0 +1,151 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "couchdb-database-info.h"
25
26struct _CouchDBDatabaseInfo {
27 gint ref_count;
28
29 char *dbname;
30 gint doc_count;
31 gint doc_del_count;
32 gint update_seq;
33 gboolean compact_running;
34 gint disk_size;
35};
36
37/*
38 * CouchDBDatabaseInfo object
39 */
40
41GType
42couchdb_database_info_get_type (void)
43{
44 static GType object_type = 0;
45
46 if (G_UNLIKELY (!object_type))
47 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDatabaseInfo"),
48 (GBoxedCopyFunc) couchdb_database_info_ref,
49 (GBoxedFreeFunc) couchdb_database_info_unref);
50
51 return object_type;
52}
53
54CouchDBDatabaseInfo *
55couchdb_database_info_new (const char *dbname,
56 gint doc_count,
57 gint doc_del_count,
58 gint update_seq,
59 gboolean compact_running,
60 gint disk_size)
61{
62 CouchDBDatabaseInfo *dbinfo;
63
64 dbinfo = g_slice_new (CouchDBDatabaseInfo);
65 dbinfo->ref_count = 1;
66 dbinfo->dbname = g_strdup (dbname);
67 dbinfo->doc_count = doc_count;
68 dbinfo->doc_del_count = doc_del_count;
69 dbinfo->update_seq = update_seq;
70 dbinfo->compact_running = compact_running;
71 dbinfo->disk_size = disk_size;
72
73 return dbinfo;
74}
75
76CouchDBDatabaseInfo *
77couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo)
78{
79 g_return_val_if_fail (dbinfo != NULL, NULL);
80 g_return_val_if_fail (dbinfo->ref_count > 0, NULL);
81
82 g_atomic_int_exchange_and_add (&dbinfo->ref_count, 1);
83
84 return dbinfo;
85}
86
87void
88couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo)
89{
90 gint old_ref;
91
92 g_return_if_fail (dbinfo != NULL);
93 g_return_if_fail (dbinfo->ref_count > 0);
94
95 old_ref = g_atomic_int_get (&dbinfo->ref_count);
96 if (old_ref > 1)
97 g_atomic_int_compare_and_exchange (&dbinfo->ref_count, old_ref, old_ref - 1);
98 else {
99 g_free (dbinfo->dbname);
100 g_slice_free (CouchDBDatabaseInfo, dbinfo);
101 }
102}
103
104const char *
105couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo)
106{
107 g_return_val_if_fail (dbinfo != NULL, NULL);
108
109 return (const char *) dbinfo->dbname;
110}
111
112gint
113couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo)
114{
115 g_return_val_if_fail (dbinfo != NULL, 0);
116
117 return dbinfo->doc_count;
118}
119
120gint
121couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo)
122{
123 g_return_val_if_fail (dbinfo != NULL, 0);
124
125 return dbinfo->doc_del_count;
126}
127
128gint
129couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo)
130{
131 g_return_val_if_fail (dbinfo != NULL, 0);
132
133 return dbinfo->update_seq;
134}
135
136gboolean
137couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo)
138{
139 g_return_val_if_fail (dbinfo != NULL, FALSE);
140
141 return dbinfo->compact_running;
142}
143
144gint
145couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo)
146{
147 g_return_val_if_fail (dbinfo != NULL, 0);
148
149 return dbinfo->disk_size;
150}
151
0152
=== added file 'couchdb-glib/couchdb-database-info.h'
--- couchdb-glib/couchdb-database-info.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-database-info.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,59 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_DATABASE_INFO_H__
25#define __COUCHDB_DATABASE_INFO_H__
26
27#include <glib.h>
28#include <glib-object.h>
29#include "couchdb-types.h"
30
31G_BEGIN_DECLS
32
33#define COUCHDB_TYPE_DATABASE_INFO (couchdb_database_info_get_type ())
34
35/*
36 * CouchDBDatabaseInfo
37 */
38
39GType couchdb_database_info_get_type (void);
40CouchDBDatabaseInfo *couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo);
41void couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo);
42
43const char *couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo);
44gint couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo);
45gint couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo);
46gint couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo);
47gboolean couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo);
48gint couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo);
49
50CouchDBDatabaseInfo* couchdb_database_info_new (const char *dbname,
51 gint doc_count,
52 gint doc_del_count,
53 gint update_seq,
54 gboolean compact_running,
55 gint disk_size);
56
57G_END_DECLS
58
59#endif /* __COUCHDB_DATABASE_INFO_H__ */
060
=== modified file 'couchdb-glib/couchdb-document-contact.c'
--- couchdb-glib/couchdb-document-contact.c 2009-09-22 12:38:41 +0000
+++ couchdb-glib/couchdb-document-contact.c 2009-10-06 18:10:22 +0000
@@ -337,7 +337,7 @@
337 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);337 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
338338
339 addresses_json = json_object_get_object_member (339 addresses_json = json_object_get_object_member (
340 json_node_get_object (document->root_node), "email_addresses");;340 couchdb_document_get_json_object (document), "email_addresses");;
341 if (addresses_json) {341 if (addresses_json) {
342 json_object_foreach_member (addresses_json,342 json_object_foreach_member (addresses_json,
343 (JsonObjectForeach) foreach_object_cb,343 (JsonObjectForeach) foreach_object_cb,
@@ -375,7 +375,7 @@
375 }375 }
376 }376 }
377377
378 json_object_set_object_member (json_node_get_object (document->root_node), "email_addresses", addresses_json);378 json_object_set_object_member (couchdb_document_get_json_object (document), "email_addresses", addresses_json);
379}379}
380380
381GSList *381GSList *
@@ -388,7 +388,7 @@
388 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);388 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
389389
390 phone_numbers = json_object_get_object_member (390 phone_numbers = json_object_get_object_member (
391 json_node_get_object (document->root_node), "phone_numbers");391 couchdb_document_get_json_object (document), "phone_numbers");
392 if (phone_numbers) {392 if (phone_numbers) {
393 json_object_foreach_member (phone_numbers,393 json_object_foreach_member (phone_numbers,
394 (JsonObjectForeach) foreach_object_cb,394 (JsonObjectForeach) foreach_object_cb,
@@ -428,7 +428,7 @@
428 }428 }
429 }429 }
430430
431 json_object_set_object_member (json_node_get_object (document->root_node), "phone_numbers", phone_numbers);431 json_object_set_object_member (couchdb_document_get_json_object (document), "phone_numbers", phone_numbers);
432}432}
433433
434GSList *434GSList *
@@ -441,7 +441,7 @@
441 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);441 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
442442
443 addresses = json_object_get_object_member (443 addresses = json_object_get_object_member (
444 json_node_get_object (document->root_node), "addresses");444 couchdb_document_get_json_object (document), "addresses");
445 if (addresses) {445 if (addresses) {
446 json_object_foreach_member (addresses,446 json_object_foreach_member (addresses,
447 (JsonObjectForeach) foreach_object_cb,447 (JsonObjectForeach) foreach_object_cb,
@@ -489,7 +489,7 @@
489 }489 }
490 }490 }
491491
492 json_object_set_object_member (json_node_get_object (document->root_node), "addresses", addresses);492 json_object_set_object_member (couchdb_document_get_json_object (document), "addresses", addresses);
493}493}
494494
495GSList *495GSList *
@@ -502,7 +502,7 @@
502 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);502 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
503503
504 im_addresses = json_object_get_object_member (504 im_addresses = json_object_get_object_member (
505 json_node_get_object (document->root_node), "im_addresses");505 couchdb_document_get_json_object (document), "im_addresses");
506 if (im_addresses != NULL) {506 if (im_addresses != NULL) {
507 json_object_foreach_member (im_addresses,507 json_object_foreach_member (im_addresses,
508 (JsonObjectForeach) foreach_object_cb,508 (JsonObjectForeach) foreach_object_cb,
@@ -542,7 +542,7 @@
542 }542 }
543 }543 }
544544
545 json_object_set_object_member (json_node_get_object (document->root_node), "im_addresses", im_addresses_json);545 json_object_set_object_member (couchdb_document_get_json_object (document), "im_addresses", im_addresses_json);
546}546}
547547
548GSList *548GSList *
@@ -555,7 +555,7 @@
555 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);555 g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
556556
557 urls = json_object_get_object_member (557 urls = json_object_get_object_member (
558 json_node_get_object (document->root_node), "urls");558 couchdb_document_get_json_object (document), "urls");
559 if (urls) {559 if (urls) {
560 json_object_foreach_member (urls,560 json_object_foreach_member (urls,
561 (JsonObjectForeach) foreach_object_cb,561 (JsonObjectForeach) foreach_object_cb,
@@ -593,7 +593,7 @@
593 }593 }
594 }594 }
595595
596 json_object_set_object_member (json_node_get_object (document->root_node), "urls", urls_json);596 json_object_set_object_member (couchdb_document_get_json_object (document), "urls", urls_json);
597}597}
598598
599const char *599const char *
600600
=== modified file 'couchdb-glib/couchdb-document-contact.h'
--- couchdb-glib/couchdb-document-contact.h 2009-09-21 22:34:18 +0000
+++ couchdb-glib/couchdb-document-contact.h 2009-10-06 18:10:22 +0000
@@ -22,7 +22,11 @@
22#ifndef __COUCHDB_DOCUMENT_CONTACT_H__22#ifndef __COUCHDB_DOCUMENT_CONTACT_H__
23#define __COUCHDB_DOCUMENT_CONTACT_H__23#define __COUCHDB_DOCUMENT_CONTACT_H__
2424
25#include <couchdb-glib.h>25#include <glib.h>
26#include "couchdb-document.h"
27#include "couchdb-struct-field.h"
28
29G_BEGIN_DECLS
2630
27#define COUCHDB_RECORD_TYPE_CONTACT "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact"31#define COUCHDB_RECORD_TYPE_CONTACT "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact"
2832
@@ -191,4 +195,7 @@
191195
192const char *couchdb_document_contact_url_get_description (CouchDBStructField *sf);196const char *couchdb_document_contact_url_get_description (CouchDBStructField *sf);
193void couchdb_document_contact_url_set_description (CouchDBStructField *sf, const char *description);197void couchdb_document_contact_url_set_description (CouchDBStructField *sf, const char *description);
194#endif198
199G_END_DECLS
200
201#endif /* __COUCHDB_DOCUMENT_CONTACT_H__ */
195202
=== added file 'couchdb-glib/couchdb-document-info.c'
--- couchdb-glib/couchdb-document-info.c 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-document-info.c 2009-10-06 18:10:22 +0000
@@ -0,0 +1,107 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "couchdb-document-info.h"
25
26struct _CouchDBDocumentInfo {
27 gint ref_count;
28
29 char *docid;
30 char *revision;
31};
32
33/*
34 * CouchDBDocumentInfo object
35 */
36
37GType
38couchdb_document_info_get_type (void)
39{
40 static GType object_type = 0;
41
42 if (G_UNLIKELY (!object_type))
43 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDocumentInfo"),
44 (GBoxedCopyFunc) couchdb_document_info_ref,
45 (GBoxedFreeFunc) couchdb_document_info_unref);
46
47 return object_type;
48}
49
50CouchDBDocumentInfo *
51couchdb_document_info_new (const char *docid, const char *revision)
52{
53 CouchDBDocumentInfo *doc_info;
54
55 doc_info = g_slice_new (CouchDBDocumentInfo);
56 doc_info->ref_count = 1;
57 doc_info->docid = g_strdup (docid);
58 doc_info->revision = g_strdup (revision);
59
60 return doc_info;
61}
62
63CouchDBDocumentInfo *
64couchdb_document_info_ref (CouchDBDocumentInfo *doc_info)
65{
66 g_return_val_if_fail (doc_info != NULL, NULL);
67 g_return_val_if_fail (doc_info->ref_count > 0, NULL);
68
69 g_atomic_int_exchange_and_add (&doc_info->ref_count, 1);
70
71 return doc_info;
72}
73
74void
75couchdb_document_info_unref (CouchDBDocumentInfo *doc_info)
76{
77 gint old_ref;
78
79 g_return_if_fail (doc_info != NULL);
80 g_return_if_fail (doc_info->ref_count > 0);
81
82 old_ref = g_atomic_int_get (&doc_info->ref_count);
83 if (old_ref > 1)
84 g_atomic_int_compare_and_exchange (&doc_info->ref_count, old_ref, old_ref - 1);
85 else {
86 g_free (doc_info->docid);
87 g_free (doc_info->revision);
88 g_slice_free (CouchDBDocumentInfo, doc_info);
89 }
90}
91
92const char *
93couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info)
94{
95 g_return_val_if_fail (doc_info != NULL, NULL);
96
97 return (const char *) doc_info->docid;
98}
99
100const char *
101couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info)
102{
103 g_return_val_if_fail (doc_info != NULL, NULL);
104
105 return (const char *) doc_info->revision;
106}
107
0108
=== added file 'couchdb-glib/couchdb-document-info.h'
--- couchdb-glib/couchdb-document-info.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-document-info.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,45 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_DOCUMENT_INFO_H__
25#define __COUCHDB_DOCUMENT_INFO_H__
26
27#include <glib.h>
28#include <glib-object.h>
29#include "couchdb-types.h"
30
31G_BEGIN_DECLS
32
33#define COUCHDB_TYPE_DOCUMENT_INFO (couchdb_document_info_get_type ())
34
35GType couchdb_document_info_get_type (void);
36CouchDBDocumentInfo *couchdb_document_info_new (const char *docid, const char *revision);
37CouchDBDocumentInfo *couchdb_document_info_ref (CouchDBDocumentInfo *dbinfo);
38void couchdb_document_info_unref (CouchDBDocumentInfo *dbinfo);
39
40const char *couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info);
41const char *couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info);
42
43G_END_DECLS
44
45#endif /* __COUCHDB_DOCUMENT_INFO_H__ */
046
=== modified file 'couchdb-glib/couchdb-document.c'
--- couchdb-glib/couchdb-document.c 2009-09-09 12:30:29 +0000
+++ couchdb-glib/couchdb-document.c 2009-10-06 18:10:22 +0000
@@ -1,8 +1,10 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
4 *5 *
5 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
6 *8 *
7 * This library is free software; you can redistribute it and/or9 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public10 * modify it under the terms of version 2 of the GNU Lesser General Public
@@ -23,9 +25,17 @@
23#include <libsoup/soup-session-async.h>25#include <libsoup/soup-session-async.h>
24#include <libsoup/soup-gnome.h>26#include <libsoup/soup-gnome.h>
25#include <json-glib/json-glib.h>27#include <json-glib/json-glib.h>
26#include "couchdb-glib.h"28#include "couchdb-document.h"
27#include "utils.h"29#include "utils.h"
2830
31struct _CouchDBDocument {
32 GObject parent;
33
34 CouchDB *couchdb;
35 char *dbname;
36 JsonNode *root_node;
37};
38
29G_DEFINE_TYPE(CouchDBDocument, couchdb_document, G_TYPE_OBJECT);39G_DEFINE_TYPE(CouchDBDocument, couchdb_document, G_TYPE_OBJECT);
3040
31static void41static void
@@ -85,17 +95,16 @@
85 g_return_val_if_fail (docid != NULL, NULL);95 g_return_val_if_fail (docid != NULL, NULL);
8696
87 encoded_docid = soup_uri_encode (docid, NULL);97 encoded_docid = soup_uri_encode (docid, NULL);
88 url = g_strdup_printf ("%s/%s/%s", couchdb->hostname, dbname, encoded_docid);98 url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (couchdb), dbname, encoded_docid);
89 parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);99 parser = json_parser_new ();
90 if (parser) {100 if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
91 document = g_object_new (COUCHDB_TYPE_DOCUMENT, NULL);101 document = g_object_new (COUCHDB_TYPE_DOCUMENT, NULL);
92 document->couchdb = couchdb;102 document->couchdb = couchdb;
93 document->dbname = g_strdup (dbname);103 document->dbname = g_strdup (dbname);
94104
95 document->root_node = json_node_copy (json_parser_get_root (parser));105 document->root_node = json_node_copy (json_parser_get_root (parser));
96 g_object_unref (G_OBJECT (parser));
97 }106 }
98107 g_object_unref (G_OBJECT (parser));
99 g_free (encoded_docid);108 g_free (encoded_docid);
100 g_free (url);109 g_free (url);
101110
@@ -111,34 +120,34 @@
111 const char *id;120 const char *id;
112 JsonParser *parser;121 JsonParser *parser;
113 gboolean result = FALSE;122 gboolean result = FALSE;
123 gboolean send_ok;;
114124
115 g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);125 g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);
116 g_return_val_if_fail (dbname != NULL, FALSE);126 g_return_val_if_fail (dbname != NULL, FALSE);
117127
118 id = couchdb_document_get_id (document);128 id = couchdb_document_get_id (document);
119 body = couchdb_document_to_string (document);129 body = couchdb_document_to_string (document);
130 parser = json_parser_new ();
120 if (id) {131 if (id) {
121 char *encoded_docid;132 char *encoded_docid;
122133
123 encoded_docid = soup_uri_encode (id, NULL);134 encoded_docid = soup_uri_encode (id, NULL);
124 url = g_strdup_printf ("%s/%s/%s", document->couchdb->hostname, dbname, encoded_docid);135 url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (document->couchdb), dbname, encoded_docid);
125 parser = send_message_and_parse (document->couchdb, SOUP_METHOD_PUT, url, body, error);136 send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_PUT, url, body, parser, error);
126137
127 g_free (encoded_docid);138 g_free (encoded_docid);
128 } else {139 } else {
129 url = g_strdup_printf ("%s/%s/", document->couchdb->hostname, dbname);140 url = g_strdup_printf ("%s/%s/", couchdb_get_hostname (document->couchdb), dbname);
130 parser = send_message_and_parse (document->couchdb, SOUP_METHOD_POST, url, body, error);141 send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_POST, url, body, parser, error);
131 }142 }
132143
133 if (parser) {144 if (send_ok) {
134 JsonObject *object;145 JsonObject *object;
135146
136 object = json_node_get_object (json_parser_get_root (parser));147 object = json_node_get_object (json_parser_get_root (parser));
137 couchdb_document_set_id (document, json_object_get_string_member (object, "id"));148 couchdb_document_set_id (document, json_object_get_string_member (object, "id"));
138 couchdb_document_set_revision (document, json_object_get_string_member (object, "rev"));149 couchdb_document_set_revision (document, json_object_get_string_member (object, "rev"));
139150
140 g_object_unref (G_OBJECT (parser));
141
142 if (document->dbname) {151 if (document->dbname) {
143 g_free (document->dbname);152 g_free (document->dbname);
144 document->dbname = g_strdup (dbname);153 document->dbname = g_strdup (dbname);
@@ -155,6 +164,7 @@
155 /* free memory */164 /* free memory */
156 g_free (url);165 g_free (url);
157 g_free (body);166 g_free (body);
167 g_object_unref (G_OBJECT (parser));
158168
159 return result;169 return result;
160}170}
@@ -174,11 +184,11 @@
174 if (!id || !revision) /* we can't remove a document without an ID and/or a REVISION */184 if (!id || !revision) /* we can't remove a document without an ID and/or a REVISION */
175 return FALSE;185 return FALSE;
176186
177 url = g_strdup_printf ("%s/%s/%s?rev=%s", document->couchdb->hostname, document->dbname, id, revision);187 url = g_strdup_printf ("%s/%s/%s?rev=%s", couchdb_get_hostname (document->couchdb), document->dbname, id, revision);
178 parser = send_message_and_parse (document->couchdb, SOUP_METHOD_DELETE, url, NULL, error);188
179 if (parser) {189 /* We don't parse the http response, therefore the parser arg is NULL */
180 g_object_unref (G_OBJECT (parser));190 if (couchdb_send_message (document->couchdb, SOUP_METHOD_DELETE, url, NULL, NULL, error)) {
181191 result = TRUE;
182 g_signal_emit_by_name (document->couchdb, "document_deleted", document->dbname, id);192 g_signal_emit_by_name (document->couchdb, "document_deleted", document->dbname, id);
183 }193 }
184194
@@ -410,7 +420,7 @@
410420
411 json_object_set_object_member (json_node_get_object (document->root_node),421 json_object_set_object_member (json_node_get_object (document->root_node),
412 field,422 field,
413 json_object_ref (value->json_object));423 json_object_ref (couchdb_struct_field_get_json_object (value)));
414}424}
415425
416CouchDBStructField *426CouchDBStructField *
@@ -450,3 +460,11 @@
450460
451 return NULL;461 return NULL;
452}462}
463
464JsonObject *
465couchdb_document_get_json_object (CouchDBDocument *document)
466{
467 g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), NULL);
468
469 return json_node_get_object (document->root_node);
470}
453471
=== added file 'couchdb-glib/couchdb-document.h'
--- couchdb-glib/couchdb-document.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-document.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,134 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_DOCUMENT_H__
25#define __COUCHDB_DOCUMENT_H__
26
27#include <glib.h>
28#include <glib-object.h>
29#include <json-glib/json-glib.h>
30#include "couchdb-types.h"
31#include "couchdb-struct-field.h"
32
33G_BEGIN_DECLS
34
35#define COUCHDB_TYPE_DOCUMENT (couchdb_document_get_type ())
36#define COUCHDB_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocument))
37#define COUCHDB_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE_DOCUMENT))
38#define COUCHDB_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
39#define COUCHDB_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE_DOCUMENT))
40#define COUCHDB_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
41
42typedef struct {
43 GObjectClass parent_class;
44} CouchDBDocumentClass;
45
46
47GType couchdb_document_get_type (void);
48
49CouchDBDocument *couchdb_document_new (CouchDB *couchdb);
50
51CouchDBDocument *couchdb_document_get (CouchDB *couchdb,
52 const char *dbname,
53 const char *docid,
54 GError **error);
55
56gboolean couchdb_document_put (CouchDBDocument *document,
57 const char *dbname,
58 GError **error);
59
60gboolean couchdb_document_delete (CouchDBDocument *document,
61 GError **error);
62
63const char *couchdb_document_get_id (CouchDBDocument *document);
64
65void couchdb_document_set_id (CouchDBDocument *document,
66 const char *id);
67
68const char *couchdb_document_get_revision (CouchDBDocument *document);
69void couchdb_document_set_revision (CouchDBDocument *document,
70 const char *revision);
71
72const char *couchdb_document_get_record_type (CouchDBDocument *document);
73
74void couchdb_document_set_record_type (CouchDBDocument *document,
75
76 const char *record_type);
77
78gboolean couchdb_document_has_field (CouchDBDocument *document,
79 const char *field);
80
81void couchdb_document_remove_field (CouchDBDocument *document,
82 const char *field);
83
84gboolean couchdb_document_get_boolean_field (CouchDBDocument *document,
85 const char *field);
86
87void couchdb_document_set_boolean_field (CouchDBDocument *document,
88 const char *field,
89 gboolean value);
90
91gint couchdb_document_get_int_field (CouchDBDocument *document,
92 const char *field);
93
94void couchdb_document_set_int_field (CouchDBDocument *document,
95 const char *field,
96 gint value);
97
98gdouble couchdb_document_get_double_field (CouchDBDocument *document,
99 const char *field);
100
101void couchdb_document_set_double_field (CouchDBDocument *document,
102 const char *field,
103 gdouble value);
104
105const char *couchdb_document_get_string_field (CouchDBDocument *document,
106 const char *field);
107
108void couchdb_document_set_string_field (CouchDBDocument *document,
109 const char *field,
110 const char *value);
111
112CouchDBStructField*
113 couchdb_document_get_struct_field (CouchDBDocument *document,
114 const char *field);
115
116void couchdb_document_set_struct_field (CouchDBDocument *document,
117 const char *field,
118 CouchDBStructField *value);
119
120CouchDBStructField*
121 couchdb_document_get_application_annotations
122 (CouchDBDocument *document);
123
124void couchdb_document_set_application_annotations
125 (CouchDBDocument *document,
126 CouchDBStructField *annotations);
127
128char* couchdb_document_to_string (CouchDBDocument *document);
129
130JsonObject* couchdb_document_get_json_object (CouchDBDocument *document);
131
132G_END_DECLS
133
134#endif /* __COUCHDB_DOCUMENT_H__ */
0135
=== modified file 'couchdb-glib/couchdb-glib.h'
--- couchdb-glib/couchdb-glib.h 2009-09-09 14:53:00 +0000
+++ couchdb-glib/couchdb-glib.h 2009-10-06 18:10:22 +0000
@@ -1,8 +1,10 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
4 *5 *
5 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
6 *8 *
7 * This library is free software; you can redistribute it and/or9 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public10 * modify it under the terms of version 2 of the GNU Lesser General Public
@@ -18,115 +20,18 @@
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.21 * Boston, MA 02110-1301, USA.
20 */22 */
2123
22#ifndef __COUCHDB_GLIB_H__24#ifndef __COUCHDB_GLIB_H__
23#define __COUCHDB_GLIB_H__25#define __COUCHDB_GLIB_H__
2426
25#include <couchdb-types.h>27#include <couchdb-types.h>
2628#include <couchdb.h>
27#define COUCHDB_TYPE (couchdb_get_type ())29#include <couchdb-database-info.h>
28#define COUCHDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE, CouchDB))30#include <couchdb-document.h>
29#define COUCHDB_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE))31#include <couchdb-document-contact.h>
30#define COUCHDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE, CouchDBClass))32#include <couchdb-document-info.h>
31#define COUCHDB_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE))33#include <couchdb-struct-field.h>
32#define COUCHDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE, CouchDBClass))34
3335#endif /* __COUCHDB_GLIB_H__ */
34typedef struct _CouchDBDocument CouchDBDocument;36
3537
36typedef struct _CouchDB CouchDB;
37typedef struct {
38 GObjectClass parent_class;
39
40 void (* database_created) (CouchDB *couchdb, const char *dbname);
41 void (* database_deleted) (CouchDB *couchdb, const char *dbname);
42
43 void (* document_created) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
44 void (* document_updated) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
45 void (* document_deleted) (CouchDB *couchdb, const char *dbname, const char *docid);
46} CouchDBClass;
47
48GType couchdb_get_type (void);
49CouchDB *couchdb_new (const char *hostname);
50
51const char *couchdb_get_hostname (CouchDB *couchdb);
52
53/*
54 * Databases API
55 */
56
57GSList *couchdb_list_databases (CouchDB *couchdb, GError **error);
58void couchdb_free_database_list (GSList *dblist);
59
60CouchDBDatabaseInfo *couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error);
61
62gboolean couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error);
63gboolean couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error);
64
65void couchdb_listen_for_changes (CouchDB *couchdb, const char *dbname);
66
67gboolean couchdb_enable_oauth (CouchDB *couchdb,
68 const char *consumer_key,
69 const char *consumer_secret,
70 const char *token_key,
71 const char *token_secret);
72void couchdb_disable_oauth (CouchDB *couchdb);
73
74/*
75 * Documents API
76 */
77
78#define COUCHDB_TYPE_DOCUMENT (couchdb_document_get_type ())
79#define COUCHDB_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocument))
80#define COUCHDB_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE_DOCUMENT))
81#define COUCHDB_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
82#define COUCHDB_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE_DOCUMENT))
83#define COUCHDB_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE_DOCUMENT, CouchDBDocumentClass))
84
85typedef struct {
86 GObjectClass parent_class;
87} CouchDBDocumentClass;
88
89GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error);
90void couchdb_free_document_list (GSList *doclist);
91
92GType couchdb_document_get_type (void);
93CouchDBDocument *couchdb_document_new (CouchDB *couchdb);
94CouchDBDocument *couchdb_document_get (CouchDB *couchdb,
95 const char *dbname,
96 const char *docid,
97 GError **error);
98gboolean couchdb_document_put (CouchDBDocument *document,
99 const char *dbname,
100 GError **error);
101gboolean couchdb_document_delete (CouchDBDocument *document, GError **error);
102
103const char *couchdb_document_get_id (CouchDBDocument *document);
104void couchdb_document_set_id (CouchDBDocument *document, const char *id);
105const char *couchdb_document_get_revision (CouchDBDocument *document);
106void couchdb_document_set_revision (CouchDBDocument *document, const char *revision);
107const char *couchdb_document_get_record_type (CouchDBDocument *document);
108void couchdb_document_set_record_type (CouchDBDocument *document, const char *record_type);
109
110gboolean couchdb_document_has_field (CouchDBDocument *document, const char *field);
111void couchdb_document_remove_field (CouchDBDocument *document, const char *field);
112
113gboolean couchdb_document_get_boolean_field (CouchDBDocument *document, const char *field);
114void couchdb_document_set_boolean_field (CouchDBDocument *document, const char *field, gboolean value);
115gint couchdb_document_get_int_field (CouchDBDocument *document, const char *field);
116void couchdb_document_set_int_field (CouchDBDocument *document, const char *field, gint value);
117gdouble couchdb_document_get_double_field (CouchDBDocument *document, const char *field);
118void couchdb_document_set_double_field (CouchDBDocument *document, const char *field, gdouble value);
119const char *couchdb_document_get_string_field (CouchDBDocument *document, const char *field);
120void couchdb_document_set_string_field (CouchDBDocument *document, const char *field, const char *value);
121CouchDBStructField *couchdb_document_get_struct_field (CouchDBDocument *document, const char *field);
122void couchdb_document_set_struct_field (CouchDBDocument *document,
123 const char *field,
124 CouchDBStructField *value);
125
126CouchDBStructField *couchdb_document_get_application_annotations (CouchDBDocument *document);
127void couchdb_document_set_application_annotations (CouchDBDocument *document, CouchDBStructField *annotations);
128
129char *couchdb_document_to_string (CouchDBDocument *document);
130
131
132#endif
13338
=== added file 'couchdb-glib/couchdb-struct-field.c'
--- couchdb-glib/couchdb-struct-field.c 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-struct-field.c 2009-10-06 18:10:22 +0000
@@ -0,0 +1,291 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "couchdb-struct-field.h"
25
26struct _CouchDBStructField {
27 gint ref_count;
28 JsonObject *json_object;
29
30 /* Extra data needed for some specific StructField's */
31 char *uuid; /* the UUID of this item */
32};
33
34GType
35couchdb_struct_field_get_type (void)
36{
37 static GType object_type = 0;
38
39 if (G_UNLIKELY (!object_type))
40 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBStructField"),
41 (GBoxedCopyFunc) couchdb_struct_field_ref,
42 (GBoxedFreeFunc) couchdb_struct_field_unref);
43
44 return object_type;
45}
46
47CouchDBStructField *
48couchdb_struct_field_new (void)
49{
50 CouchDBStructField *sf;
51
52 sf = g_slice_new (CouchDBStructField);
53 sf->ref_count = 1;
54 sf->json_object = json_object_new ();
55 sf->uuid = NULL;
56
57 return sf;
58}
59
60CouchDBStructField *
61couchdb_struct_field_new_from_string (const char *str)
62{
63 JsonParser *parser;
64 GError *error = NULL;
65 CouchDBStructField *sf = NULL;
66
67 g_return_val_if_fail (str != NULL, NULL);
68
69 parser = json_parser_new ();
70 if (json_parser_load_from_data (parser, str, strlen (str), &error)) {
71 JsonNode *node = json_parser_get_root (parser);
72
73 if (json_node_get_node_type (node) == JSON_NODE_OBJECT)
74 sf = couchdb_struct_field_new_from_json_object (json_node_get_object (node));
75 } else {
76 g_warning ("Could not parse string: %s", error->message);
77 g_error_free (error);
78 }
79
80 g_object_unref (G_OBJECT (parser));
81
82 return sf;
83}
84
85CouchDBStructField *
86couchdb_struct_field_new_from_json_object (JsonObject *json_object)
87{
88 CouchDBStructField *sf;
89
90 sf = g_slice_new (CouchDBStructField);
91 sf->ref_count = 1;
92 sf->json_object = json_object_ref (json_object);
93 sf->uuid = NULL;
94
95 return sf;
96}
97
98CouchDBStructField *
99couchdb_struct_field_ref (CouchDBStructField *sf)
100{
101 g_return_val_if_fail (sf != NULL, NULL);
102 g_return_val_if_fail (sf->ref_count > 0, NULL);
103
104 g_atomic_int_exchange_and_add (&sf->ref_count, 1);
105
106 return sf;
107}
108
109void
110couchdb_struct_field_unref (CouchDBStructField *sf)
111{
112 gint old_ref;
113
114 g_return_if_fail (sf != NULL);
115 g_return_if_fail (sf->ref_count > 0);
116
117 old_ref = g_atomic_int_get (&sf->ref_count);
118 if (old_ref > 1)
119 g_atomic_int_compare_and_exchange (&sf->ref_count, old_ref, old_ref - 1);
120 else {
121 json_object_unref (sf->json_object);
122 g_slice_free (CouchDBStructField, sf);
123 }
124}
125
126gboolean
127couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field)
128{
129 g_return_val_if_fail (sf != NULL, FALSE);
130 g_return_val_if_fail (field != NULL, FALSE);
131
132 return json_object_has_member (sf->json_object, field);
133}
134
135void
136couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field)
137{
138 g_return_if_fail (sf != NULL);
139 g_return_if_fail (field != NULL);
140
141 json_object_remove_member (sf->json_object, field);
142}
143
144gboolean
145couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field)
146{
147 g_return_val_if_fail (sf != NULL, 0);
148 g_return_val_if_fail (field != NULL, 0);
149
150 return json_object_get_boolean_member (sf->json_object, field);
151}
152
153void
154couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value)
155{
156 g_return_if_fail (sf != NULL);
157 g_return_if_fail (field != NULL);
158
159 json_object_set_boolean_member (sf->json_object, field, value);
160}
161
162gdouble
163couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field)
164{
165 g_return_val_if_fail (sf != NULL, 0);
166 g_return_val_if_fail (field != NULL, 0);
167
168 return json_object_get_double_member (sf->json_object, field);
169}
170
171void
172couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value)
173{
174 g_return_if_fail (sf != NULL);
175 g_return_if_fail (field != NULL);
176
177 json_object_set_double_member (sf->json_object, field, value);
178}
179
180gint
181couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field)
182{
183 g_return_val_if_fail (sf != NULL, 0);
184 g_return_val_if_fail (field != NULL, 0);
185
186 return json_object_get_int_member (sf->json_object, field);
187}
188
189void
190couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value)
191{
192 g_return_if_fail (sf != NULL);
193 g_return_if_fail (field != NULL);
194
195 json_object_set_int_member (sf->json_object, field, value);
196}
197
198const char *
199couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field)
200{
201 g_return_val_if_fail (sf != NULL, NULL);
202 g_return_val_if_fail (field != NULL, NULL);
203
204 return json_object_get_string_member (sf->json_object, field);
205}
206
207void
208couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value)
209{
210 g_return_if_fail (sf != NULL);
211 g_return_if_fail (field != NULL);
212
213 if (value)
214 json_object_set_string_member (sf->json_object, field, value);
215 else {
216 /* Remove the field if the value is NULL */
217 couchdb_struct_field_remove_field (sf, field);
218 }
219}
220
221CouchDBStructField *
222couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field)
223{
224 g_return_val_if_fail (sf != NULL, NULL);
225 g_return_val_if_fail (field != NULL, NULL);
226
227 return couchdb_struct_field_new_from_json_object (
228 json_object_get_object_member (sf->json_object, field));
229}
230
231void
232couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value)
233{
234 g_return_if_fail (sf != NULL);
235 g_return_if_fail (field != NULL);
236 g_return_if_fail (value != NULL);
237
238 json_object_set_object_member (sf->json_object, field, json_object_ref (value->json_object));
239}
240
241const char *
242couchdb_struct_field_get_uuid (CouchDBStructField *sf)
243{
244 g_return_val_if_fail (sf != NULL, NULL);
245
246 return (const char *) sf->uuid;
247}
248
249void
250couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid)
251{
252 g_return_if_fail (sf != NULL);
253
254 if (sf->uuid)
255 g_free (sf->uuid);
256
257 sf->uuid = g_strdup (uuid);
258}
259
260char *
261couchdb_struct_field_to_string (CouchDBStructField *sf)
262{
263 JsonNode *node;
264 JsonGenerator *generator;
265 gsize size;
266 char *str = NULL;
267
268 g_return_val_if_fail (sf != NULL, NULL);
269
270 node = json_node_new (JSON_NODE_OBJECT);
271 json_node_set_object (node, sf->json_object);
272
273 generator = json_generator_new ();
274 json_generator_set_root (generator, node);
275
276 str = json_generator_to_data (generator, &size);
277 g_object_unref (G_OBJECT (generator));
278
279 json_node_free (node);
280
281 return str;
282}
283
284JsonObject *
285couchdb_struct_field_get_json_object (CouchDBStructField *sf)
286{
287 g_return_val_if_fail (sf != NULL, NULL);
288
289 return sf->json_object;
290}
291
0292
=== added file 'couchdb-glib/couchdb-struct-field.h'
--- couchdb-glib/couchdb-struct-field.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-struct-field.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,68 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_STRUCT_FIELD_H__
25#define __COUCHDB_STRUCT_FIELD_H__
26
27#include <glib.h>
28#include <glib-object.h>
29#include <json-glib/json-glib.h>
30#include "couchdb.h"
31#include "couchdb-types.h"
32
33G_BEGIN_DECLS
34
35#define COUCHDB_TYPE_STRUCT_FIELD (couchdb_struct_field_get_type ())
36
37GType couchdb_struct_field_get_type (void);
38CouchDBStructField *couchdb_struct_field_new (void);
39CouchDBStructField *couchdb_struct_field_new_from_string (const char *str);
40CouchDBStructField *couchdb_struct_field_ref (CouchDBStructField *sf);
41void couchdb_struct_field_unref (CouchDBStructField *sf);
42
43gboolean couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field);
44void couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field);
45
46gboolean couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field);
47void couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value);
48gdouble couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field);
49void couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value);
50gint couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field);
51void couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value);
52const char *couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field);
53void couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value);
54CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
55void couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value);
56
57const char *couchdb_struct_field_get_uuid (CouchDBStructField *sf);
58void couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid);
59
60char *couchdb_struct_field_to_string (CouchDBStructField *sf);
61
62CouchDBStructField *couchdb_struct_field_new_from_json_object (JsonObject *json_object);
63
64JsonObject *couchdb_struct_field_get_json_object (CouchDBStructField *sf);
65
66G_END_DECLS
67
68#endif /* __COUCHDB_STRUCT_FIELD__ */
069
=== removed file 'couchdb-glib/couchdb-types.c'
--- couchdb-glib/couchdb-types.c 2009-08-19 16:43:24 +0000
+++ couchdb-glib/couchdb-types.c 1970-01-01 00:00:00 +0000
@@ -1,466 +0,0 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 *
5 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#include "couchdb-glib.h"
23#include "utils.h"
24
25/*
26 * CouchDBDatabaseInfo object
27 */
28
29GType
30couchdb_database_info_get_type (void)
31{
32 static GType object_type = 0;
33
34 if (G_UNLIKELY (!object_type))
35 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDatabaseInfo"),
36 (GBoxedCopyFunc) couchdb_database_info_ref,
37 (GBoxedFreeFunc) couchdb_database_info_unref);
38
39 return object_type;
40}
41
42CouchDBDatabaseInfo *
43couchdb_database_info_new (const char *dbname,
44 gint doc_count,
45 gint doc_del_count,
46 gint update_seq,
47 gboolean compact_running,
48 gint disk_size)
49{
50 CouchDBDatabaseInfo *dbinfo;
51
52 dbinfo = g_slice_new (CouchDBDatabaseInfo);
53 dbinfo->ref_count = 1;
54 dbinfo->dbname = g_strdup (dbname);
55 dbinfo->doc_count = doc_count;
56 dbinfo->doc_del_count = doc_del_count;
57 dbinfo->update_seq = update_seq;
58 dbinfo->compact_running = compact_running;
59 dbinfo->disk_size = disk_size;
60
61 return dbinfo;
62}
63
64CouchDBDatabaseInfo *
65couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo)
66{
67 g_return_val_if_fail (dbinfo != NULL, NULL);
68 g_return_val_if_fail (dbinfo->ref_count > 0, NULL);
69
70 g_atomic_int_exchange_and_add (&dbinfo->ref_count, 1);
71
72 return dbinfo;
73}
74
75void
76couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo)
77{
78 gint old_ref;
79
80 g_return_if_fail (dbinfo != NULL);
81 g_return_if_fail (dbinfo->ref_count > 0);
82
83 old_ref = g_atomic_int_get (&dbinfo->ref_count);
84 if (old_ref > 1)
85 g_atomic_int_compare_and_exchange (&dbinfo->ref_count, old_ref, old_ref - 1);
86 else {
87 g_free (dbinfo->dbname);
88 g_slice_free (CouchDBDatabaseInfo, dbinfo);
89 }
90}
91
92const char *
93couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo)
94{
95 g_return_val_if_fail (dbinfo != NULL, NULL);
96
97 return (const char *) dbinfo->dbname;
98}
99
100gint
101couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo)
102{
103 g_return_val_if_fail (dbinfo != NULL, 0);
104
105 return dbinfo->doc_count;
106}
107
108gint
109couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo)
110{
111 g_return_val_if_fail (dbinfo != NULL, 0);
112
113 return dbinfo->doc_del_count;
114}
115
116gint
117couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo)
118{
119 g_return_val_if_fail (dbinfo != NULL, 0);
120
121 return dbinfo->update_seq;
122}
123
124gboolean
125couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo)
126{
127 g_return_val_if_fail (dbinfo != NULL, FALSE);
128
129 return dbinfo->compact_running;
130}
131
132gint
133couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo)
134{
135 g_return_val_if_fail (dbinfo != NULL, 0);
136
137 return dbinfo->disk_size;
138}
139
140/*
141 * CouchDBDocumentInfo object
142 */
143
144GType
145couchdb_document_info_get_type (void)
146{
147 static GType object_type = 0;
148
149 if (G_UNLIKELY (!object_type))
150 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBDocumentInfo"),
151 (GBoxedCopyFunc) couchdb_document_info_ref,
152 (GBoxedFreeFunc) couchdb_document_info_unref);
153
154 return object_type;
155}
156
157CouchDBDocumentInfo *
158couchdb_document_info_new (const char *docid, const char *revision)
159{
160 CouchDBDocumentInfo *doc_info;
161
162 doc_info = g_slice_new (CouchDBDocumentInfo);
163 doc_info->ref_count = 1;
164 doc_info->docid = g_strdup (docid);
165 doc_info->revision = g_strdup (revision);
166
167 return doc_info;
168}
169
170CouchDBDocumentInfo *
171couchdb_document_info_ref (CouchDBDocumentInfo *doc_info)
172{
173 g_return_val_if_fail (doc_info != NULL, NULL);
174 g_return_val_if_fail (doc_info->ref_count > 0, NULL);
175
176 g_atomic_int_exchange_and_add (&doc_info->ref_count, 1);
177
178 return doc_info;
179}
180
181void
182couchdb_document_info_unref (CouchDBDocumentInfo *doc_info)
183{
184 gint old_ref;
185
186 g_return_if_fail (doc_info != NULL);
187 g_return_if_fail (doc_info->ref_count > 0);
188
189 old_ref = g_atomic_int_get (&doc_info->ref_count);
190 if (old_ref > 1)
191 g_atomic_int_compare_and_exchange (&doc_info->ref_count, old_ref, old_ref - 1);
192 else {
193 g_free (doc_info->docid);
194 g_free (doc_info->revision);
195 g_slice_free (CouchDBDocumentInfo, doc_info);
196 }
197}
198
199const char *
200couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info)
201{
202 g_return_val_if_fail (doc_info != NULL, NULL);
203
204 return (const char *) doc_info->docid;
205}
206
207const char *
208couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info)
209{
210 g_return_val_if_fail (doc_info != NULL, NULL);
211
212 return (const char *) doc_info->revision;
213}
214
215/*
216 * CouchDBStructField
217 */
218GType
219couchdb_struct_field_get_type (void)
220{
221 static GType object_type = 0;
222
223 if (G_UNLIKELY (!object_type))
224 object_type = g_boxed_type_register_static (g_intern_static_string ("CouchDBStructField"),
225 (GBoxedCopyFunc) couchdb_struct_field_ref,
226 (GBoxedFreeFunc) couchdb_struct_field_unref);
227
228 return object_type;
229}
230
231CouchDBStructField *
232couchdb_struct_field_new (void)
233{
234 CouchDBStructField *sf;
235
236 sf = g_slice_new (CouchDBStructField);
237 sf->ref_count = 1;
238 sf->json_object = json_object_new ();
239 sf->uuid = NULL;
240
241 return sf;
242}
243
244CouchDBStructField *
245couchdb_struct_field_new_from_string (const char *str)
246{
247 JsonParser *parser;
248 GError *error = NULL;
249 CouchDBStructField *sf = NULL;
250
251 g_return_val_if_fail (str != NULL, NULL);
252
253 parser = json_parser_new ();
254 if (json_parser_load_from_data (parser, str, strlen (str), &error)) {
255 JsonNode *node = json_parser_get_root (parser);
256
257 if (json_node_get_node_type (node) == JSON_NODE_OBJECT)
258 sf = couchdb_struct_field_new_from_json_object (json_node_get_object (node));
259 } else {
260 g_warning ("Could not parse string: %s", error->message);
261 g_error_free (error);
262 }
263
264 g_object_unref (G_OBJECT (parser));
265
266 return sf;
267}
268
269CouchDBStructField *
270couchdb_struct_field_new_from_json_object (JsonObject *json_object)
271{
272 CouchDBStructField *sf;
273
274 sf = g_slice_new (CouchDBStructField);
275 sf->ref_count = 1;
276 sf->json_object = json_object_ref (json_object);
277 sf->uuid = NULL;
278
279 return sf;
280}
281
282CouchDBStructField *
283couchdb_struct_field_ref (CouchDBStructField *sf)
284{
285 g_return_val_if_fail (sf != NULL, NULL);
286 g_return_val_if_fail (sf->ref_count > 0, NULL);
287
288 g_atomic_int_exchange_and_add (&sf->ref_count, 1);
289
290 return sf;
291}
292
293void
294couchdb_struct_field_unref (CouchDBStructField *sf)
295{
296 gint old_ref;
297
298 g_return_if_fail (sf != NULL);
299 g_return_if_fail (sf->ref_count > 0);
300
301 old_ref = g_atomic_int_get (&sf->ref_count);
302 if (old_ref > 1)
303 g_atomic_int_compare_and_exchange (&sf->ref_count, old_ref, old_ref - 1);
304 else {
305 json_object_unref (sf->json_object);
306 g_slice_free (CouchDBStructField, sf);
307 }
308}
309
310gboolean
311couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field)
312{
313 g_return_val_if_fail (sf != NULL, FALSE);
314 g_return_val_if_fail (field != NULL, FALSE);
315
316 return json_object_has_member (sf->json_object, field);
317}
318
319void
320couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field)
321{
322 g_return_if_fail (sf != NULL);
323 g_return_if_fail (field != NULL);
324
325 json_object_remove_member (sf->json_object, field);
326}
327
328gboolean
329couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field)
330{
331 g_return_val_if_fail (sf != NULL, 0);
332 g_return_val_if_fail (field != NULL, 0);
333
334 return json_object_get_boolean_member (sf->json_object, field);
335}
336
337void
338couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value)
339{
340 g_return_if_fail (sf != NULL);
341 g_return_if_fail (field != NULL);
342
343 json_object_set_boolean_member (sf->json_object, field, value);
344}
345
346gdouble
347couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field)
348{
349 g_return_val_if_fail (sf != NULL, 0);
350 g_return_val_if_fail (field != NULL, 0);
351
352 return json_object_get_double_member (sf->json_object, field);
353}
354
355void
356couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value)
357{
358 g_return_if_fail (sf != NULL);
359 g_return_if_fail (field != NULL);
360
361 json_object_set_double_member (sf->json_object, field, value);
362}
363
364gint
365couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field)
366{
367 g_return_val_if_fail (sf != NULL, 0);
368 g_return_val_if_fail (field != NULL, 0);
369
370 return json_object_get_int_member (sf->json_object, field);
371}
372
373void
374couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value)
375{
376 g_return_if_fail (sf != NULL);
377 g_return_if_fail (field != NULL);
378
379 json_object_set_int_member (sf->json_object, field, value);
380}
381
382const char *
383couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field)
384{
385 g_return_val_if_fail (sf != NULL, NULL);
386 g_return_val_if_fail (field != NULL, NULL);
387
388 return json_object_get_string_member (sf->json_object, field);
389}
390
391void
392couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value)
393{
394 g_return_if_fail (sf != NULL);
395 g_return_if_fail (field != NULL);
396
397 if (value)
398 json_object_set_string_member (sf->json_object, field, value);
399 else {
400 /* Remove the field if the value is NULL */
401 couchdb_struct_field_remove_field (sf, field);
402 }
403}
404
405CouchDBStructField *
406couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field)
407{
408 g_return_val_if_fail (sf != NULL, NULL);
409 g_return_val_if_fail (field != NULL, NULL);
410
411 return couchdb_struct_field_new_from_json_object (
412 json_object_get_object_member (sf->json_object, field));
413}
414
415void
416couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value)
417{
418 g_return_if_fail (sf != NULL);
419 g_return_if_fail (field != NULL);
420 g_return_if_fail (value != NULL);
421
422 json_object_set_object_member (sf->json_object, field, json_object_ref (value->json_object));
423}
424
425const char *
426couchdb_struct_field_get_uuid (CouchDBStructField *sf)
427{
428 g_return_val_if_fail (sf != NULL, NULL);
429
430 return (const char *) sf->uuid;
431}
432
433void
434couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid)
435{
436 g_return_if_fail (sf != NULL);
437
438 if (sf->uuid)
439 g_free (sf->uuid);
440
441 sf->uuid = g_strdup (uuid);
442}
443
444char *
445couchdb_struct_field_to_string (CouchDBStructField *sf)
446{
447 JsonNode *node;
448 JsonGenerator *generator;
449 gsize size;
450 char *str = NULL;
451
452 g_return_val_if_fail (sf != NULL, NULL);
453
454 node = json_node_new (JSON_NODE_OBJECT);
455 json_node_set_object (node, sf->json_object);
456
457 generator = json_generator_new ();
458 json_generator_set_root (generator, node);
459
460 str = json_generator_to_data (generator, &size);
461 g_object_unref (G_OBJECT (generator));
462
463 json_node_free (node);
464
465 return str;
466}
4670
=== added file 'couchdb-glib/couchdb-types.h'
--- couchdb-glib/couchdb-types.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb-types.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,39 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_TYPES_H__
25#define __COUCHDB_TYPES_H__
26
27#include <glib.h>
28
29G_BEGIN_DECLS
30
31typedef struct _CouchDBDocument CouchDBDocument;
32typedef struct _CouchDB CouchDB;
33typedef struct _CouchDBDatabaseInfo CouchDBDatabaseInfo;
34typedef struct _CouchDBDocumentInfo CouchDBDocumentInfo;
35typedef struct _CouchDBStructField CouchDBStructField;
36
37G_END_DECLS
38
39#endif /* __COUCHDB_TYPES_H__ */
040
=== removed file 'couchdb-glib/couchdb-types.h'
--- couchdb-glib/couchdb-types.h 2009-08-19 16:43:24 +0000
+++ couchdb-glib/couchdb-types.h 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 *
5 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#ifndef __COUCHDB_TYPES_H__
23#define __COUCHDB_TYPES_H__
24
25#include <glib-object.h>
26
27#define COUCHDB_TYPE_DATABASE_INFO (couchdb_database_info_get_type ())
28#define COUCHDB_TYPE_DOCUMENT_INFO (couchdb_document_info_get_type ())
29#define COUCHDB_TYPE_STRUCT_FIELD (couchdb_struct_field_get_type ())
30
31/*
32 * CouchDBDatabaseInfo
33 */
34typedef struct _CouchDBDatabaseInfo CouchDBDatabaseInfo;
35
36GType couchdb_database_info_get_type (void);
37CouchDBDatabaseInfo *couchdb_database_info_ref (CouchDBDatabaseInfo *dbinfo);
38void couchdb_database_info_unref (CouchDBDatabaseInfo *dbinfo);
39
40const char *couchdb_database_info_get_dbname (CouchDBDatabaseInfo *dbinfo);
41gint couchdb_database_info_get_documents_count (CouchDBDatabaseInfo *dbinfo);
42gint couchdb_database_info_get_deleted_documents_count (CouchDBDatabaseInfo *dbinfo);
43gint couchdb_database_info_get_update_sequence (CouchDBDatabaseInfo *dbinfo);
44gboolean couchdb_database_info_is_compact_running (CouchDBDatabaseInfo *dbinfo);
45gint couchdb_database_info_get_disk_size (CouchDBDatabaseInfo *dbinfo);
46
47/*
48 * CouchDBDocumentInfo
49 */
50typedef struct _CouchDBDocumentInfo CouchDBDocumentInfo;
51
52GType couchdb_document_info_get_type (void);
53CouchDBDocumentInfo *couchdb_document_info_ref (CouchDBDocumentInfo *doc_info);
54void couchdb_document_info_unref (CouchDBDocumentInfo *doc_info);
55
56const char *couchdb_document_info_get_docid (CouchDBDocumentInfo *doc_info);
57const char *couchdb_document_info_get_revision (CouchDBDocumentInfo *doc_info);
58
59/*
60 * CouchDBStructField
61 */
62typedef struct _CouchDBStructField CouchDBStructField;
63
64GType couchdb_struct_field_get_type (void);
65CouchDBStructField *couchdb_struct_field_new (void);
66CouchDBStructField *couchdb_struct_field_new_from_string (const char *str);
67CouchDBStructField *couchdb_struct_field_ref (CouchDBStructField *sf);
68void couchdb_struct_field_unref (CouchDBStructField *sf);
69
70gboolean couchdb_struct_field_has_field (CouchDBStructField *sf, const char *field);
71void couchdb_struct_field_remove_field (CouchDBStructField *sf, const char *field);
72
73gboolean couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field);
74void couchdb_struct_field_set_boolean_field (CouchDBStructField *sf, const char *field, gboolean value);
75gdouble couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field);
76void couchdb_struct_field_set_double_field (CouchDBStructField *sf, const char *field, gdouble value);
77gint couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field);
78void couchdb_struct_field_set_int_field (CouchDBStructField *sf, const char *field, gint value);
79const char *couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field);
80void couchdb_struct_field_set_string_field (CouchDBStructField *sf, const char *field, const char *value);
81CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
82void couchdb_struct_field_set_struct_field (CouchDBStructField *sf, const char *field, CouchDBStructField *value);
83
84const char *couchdb_struct_field_get_uuid (CouchDBStructField *sf);
85void couchdb_struct_field_set_uuid (CouchDBStructField *sf, const char *uuid);
86
87char *couchdb_struct_field_to_string (CouchDBStructField *sf);
88
89#endif
900
=== modified file 'couchdb-glib/couchdb.c'
--- couchdb-glib/couchdb.c 2009-09-21 22:34:56 +0000
+++ couchdb-glib/couchdb.c 2009-10-06 18:10:22 +0000
@@ -1,8 +1,10 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
4 *5 *
5 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
6 *8 *
7 * This library is free software; you can redistribute it and/or9 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public10 * modify it under the terms of version 2 of the GNU Lesser General Public
@@ -21,11 +23,32 @@
2123
22#include <libsoup/soup-logger.h>24#include <libsoup/soup-logger.h>
23#include <libsoup/soup-gnome.h>25#include <libsoup/soup-gnome.h>
24#include <json-glib/json-glib.h>26#include <libsoup/soup-message.h>
25#include "couchdb-glib.h"27#include "couchdb.h"
28#include "couchdb-document-info.h"
26#include "couchdb-marshal.h"29#include "couchdb-marshal.h"
27#include "dbwatch.h"30#include "dbwatch.h"
28#include "utils.h"31#include "utils.h"
32#include <string.h>
33#ifdef HAVE_OAUTH
34#include <time.h>
35#include "oauth.h"
36#endif
37
38struct _CouchDB {
39 GObject parent;
40
41 char *hostname;
42 SoupSession *http_session;
43
44 GHashTable *db_watchlist;
45
46 gboolean oauth_enabled;
47 char *oauth_consumer_key;
48 char *oauth_consumer_secret;
49 char *oauth_token_key;
50 char *oauth_token_secret;
51};
2952
30G_DEFINE_TYPE(CouchDB, couchdb, G_TYPE_OBJECT)53G_DEFINE_TYPE(CouchDB, couchdb, G_TYPE_OBJECT)
3154
@@ -49,12 +72,14 @@
49 g_free (couchdb->hostname);72 g_free (couchdb->hostname);
50 g_object_unref (couchdb->http_session);73 g_object_unref (couchdb->http_session);
5174
52#ifdef HAVE_OAUTH75 if (couchdb->oauth_consumer_key)
53 g_free (couchdb->oauth_consumer_key);76 g_free (couchdb->oauth_consumer_key);
54 g_free (couchdb->oauth_consumer_secret);77 if (couchdb->oauth_consumer_secret)
55 g_free (couchdb->oauth_token_key);78 g_free (couchdb->oauth_consumer_secret);
56 g_free (couchdb->oauth_token_secret);79 if (couchdb->oauth_token_key)
57#endif80 g_free (couchdb->oauth_token_key);
81 if (couchdb->oauth_token_secret)
82 g_free (couchdb->oauth_token_secret);
5883
59 G_OBJECT_CLASS (couchdb_parent_class)->finalize (object);84 G_OBJECT_CLASS (couchdb_parent_class)->finalize (object);
60}85}
@@ -135,6 +160,13 @@
135 couchdb->http_session = soup_session_sync_new_with_options (160 couchdb->http_session = soup_session_sync_new_with_options (
136 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,161 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
137 NULL);162 NULL);
163
164 couchdb->oauth_consumer_key = NULL;
165 couchdb->oauth_consumer_secret = NULL;
166 couchdb->oauth_token_key = NULL;
167 couchdb->oauth_token_secret = NULL;
168 couchdb->oauth_enabled = FALSE;
169
138 soup_session_add_feature_by_type (couchdb->http_session, SOUP_TYPE_LOGGER);170 soup_session_add_feature_by_type (couchdb->http_session, SOUP_TYPE_LOGGER);
139171
140 return couchdb;172 return couchdb;
@@ -159,8 +191,8 @@
159191
160 /* Prepare request */192 /* Prepare request */
161 url = g_strdup_printf ("%s/_all_dbs", couchdb->hostname);193 url = g_strdup_printf ("%s/_all_dbs", couchdb->hostname);
162 parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);194 parser = json_parser_new ();
163 if (parser) {195 if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
164 JsonNode *root_node;196 JsonNode *root_node;
165197
166 root_node = json_parser_get_root (parser);198 root_node = json_parser_get_root (parser);
@@ -173,10 +205,9 @@
173 dblist,205 dblist,
174 g_strdup (json_node_get_string ((JsonNode *) sl->data)));206 g_strdup (json_node_get_string ((JsonNode *) sl->data)));
175 }207 }
176 }208 }
177
178 g_object_unref (G_OBJECT (parser));
179 }209 }
210 g_object_unref (G_OBJECT (parser));
180211
181 /* Free memory */212 /* Free memory */
182 g_free (url);213 g_free (url);
@@ -195,8 +226,8 @@
195 g_return_val_if_fail (dbname != NULL, NULL);226 g_return_val_if_fail (dbname != NULL, NULL);
196227
197 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);228 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
198 parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);229 parser = json_parser_new ();
199 if (parser) {230 if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
200 JsonNode *root_node;231 JsonNode *root_node;
201232
202 root_node = json_parser_get_root (parser);233 root_node = json_parser_get_root (parser);
@@ -210,9 +241,8 @@
210 json_object_get_boolean_member (object, "compact_running"),241 json_object_get_boolean_member (object, "compact_running"),
211 json_object_get_int_member (object, "disk_size"));242 json_object_get_int_member (object, "disk_size"));
212 }243 }
213
214 g_object_unref (G_OBJECT (parser));
215 }244 }
245 g_object_unref (G_OBJECT (parser));
216246
217 return result;247 return result;
218}248}
@@ -228,18 +258,17 @@
228 g_return_val_if_fail (dbname != NULL, FALSE);258 g_return_val_if_fail (dbname != NULL, FALSE);
229259
230 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);260 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
231 parser = send_message_and_parse (couchdb, SOUP_METHOD_PUT, url, NULL, error);261 parser = json_parser_new ();
232 if (parser) {262 if (couchdb_send_message (couchdb, SOUP_METHOD_PUT, url, NULL, parser, error)) {
233 JsonNode *root_node;263 JsonNode *root_node;
234264
235 root_node = json_parser_get_root (parser);265 root_node = json_parser_get_root (parser);
236 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)266 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
237 result = json_object_get_boolean_member (267 result = json_object_get_boolean_member (
238 json_node_get_object (root_node), "ok");268 json_node_get_object (root_node), "ok");
239
240 g_object_unref (G_OBJECT (parser));
241 }269 }
242270
271 g_object_unref (G_OBJECT (parser));
243 g_free (url);272 g_free (url);
244273
245 if (result)274 if (result)
@@ -259,17 +288,16 @@
259 g_return_val_if_fail (dbname != NULL, FALSE);288 g_return_val_if_fail (dbname != NULL, FALSE);
260289
261 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);290 url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
262 parser = send_message_and_parse (couchdb, SOUP_METHOD_DELETE, url, NULL, error);291 parser = json_parser_new ();
263 if (parser) {292 if (couchdb_send_message (couchdb, SOUP_METHOD_DELETE, url, NULL, parser, error)) {
264 JsonNode *root_node;293 JsonNode *root_node;
265294
266 root_node = json_parser_get_root (parser);295 root_node = json_parser_get_root (parser);
267 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)296 if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
268 result = json_object_get_boolean_member (297 result = json_object_get_boolean_member (
269 json_node_get_object (root_node), "ok");298 json_node_get_object (root_node), "ok");
270
271 g_object_unref (G_OBJECT (parser));
272 }299 }
300 g_object_unref (G_OBJECT (parser));
273301
274 g_free (url);302 g_free (url);
275303
@@ -304,8 +332,8 @@
304 g_return_val_if_fail (dbname != NULL, NULL);332 g_return_val_if_fail (dbname != NULL, NULL);
305333
306 url = g_strdup_printf ("%s/%s/_all_docs", couchdb->hostname, dbname);334 url = g_strdup_printf ("%s/%s/_all_docs", couchdb->hostname, dbname);
307 parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);335 parser = json_parser_new ();
308 if (parser) {336 if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
309 JsonNode *root_node;337 JsonNode *root_node;
310338
311 root_node = json_parser_get_root (parser);339 root_node = json_parser_get_root (parser);
@@ -332,7 +360,7 @@
332 }360 }
333 }361 }
334 }362 }
335363 g_object_unref (G_OBJECT (parser));
336 g_free (url);364 g_free (url);
337365
338 return doclist;366 return doclist;
@@ -423,3 +451,158 @@
423 return FALSE;451 return FALSE;
424#endif452#endif
425}453}
454
455gboolean
456couchdb_is_oauth_enabled (CouchDB *couchdb)
457{
458 g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
459
460 return couchdb->oauth_enabled;
461}
462
463
464static void
465couchdb_add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
466{
467 /* This method is a no-op if we are configured without OAUTH */
468#ifdef HAVE_OAUTH
469 char *signed_url;
470
471 signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
472 couchdb->oauth_consumer_key,
473 couchdb->oauth_consumer_secret,
474 couchdb->oauth_token_key,
475 couchdb->oauth_token_secret);
476 if (signed_url != NULL) {
477 char **parsed_url;
478 GString *header = NULL;
479
480 /* Get the OAuth signature from the signed URL */
481 parsed_url = g_strsplit (signed_url, "?", 2);
482 if (parsed_url != NULL) {
483 gchar **params;
484 int i;
485
486 params = g_strsplit (parsed_url[1], "&", 0);
487#ifdef DEBUG_OAUTH
488 g_debug ("Parsing %s", parsed_url[1]);
489#endif
490 for (i = 0; params[i] != NULL; i++) {
491 gchar **url_param;
492
493 /* Don't include non-OAuth URL parameters in OAuth header */
494 if (!g_str_has_prefix (params[i], "oauth_"))
495 continue;
496
497#ifdef DEBUG_OAUTH
498 g_debug ("%s\n", params[i]);
499#endif
500 url_param = g_strsplit (params[i], "=", 2);
501 if (url_param == NULL)
502 continue;
503
504 if (header != NULL)
505 header = g_string_append (header, ", ");
506 else
507 header = g_string_new ("OAuth ");
508
509 header = g_string_append (header, url_param[0]);
510 header = g_string_append (header, "=\"");
511 header = g_string_append (header, url_param[1]);
512 header = g_string_append (header, "\"");
513
514 g_strfreev (url_param);
515 }
516
517 if (params)
518 g_strfreev (params);
519
520 g_strfreev (parsed_url);
521 }
522
523 if (header != NULL) {
524 soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
525
526 g_string_free (header, TRUE);
527 }
528
529 free (signed_url);
530 }
531#endif /* HAVE_OAUTH */
532}
533
534static gboolean
535parse_json_response (CouchDB *couchdb, JsonParser *json_parser, SoupMessage *http_message, GError **error)
536{
537 SoupBuffer *buffer;
538 GString *str = NULL;
539 goffset offset = 0;
540 gboolean success = TRUE;
541
542 while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
543 if (!str)
544 str = g_string_new ("");
545 g_string_append_len (str, buffer->data, buffer->length);
546
547 offset += buffer->length;
548 soup_buffer_free (buffer);
549 }
550
551 if (str && str->len > 0) {
552 g_debug ("Response body: %s", str->str);
553 if (!json_parser_load_from_data (json_parser,
554 (const gchar *) str->str,
555 str->len,
556 error)) {
557 g_object_unref (G_OBJECT (json_parser));
558 g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
559 success = FALSE;
560 }
561
562 g_string_free (str, TRUE);
563 }
564
565 return success;
566}
567
568static void
569debug_print_headers (const char *name, const char *value, gpointer user_data)
570{
571 g_print ("\t%s: %s\n", name, value);
572}
573
574gboolean
575couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error)
576{
577 SoupMessage *http_message;
578 guint status;
579
580 g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
581 g_return_val_if_fail (method != NULL, FALSE);
582 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
583
584 http_message = soup_message_new (method, url);
585 if (body != NULL) {
586 soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
587 body, strlen (body));
588 }
589
590 if (couchdb_is_oauth_enabled (couchdb))
591 couchdb_add_oauth_signature (couchdb, http_message, method, url);
592
593
594 g_debug ("Sending %s to %s... with headers\n: ", method, url);
595 soup_message_headers_foreach (http_message->request_headers,
596 (SoupMessageHeadersForeachFunc) debug_print_headers,
597 NULL);
598
599 status = soup_session_send_message (couchdb->http_session, http_message);
600 if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
601 if (parser != NULL)
602 parse_json_response (couchdb, parser, http_message, error);
603 return TRUE;
604 } else {
605 g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
606 return FALSE;
607 }
608}
426609
=== added file 'couchdb-glib/couchdb.h'
--- couchdb-glib/couchdb.h 1970-01-01 00:00:00 +0000
+++ couchdb-glib/couchdb.h 2009-10-06 18:10:22 +0000
@@ -0,0 +1,84 @@
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
4 * 2009 Mikkel Kamstrup Erlandsen
5 *
6 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
7 * Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU Lesser General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef __COUCHDB_H__
25#define __COUCHDB_H__
26
27#include <glib.h>
28#include <glib-object.h>
29#include <json-glib/json-glib.h>
30#include "couchdb-types.h"
31#include "couchdb-database-info.h"
32
33G_BEGIN_DECLS
34
35#define COUCHDB_TYPE (couchdb_get_type ())
36#define COUCHDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COUCHDB_TYPE, CouchDB))
37#define COUCHDB_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COUCHDB_TYPE))
38#define COUCHDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COUCHDB_TYPE, CouchDBClass))
39#define COUCHDB_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE))
40#define COUCHDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE, CouchDBClass))
41
42typedef struct {
43 GObjectClass parent_class;
44
45 void (* database_created) (CouchDB *couchdb, const char *dbname);
46 void (* database_deleted) (CouchDB *couchdb, const char *dbname);
47
48 void (* document_created) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
49 void (* document_updated) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document);
50 void (* document_deleted) (CouchDB *couchdb, const char *dbname, const char *docid);
51} CouchDBClass;
52
53GType couchdb_get_type (void);
54CouchDB *couchdb_new (const char *hostname);
55
56const char *couchdb_get_hostname (CouchDB *couchdb);
57
58GSList *couchdb_list_databases (CouchDB *couchdb, GError **error);
59void couchdb_free_database_list (GSList *dblist);
60
61CouchDBDatabaseInfo *couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error);
62
63gboolean couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error);
64gboolean couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error);
65
66void couchdb_listen_for_changes (CouchDB *couchdb, const char *dbname);
67
68gboolean couchdb_enable_oauth (CouchDB *couchdb,
69 const char *consumer_key,
70 const char *consumer_secret,
71 const char *token_key,
72 const char *token_secret);
73void couchdb_disable_oauth (CouchDB *couchdb);
74
75gboolean couchdb_is_oauth_enabled (CouchDB *couchdb);
76
77gboolean couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error);
78
79GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error);
80void couchdb_free_document_list (GSList *doclist);
81
82G_END_DECLS
83
84#endif /* __COUCHDB_H__ */
085
=== modified file 'couchdb-glib/dbwatch.c'
--- couchdb-glib/dbwatch.c 2009-08-31 15:48:46 +0000
+++ couchdb-glib/dbwatch.c 2009-10-06 18:10:22 +0000
@@ -19,7 +19,8 @@
19 * Boston, MA 02110-1301, USA.19 * Boston, MA 02110-1301, USA.
20 */20 */
2121
22#include "couchdb-glib.h"22#include <libsoup/soup-method.h>
23#include "couchdb-document.h"
23#include "dbwatch.h"24#include "dbwatch.h"
24#include "utils.h"25#include "utils.h"
2526
@@ -78,11 +79,11 @@
78 DBWatch *watch = (DBWatch *) user_data;79 DBWatch *watch = (DBWatch *) user_data;
7980
80 url = g_strdup_printf ("%s/%s/_changes?since=%d",81 url = g_strdup_printf ("%s/%s/_changes?since=%d",
81 watch->couchdb->hostname,82 couchdb_get_hostname (watch->couchdb),
82 watch->dbname,83 watch->dbname,
83 watch->last_update_seq);84 watch->last_update_seq);
84 parser = send_message_and_parse (watch->couchdb, SOUP_METHOD_GET, url, NULL, &error);85 parser = json_parser_new ();
85 if (parser != NULL) {86 if (couchdb_send_message (watch->couchdb, SOUP_METHOD_GET, url, NULL, parser, &error)) {
86 JsonNode *root_node;87 JsonNode *root_node;
8788
88 root_node = json_parser_get_root (parser);89 root_node = json_parser_get_root (parser);
@@ -102,12 +103,11 @@
102103
103 if (json_object_has_member (root_object, "last_seq"))104 if (json_object_has_member (root_object, "last_seq"))
104 watch->last_update_seq = json_object_get_int_member (root_object, "last_seq");105 watch->last_update_seq = json_object_get_int_member (root_object, "last_seq");
105 }106 }
106
107 g_object_unref (G_OBJECT (parser));
108 }107 }
109108
110 /* Free memory */109 /* Free memory */
110 g_object_unref (G_OBJECT (parser));
111 g_free (url);111 g_free (url);
112}112}
113113
114114
=== modified file 'couchdb-glib/dbwatch.h'
--- couchdb-glib/dbwatch.h 2009-08-31 15:48:46 +0000
+++ couchdb-glib/dbwatch.h 2009-10-06 18:10:22 +0000
@@ -22,6 +22,8 @@
22#ifndef __DBWATCH_H__22#ifndef __DBWATCH_H__
23#define __DBWATCH_H__23#define __DBWATCH_H__
2424
25#include <glib.h>
26#include "couchdb.h"
25#include "utils.h"27#include "utils.h"
2628
27typedef struct {29typedef struct {
@@ -34,4 +36,4 @@
34DBWatch *dbwatch_new (CouchDB *couchdb, const gchar *dbname, gint update_seq);36DBWatch *dbwatch_new (CouchDB *couchdb, const gchar *dbname, gint update_seq);
35void dbwatch_free (DBWatch *watch);37void dbwatch_free (DBWatch *watch);
3638
37#endif39#endif /* __DBWATCH_H__ */
3840
=== modified file 'couchdb-glib/utils.c'
--- couchdb-glib/utils.c 2009-09-09 14:53:00 +0000
+++ couchdb-glib/utils.c 2009-10-06 18:10:22 +0000
@@ -24,46 +24,6 @@
24#include <libsoup/soup-session-async.h>24#include <libsoup/soup-session-async.h>
25#include "couchdb-glib.h"25#include "couchdb-glib.h"
26#include "utils.h"26#include "utils.h"
27#ifdef HAVE_OAUTH
28#include <time.h>
29#include "oauth.h"
30#endif
31
32static JsonParser *
33parse_json_response (SoupMessage *http_message, GError **error)
34{
35 SoupBuffer *buffer;
36 GString *str = NULL;
37 goffset offset = 0;
38 JsonParser *json_parser = NULL;
39
40 while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
41 if (!str)
42 str = g_string_new ("");
43 g_string_append_len (str, buffer->data, buffer->length);
44
45 offset += buffer->length;
46 soup_buffer_free (buffer);
47 }
48
49 if (str && str->len > 0) {
50 g_debug ("Response body: %s", str->str);
51 json_parser = json_parser_new ();
52 if (!json_parser_load_from_data (json_parser,
53 (const gchar *) str->str,
54 str->len,
55 error)) {
56 g_object_unref (G_OBJECT (json_parser));
57 json_parser = NULL;
58
59 g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
60 }
61
62 g_string_free (str, TRUE);
63 }
64
65 return json_parser;
66}
6727
68GQuark28GQuark
69couchdb_error_quark (void)29couchdb_error_quark (void)
@@ -76,110 +36,6 @@
76 return error;36 return error;
77}37}
7838
79#ifdef HAVE_OAUTH
80static void
81add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
82{
83 char *signed_url;
84
85 signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
86 couchdb->oauth_consumer_key,
87 couchdb->oauth_consumer_secret,
88 couchdb->oauth_token_key,
89 couchdb->oauth_token_secret);
90 if (signed_url != NULL) {
91 char **parsed_url;
92 GString *header = NULL;
93
94 /* Get the OAuth signature from the signed URL */
95 parsed_url = g_strsplit (signed_url, "?", 2);
96 if (parsed_url != NULL) {
97 gchar **params;
98 int i;
99
100 params = g_strsplit (parsed_url[1], "&", 0);
101#ifdef DEBUG_OAUTH
102 g_debug ("Parsing %s", parsed_url[1]);
103#endif
104 for (i = 0; params[i] != NULL; i++) {
105 gchar **url_param;
106
107#ifdef DEBUG_OAUTH
108 g_debug ("%s\n", params[i]);
109#endif
110 url_param = g_strsplit (params[i], "=", 2);
111 if (url_param == NULL)
112 continue;
113
114 if (header != NULL)
115 header = g_string_append (header, ", ");
116 else
117 header = g_string_new ("OAuth ");
118
119 header = g_string_append (header, url_param[0]);
120 header = g_string_append (header, "=\"");
121 header = g_string_append (header, url_param[1]);
122 header = g_string_append (header, "\"");
123
124 g_strfreev (url_param);
125 }
126
127 if (params)
128 g_strfreev (params);
129
130 g_strfreev (parsed_url);
131 }
132
133 if (header != NULL) {
134 soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
135
136 g_string_free (header, TRUE);
137 }
138
139 free (signed_url);
140 }
141}
142#endif
143
144static void
145debug_print_headers (const char *name, const char *value, gpointer user_data)
146{
147 g_print ("\t%s: %s\n", name, value);
148}
149
150JsonParser *
151send_message_and_parse (CouchDB *couchdb, const char *method, const char *url, const char *body, GError **error)
152{
153 SoupMessage *http_message;
154 guint status;
155 JsonParser *parser = NULL;
156
157 http_message = soup_message_new (method, url);
158 if (body != NULL) {
159 soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
160 body, strlen (body));
161 }
162
163#ifdef HAVE_OAUTH
164 if (couchdb->oauth_enabled)
165 add_oauth_signature (couchdb, http_message, method, url);
166#endif
167
168 g_debug ("Sending %s to %s... with headers\n: ", method, url);
169 soup_message_headers_foreach (http_message->request_headers,
170 (SoupMessageHeadersForeachFunc) debug_print_headers,
171 NULL);
172
173 status = soup_session_send_message (couchdb->http_session, http_message);
174 if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
175 parser = parse_json_response (http_message, error);
176 } else {
177 g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
178 }
179
180 return parser;
181}
182
183char *39char *
184generate_uuid (void)40generate_uuid (void)
185{41{
18642
=== modified file 'couchdb-glib/utils.h'
--- couchdb-glib/utils.h 2009-09-09 14:53:00 +0000
+++ couchdb-glib/utils.h 2009-10-06 18:10:22 +0000
@@ -22,85 +22,14 @@
22#ifndef __UTILS_H__22#ifndef __UTILS_H__
23#define __UTILS_H__23#define __UTILS_H__
2424
25#include <glib.h>
26#include <json-glib/json-glib.h>
25#include "config.h"27#include "config.h"
26#include <libsoup/soup-session-async.h>28#include "couchdb.h"
27#include <json-glib/json-glib.h>
28
29struct _CouchDB {
30 GObject parent;
31
32 char *hostname;
33 SoupSession *http_session;
34
35 GHashTable *db_watchlist;
36
37#ifdef HAVE_OAUTH
38 gboolean oauth_enabled;
39 char *oauth_consumer_key;
40 char *oauth_consumer_secret;
41 char *oauth_token_key;
42 char *oauth_token_secret;
43#endif
44};
45
46struct _CouchDBDocument {
47 GObject parent;
48
49 CouchDB *couchdb;
50 char *dbname;
51 JsonNode *root_node;
52};
53
54struct _CouchDBDatabaseInfo {
55 gint ref_count;
56
57 char *dbname;
58 gint doc_count;
59 gint doc_del_count;
60 gint update_seq;
61 gboolean compact_running;
62 gint disk_size;
63};
64
65CouchDBDatabaseInfo *couchdb_database_info_new (const char *dbname,
66 gint doc_count,
67 gint doc_del_count,
68 gint update_seq,
69 gboolean compact_running,
70 gint disk_size);
71
72struct _CouchDBDocumentInfo {
73 gint ref_count;
74
75 char *docid;
76 char *revision;
77};
78
79CouchDBDocumentInfo *couchdb_document_info_new (const char *docid, const char *revision);
80
81struct _CouchDBStructField {
82 gint ref_count;
83 JsonObject *json_object;
84
85 /* Extra data needed for some specific StructField's */
86 char *uuid; /* the UUID of this item */
87};
88
89CouchDBStructField *couchdb_struct_field_new_from_json_object (JsonObject *json_object);
90
91/*
92 * Utility functions
93 */
9429
95#define COUCHDB_ERROR couchdb_error_quark()30#define COUCHDB_ERROR couchdb_error_quark()
96GQuark couchdb_error_quark (void);31GQuark couchdb_error_quark (void);
9732
98JsonParser *send_message_and_parse (CouchDB *couchdb,33char* generate_uuid (void);
99 const char *method,
100 const char *url,
101 const char *body,
102 GError **error);
103
104char *generate_uuid (void);
10534
106#endif35#endif
10736
=== modified file 'debian/control'
--- debian/control 2009-08-11 15:04:39 +0000
+++ debian/control 2009-10-06 18:10:22 +0000
@@ -27,3 +27,15 @@
27 Ubuntu One.27 Ubuntu One.
28 .28 .
29 This package contains the development files.29 This package contains the development files.
30
31Package: libcouchdb-glib-doc
32Section: doc
33Architecture: any
34Depends: ${misc:Depends}
35Description: API documentation for GLib-based API for CouchDB
36 CouchDB-GLib is a GLib-based API to access CouchDB servers
37 (http://couchdb.apache.org), a replication/synchronization
38 database of JSON documents, used in online services like
39 Ubuntu One.
40 .
41 This package contains the API documentation for the couchdb-glib library
3042
=== added file 'debian/libcouchdb-glib-doc.install'
--- debian/libcouchdb-glib-doc.install 1970-01-01 00:00:00 +0000
+++ debian/libcouchdb-glib-doc.install 2009-10-06 18:10:22 +0000
@@ -0,0 +1,1 @@
1debian/tmp/usr/share/gtk-doc
02
=== modified file 'debian/rules'
--- debian/rules 2009-07-20 12:11:54 +0000
+++ debian/rules 2009-10-06 18:10:22 +0000
@@ -2,3 +2,5 @@
22
3include /usr/share/cdbs/1/rules/debhelper.mk3include /usr/share/cdbs/1/rules/debhelper.mk
4include /usr/share/cdbs/1/class/gnome.mk4include /usr/share/cdbs/1/class/gnome.mk
5include /usr/share/cdbs/1/rules/utils.mk
6
57
=== added directory 'doc'
=== added file 'doc/Makefile.am'
--- doc/Makefile.am 1970-01-01 00:00:00 +0000
+++ doc/Makefile.am 2009-10-06 18:10:22 +0000
@@ -0,0 +1,4 @@
1# Include to make 'make check' work with GTest
2#include $(top_srcdir)/Makefile.decl
3
4SUBDIRS = reference
05
=== added directory 'doc/reference'
=== added file 'doc/reference/Makefile.am'
--- doc/reference/Makefile.am 1970-01-01 00:00:00 +0000
+++ doc/reference/Makefile.am 2009-10-06 18:10:22 +0000
@@ -0,0 +1,67 @@
1## Process this file with automake to produce Makefile.in
2
3# Dummy targets we need to make distcheck and check pass
4test test-report perf-report full-report:
5 ## Ignore
6
7# automake requirements
8AUTOMAKE_OPTIONS = 1.7
9
10# The name of the module
11DOC_MODULE=couchdb-glib
12
13# The top-level SGML file. You can change this if you want to.
14DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
15
16# The directory containing the source code. Relative to $(srcdir).
17DOC_SOURCE_DIR=../..
18
19# Extra options to pass to gtkdoc-scangobj. Not normally needed.
20SCANGOBJ_OPTIONS=
21
22# Extra options to supply to gtkdoc-scan.
23# Fx --rebuild-types --rebuild-sections
24SCAN_OPTIONS=
25
26# Extra options to supply to gtkdoc-mkdb.
27MKDB_OPTIONS=--sgml-mode --output-format=xml --ignore-files=trio
28
29# Extra options to supply to gtkdoc-fixref. Not normally needed.
30FIXXREF_OPTIONS=
31
32# Used for dependencies. The docs will be rebuilt if any of these change.
33HFILE_GLOB=$(top_srcdir)/couchdb-glib/couchdb*.h
34CFILE_GLOB=$(top_srcdir)/couchdb-glib/couchdb*.c
35
36# Header files to ignore when scanning.
37IGNORE_HFILES= \
38 xmalloc.h \
39 dbwatch.h \
40 oauth.h \
41 utils.h \
42 xmalloc.h \
43 config.h
44
45# Images to copy into HTML directory.
46HTML_IMAGES=
47
48# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
49content_files =
50
51# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
52INCLUDES=-I$(top_srcdir)/couchdb-glib \
53 $(COUCHDB_GLIB_CFLAGS)
54
55GTKDOC_LIBS=$(COUCHDB_GLIB_LIBS) \
56 $(top_builddir)/couchdb-glib/libcouchdb-glib-1.0.la
57
58# This includes the standard gtk-doc make rules, copied by gtkdocize.
59include $(top_srcdir)/gtk-doc.make
60
61# Other files to distribute
62# e.g. EXTRA_DIST += version.xml.in
63EXTRA_DIST += \
64 couchdb-glib.types \
65 couchdb-glib-docs.sgml
66# couchdb-glib-sections.txt
67
068
=== added file 'doc/reference/couchdb-glib-docs.sgml'
--- doc/reference/couchdb-glib-docs.sgml 1970-01-01 00:00:00 +0000
+++ doc/reference/couchdb-glib-docs.sgml 2009-10-06 18:10:22 +0000
@@ -0,0 +1,19 @@
1<?xml version="1.0"?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
4<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
5 <bookinfo>
6 <title>Reference Manual for CouchDB GLib Bindings</title>
7 </bookinfo>
8
9 <chapter>
10 <title>Core API</title>
11 <xi:include href="xml/couchdb.xml"/>
12 <xi:include href="xml/couchdb-document.xml"/>
13 <xi:include href="xml/couchdb-document-contact.xml"/>
14 <xi:include href="xml/couchdb-document-info.xml"/>
15 <xi:include href="xml/couchdb-database-info.xml"/>
16 <xi:include href="xml/couchdb-struct-field.xml"/>
17 </chapter>
18
19</book>
020
=== added file 'doc/reference/couchdb-glib.types'
--- doc/reference/couchdb-glib.types 1970-01-01 00:00:00 +0000
+++ doc/reference/couchdb-glib.types 2009-10-06 18:10:22 +0000
@@ -0,0 +1,6 @@
1couchdb_get_type
2couchdb_database_info_get_type
3couchdb_document_get_type
4couchdb_document_info_get_type
5couchdb_struct_field_get_type
6
07
=== modified file 'tests/test-couchdb-glib.c'
--- tests/test-couchdb-glib.c 2009-08-31 15:48:46 +0000
+++ tests/test-couchdb-glib.c 2009-10-06 18:10:22 +0000
@@ -31,7 +31,12 @@
31 GSList *dblist;31 GSList *dblist;
3232
33 dblist = couchdb_list_databases (couchdb, &error);33 dblist = couchdb_list_databases (couchdb, &error);
34 g_assert (error == NULL);34 if (error != NULL) {
35 /* A critical will abort the test case */
36 g_critical ("Error listing databases: %s", error->message);
37 g_error_free (error);
38 error = NULL;
39 }
3540
36 while (dblist != NULL) {41 while (dblist != NULL) {
37 CouchDBDatabaseInfo *dbinfo;42 CouchDBDatabaseInfo *dbinfo;
@@ -112,7 +117,10 @@
112117
113 /* Create database */118 /* Create database */
114 couchdb_create_database (couchdb, dbname, &error);119 couchdb_create_database (couchdb, dbname, &error);
115 g_assert (error == NULL);120 if (error) {
121 g_critical ("Error creating database '%s': %s", dbname, error->message);
122 g_error_free (error);
123 }
116124
117 couchdb_listen_for_changes (couchdb, dbname);125 couchdb_listen_for_changes (couchdb, dbname);
118126
@@ -184,7 +192,9 @@
184 g_test_init (&argc, &argv, NULL);192 g_test_init (&argc, &argv, NULL);
185193
186 /* Initialize data needed for all tests */194 /* Initialize data needed for all tests */
187 couchdb = couchdb_new (NULL);195 couchdb = argc > 1 ? couchdb_new (argv[1]) : couchdb_new (NULL);
196 g_printf ("Connecting to CouchDB at %s\n", couchdb_get_hostname (couchdb));
197
188 if (!couchdb) {198 if (!couchdb) {
189 g_print ("Could not create CouchDB object\n");199 g_print ("Could not create CouchDB object\n");
190 return -1;200 return -1;
191201
=== modified file 'tests/test-list-databases.c'
--- tests/test-list-databases.c 2009-07-27 21:52:04 +0000
+++ tests/test-list-databases.c 2009-10-06 18:10:22 +0000
@@ -32,14 +32,21 @@
32 g_type_init ();32 g_type_init ();
33 g_thread_init (NULL);33 g_thread_init (NULL);
3434
35 /* initialize CouchDB */35 /* Initialize CouchDB */
36 couchdb = couchdb_new (NULL);36 couchdb = argc > 1 ? couchdb_new (argv[1]) : couchdb_new (NULL);
37 g_printf ("Connecting to CouchDB at %s\n", couchdb_get_hostname (couchdb));
38
37 if (!couchdb) {39 if (!couchdb) {
38 g_print ("Could not create CouchDB object\n");40 g_print ("Could not create CouchDB object\n");
39 return -1;41 return -1;
40 }42 }
4143
42 dblist = couchdb_list_databases (couchdb, &error);44 dblist = couchdb_list_databases (couchdb, &error);
45 if (error != NULL) {
46 g_critical ("Error listing databases: %s", error->message);
47 g_error_free (error);
48 }
49
43 for (sl = dblist; sl != NULL; sl = sl->next) {50 for (sl = dblist; sl != NULL; sl = sl->next) {
44 CouchDBDatabaseInfo *dbinfo;51 CouchDBDatabaseInfo *dbinfo;
45 GSList *doclist;52 GSList *doclist;

Subscribers

People subscribed via source and target branches