1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2011 Shaun McCance <shaunm@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 * Author: Shaun McCance <shaunm@gnome.org>
23 #include <glib/gi18n.h>
26 #include "yelp-sqlite-storage.h"
28 static void yelp_sqlite_storage_iface_init (YelpStorageInterface
*iface
);
29 static void yelp_sqlite_storage_finalize (GObject
*object
);
30 static void yelp_sqlite_storage_get_property (GObject
*object
,
34 static void yelp_sqlite_storage_set_property (GObject
*object
,
39 static void yelp_sqlite_storage_update (YelpStorage
*storage
,
41 const gchar
*full_uri
,
46 static GVariant
* yelp_sqlite_storage_search (YelpStorage
*storage
,
49 static gchar
* yelp_sqlite_storage_get_root_title (YelpStorage
*storage
,
50 const gchar
*doc_uri
);
51 static void yelp_sqlite_storage_set_root_title (YelpStorage
*storage
,
55 typedef struct _YelpSqliteStoragePrivate YelpSqliteStoragePrivate
;
56 struct _YelpSqliteStoragePrivate
{
67 G_DEFINE_TYPE_WITH_CODE (YelpSqliteStorage
, yelp_sqlite_storage
, G_TYPE_OBJECT
,
68 G_IMPLEMENT_INTERFACE (YELP_TYPE_STORAGE
,
69 yelp_sqlite_storage_iface_init
))
70 #define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStoragePrivate))
73 yelp_sqlite_storage_finalize (GObject
*object
)
75 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
78 g_free (priv
->filename
);
81 sqlite3_close (priv
->db
);
83 g_mutex_clear (&priv
->mutex
);
85 G_OBJECT_CLASS (yelp_sqlite_storage_parent_class
)->finalize (object
);
89 yelp_sqlite_storage_init (YelpSqliteStorage
*storage
)
91 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
92 g_mutex_init (&priv
->mutex
);
96 yelp_sqlite_storage_constructed (GObject
*object
)
99 sqlite3_stmt
*stmt
= NULL
;
100 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
102 if (priv
->filename
!= NULL
)
103 status
= sqlite3_open (priv
->filename
, &(priv
->db
));
105 status
= sqlite3_open (":memory:", &(priv
->db
));
107 if (status
!= SQLITE_OK
)
110 status
= sqlite3_prepare_v2 (priv
->db
,
111 "create virtual table pages using fts4("
112 " doc_uri, lang, full_uri,"
113 " title, desc, icon, body"
116 if (status
!= SQLITE_OK
)
119 sqlite3_finalize (stmt
);
121 status
= sqlite3_prepare_v2 (priv
->db
,
122 "create table titles (doc_uri text, lang text, title text);",
124 if (status
!= SQLITE_OK
)
127 sqlite3_finalize (stmt
);
131 yelp_sqlite_storage_class_init (YelpSqliteStorageClass
*klass
)
133 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
135 object_class
->constructed
= yelp_sqlite_storage_constructed
;
136 object_class
->finalize
= yelp_sqlite_storage_finalize
;
137 object_class
->get_property
= yelp_sqlite_storage_get_property
;
138 object_class
->set_property
= yelp_sqlite_storage_set_property
;
140 g_type_class_add_private (klass
, sizeof (YelpSqliteStoragePrivate
));
142 g_object_class_install_property (object_class
,
144 g_param_spec_string ("filename",
146 "The filename of the sqlite database",
148 G_PARAM_CONSTRUCT_ONLY
| G_PARAM_READWRITE
|
149 G_PARAM_STATIC_STRINGS
));
153 yelp_sqlite_storage_iface_init (YelpStorageInterface
*iface
)
155 iface
->update
= yelp_sqlite_storage_update
;
156 iface
->search
= yelp_sqlite_storage_search
;
157 iface
->get_root_title
= yelp_sqlite_storage_get_root_title
;
158 iface
->set_root_title
= yelp_sqlite_storage_set_root_title
;
162 yelp_sqlite_storage_new (const gchar
*filename
)
164 YelpStorage
*storage
;
166 storage
= g_object_new (YELP_TYPE_SQLITE_STORAGE
,
167 "filename", filename
,
174 yelp_sqlite_storage_get_property (GObject
*object
,
179 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
183 g_value_set_string (value
, priv
->filename
);
186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
192 yelp_sqlite_storage_set_property (GObject
*object
,
197 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
201 priv
->filename
= g_value_dup_string (value
);
204 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
209 /******************************************************************************/
212 yelp_sqlite_storage_update (YelpStorage
*storage
,
213 const gchar
*doc_uri
,
214 const gchar
*full_uri
,
220 sqlite3_stmt
*stmt
= NULL
;
221 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
223 g_mutex_lock (&priv
->mutex
);
225 sqlite3_prepare_v2 (priv
->db
,
226 "delete from pages where doc_uri = ? and lang = ? and full_uri = ?;",
228 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
229 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
230 sqlite3_bind_text (stmt
, 3, full_uri
, -1, SQLITE_TRANSIENT
);
232 sqlite3_finalize (stmt
);
234 sqlite3_prepare_v2 (priv
->db
,
235 "insert into pages (doc_uri, lang, full_uri, title, desc, icon, body)"
236 " values (?, ?, ?, ?, ?, ?, ?);",
238 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
239 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
240 sqlite3_bind_text (stmt
, 3, full_uri
, -1, SQLITE_TRANSIENT
);
241 sqlite3_bind_text (stmt
, 4, title
, -1, SQLITE_TRANSIENT
);
242 sqlite3_bind_text (stmt
, 5, desc
, -1, SQLITE_TRANSIENT
);
243 sqlite3_bind_text (stmt
, 6, icon
, -1, SQLITE_TRANSIENT
);
244 sqlite3_bind_text (stmt
, 7, text
, -1, SQLITE_TRANSIENT
);
246 sqlite3_finalize (stmt
);
248 g_mutex_unlock (&priv
->mutex
);
252 yelp_sqlite_storage_search (YelpStorage
*storage
,
253 const gchar
*doc_uri
,
256 sqlite3_stmt
*stmt
= NULL
;
257 GVariantBuilder builder
;
259 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
261 g_mutex_lock (&priv
->mutex
);
263 sqlite3_prepare_v2 (priv
->db
,
264 "select full_uri, title, desc, icon from pages where"
265 " doc_uri = ? and lang = ? and body match ?;",
267 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
268 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
269 sqlite3_bind_text (stmt
, 3, text
, -1, SQLITE_TRANSIENT
);
271 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("a(ssss)"));
272 while (sqlite3_step (stmt
) == SQLITE_ROW
) {
273 g_variant_builder_add (&builder
, "(ssss)",
274 sqlite3_column_text (stmt
, 0),
275 sqlite3_column_text (stmt
, 1),
276 sqlite3_column_text (stmt
, 2),
277 sqlite3_column_text (stmt
, 3));
279 sqlite3_finalize (stmt
);
280 ret
= g_variant_new ("a(ssss)", &builder
);
282 g_mutex_unlock (&priv
->mutex
);
288 yelp_sqlite_storage_get_root_title (YelpStorage
*storage
,
289 const gchar
*doc_uri
)
292 sqlite3_stmt
*stmt
= NULL
;
293 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
295 g_mutex_lock (&priv
->mutex
);
297 sqlite3_prepare_v2 (priv
->db
,
298 "select title from titles where doc_uri = ? and lang = ?;",
300 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
301 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
302 if (sqlite3_step (stmt
) == SQLITE_ROW
)
303 ret
= g_strdup ((const gchar
*) sqlite3_column_text (stmt
, 0));
304 sqlite3_finalize (stmt
);
306 g_mutex_unlock (&priv
->mutex
);
311 yelp_sqlite_storage_set_root_title (YelpStorage
*storage
,
312 const gchar
*doc_uri
,
315 sqlite3_stmt
*stmt
= NULL
;
316 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
318 g_mutex_lock (&priv
->mutex
);
320 sqlite3_prepare_v2 (priv
->db
,
321 "delete from titles where doc_uri = ? and lang = ?;",
323 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
324 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
326 sqlite3_finalize (stmt
);
328 sqlite3_prepare_v2 (priv
->db
,
329 "insert into titles (doc_uri, lang, title)"
330 " values (?, ?, ?);",
332 sqlite3_bind_text (stmt
, 1, doc_uri
, -1, SQLITE_TRANSIENT
);
333 sqlite3_bind_text (stmt
, 2, g_get_language_names()[0], -1, SQLITE_STATIC
);
334 sqlite3_bind_text (stmt
, 3, title
, -1, SQLITE_TRANSIENT
);
336 sqlite3_finalize (stmt
);
338 g_mutex_unlock (&priv
->mutex
);