[yelp: 1/17] libyelp: All the hooks in place for search stuff



commit 70bc039b40482243830363e54f87b6a49647ee30
Author: Shaun McCance <shaunm gnome org>
Date:   Tue Feb 8 22:15:28 2011 -0500

    libyelp: All the hooks in place for search stuff

 configure.ac                    |    1 +
 libyelp/Makefile.am             |   14 ++-
 libyelp/yelp-docbook-document.c |    7 +-
 libyelp/yelp-document.c         |  195 +++++++++++++++++++++++++++++++++++-
 libyelp/yelp-document.h         |    5 +-
 libyelp/yelp-info-document.c    |    7 +-
 libyelp/yelp-location-entry.c   |    9 ++-
 libyelp/yelp-mallard-document.c |    7 +-
 libyelp/yelp-man-document.c     |    7 +-
 libyelp/yelp-simple-document.c  |    7 +-
 libyelp/yelp-sqlite-storage.c   |  212 +++++++++++++++++++++++++++++++++++++++
 libyelp/yelp-sqlite-storage.h   |   56 ++++++++++
 libyelp/yelp-storage.c          |   87 ++++++++++++++++
 libyelp/yelp-storage.h          |   71 +++++++++++++
 libyelp/yelp-uri.c              |   24 ++++-
 libyelp/yelp-uri.h              |    3 +-
 16 files changed, 692 insertions(+), 20 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9900164..c36dae5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,7 @@ PKG_CHECK_MODULES(YELP,
 	libxml-2.0 >= 2.6.5
 	libxslt >= 1.1.4
 	libexslt >= 0.8.1
+	sqlite3
 	webkitgtk-3.0 >= 1.3.2
 	yelp-xsl >= 2.91.9
 ])
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 30e26b6..a4dd68b 100644
--- a/libyelp/Makefile.am
+++ b/libyelp/Makefile.am
@@ -1,6 +1,6 @@
 lib_LTLIBRARIES = libyelp.la
 
-libyelp_la_SOURCES =            \
+libyelp_la_SOURCES =                \
 	yelp-bookmarks.c            \
 	yelp-debug.c                \
 	yelp-error.c                \
@@ -17,12 +17,14 @@ libyelp_la_SOURCES =            \
 	yelp-marshal.c              \
 	yelp-settings.c             \
 	yelp-simple-document.c      \
+	yelp-sqlite-storage.c       \
+	yelp-storage.c              \
 	yelp-transform.c            \
 	yelp-uri.c                  \
 	yelp-types.c                \
 	yelp-view.c
 
-EXTRA_DIST =                    \
+EXTRA_DIST =                        \
 	yelp-bz2-decompressor.h     \
 	yelp-debug.h                \
 	yelp-error.h                \
@@ -44,14 +46,14 @@ else
 EXTRA_DIST += yelp-bz2-decompressor.c
 endif
 
-libyelp_la_CFLAGS =                         \
+libyelp_la_CFLAGS =                             \
 	$(YELP_CFLAGS)                          \
 	-DDATADIR=\""$(datadir)"\"              \
 	-DYELP_ICON_PATH=\"$(YELP_ICON_PATH)\"
 
 libyelp_la_LIBADD = $(YELP_LIBS)
 
-libyelp_headers =               \
+libyelp_headers =                   \
 	yelp-bookmarks.h            \
 	yelp-docbook-document.h     \
 	yelp-document.h             \
@@ -62,6 +64,8 @@ libyelp_headers =               \
 	yelp-man-document.h         \
 	yelp-settings.h             \
 	yelp-simple-document.h      \
+	yelp-sqlite-storage.h       \
+	yelp-storage.h              \
 	yelp-transform.h            \
 	yelp-uri.h                  \
 	yelp-view.h
@@ -70,7 +74,7 @@ libyelp_includedir = $(includedir)/libyelp/
 
 libyelp_include_HEADERS = $(libyelp_headers) yelp-types.h
 
-BUILT_SOURCES =              \
+BUILT_SOURCES =                  \
 	stamp-yelp-marshal.h     \
 	yelp-marshal.c           \
 	yelp-marshal.h           \
