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_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
,
36 static void yelp_sqlite_storage_set_property (GObject
*object
,
41 static void yelp_sqlite_storage_update (YelpStorage
*storage
,
43 const gchar
*full_uri
,
48 static GVariant
* yelp_sqlite_storage_search (YelpStorage
*storage
,
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
,
57 typedef struct _YelpSqliteStoragePrivate YelpSqliteStoragePrivate
;
58 struct _YelpSqliteStoragePrivate
{
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))
75 yelp_sqlite_storage_finalize (GObject
*object
)
77 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
80 g_free (priv
->filename
);
83 sqlite3_close (priv
->db
);
85 g_mutex_clear (&priv
->mutex
);
87 G_OBJECT_CLASS (yelp_sqlite_storage_parent_class
)->finalize (object
);
91 yelp_sqlite_storage_init (YelpSqliteStorage
*storage
)
93 YelpSqliteStoragePrivate
*priv
= GET_PRIV (storage
);
94 g_mutex_init (&priv
->mutex
);
98 yelp_sqlite_storage_constructed (GObject
*object
)
101 sqlite3_stmt
*stmt
= NULL
;
102 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
104 if (priv
->filename
!= NULL
)
105 status
= sqlite3_open (priv
->filename
, &(priv
->db
));
107 status
= sqlite3_open (":memory:", &(priv
->db
));
109 if (status
!= SQLITE_OK
)
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"
118 if (status
!= SQLITE_OK
)
121 sqlite3_finalize (stmt
);
123 status
= sqlite3_prepare_v2 (priv
->db
,
124 "create table titles (doc_uri text, lang text, title text);",
126 if (status
!= SQLITE_OK
)
129 sqlite3_finalize (stmt
);
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
,
146 g_param_spec_string ("filename",
147 N_("Database filename"),
148 N_("The filename of the sqlite database"),
150 G_PARAM_CONSTRUCT_ONLY
| G_PARAM_READWRITE
|
151 G_PARAM_STATIC_STRINGS
));
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
;
164 yelp_sqlite_storage_new (const gchar
*filename
)
166 YelpStorage
*storage
;
168 storage
= g_object_new (YELP_TYPE_SQLITE_STORAGE
,
169 "filename", filename
,
176 yelp_sqlite_storage_get_property (GObject
*object
,
181 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
185 g_value_set_string (value
, priv
->filename
);
188 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
194 yelp_sqlite_storage_set_property (GObject
*object
,
199 YelpSqliteStoragePrivate
*priv
= GET_PRIV (object
);
203 priv
->filename
= g_value_dup_string (value
);
206 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
211 /******************************************************************************/
214 yelp_sqlite_storage_update (YelpStorage
*storage
,
215 const gchar
*doc_uri
,
216 const gchar
*full_uri
,
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 = ?;",
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
);
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 (?, ?, ?, ?, ?, ?, ?);",
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
);
248 sqlite3_finalize (stmt
);
250 g_mutex_unlock (&priv
->mutex
);
254 yelp_sqlite_storage_search (YelpStorage
*storage
,
255 const gchar
*doc_uri
,
258 sqlite3_stmt
*stmt
= NULL
;
259 GVariantBuilder builder
;
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 ?;",
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
);
290 yelp_sqlite_storage_get_root_title (YelpStorage
*storage
,
291 const gchar
*doc_uri
)
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 = ?;",
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
);
313 yelp_sqlite_storage_set_root_title (YelpStorage
*storage
,
314 const gchar
*doc_uri
,
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 = ?;",
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
);
328 sqlite3_finalize (stmt
);
330 sqlite3_prepare_v2 (priv
->db
,
331 "insert into titles (doc_uri, lang, title)"
332 " values (?, ?, ?);",
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
);
338 sqlite3_finalize (stmt
);
340 g_mutex_unlock (&priv
->mutex
);