Updated French translation
[yelp.git] / libyelp / yelp-sqlite-storage.c
blob6c9a9d4b8390cf2c3507c16282c84fc6ac97e99f
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
21 #include "config.h"
23 #include <glib/gi18n.h>
24 #include <sqlite3.h>
26 #include "yelp-sqlite-storage.h"
28 static void yelp_sqlite_storage_init (YelpSqliteStorage *storage);
29 static void yelp_sqlite_storage_class_init (YelpSqliteStorageClass *klass);
30 static void yelp_sqlite_storage_iface_init (YelpStorageInterface *iface);
31 static void yelp_sqlite_storage_finalize (GObject *object);
32 static void yelp_sqlite_storage_get_property (GObject *object,
33 guint prop_id,
34 GValue *value,
35 GParamSpec *pspec);
36 static void yelp_sqlite_storage_set_property (GObject *object,
37 guint prop_id,
38 const GValue *value,
39 GParamSpec *pspec);
41 static void yelp_sqlite_storage_update (YelpStorage *storage,
42 const gchar *doc_uri,
43 const gchar *full_uri,
44 const gchar *title,
45 const gchar *desc,
46 const gchar *icon,
47 const gchar *text);
48 static GVariant * yelp_sqlite_storage_search (YelpStorage *storage,
49 const gchar *doc_uri,
50 const gchar *text);
51 static gchar * yelp_sqlite_storage_get_root_title (YelpStorage *storage,
52 const gchar *doc_uri);
53 static void yelp_sqlite_storage_set_root_title (YelpStorage *storage,
54 const gchar *doc_uri,
55 const gchar *title);
57 typedef struct _YelpSqliteStoragePrivate YelpSqliteStoragePrivate;
58 struct _YelpSqliteStoragePrivate {
59 gchar *filename;
60 sqlite3 *db;
61 GMutex mutex;
64 enum {
65 PROP_0,
66 PROP_FILENAME
69 G_DEFINE_TYPE_WITH_CODE (YelpSqliteStorage, yelp_sqlite_storage, G_TYPE_OBJECT,
70 G_IMPLEMENT_INTERFACE (YELP_TYPE_STORAGE,
71 yelp_sqlite_storage_iface_init))
72 #define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SQLITE_STORAGE, YelpSqliteStoragePrivate))
74 static void
75 yelp_sqlite_storage_finalize (GObject *object)
77 YelpSqliteStoragePrivate *priv = GET_PRIV (object);
79 if (priv->filename)
80 g_free (priv->filename);
82 if (priv->db)
83 sqlite3_close (priv->db);
85 g_mutex_clear (&priv->mutex);
87 G_OBJECT_CLASS (yelp_sqlite_storage_parent_class)->finalize (object);
90 static void
91 yelp_sqlite_storage_init (YelpSqliteStorage *storage)
93 YelpSqliteStoragePrivate *priv = GET_PRIV (storage);
94 g_mutex_init (&priv->mutex);
97 static void
98 yelp_sqlite_storage_constructed (GObject *object)
100 int status;
101 sqlite3_stmt *stmt = NULL;
102 YelpSqliteStoragePrivate *priv = GET_PRIV (object);
104 if (priv->filename != NULL)
105 status = sqlite3_open (priv->filename, &(priv->db));
106 else
107 status = sqlite3_open (":memory:", &(priv->db));
109 if (status != SQLITE_OK)
110 return;
112 status = sqlite3_prepare_v2 (priv->db,
113 "create virtual table pages using fts4("
114 " doc_uri, lang, full_uri,"
115 " title, desc, icon, body"
116 ");",
117 -1, &stmt, NULL);
118 if (status != SQLITE_OK)
119 return;
120 sqlite3_step (stmt);
121 sqlite3_finalize (stmt);
123 status = sqlite3_prepare_v2 (priv->db,
124 "create table titles (doc_uri text, lang text, title text);",
125 -1, &stmt, NULL);
126 if (status != SQLITE_OK)
127 return;
128 sqlite3_step (stmt);
129 sqlite3_finalize (stmt);
132 static void
133 yelp_sqlite_storage_class_init (YelpSqliteStorageClass *klass)
135 GObjectClass *object_class = G_OBJECT_CLASS (klass);
137 object_class->constructed = yelp_sqlite_storage_constructed;
138 object_class->finalize = yelp_sqlite_storage_finalize;
139 object_class->get_property = yelp_sqlite_storage_get_property;
140 object_class->set_property = yelp_sqlite_storage_set_property;
142 g_type_class_add_private (klass, sizeof (YelpSqliteStoragePrivate));
144 g_object_class_install_property (object_class,
145 PROP_FILENAME,
146 g_param_spec_string ("filename",
147 N_("Database filename"),
148 N_("The filename of the sqlite database"),
149 NULL,
150 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
151 G_PARAM_STATIC_STRINGS));
154 static void
155 yelp_sqlite_storage_iface_init (YelpStorageInterface *iface)
157 iface->update = yelp_sqlite_storage_update;
158 iface->search = yelp_sqlite_storage_search;
159 iface->get_root_title = yelp_sqlite_storage_get_root_title;
160 iface->set_root_title = yelp_sqlite_storage_set_root_title;
163 YelpStorage *
164 yelp_sqlite_storage_new (const gchar *filename)
166 YelpStorage *storage;
168 storage = g_object_new (YELP_TYPE_SQLITE_STORAGE,
169 "filename", filename,
170 NULL);
172 return storage;
175 static void
176 yelp_sqlite_storage_get_property (GObject *object,
177 guint prop_id,
178 GValue *value,
179 GParamSpec *pspec)
181 YelpSqliteStoragePrivate *priv = GET_PRIV (object);
183 switch (prop_id) {
184 case PROP_FILENAME:
185 g_value_set_string (value, priv->filename);
186 break;
187 default:
188 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
189 break;
193 static void
194 yelp_sqlite_storage_set_property (GObject *object,
195 guint prop_id,
196 const GValue *value,
197 GParamSpec *pspec)
199 YelpSqliteStoragePrivate *priv = GET_PRIV (object);
201 switch (prop_id) {
202 case PROP_FILENAME:
203 priv->filename = g_value_dup_string (value);
204 break;
205 default:
206 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
207 break;
211 /******************************************************************************/
213 static void
214 yelp_sqlite_storage_update (YelpStorage *storage,
215 const gchar *doc_uri,
216 const gchar *full_uri,
217 const gchar *title,
218 const gchar *desc,
219 const gchar *icon,
220 const gchar *text)
222 sqlite3_stmt *stmt = NULL;
223 YelpSqliteStoragePrivate *priv = GET_PRIV (storage);
225 g_mutex_lock (&priv->mutex);
227 sqlite3_prepare_v2 (priv->db,
228 "delete from pages where doc_uri = ? and lang = ? and full_uri = ?;",
229 -1, &stmt, NULL);
230 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
231 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
232 sqlite3_bind_text (stmt, 3, full_uri, -1, SQLITE_TRANSIENT);
233 sqlite3_step (stmt);
234 sqlite3_finalize (stmt);
236 sqlite3_prepare_v2 (priv->db,
237 "insert into pages (doc_uri, lang, full_uri, title, desc, icon, body)"
238 " values (?, ?, ?, ?, ?, ?, ?);",
239 -1, &stmt, NULL);
240 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
241 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
242 sqlite3_bind_text (stmt, 3, full_uri, -1, SQLITE_TRANSIENT);
243 sqlite3_bind_text (stmt, 4, title, -1, SQLITE_TRANSIENT);
244 sqlite3_bind_text (stmt, 5, desc, -1, SQLITE_TRANSIENT);
245 sqlite3_bind_text (stmt, 6, icon, -1, SQLITE_TRANSIENT);
246 sqlite3_bind_text (stmt, 7, text, -1, SQLITE_TRANSIENT);
247 sqlite3_step (stmt);
248 sqlite3_finalize (stmt);
250 g_mutex_unlock (&priv->mutex);
253 static GVariant *
254 yelp_sqlite_storage_search (YelpStorage *storage,
255 const gchar *doc_uri,
256 const gchar *text)
258 sqlite3_stmt *stmt = NULL;
259 GVariantBuilder builder;
260 GVariant *ret;
261 YelpSqliteStoragePrivate *priv = GET_PRIV (storage);
263 g_mutex_lock (&priv->mutex);
265 sqlite3_prepare_v2 (priv->db,
266 "select full_uri, title, desc, icon from pages where"
267 " doc_uri = ? and lang = ? and body match ?;",
268 -1, &stmt, NULL);
269 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
270 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
271 sqlite3_bind_text (stmt, 3, text, -1, SQLITE_TRANSIENT);
273 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ssss)"));
274 while (sqlite3_step (stmt) == SQLITE_ROW) {
275 g_variant_builder_add (&builder, "(ssss)",
276 sqlite3_column_text (stmt, 0),
277 sqlite3_column_text (stmt, 1),
278 sqlite3_column_text (stmt, 2),
279 sqlite3_column_text (stmt, 3));
281 sqlite3_finalize (stmt);
282 ret = g_variant_new ("a(ssss)", &builder);
284 g_mutex_unlock (&priv->mutex);
286 return ret;
289 static gchar *
290 yelp_sqlite_storage_get_root_title (YelpStorage *storage,
291 const gchar *doc_uri)
293 gchar *ret = NULL;
294 sqlite3_stmt *stmt = NULL;
295 YelpSqliteStoragePrivate *priv = GET_PRIV (storage);
297 g_mutex_lock (&priv->mutex);
299 sqlite3_prepare_v2 (priv->db,
300 "select title from titles where doc_uri = ? and lang = ?;",
301 -1, &stmt, NULL);
302 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
303 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
304 if (sqlite3_step (stmt) == SQLITE_ROW)
305 ret = g_strdup (sqlite3_column_text (stmt, 0));
306 sqlite3_finalize (stmt);
308 g_mutex_unlock (&priv->mutex);
309 return ret;
312 static void
313 yelp_sqlite_storage_set_root_title (YelpStorage *storage,
314 const gchar *doc_uri,
315 const gchar *title)
317 sqlite3_stmt *stmt = NULL;
318 YelpSqliteStoragePrivate *priv = GET_PRIV (storage);
320 g_mutex_lock (&priv->mutex);
322 sqlite3_prepare_v2 (priv->db,
323 "delete from titles where doc_uri = ? and lang = ?;",
324 -1, &stmt, NULL);
325 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
326 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
327 sqlite3_step (stmt);
328 sqlite3_finalize (stmt);
330 sqlite3_prepare_v2 (priv->db,
331 "insert into titles (doc_uri, lang, title)"
332 " values (?, ?, ?);",
333 -1, &stmt, NULL);
334 sqlite3_bind_text (stmt, 1, doc_uri, -1, SQLITE_TRANSIENT);
335 sqlite3_bind_text (stmt, 2, g_get_language_names()[0], -1, SQLITE_STATIC);
336 sqlite3_bind_text (stmt, 3, title, -1, SQLITE_TRANSIENT);
337 sqlite3_step (stmt);
338 sqlite3_finalize (stmt);
340 g_mutex_unlock (&priv->mutex);