diff --git a/libyelp/yelp-docbook-document.c b/libyelp/yelp-docbook-document.c
index d4b4cec..29155d9 100644
--- a/libyelp/yelp-docbook-document.c
+++ b/libyelp/yelp-docbook-document.c
@@ -204,10 +204,15 @@ yelp_docbook_document_new (YelpUri *uri)
 {
     YelpDocbookDocument *docbook;
     YelpDocbookDocumentPrivate *priv;
+    gchar *doc_uri;
 
     g_return_val_if_fail (uri != NULL, NULL);
 
-    docbook = (YelpDocbookDocument *) g_object_new (YELP_TYPE_DOCBOOK_DOCUMENT, NULL);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    docbook = (YelpDocbookDocument *) g_object_new (YELP_TYPE_DOCBOOK_DOCUMENT,
+                                                    "document-uri", doc_uri,
+                                                    NULL);
+    g_free (doc_uri);
     priv = GET_PRIV (docbook);
 
     priv->uri = g_object_ref (uri);
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index b1d17b8..52f9399 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -36,6 +36,13 @@
 #include "yelp-mallard-document.h"
 #include "yelp-man-document.h"
 #include "yelp-simple-document.h"
+#include "yelp-storage.h"
+
+enum {
+    PROP_0,
+    PROP_URI,
+    PROP_INDEXED
+};
 
 typedef struct _Request Request;
 struct _Request {
@@ -63,6 +70,11 @@ struct _YelpDocumentPriv {
     Hash   *reqs_by_page_id;  /* Indexed by page ID, contains GSList */
     GSList *reqs_pending;     /* List of requests that need a page */
 
+    GSList *reqs_search;      /* Pending search requests, not in reqs_all */
+    gboolean indexed;
+
+    gchar  *doc_uri;
+
     /* Real page IDs map to themselves, so this list doubles
      * as a list of all valid page IDs.
      */
@@ -90,18 +102,27 @@ static void           yelp_document_class_init  (YelpDocumentClass    *klass);
 static void           yelp_document_init        (YelpDocument         *document);
 static void           yelp_document_dispose     (GObject              *object);
 static void           yelp_document_finalize    (GObject              *object);
-
+static void           document_get_property     (GObject              *object,
+                                                 guint                 prop_id,
+                                                 GValue               *value,
+                                                 GParamSpec           *pspec);
+static void           document_set_property     (GObject              *object,
+                                                 guint                 prop_id,
+                                                 const GValue         *value,
+                                                 GParamSpec           *pspec);
 static gboolean       document_request_page     (YelpDocument         *document,
                                                  const gchar          *page_id,
                                                  GCancellable         *cancellable,
                                                  YelpDocumentCallback  callback,
                                                  gpointer              user_data);
+static void           document_indexed          (YelpDocument         *document);
 static const gchar *  document_read_contents    (YelpDocument         *document,
                                                  const gchar          *page_id);
 static void           document_finish_read      (YelpDocument         *document,
                                                  const gchar          *contents);
 static gchar *        document_get_mime_type    (YelpDocument         *document,
                                                  const gchar          *mime_type);
+static void           document_index            (YelpDocument         *document);
 
 static Hash *         hash_new                  (GDestroyNotify        destroy);
 static void           hash_free                 (Hash                 *hash);
@@ -204,9 +225,6 @@ yelp_document_get_for_uri (YelpUri *uri)
     case YELP_URI_DOCUMENT_TYPE_HELP_LIST:
         document = yelp_help_list_new (uri);
         break;
-    case YELP_URI_DOCUMENT_TYPE_SEARCH:
-        /* FIXME */
-        break;
     case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
     case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
     case YELP_URI_DOCUMENT_TYPE_ERROR:
@@ -231,11 +249,32 @@ yelp_document_class_init (YelpDocumentClass *klass)
 
     object_class->dispose  = yelp_document_dispose;
     object_class->finalize = yelp_document_finalize;
+    object_class->get_property = document_get_property;
+    object_class->set_property = document_set_property;
 
     klass->request_page =   document_request_page;
     klass->read_contents =  document_read_contents;
     klass->finish_read =    document_finish_read;
     klass->get_mime_type =  document_get_mime_type;
+    klass->index =          document_index;
+
+    g_object_class_install_property (object_class,
+                                     PROP_INDEXED,
+                                     g_param_spec_boolean ("indexed",
+                                                           N_("Indexed"),
+                                                           N_("Whether the document content has been indexed"),
+                                                           FALSE,
+                                                           G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
+                                                           G_PARAM_STATIC_STRINGS));
+
+    g_object_class_install_property (object_class,
+                                     PROP_URI,
+                                     g_param_spec_string ("document-uri",
+                                                          N_("Document URI"),
+                                                          N_("The URI which identifies the document"),
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+                                                          G_PARAM_STATIC_STRINGS));
 
     g_type_class_add_private (klass, sizeof (YelpDocumentPriv));
 }
@@ -252,6 +291,7 @@ yelp_document_init (YelpDocument *document)
     priv->reqs_by_page_id = hash_new ((GDestroyNotify) g_slist_free);
     priv->reqs_all = NULL;
     priv->reqs_pending = NULL;
+    priv->reqs_search = NULL;
 
     priv->core_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
     priv->page_ids = hash_new (g_free );
@@ -280,6 +320,14 @@ yelp_document_dispose (GObject *object)
 	document->priv->reqs_all = NULL;
     }
 
+    if (document->priv->reqs_search) {
+	g_slist_foreach (document->priv->reqs_search,
+			 (GFunc) request_try_free,
+			 NULL);
+	g_slist_free (document->priv->reqs_search);
+	document->priv->reqs_search = NULL;
+    }
+
     G_OBJECT_CLASS (yelp_document_parent_class)->dispose (object);
 }
 
