[couchdb-glib/wip/query-response] introduce couchdb_database_execute_query and port all CouchdbDatabase methods to it
- From: Krzysztof Klimonda <kklimonda src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [couchdb-glib/wip/query-response] introduce couchdb_database_execute_query and port all CouchdbDatabase methods to it
- Date: Wed, 19 Jan 2011 12:55:34 +0000 (UTC)
commit 17811c92b3027b76ce6ab48e4fc5733bd4983f47
Author: Krzysztof Klimonda <kklimonda syntaxhighlighted com>
Date: Wed Jan 19 13:35:57 2011 +0100
introduce couchdb_database_execute_query and port all CouchdbDatabase methods to it
couchdb-glib/couchdb-database.c | 617 ++++++++++++++-------------------------
couchdb-glib/couchdb-database.h | 64 +++--
2 files changed, 267 insertions(+), 414 deletions(-)
---
diff --git a/couchdb-glib/couchdb-database.c b/couchdb-glib/couchdb-database.c
index 81a12ed..ede559b 100644
--- a/couchdb-glib/couchdb-database.c
+++ b/couchdb-glib/couchdb-database.c
@@ -177,33 +177,10 @@ couchdb_database_init (CouchdbDatabase *database)
database->priv = g_new0 (CouchdbDatabasePrivate, 1);
}
-static CouchdbDocument *
-create_document_from_json_object (JsonObject *json_object)
+GQuark
+couchdb_database_error_quark ()
{
- CouchdbDocument *document;
-
- if (g_str_has_prefix (json_object_get_string_member (json_object, "id"),
- "_design/")) {
- document = COUCHDB_DOCUMENT (couchdb_design_document_new ());
- couchdb_document_set_from_json_object (document,
- json_object_get_object_member (json_object, "doc"));
- } else {
- if (json_object_has_member (json_object, "record_type")) {
- if (g_strcmp0 (json_object_get_string_member (json_object, "record_type"),
- COUCHDB_RECORD_TYPE_CONTACT) == 0) {
- document = COUCHDB_DOCUMENT (couchdb_document_contact_new ());
- } else if (g_strcmp0 (json_object_get_string_member (json_object, "record_type"),
- COUCHDB_RECORD_TYPE_TASK) == 0) {
- document = COUCHDB_DOCUMENT (couchdb_document_task_new ());
- } else
- document = couchdb_document_new ();
-
- couchdb_document_set_from_json_object (document, json_object);
- } else
- document = couchdb_document_new_from_json_object (json_object);
- }
-
- return document;
+ return g_quark_from_static_string ("couchdb-database-error-quark");
}
/**
@@ -211,8 +188,8 @@ create_document_from_json_object (JsonObject *json_object)
* @session: A #CouchdbSession object
* @dbname: Name of the database
*
- * Create a new #CouchdbDatabase object, which is to be used for operations on specific
- * databases on the underlying CouchDB instance.
+ * Create a new #CouchdbDatabase object, which is to be used for
+ * operations on specific databases on the underlying CouchDB instance.
*
* Return value: A new #CouchdbDatabase object.
*/
@@ -225,137 +202,58 @@ couchdb_database_new (CouchdbSession *session, const char *dbname)
NULL);
}
-static JsonArray *
-call_all_docs_uri (CouchdbSession *session, const char *url, JsonParser *parser, GError **error)
-{
- JsonArray *rows = NULL;
-
- if (couchdb_session_send_message (session, SOUP_METHOD_GET, url, NULL, parser, error)) {
- JsonNode *root_node;
-
- root_node = json_parser_get_root (parser);
- if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT) {
- rows = json_object_get_array_member (
- json_node_get_object (root_node), "rows");
- }
- }
-
- return rows;
-}
-
-/**
- * couchdb_database_list_documents:
- * @database: A #CouchdbDatabase object
- * @error: Placeholder for error information
- *
- * Retrieve the list of all documents from a database on a running CouchDB instance.
- * For each document, a #CouchdbDocumentInfo object is returned on the list, which
- * can then be used for retrieving specific information for each document.
- *
- * Return Value: a list of #CouchdbDocumentInfo objects, or NULL if there are none
- * or there was an error (in which case the error argument will contain information
- * about the error). Once no longer needed, the list should be freed by calling
- * #couchdb_database_free_document_list.
- */
-GSList *
-couchdb_database_list_documents (CouchdbDatabase *database, GError **error)
-{
- char *url;
- JsonParser *parser;
- JsonArray *rows;
- GSList *doclist = NULL;
-
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
-
- url = g_strdup_printf ("%s/%s/_all_docs",
- couchdb_session_get_uri (database->priv->session),
- database->priv->dbname);
- parser = json_parser_new ();
-
- rows = call_all_docs_uri (database->priv->session, url, parser, error);
- if (rows != NULL) {
- gint i;
- for (i = 0; i < json_array_get_length (rows); i++) {
- JsonObject *doc;
- CouchdbDocumentInfo *doc_info;
-
- doc = json_array_get_object_element (rows, i);
- if (!doc)
- continue;
-
- doc_info = couchdb_document_info_new (
- json_object_get_string_member (doc, "id"),
- json_object_get_string_member (
- json_object_get_object_member (doc, "value"),
- "rev"));
- doclist = g_slist_append (doclist, doc_info);
- }
- }
-
- g_object_unref (G_OBJECT (parser));
- g_free (url);
-
- return doclist;
-}
-
/**
* couchdb_database_get_design_documents:
* @database: A #CouchdbDatabase object
* @error: Placeholder for error information
*
- * Retrieve all design documents from the given database.
+ * Retrieve all design documents from the given database. For each document
+ * a #JsonObject is returned.
*
- * Design documents are special documents (well, they are really normal documents in
- * the CouchDB database, just with a special ID) that contain views' code, which are used
- * to create queries on the database that are cached and so make access to the database
- * much quicker.
+ * Design documents are special documents (well, they are really normal documents
+ * in the CouchDB database, just with a special ID) that contain views' code,
+ * which are used to create queries on the database that are cached and so make
+ * access to the database much quicker.
*
- * Return value: A list of #CouchdbDesignDocument objects, or NULL if there are none
- * or there was an error (in which case the error argument will contain information
- * about the error). Once no longer needed, the list should be freed by calling
- * #couchdb_database_free_document_list.
+ * Return value: (element-type Json.Object) (transfer full): A #GList
+ * of #Json.Object objects, or %NULL if there aren't any documents,
+ * or there was an error (in which case the error argument will contain
+ * information about the error). Both #GList and documents should be freed
+ * once they are no longer needed.
*/
-GSList *
-couchdb_database_get_design_documents (CouchdbDatabase *database, GError **error)
+GList *
+couchdb_database_get_design_documents (CouchdbDatabase *self, GError **error)
{
- char *url;
- JsonParser *parser;
- JsonArray *rows;
- GSList *doclist = NULL;
-
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
-
- url = g_strdup_printf ("%s/%s/_all_docs?include_docs=true",
- couchdb_session_get_uri (database->priv->session),
- database->priv->dbname);
- parser = json_parser_new ();
-
- rows = call_all_docs_uri (database->priv->session, url, parser, error);
- if (rows != NULL) {
- gint i;
- for (i = 0; i < json_array_get_length (rows); i++) {
- JsonObject *obj;
- const gchar *id;
- CouchdbDesignDocument *document;
-
- obj = json_array_get_object_element (rows, i);
- if (!obj)
- continue;
-
- id = json_object_get_string_member (obj, "_id");
- if (!g_str_has_prefix (id, "_design/"))
- continue;
-
- document = couchdb_design_document_new ();
- if (document != NULL) {
- couchdb_document_set_from_json_object (COUCHDB_DOCUMENT (document), obj);
- doclist = g_slist_append (doclist, document);
- }
- }
+ CouchdbQuery *query;
+ CouchdbResponse *response;
+ GList *doclist = NULL, *rows, *iter;
+
+ g_return_val_if_fail (COUCHDB_IS_DATABASE (self), NULL);
+
+ query = couchdb_query_new_for_path ("/_all_docs");
+ couchdb_query_set_option (query, "include_docs", "true");
+ /* get only design documents, the idea to use startkey and endkey
+ * this way comes from CouchDB's futon. All design documents have
+ * IDs starting with _design and here we make use of the fact that,
+ * when comparing strings "0" is bigger than "/". */
+ couchdb_query_set_option (query, "startkey", "_design/");
+ couchdb_query_set_option (query, "endkey", "_design0");
+
+ response = couchdb_database_execute_query (self, query, error);
+ rows = couchdb_response_get_rows (response);
+
+ for (iter = rows; iter != NULL; iter = g_list_next (iter)) {
+ JsonObject *document;
+
+ document = json_object_ref (
+ json_object_get_object_member (iter->data, "doc"));
+ doclist = g_list_prepend (doclist, document);
}
+ doclist = g_list_reverse (doclist);
- g_object_unref (G_OBJECT (parser));
- g_free (url);
+ g_list_free (rows);
+ g_object_unref (response);
+ g_object_unref (query);
return doclist;
}
@@ -370,147 +268,82 @@ couchdb_database_get_design_documents (CouchdbDatabase *database, GError **error
* on the list, which represents the document's contents as found on the
* underlying database.
*
- * Return value: a list of #CouchdbDocument objects, or NULL if there are none
- * or there was an error (in which case the error argument will contain information
- * about the error). Once no longer needed, the list should be freed by calling
- * #couchdb_database_free_document_list.
+ * Return value: (element-type Json.Object) (transfer full): A #GList
+ * of #Json.Object objects, or %NULL if there aren't any documents,
+ * or there was an error (in which case the error argument will contain
+ * information about the error). Both #GList and documents should be freed
+ * once they are no longer needed.
*/
-GSList *
-couchdb_database_get_all_documents (CouchdbDatabase *database, GError **error)
+GList *
+couchdb_database_get_all_documents (CouchdbDatabase *self, GError **error)
{
- char *url;
- JsonParser *parser;
- JsonArray *rows;
- GSList *doclist = NULL;
+ CouchdbQuery *query;
+ CouchdbResponse *response;
+ GList *documents, *iter, *doclist = NULL;
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
+ g_return_val_if_fail (COUCHDB_IS_DATABASE (self), NULL);
- url = g_strdup_printf ("%s/%s/_all_docs?include_docs=true",
- couchdb_session_get_uri (database->priv->session),
- database->priv->dbname);
- parser = json_parser_new ();
-
- rows = call_all_docs_uri (database->priv->session, url, parser, error);
- if (rows != NULL) {
- gint i;
- for (i = 0; i < json_array_get_length (rows); i++) {
- JsonObject *obj;
- CouchdbDocument *document = NULL;
-
- obj = json_array_get_object_element (rows, i);
- if (!obj)
- continue;
-
- document = create_document_from_json_object (json_object_get_object_member (obj, "doc"));
- if (document != NULL) {
- g_object_set (G_OBJECT (document), "database", database, NULL);
- doclist = g_slist_append (doclist, document);
- }
- }
- }
+ query = couchdb_query_new_for_path ("/_all_docs");
+ couchdb_query_set_option (query, "include_docs", "true");
- g_object_unref (G_OBJECT (parser));
- g_free (url);
+ response = couchdb_database_execute_query (self, query, error);
+ documents = couchdb_response_get_rows (response);
- return doclist;
-}
+ for (iter = documents; iter != NULL; iter = g_list_next (iter)) {
+ JsonObject *document;
-/**
- * couchdb_database_execute_view:
- * @database: A #CouchdbDatabase object
- * @design_doc: Name of the design document where the view to execute is
- * @view_name: Name of the view to execute
- * @error: Placeholder for error information
- *
- * Run a view on the database to retrieve documents. For
- * each document found in the database, a #CouchdbDocument object is returned
- * on the list, which represents the document's contents as found on the
- * underlying database.
- *
- * Return value: a list of #CouchdbDocument objects, or NULL if there are none
- * or there was an error (in which case the error argument will contain information
- * about the error). Once no longer needed, the list should be freed by calling
- * #couchdb_database_free_document_list.
- */
-GSList *
-couchdb_database_execute_view (CouchdbDatabase *database,
- const char *design_doc,
- const char *view_name,
- GError **error)
-{
- char *url;
- JsonParser *parser;
- JsonArray *rows;
- GSList *doclist = NULL;
-
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
+ document = json_object_ref (
+ json_object_get_object_member (iter->data, "doc"));
+ doclist = g_list_prepend (doclist, document);
- if (g_str_has_prefix (design_doc, "_design/")) {
- url = g_strdup_printf ("%s/%s/%s/_view/%s",
- couchdb_session_get_uri (database->priv->session),
- database->priv->dbname,
- design_doc,
- view_name);
- } else {
- url = g_strdup_printf ("%s/%s/_design/%s/_view/%s",
- couchdb_session_get_uri (database->priv->session),
- database->priv->dbname,
- design_doc,
- view_name);
- }
-
- parser = json_parser_new ();
-
- rows = call_all_docs_uri (database->priv->session, url, parser, error);
- if (rows != NULL) {
- gint i;
- for (i = 0; i < json_array_get_length (rows); i++) {
- JsonObject *obj;
- CouchdbDocument *document = NULL;
-
- obj = json_array_get_object_element (rows, i);
- if (!obj)
- continue;
-
- document = create_document_from_json_object (json_object_get_object_member (obj, "value"));
-
- if (document != NULL) {
- couchdb_document_set_id (document, json_object_get_string_member (obj, "id"));
- g_object_set (G_OBJECT (document), "database", database, NULL);
- doclist = g_slist_append (doclist, document);
- }
- }
}
+ doclist = g_list_reverse (doclist);
- g_object_unref (G_OBJECT (parser));
- g_free (url);
+ g_list_free (documents);
+ g_object_unref (response);
+ g_object_unref (query);
return doclist;
}
/**
- * couchdb_session_free_document_list:
- * @doclist: A list of #CouchdbDocumentInfo or #CouchdbDocument objects, as returned by
- * #couchdb_database_list_documents or #couchdb_database_get_all_documents
+ * couchdb_database_execute_query:
+ * @self: A #CouchdbDatabase object
+ * @query: A #CouchdbQuery object describing a query
+ * @error: Placeholder for error information
*
- * Free the list of documents returned by #couchdb_database_list_documents or
- * #couchdb_database_get_all_documents
+ * A helper function to execute created queries on a specified database,
+ * as opposed on session itself. It prepend database's name to query's path
+ * and calls couchdb_session_execute_query with it.
+ *
+ * Return value: (transfer full): A #CouchdbResponse object that contains
+ * response from the server, or %NULL if there was an error, in which case
+ * @error will be set appropriately.
*/
-void
-couchdb_database_free_document_list (GSList *doclist)
+CouchdbResponse *
+couchdb_database_execute_query (CouchdbDatabase * self,
+ CouchdbQuery * query, GError **error)
{
- g_return_if_fail (doclist != NULL);
+ CouchdbResponse *response;
+ const char *path;
+ char *full_path, *encoded_dbname;
- while (doclist != NULL) {
- gpointer data = doclist->data;
+ path = couchdb_query_get_path (query);
+ encoded_dbname = couchdb_uri_encode (self->priv->dbname);
- doclist = g_slist_remove (doclist, data);
+ /* to prevent creating uri with two slashes check if first character
+ of path is slash and, if it is, skip it. */
+ full_path = g_strconcat (encoded_dbname, "/",
+ path ? (*path == '/' ? path+1 : path) : "", NULL);
+ couchdb_query_set_path (query, full_path);
- if (COUCHDB_IS_DOCUMENT (data))
- g_object_unref (G_OBJECT (data));
- else
- couchdb_document_info_unref (data);
- }
+
+ response = couchdb_session_execute_query (self->priv->session,
+ query, error);
+ g_free (full_path);
+ g_free (encoded_dbname);
+
+ return response;
}
/**
@@ -524,78 +357,34 @@ couchdb_database_free_document_list (GSList *doclist)
* Return value: A #CouchdbDocument object if successful, NULL otherwise, in
* which case, the error argument will contain information about the error.
*/
-CouchdbDocument *
-couchdb_database_get_document (CouchdbDatabase *database,
- const char *docid,
+JsonObject *
+couchdb_database_get_document (CouchdbDatabase *self,
+ const char *id,
+ const char *revision,
GError **error)
{
- char *url, *encoded_docid;
- JsonParser *parser;
- CouchdbDocument *document = NULL;
-
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
- g_return_val_if_fail (docid != NULL, NULL);
-
- encoded_docid = soup_uri_encode (docid, NULL);
- url = g_strdup_printf ("%s/%s/%s", couchdb_session_get_uri (database->priv->session),
- database->priv->dbname, encoded_docid);
- parser = json_parser_new ();
- if (couchdb_session_send_message (database->priv->session, SOUP_METHOD_GET, url, NULL, parser, error)) {
- JsonObject *json_object = json_node_get_object (json_parser_get_root (parser));
-
- document = create_document_from_json_object (json_object);
- g_object_set (G_OBJECT (document), "database", database, NULL);
+ CouchdbQuery *query;
+ CouchdbResponse *response;
+ char *encoded_docid;
+ JsonObject *object;
+
+ g_return_val_if_fail (COUCHDB_IS_DATABASE (self), NULL);
+ g_return_val_if_fail (id != NULL, NULL);
+
+ encoded_docid = couchdb_uri_encode (id);
+ query = couchdb_query_new_for_path (encoded_docid);
+ if (revision != NULL) {
+ couchdb_query_set_option (query, "rev", revision);
}
+
+ response = couchdb_database_execute_query (self, query, error);
+ object = json_object_ref (couchdb_response_get_json_object (response));
- g_object_unref (G_OBJECT (parser));
+ g_object_unref (query);
+ g_object_unref (response);
g_free (encoded_docid);
- g_free (url);
-
- return document;
-}
-
-/**
- * couchdb_database_get_design_document:
- * @database: A #CouchdbDatabase object
- * @docid: ID of the design document
- * @error: Placeholder for error information
- *
- * Retrieve a design document from the given database.
- *
- * Return value: A #CouchdbDesignDocument object if successful, NULL otherwise, in
- * which case, the error argument will contain information about the error.
- */
-CouchdbDesignDocument *
-couchdb_database_get_design_document (CouchdbDatabase *database, const char *docid, GError **error)
-{
- char *url;
- JsonParser *parser;
- CouchdbDesignDocument *document = NULL;
-
- g_return_val_if_fail (COUCHDB_IS_DATABASE (database), NULL);
- g_return_val_if_fail (docid != NULL, NULL);
-
- if (g_str_has_prefix (docid, "_design/")) {
- url = g_strdup_printf ("%s/%s/%s", couchdb_session_get_uri (database->priv->session),
- database->priv->dbname, docid);
- } else {
- url = g_strdup_printf ("%s/%s/_design/%s", couchdb_session_get_uri (database->priv->session),
- database->priv->dbname, docid);
- }
-
- parser = json_parser_new ();
- if (couchdb_session_send_message (database->priv->session, SOUP_METHOD_GET, url, NULL, parser, error)) {
- document = couchdb_design_document_new ();
- couchdb_document_set_from_json_object (COUCHDB_DOCUMENT (document),
- json_node_get_object (json_parser_get_root (parser)));
-
- g_object_set (G_OBJECT (document), "database", database, NULL);
- }
-
- g_object_unref (G_OBJECT (parser));
- g_free (url);
- return document;
+ return object;
}
/**
@@ -618,57 +407,79 @@ couchdb_database_get_design_document (CouchdbDatabase *database, const char *doc
*/
gboolean
couchdb_database_put_document (CouchdbDatabase *database,
- CouchdbDocument *document,
+ JsonObject *document,
GError **error)
{
- char *url, *body;
+ CouchdbQuery *query;
+ CouchdbResponse *response;
+ char *body;
const char *id;
+ JsonObject *object;
JsonParser *parser;
gboolean result = FALSE;
gboolean send_ok;
g_return_val_if_fail (COUCHDB_IS_DATABASE (database), FALSE);
- g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);
+ g_return_val_if_fail (document != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- id = couchdb_document_get_id (document);
- body = couchdb_document_to_string (document);
- parser = json_parser_new ();
- if (id) {
- char *encoded_docid;
+ if (json_object_has_member (document, "_id")) {
+ char *encoded_id;
- encoded_docid = soup_uri_encode (id, NULL);
- url = g_strdup_printf ("%s/%s/%s", couchdb_session_get_uri (database->priv->session), database->priv->dbname, encoded_docid);
- send_ok = couchdb_session_send_message (database->priv->session, SOUP_METHOD_PUT, url, body, parser, error);
+ id = json_object_get_string_member (document, "_id");
+ encoded_id = couchdb_uri_encode (id);
+ query = couchdb_query_new_for_path (encoded_id);
+ couchdb_query_set_method (query, "PUT");
+ couchdb_query_set_json_object (query, document);
- g_free (encoded_docid);
+ g_free (encoded_id);
} else {
- url = g_strdup_printf ("%s/%s/", couchdb_session_get_uri (database->priv->session), database->priv->dbname);
- send_ok = couchdb_session_send_message (database->priv->session, SOUP_METHOD_POST, url, body, parser, error);
+ query = couchdb_query_new ();
+ couchdb_query_set_method (query, "POST");
+ couchdb_query_set_json_object (query, document);
}
- if (send_ok) {
- JsonObject *object;
+ response = couchdb_database_execute_query (database, query, error);
+ if (!response) {
+ g_assert (error == NULL || *error != NULL);
+
+ if ((*error)->code == COUCHDB_SESSION_ERROR_CONFLICT) {
+ g_clear_error (error);
+ g_set_error_literal (error,
+ COUCHDB_DATABASE_ERROR,
+ COUCHDB_DATABASE_ERROR_DOCUMENT_CONFLICT,
+ "Document you are trying to put " \
+ "already exists and revisions " \
+ "don't match");
+ }
- object = json_node_get_object (json_parser_get_root (parser));
- couchdb_document_set_id (document, json_object_get_string_member (object, "id"));
- couchdb_document_set_revision (document, json_object_get_string_member (object, "rev"));
+ g_object_unref (query);
- if (id)
- g_signal_emit_by_name (database, "document_updated", document);
- else
- g_signal_emit_by_name (database, "document_created", document);
+ return FALSE;
+ }
- g_object_set (G_OBJECT (document), "database", database, NULL);
+ object = couchdb_response_get_json_object (response);
- result = TRUE;
+ if (json_object_has_member (object, "id")) {
+ id = json_object_get_string_member (object, "id");
+ json_object_set_string_member (document, "_id", id);
}
+ if (json_object_has_member (object, "rev")) {
+ const char *rev;
- /* free memory */
- g_free (url);
- g_free (body);
- g_object_unref (G_OBJECT (parser));
+ rev = json_object_get_string_member (object, "rev");
+ json_object_set_string_member (document, "_rev", rev);
+ }
- return result;
+ if (id)
+ g_signal_emit_by_name (database, "document_updated", document);
+ else
+ g_signal_emit_by_name (database, "document_created", document);
+
+ g_object_unref (query);
+ g_object_unref (response);
+
+ return TRUE;
}
/**
@@ -684,38 +495,52 @@ couchdb_database_put_document (CouchdbDatabase *database,
* This is due to the fact that, to remove a document from CouchDB, the latest
* revision needs to be sent, so if the #CouchdbDocument object passed to this
* function does not contain the last revision, the operation will fail. In that
- * case, retrieving the latest revision from CouchDB (with #couchdb_database_get_document)
- * and trying the delete operation again should fix the issue.
+ * case, retrieving the latest revision from CouchDB (with
+ * #couchdb_database_get_document) and trying the delete operation again should
+ * fix the issue.
*
* Return value: TRUE if successful, FALSE otherwise, in which case the error
* argument will contain information about the error.
*/
gboolean
-couchdb_database_delete_document (CouchdbDatabase *database, CouchdbDocument *document, GError **error)
+couchdb_database_delete_document (CouchdbDatabase * database,
+ JsonObject * document, GError **error)
{
- const char *id, *revision;
- char *url;
- gboolean result = FALSE;
+ CouchdbQuery *query;
+ CouchdbResponse *response;
+ const gchar *id, *revision;
+ gchar *encoded_id;
g_return_val_if_fail (COUCHDB_IS_DATABASE (database), FALSE);
- g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);
+ g_return_val_if_fail (document != NULL, FALSE);
- id = couchdb_document_get_id (document);
- revision = couchdb_document_get_revision (document);
- if (!id || !revision) /* we can't remove a document without an ID and/or a REVISION */
- return FALSE;
+ id = json_object_get_string_member (document, "_id");
+ revision = json_object_get_string_member (document, "_rev");
- url = g_strdup_printf ("%s/%s/%s?rev=%s", couchdb_session_get_uri (database->priv->session), database->priv->dbname, id, revision);
+ /* we can't remove a document without an ID and/or a REVISION */
+ if (!id || !revision)
+ return FALSE;
- /* We don't parse the http response, therefore the parser arg is NULL */
- if (couchdb_session_send_message (database->priv->session, SOUP_METHOD_DELETE, url, NULL, NULL, error)) {
- result = TRUE;
- g_signal_emit_by_name (database, "document_deleted", id);
+ encoded_id = couchdb_uri_encode (id);
+ query = couchdb_query_new_for_path (encoded_id);
+ couchdb_query_set_method (query, "DELETE");
+ couchdb_query_set_option (query, "rev", revision);
+
+ error = NULL;
+ response = couchdb_database_execute_query (database, query, error);
+ if (error != NULL) {
+ g_free (encoded_id);
+ g_object_unref (query);
+
+ return FALSE;
}
- g_free (url);
- return result;
+ g_free (encoded_id);
+ g_object_unref (query);
+ g_object_unref (response);
+
+ return TRUE;
}
/**
@@ -723,25 +548,28 @@ couchdb_database_delete_document (CouchdbDatabase *database, CouchdbDocument *do
* @database: A #CouchdbDatabase object
* @dbname: Name of the database to poll changes for
*
- * Setup a listener to get information about changes done to a specific database. Please
- * note that changes done in the application using couchdb-glib will be notified
- * without the need of calling this function. But if the application wants to receive
- * notifications of changes done externally (by another application, or by any other
- * means, like replication with a remote database), it needs to call this function.
+ * Setup a listener to get information about changes done to a specific
+ * database. Please note that changes done in the application using
+ * couchdb-glib will be notified without the need of calling this function.
+ * But if the application wants to receive notifications of changes done
+ * externally (by another application, or by any other means, like replication
+ * with a remote database), it needs to call this function.
*
- * For each change, one of the signals on the #CouchdbDatabase object will be emitted,
- * so applications just have to connect to those signals before calling this function.
+ * For each change, one of the signals on the #CouchdbDatabase object will
+ * be emitted, so applications just have to connect to those signals before
+ * calling this function.
*/
void
couchdb_database_listen_for_changes (CouchdbDatabase *database)
{
- CouchdbDatabaseInfo *db_info;
+ JsonObject *db_info;
GError *error = NULL;
g_return_if_fail (COUCHDB_IS_DATABASE (database));
if (database->priv->db_watch != NULL) {
- g_warning ("Already listening for changes in '%s' database", database->priv->dbname);
+ g_warning ("Already listening for changes in '%s' database",
+ database->priv->dbname);
return;
}
@@ -757,11 +585,12 @@ couchdb_database_listen_for_changes (CouchdbDatabase *database)
return;
}
- database->priv->db_watch = dbwatch_new (database,
- couchdb_database_info_get_update_sequence (db_info));
+ database->priv->db_watch =
+ dbwatch_new (database,
+ json_object_get_int_member (db_info, "update_seq"));
/* Free memory */
- couchdb_database_info_unref (db_info);
+ json_object_unref (db_info);
}
/**
diff --git a/couchdb-glib/couchdb-database.h b/couchdb-glib/couchdb-database.h
index 072aa7a..663c41c 100644
--- a/couchdb-glib/couchdb-database.h
+++ b/couchdb-glib/couchdb-database.h
@@ -23,8 +23,9 @@
#define __COUCHDB_DATABASE_H__
#include <glib-object.h>
-#include "couchdb-design-document.h"
-#include "couchdb-document.h"
+#include <json-glib/json-glib.h>
+#include "couchdb-query.h"
+#include "couchdb-response.h"
#include "couchdb-session.h"
G_BEGIN_DECLS
@@ -36,6 +37,8 @@ G_BEGIN_DECLS
#define COUCHDB_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COUCHDB_TYPE_DATABASE))
#define COUCHDB_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COUCHDB_TYPE_DATABASE, CouchdbDatabaseClass))
+#define COUCHDB_DATABASE_ERROR (couchdb_database_error_quark ())
+
typedef struct _CouchdbDatabasePrivate CouchdbDatabasePrivate;
struct _CouchdbDatabase {
@@ -47,34 +50,55 @@ typedef struct {
GObjectClass parent_class;
/* Signals */
- void (* document_created) (CouchdbDatabase *database, CouchdbDocument *document);
- void (* document_updated) (CouchdbDatabase *database, CouchdbDocument *document);
+ void (* document_created) (CouchdbDatabase *database, JsonObject *document);
+ void (* document_updated) (CouchdbDatabase *database, JsonObject *document);
void (* document_deleted) (CouchdbDatabase *database, const char *docid);
} CouchdbDatabaseClass;
+enum {
+ COUCHDB_DATABASE_ERROR_DOCUMENT_CONFLICT,
+ COUCHDB_DATABASE_ERROR_UNKNOWN
+};
+
+GQuark couchdb_database_error_quark (void);
+
GType couchdb_database_get_type (void);
CouchdbDatabase *couchdb_database_new (CouchdbSession *session, const char *dbname);
-GSList *couchdb_database_list_documents (CouchdbDatabase *database, GError **error);
-GSList *couchdb_database_get_design_documents (CouchdbDatabase *database, GError **error);
-GSList *couchdb_database_get_all_documents (CouchdbDatabase *database, GError **error);
-GSList *couchdb_database_execute_view (CouchdbDatabase *database,
- const char *design_doc,
- const char *view_name,
- GError **error);
-void couchdb_database_free_document_list (GSList *doclist);
+GList *couchdb_database_list_documents (CouchdbDatabase *database, GError **error);
+GList *couchdb_database_get_design_documents (CouchdbDatabase *database, GError **error);
+GList *couchdb_database_get_all_documents (CouchdbDatabase *database, GError **error);
-CouchdbDocument *couchdb_database_get_document (CouchdbDatabase *database,
- const char *docid,
+CouchdbResponse * couchdb_database_execute_query (CouchdbDatabase *self,
+ CouchdbQuery *query,
+ GError **error);
+
+JsonObject *couchdb_database_get_document (CouchdbDatabase *database,
+ const char *id,
+ const char *revision,
GError **error);
-CouchdbDesignDocument *couchdb_database_get_design_document (CouchdbDatabase *database,
+JsonObject *couchdb_database_get_design_document (CouchdbDatabase *database,
const char *docid,
GError **error);
-gboolean couchdb_database_put_document (CouchdbDatabase *database,
- CouchdbDocument *document,
- GError **error);
-gboolean couchdb_database_delete_document (CouchdbDatabase *database, CouchdbDocument *document, GError **error);
-
+gboolean couchdb_database_put_document (CouchdbDatabase *database,
+ JsonObject *document,
+ GError **error);
+gboolean couchdb_database_delete_document (CouchdbDatabase *database,
+ JsonObject *document,
+ GError **error);
+#if 0
+void couchdb_database_put_attachment (CouchdbDatabase * self,
+ JsonObject * document,
+ CouchdbAttachment * attachment,
+ GError ** error);
+CouchdbAttachment * couchdb_database_get_attachment (CouchdbDatabase * self,
+ JsonObject * document,
+ GError ** error);
+void couchdb_database_delete_attachment (CouchdbDatabase * self,
+ JsonObject * document,
+ CouchdbAttachment * attachment,
+ GError ** error);
+#endif
void couchdb_database_listen_for_changes (CouchdbDatabase *database);
CouchdbSession *couchdb_database_get_session (CouchdbDatabase *database);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]