@@ -311,6 +359,52 @@ yelp_document_finalize (GObject *object)
     G_OBJECT_CLASS (yelp_document_parent_class)->finalize (object);
 }
 
+static void
+document_get_property (GObject      *object,
+                       guint         prop_id,
+                       GValue       *value,
+                       GParamSpec   *pspec)
+{
+    YelpDocument *document = YELP_DOCUMENT (object);
+
+    switch (prop_id) {
+    case PROP_INDEXED:
+        g_value_set_boolean (value, document->priv->indexed);
+        break;
+    case PROP_URI:
+        g_value_set_string (value, document->priv->doc_uri);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+document_set_property (GObject      *object,
+                       guint         prop_id,
+                       const GValue *value,
+                       GParamSpec   *pspec)
+{
+    YelpDocument *document = YELP_DOCUMENT (object);
+
+    switch (prop_id) {
+    case PROP_INDEXED:
+        document->priv->indexed = g_value_get_boolean (value);
+        if (document->priv->indexed)
+            g_idle_add ((GSourceFunc) document_indexed, document);
+        break;
+    case PROP_URI:
+        if (document->priv->doc_uri != NULL)
+            g_free (document->priv->doc_uri);
+        document->priv->doc_uri = g_value_dup_string (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
 /******************************************************************************/
 
 gchar **
@@ -642,6 +736,20 @@ yelp_document_set_page_icon (YelpDocument *document,
     g_mutex_unlock (document->priv->mutex);
 }
 
+static void
+document_indexed (YelpDocument *document)
+{
+    g_mutex_lock (document->priv->mutex);
+    while (document->priv->reqs_search != NULL) {
+        Request *request = (Request *) document->priv->reqs_search->data;
+        request->idle_funcs++;
+        g_idle_add ((GSourceFunc) request_idle_contents, request);
+        document->priv->reqs_search = g_slist_delete_link (document->priv->reqs_search,
+                                                           document->priv->reqs_search);
+    }
+    g_mutex_unlock (document->priv->mutex);
+}
+
 /******************************************************************************/
 
 gboolean
@@ -693,6 +801,16 @@ document_request_page (YelpDocument         *document,
 
     g_mutex_lock (document->priv->mutex);
 
+    if (g_str_has_prefix (page_id, "search=")) {
+        document->priv->reqs_search = g_slist_prepend (document->priv->reqs_search, request);
+        if (document->priv->indexed)
+            g_idle_add ((GSourceFunc) document_indexed, document);
+        else
+            yelp_document_index (document);
+        g_mutex_unlock (document->priv->mutex);
+        return TRUE;
+    }
+
     hash_slist_insert (document->priv->reqs_by_page_id,
 		       request->page_id,
 		       request);
@@ -736,6 +854,48 @@ document_read_contents (YelpDocument *document,
 
     g_mutex_lock (document->priv->mutex);
 
+    if (page_id != NULL && g_str_has_prefix (page_id, "search=")) {
+        gchar *tmp, *txt;
+        GVariant *value;
+        GVariantIter *iter;
+        gchar *url, *title, *desc, *icon; /* do not free */
+        GString *ret = g_string_new ("<html><body>");
+
+        str = hash_lookup (document->priv->contents, real);
+        if (str) {
+            str_ref (str);
+            g_mutex_unlock (document->priv->mutex);
+            return (const gchar *) str;
+        }
+
+        txt = g_uri_unescape_string (page_id + 7, NULL);
+        tmp = g_markup_printf_escaped ("<h1>Search results for â??%sâ??</h1>", txt);
+        g_string_append (ret, tmp);
+        g_free (tmp);
+
+        value = yelp_storage_search (yelp_storage_get_default (),
+                                     document->priv->doc_uri,
+                                     txt);
+        iter = g_variant_iter_new (value);
+        while (g_variant_iter_loop (iter, "(&s&s&s&s)", &url, &title, &desc, &icon)) {
+            tmp = g_strdup_printf ("<div><a href='%s'>%s</a></div>", url, title);
+            g_string_append (ret, tmp);
+            g_free (tmp);
+        }
+        g_variant_iter_free (iter);
+        g_variant_unref (value);
+
+        g_free (txt);
+        g_string_append (ret, "</body></html>");
+        g_mutex_unlock (document->priv->mutex);
+
+        hash_replace (document->priv->contents, page_id, g_string_free (ret, FALSE));
+        str = hash_lookup (document->priv->contents, page_id);
+        str_ref (str);
+        g_mutex_unlock (document->priv->mutex);
+        return (const gchar *) str;
+    }
+
     real = hash_lookup (document->priv->page_ids, page_id);
     str = hash_lookup (document->priv->contents, real);
     if (str)
@@ -818,6 +978,23 @@ document_get_mime_type (YelpDocument *document,
 /******************************************************************************/
 
 void
+yelp_document_index (YelpDocument *document)
+{
+    g_return_if_fail (YELP_IS_DOCUMENT (document));
+    g_return_if_fail (YELP_DOCUMENT_GET_CLASS (document)->index != NULL);
+
+    YELP_DOCUMENT_GET_CLASS (document)->index (document);
+}
+
+static void
+document_index (YelpDocument *document)
+{
+    g_object_set (document, "indexed", TRUE, NULL);
+}
+
+/******************************************************************************/
+
+void
 yelp_document_signal (YelpDocument       *document,
 		      const gchar        *page_id,
 		      YelpDocumentSignal  signal,
@@ -994,6 +1171,7 @@ request_cancel (GCancellable *cancellable, Request *request)
 {
     GSList *cur;
     YelpDocument *document = request->document;
+    gboolean found = FALSE;
 
     g_assert (document != NULL && YELP_IS_DOCUMENT (document));
 
@@ -1007,9 +1185,18 @@ request_cancel (GCancellable *cancellable, Request *request)
     for (cur = document->priv->reqs_all; cur != NULL; cur = cur->next) {
 	if (cur->data == request) {
 	    document->priv->reqs_all = g_slist_delete_link (document->priv->reqs_all, cur);
+            found = TRUE;
 	    break;
 	}
     }
+    if (!found) {
+        for (cur = document->priv->reqs_search; cur != NULL; cur = cur->next) {
+            if (cur->data == request) {
+                document->priv->reqs_search = g_slist_delete_link (document->priv->reqs_search, cur);
+                break;
+            }
+        }
+    }
     request_try_free (request);
 
     g_mutex_unlock (document->priv->mutex);
diff --git a/libyelp/yelp-document.h b/libyelp/yelp-document.h
index d9f30af..b79d47b 100644
--- a/libyelp/yelp-document.h
+++ b/libyelp/yelp-document.h
@@ -71,7 +71,8 @@ struct _YelpDocumentClass {
     void          (*finish_read)               (YelpDocument         *document,
                                                 const gchar          *contents);
     gchar *       (*get_mime_type)             (YelpDocument         *document,
-                                                const gchar          *mime_type);
+                                                const gchar          *page_id);
+    void          (*index)                     (YelpDocument         *document);
 
 };
 
@@ -96,6 +97,8 @@ const gchar *     yelp_document_read_contents  (YelpDocument         *document,
 void              yelp_document_finish_read    (YelpDocument         *document,
                                                 const gchar          *contents);
 
+void              yelp_document_index          (YelpDocument         *document);
+
 gchar **          yelp_document_list_page_ids  (YelpDocument         *document);
 
 gchar *           yelp_document_get_page_id    (YelpDocument         *document,
diff --git a/libyelp/yelp-info-document.c b/libyelp/yelp-info-document.c
index acfb33f..136b274 100644
--- a/libyelp/yelp-info-document.c
+++ b/libyelp/yelp-info-document.c
@@ -174,10 +174,15 @@ yelp_info_document_new (YelpUri *uri)
 {
     YelpInfoDocument *info;
     YelpInfoDocumentPrivate *priv;
+    gchar *doc_uri;
 
     g_return_val_if_fail (uri != NULL, NULL);
 
-    info = (YelpInfoDocument *) g_object_new (YELP_TYPE_INFO_DOCUMENT, NULL);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    info = (YelpInfoDocument *) g_object_new (YELP_TYPE_INFO_DOCUMENT,
+                                              "document-uri", doc_uri,
+                                              NULL);
+    g_free (doc_uri);
     priv = GET_PRIV (info);
 
     priv->uri = g_object_ref (uri);
diff --git a/libyelp/yelp-location-entry.c b/libyelp/yelp-location-entry.c
index b206afd..8af9026 100644
--- a/libyelp/yelp-location-entry.c
+++ b/libyelp/yelp-location-entry.c
@@ -611,7 +611,14 @@ location_entry_location_selected (YelpLocationEntry *entry)
 static void
 location_entry_search_activated  (YelpLocationEntry *entry)
 {
-    printf ("FIXME: search_activated\n");
+    YelpUri *base, *uri;
+    YelpLocationEntryPrivate *priv = GET_PRIV (entry);
+
+    g_object_get (priv->view, "yelp-uri", &base, NULL);
+    uri = yelp_uri_new_search (base,
+                               gtk_entry_get_text (GTK_ENTRY (priv->text_entry)));
+    g_object_unref (base);
+    yelp_view_load_uri (priv->view, uri);
 }
 
 static void
diff --git a/libyelp/yelp-mallard-document.c b/libyelp/yelp-mallard-document.c
index 6b64633..9c28658 100644
--- a/libyelp/yelp-mallard-document.c
+++ b/libyelp/yelp-mallard-document.c
@@ -194,10 +194,15 @@ yelp_mallard_document_new (YelpUri *uri)
 {
     YelpMallardDocument *mallard;
     YelpMallardDocumentPrivate *priv;
+    gchar *doc_uri;
 
     g_return_val_if_fail (uri != NULL, NULL);
 
-    mallard = (YelpMallardDocument *) g_object_new (YELP_TYPE_MALLARD_DOCUMENT, NULL);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    mallard = (YelpMallardDocument *) g_object_new (YELP_TYPE_MALLARD_DOCUMENT,
+                                                    "document-uri", doc_uri,
+                                                    NULL);
+    g_free (doc_uri);
     priv = GET_PRIV (mallard);
     priv->uri = g_object_ref (uri);
 
diff --git a/libyelp/yelp-man-document.c b/libyelp/yelp-man-document.c
index f3c42a6..a49dfba 100644
--- a/libyelp/yelp-man-document.c
+++ b/libyelp/yelp-man-document.c
@@ -209,10 +209,15 @@ yelp_man_document_new (YelpUri *uri)
 {
     YelpManDocument *man;
     YelpManDocumentPrivate *priv;
+    gchar *doc_uri;
 
     g_return_val_if_fail (uri != NULL, NULL);
 
-    man = (YelpManDocument *) g_object_new (YELP_TYPE_MAN_DOCUMENT, NULL);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    man = (YelpManDocument *) g_object_new (YELP_TYPE_MAN_DOCUMENT,
+                                            "document-uri", doc_uri,
+                                            NULL);
+    g_free (doc_uri);
     priv = GET_PRIV (man);
 
     priv->uri = g_object_ref (uri);
diff --git a/libyelp/yelp-simple-document.c b/libyelp/yelp-simple-document.c
index de62a9b..8f2dadc 100644
--- a/libyelp/yelp-simple-document.c
+++ b/libyelp/yelp-simple-document.c
@@ -166,8 +166,13 @@ YelpDocument *
 yelp_simple_document_new (YelpUri *uri)
 {
     YelpSimpleDocument *document;
+    gchar *doc_uri;
 
-    document = (YelpSimpleDocument *) g_object_new (YELP_TYPE_SIMPLE_DOCUMENT, NULL);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    document = (YelpSimpleDocument *) g_object_new (YELP_TYPE_SIMPLE_DOCUMENT,
+                                                    "document-uri", doc_uri,
+                                                    NULL);
+    g_free (doc_uri);
 
     document->priv->file = yelp_uri_get_file (uri);
 
diff --git a/libyelp/yelp-sqlite-storage.c b/libyelp/yelp-sqlite-storage.c
new file mode 100644
index 0000000..17a987d
--- /dev/null
+++ b/libyelp/yelp-sqlite-storage.c
@@ -0,0 +1,212 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2011 Shaun McCance <shaunm gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "yelp-sqlite-storage.h"
+
+static void        yelp_sqlite_storage_init         (YelpSqliteStorage      *storage);
+static void        yelp_sqlite_storage_class_init   (YelpSqliteStorageClass *klass);
+static void        yelp_sqlite_storage_iface_init   (YelpStorageInterface   *iface);
+static void        yelp_sqlite_storage_finalize     (GObject                *object);
+static void        yelp_sqlite_storage_get_property (GObject                *object,
+                                                     guint                   prop_id,
+                                                     GValue                 *value,
+                                                     GParamSpec             *pspec);
+static void        yelp_sqlite_storage_set_property (GObject                *object,
+                                                     guint                   prop_id,
+                                                     const GValue           *value,
+                                                     GParamSpec             *pspec);
+
+static void        yelp_sqlite_storage_update      (YelpStorage      *storage,
+                                                    const gchar      *doc_uri,
+                                                    const gchar      *full_uri,
+                                                    const gchar      *title,
+                                                    const gchar      *desc,
+                                                    const gchar      *icon,
+                                                    const gchar      *text);
+static GVariant *  yelp_sqlite_storage_search      (YelpStorage      *storage,
+                                                    const gchar      *doc_uri,
+                                                    const gchar      *text);
+
+typedef struct _YelpSqliteStoragePrivate YelpSqliteStoragePrivate;
+struct _YelpSqliteStoragePrivate {
+    gchar   *filename;
+    sqlite3 *db;
+};
+
+enum {  
+    PROP_0,
+    PROP_FILENAME
+};
+
+G_DEFINE_TYPE_WITH_CODE (YelpSqliteStorage, yelp_sqlite_storage, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (YELP_TYPE_STORAGE,
+                                                yelp_sqlite_storage_iface_init))
+#define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStoragePrivate))
+
+static void
+yelp_sqlite_storage_finalize (GObject *object)
+{
+    YelpSqliteStoragePrivate *priv = GET_PRIV (object);
+
+    if (priv->filename)
+        g_free (priv->filename);
+
+    if (priv->db)
+        sqlite3_close (priv->db);
+
+    G_OBJECT_CLASS (yelp_sqlite_storage_parent_class)->finalize (object);
+}
+
+static void
+yelp_sqlite_storage_init (YelpSqliteStorage *storage)
+{
+}
+
+static void
+yelp_sqlite_storage_constructed (GObject *object)
+{
+    YelpSqliteStoragePrivate *priv = GET_PRIV (object);
+
+    if (priv->filename != NULL)
+        sqlite3_open (priv->filename, &(priv->db));
+    else
+        sqlite3_open (":memory:", &(priv->db));
+
+    /* FIXME: create tables if necessary */
+}
+
+static void
+yelp_sqlite_storage_class_init (YelpSqliteStorageClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->constructed = yelp_sqlite_storage_constructed;
+    object_class->finalize = yelp_sqlite_storage_finalize;
+    object_class->get_property = yelp_sqlite_storage_get_property;
+    object_class->set_property = yelp_sqlite_storage_set_property;
+
+    g_type_class_add_private (klass, sizeof (YelpSqliteStoragePrivate));
+
+    g_object_class_install_property (object_class,
+                                     PROP_FILENAME,
+                                     g_param_spec_string ("filename",
+                                                          N_("Database filename"),
+                                                          N_("The filename of the sqlite database"),
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+                                                          G_PARAM_STATIC_STRINGS));
+}
+
+static void
+yelp_sqlite_storage_iface_init (YelpStorageInterface *iface)
+{
+    iface->update = yelp_sqlite_storage_update;
+    iface->search = yelp_sqlite_storage_search;
+}
+
+YelpStorage *
+yelp_sqlite_storage_new (const gchar *filename)
+{
+    YelpStorage *storage;
+
+    storage = g_object_new (YELP_TYPE_SQLITE_STORAGE,
+                            "filename", filename,
+                            NULL);
+
+    return storage;
+}
+
+static void
+yelp_sqlite_storage_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+    YelpSqliteStoragePrivate *priv = GET_PRIV (object);
+
+    switch (prop_id) {
+    case PROP_FILENAME:
+        g_value_set_string (value, priv->filename);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+yelp_sqlite_storage_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+    YelpSqliteStoragePrivate *priv = GET_PRIV (object);
+
+    switch (prop_id) {
+    case PROP_FILENAME:
+        priv->filename = g_value_dup_string (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/******************************************************************************/
+
+static void
+yelp_sqlite_storage_update (YelpStorage   *storage,
+                            const gchar   *doc_uri,
+                            const gchar   *full_uri,
+                            const gchar   *title,
+                            const gchar   *desc,
+                            const gchar   *icon,
+                            const gchar   *text)
+{
+}
+
+static GVariant *
+yelp_sqlite_storage_search (YelpStorage   *storage,
+                            const gchar   *doc_uri,
+                            const gchar   *text)
+{
+    GVariantBuilder builder;
+    GVariant *ret;
+    int i;
+
+    /* FIXME */
+    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ssss)"));
+    for (i = 0; i < 1; i++) {
+        g_variant_builder_add (&builder, "(ssss)",
+                               doc_uri,
+                               doc_uri,
+                               "Description",
+                               "help-contents");
+    }
+    ret = g_variant_new ("a(ssss)", &builder);
+    return ret;
+}
diff --git a/libyelp/yelp-sqlite-storage.h b/libyelp/yelp-sqlite-storage.h
new file mode 100644
index 0000000..56ebddd
--- /dev/null
+++ b/libyelp/yelp-sqlite-storage.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 
+ * Copyright (C) 2011 Shaun McCance <shaunm gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_SQLITE_STORAGE_H__
+#define __YELP_SQLITE_STORAGE_H__
+
+#include <glib-object.h>
+
+#include "yelp-storage.h"
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_SQLITE_STORAGE         (yelp_sqlite_storage_get_type ())
+#define YELP_SQLITE_STORAGE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStorage))
+#define YELP_SQLITE_STORAGE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStorageClass))
+#define YELP_IS_SQLITE_STORAGE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_SQLITE_STORAGE))
+#define YELP_IS_SQLITE_STORAGE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_SQLITE_STORAGE))
+#define YELP_SQLITE_STORAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStorageClass))
+
+typedef struct _YelpSqliteStorage        YelpSqliteStorage;
+typedef struct _YelpSqliteStorageClass   YelpSqliteStorageClass;
+
+struct _YelpSqliteStorage {
+    GObject parent_instance;
+};
+
+struct _YelpSqliteStorageClass {
+    GObjectClass parent_class;
+};
+
+GType                 yelp_sqlite_storage_get_type    (void);
+
+YelpStorage *         yelp_sqlite_storage_new         (const gchar   *filename);
+
+G_END_DECLS
+
+#endif /* __YELP_SQLITE_STORAGE_H__ */
diff --git a/libyelp/yelp-storage.c b/libyelp/yelp-storage.c
new file mode 100644
index 0000000..c4886fe
--- /dev/null
+++ b/libyelp/yelp-storage.c
@@ -0,0 +1,87 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2011 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "yelp-storage.h"
+#include "yelp-sqlite-storage.h"
+
+G_DEFINE_INTERFACE (YelpStorage, yelp_storage, G_TYPE_OBJECT)
+
+static YelpStorage *default_storage;
+
+static void
+yelp_storage_default_init (YelpStorageInterface *iface)
+{
+    default_storage = NULL;
+}
+
+void
+yelp_storage_set_default (YelpStorage *storage)
+{
+    default_storage = g_object_ref (storage);
+}
+
+YelpStorage *
+yelp_storage_get_default (void)
+{
+    if (default_storage == NULL)
+        default_storage = yelp_sqlite_storage_new (":memory:");
+    return default_storage;
+}
+
+void
+yelp_storage_update (YelpStorage   *storage,
+                     const gchar   *doc_uri,
+                     const gchar   *full_uri,
+                     const gchar   *title,
+                     const gchar   *desc,
+                     const gchar   *icon,
+                     const gchar   *text)
+{
+    YelpStorageInterface *iface;
+
+    g_return_if_fail (YELP_IS_STORAGE (storage));
+
+    iface = YELP_STORAGE_GET_INTERFACE (storage);
+
+    if (iface->update)
+        (*iface->update) (storage,
+                          doc_uri, full_uri,
+                          title, desc, icon,
+                          text);
+}
+
+GVariant *
+yelp_storage_search (YelpStorage   *storage,
+                     const gchar   *doc_uri,
+                     const gchar   *text)
+{
+    YelpStorageInterface *iface;
+
+    g_return_if_fail (YELP_IS_STORAGE (storage));
+
+    iface = YELP_STORAGE_GET_INTERFACE (storage);
+
+    if (iface->search)
+        return (*iface->search) (storage, doc_uri, text);
+    else
+        return NULL;
+}
diff --git a/libyelp/yelp-storage.h b/libyelp/yelp-storage.h
new file mode 100644
index 0000000..57666a0
--- /dev/null
+++ b/libyelp/yelp-storage.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2011 Shaun McCance  <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance  <shaunm gnome org>
+ */
+
+#ifndef __YELP_STORAGE_H__
+#define __YELP_STORAGE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_STORAGE             (yelp_storage_get_type ())
+#define YELP_STORAGE(o)               (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_STORAGE, YelpStorage))
+#define YELP_IS_STORAGE(o)            (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_STORAGE))
+#define YELP_STORAGE_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), YELP_TYPE_STORAGE, YelpStorageInterface))
+
+typedef struct _YelpStorage          YelpStorage;
+typedef struct _YelpStorageInterface YelpStorageInterface;
+
+struct _YelpStorageInterface {
+    GTypeInterface base_iface;
+
+    void          (*update)        (YelpStorage   *storage,
+                                    const gchar   *doc_uri,
+                                    const gchar   *full_uri,
+                                    const gchar   *title,
+                                    const gchar   *desc,
+                                    const gchar   *icon,
+                                    const gchar   *text);
+    GVariant *    (*search)        (YelpStorage   *storage,
+                                    const gchar   *doc_uri,
+                                    const gchar   *text);
+};
+
+GType             yelp_storage_get_type       (void);
+
+void              yelp_storage_set_default    (YelpStorage   *storage);
+YelpStorage *     yelp_storage_get_default    (void);
+
+void              yelp_storage_update         (YelpStorage   *storage,
+                                               const gchar   *doc_uri,
+                                               const gchar   *full_uri,
+                                               const gchar   *title,
+                                               const gchar   *desc,
+                                               const gchar   *icon,
+                                               const gchar   *text);
+GVariant *        yelp_storage_search         (YelpStorage   *storage,
+                                               const gchar   *doc_uri,
+                                               const gchar   *text);
+
+G_END_DECLS
+
+#endif /* __YELP_STORAGE_H__ */
diff --git a/libyelp/yelp-uri.c b/libyelp/yelp-uri.c
index 9ef480e..511de8f 100644
--- a/libyelp/yelp-uri.c
+++ b/libyelp/yelp-uri.c
@@ -204,6 +204,27 @@ yelp_uri_new_relative (YelpUri *base, const gchar *arg)
     return uri;
 }
 
+YelpUri *
+yelp_uri_new_search (YelpUri      *base,
+                     const gchar  *text)
+{
+    YelpUri *uri;
+    YelpUriPrivate *priv;
+    gchar *tmp;
+
+    uri = (YelpUri *) g_object_new (YELP_TYPE_URI, NULL);
+
+    priv = GET_PRIV (uri);
+    priv->doctype = YELP_URI_DOCUMENT_TYPE_UNRESOLVED;
+    if (base)
+        priv->res_base = g_object_ref (base);
+    tmp = g_uri_escape_string (text, NULL, FALSE);
+    priv->res_arg = g_strconcat("xref:search=", tmp, NULL);
+    g_free (tmp);
+
+    return uri;
+}
+
 /******************************************************************************/
 
 void
@@ -312,9 +333,6 @@ resolve_async (YelpUri *uri)
         case YELP_URI_DOCUMENT_TYPE_HELP_LIST:
             /* FIXME: what do we do? */
             break;
-        case YELP_URI_DOCUMENT_TYPE_SEARCH:
-            /* FIXME: what do we do? */
-            break;
         case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
         case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
         case YELP_URI_DOCUMENT_TYPE_ERROR:
diff --git a/libyelp/yelp-uri.h b/libyelp/yelp-uri.h
index 86d7ae5..ab80bab 100644
--- a/libyelp/yelp-uri.h
+++ b/libyelp/yelp-uri.h
@@ -47,7 +47,6 @@ typedef enum {
     YELP_URI_DOCUMENT_TYPE_HTML,
     YELP_URI_DOCUMENT_TYPE_XHTML,
     YELP_URI_DOCUMENT_TYPE_HELP_LIST,
-    YELP_URI_DOCUMENT_TYPE_SEARCH,
     YELP_URI_DOCUMENT_TYPE_NOT_FOUND,
     YELP_URI_DOCUMENT_TYPE_EXTERNAL,
     YELP_URI_DOCUMENT_TYPE_ERROR
@@ -67,6 +66,8 @@ GType                yelp_uri_get_type           (void);
 YelpUri *            yelp_uri_new                (const gchar  *arg);
 YelpUri *            yelp_uri_new_relative       (YelpUri      *base,
                                                   const gchar  *arg);
+YelpUri *            yelp_uri_new_search         (YelpUri      *base,
+                                                  const gchar  *text);
 
 void                 yelp_uri_resolve            (YelpUri      *uri);
 



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