Merge lp:~kalikiana/midori/databaseapi into lp:midori

Proposed by Cris Dywan
Status: Merged
Approved by: André Stösel
Approved revision: 6395
Merged at revision: 6400
Proposed branch: lp:~kalikiana/midori/databaseapi
Merge into: lp:midori
Diff against target: 326 lines (+134/-81)
8 files modified
data/history/Create.sql (+13/-0)
extensions/tabby.vala (+19/-30)
midori/midori-database.vala (+76/-0)
midori/midori-history.c (+8/-32)
midori/midori-historycompletion.vala (+6/-2)
midori/midori-historydatabase.vala (+6/-9)
po/POTFILES.in (+1/-0)
tests/completion.vala (+5/-8)
To merge this branch: bzr merge lp:~kalikiana/midori/databaseapi
Reviewer Review Type Date Requested Status
André Stösel Approve
Review via email: mp+185600@code.launchpad.net

Commit message

Introduce Midori.Database and use for history and tabby

To post a comment you must log in.
Revision history for this message
André Stösel (ivaldi) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'data/history'
2=== added file 'data/history/Create.sql'
3--- data/history/Create.sql 1970-01-01 00:00:00 +0000
4+++ data/history/Create.sql 2013-09-13 21:27:32 +0000
5@@ -0,0 +1,13 @@
6+CREATE TABLE IF NOT EXISTS history
7+(
8+ uri text,
9+ title text,
10+ date integer,
11+ day integer
12+);
13+CREATE TABLE IF NOT EXISTS search
14+(
15+ keywords text,
16+ uri text,
17+ day integer
18+);
19
20=== modified file 'extensions/tabby.vala'
21--- extensions/tabby.vala 2013-09-09 21:00:43 +0000
22+++ extensions/tabby.vala 2013-09-13 21:27:32 +0000
23@@ -282,7 +282,8 @@
24 }
25
26 private class Storage : Base.Storage {
27- protected Sqlite.Database db;
28+ private Midori.Database database;
29+ private unowned Sqlite.Database db;
30
31 public override Katze.Array get_sessions () {
32 Katze.Array sessions = new Katze.Array (typeof (Session));
33@@ -323,36 +324,24 @@
34 internal Storage (Midori.App app) {
35 GLib.Object (app: app);
36
37- string db_path = Midori.Paths.get_config_filename_for_writing ("tabby.db");
38-
39- bool db_exists = GLib.FileUtils.test(db_path, GLib.FileTest.EXISTS);
40-
41- if (Sqlite.Database.open_v2 (db_path, out this.db) != Sqlite.OK)
42- critical (_("Failed to open stored session: %s"), db.errmsg);
43-
44- string filename = Midori.Paths.get_res_filename ("tabby/Create.sql");
45- string schema;
46 try {
47- bool success = FileUtils.get_contents (filename, out schema, null);
48- if (!success || schema == null)
49- critical (_("Failed to open database schema file: %s"), filename);
50- if (success && schema != null)
51- if (this.db.exec (schema) != Sqlite.OK)
52- critical (_("Failed to execute database schema: %s"), filename);
53- else if (db_exists == false) {
54- string config_file = Midori.Paths.get_config_filename_for_reading ("session.xbel");
55- try {
56- Katze.Array old_session = new Katze.Array (typeof (Katze.Item));
57- Midori.array_from_file (old_session, config_file, "xbel-tiny");
58- this.import_session (old_session);
59- } catch (GLib.FileError file_error) {
60- /* no old session.xbel -> could be a new profile -> ignore it */
61- } catch (GLib.Error error) {
62- critical (_("Failed to import legacy session: %s"), error.message);
63- }
64- }
65- } catch (GLib.FileError schema_error) {
66- critical (_("Failed to open database schema file: %s"), schema_error.message);
67+ database = new Midori.Database ("tabby.db");
68+ } catch (Midori.DatabaseError schema_error) {
69+ error (schema_error.message);
70+ }
71+ db = database.db;
72+
73+ if (database.first_use) {
74+ string config_file = Midori.Paths.get_config_filename_for_reading ("session.xbel");
75+ try {
76+ Katze.Array old_session = new Katze.Array (typeof (Katze.Item));
77+ Midori.array_from_file (old_session, config_file, "xbel-tiny");
78+ this.import_session (old_session);
79+ } catch (GLib.FileError file_error) {
80+ /* no old session.xbel -> could be a new profile -> ignore it */
81+ } catch (GLib.Error error) {
82+ critical (_("Failed to import legacy session: %s"), error.message);
83+ }
84 }
85 }
86 }
87
88=== added file 'midori/midori-database.vala'
89--- midori/midori-database.vala 1970-01-01 00:00:00 +0000
90+++ midori/midori-database.vala 2013-09-13 21:27:32 +0000
91@@ -0,0 +1,76 @@
92+/*
93+ Copyright (C) 2013 Christian Dywan <christian@twotoats.de>
94+
95+ This library is free software; you can redistribute it and/or
96+ modify it under the terms of the GNU Lesser General Public
97+ License as published by the Free Software Foundation; either
98+ version 2.1 of the License, or (at your option) any later version.
99+
100+ See the file COPYING for the full license text.
101+*/
102+
103+namespace Midori {
104+ public errordomain DatabaseError {
105+ OPEN,
106+ SCHEMA,
107+ EXECUTE,
108+ }
109+
110+ public class Database : GLib.Object, GLib.Initable {
111+ public Sqlite.Database? db { get { return _db; } }
112+ protected Sqlite.Database? _db = null;
113+ public string? path { get; protected set; default = ":memory:"; }
114+
115+ /*
116+ * A new database successfully opened for the first time.
117+ * Old or additional data should be opened if this is true.
118+ */
119+ public bool first_use { get; protected set; default = false; }
120+
121+ /*
122+ * If a filename is passed it's assumed to be in the config folder.
123+ * Otherwise the database is in memory only (useful for private browsing).
124+ */
125+ public Database (string? path) throws DatabaseError {
126+ Object (path: path);
127+ init ();
128+ }
129+
130+ public virtual bool init (GLib.Cancellable? cancellable = null) throws DatabaseError {
131+ if (path == null)
132+ path = ":memory:";
133+ else if (!Path.is_absolute (path))
134+ path = Midori.Paths.get_config_filename_for_writing (path);
135+ bool exists = Posix.access (path, Posix.F_OK) == 0;
136+
137+ if (Sqlite.Database.open_v2 (path, out _db) != Sqlite.OK)
138+ throw new DatabaseError.OPEN ("Failed to open database %s".printf (path));
139+
140+ if (db.exec ("PRAGMA journal_mode = WAL; PRAGMA cache_size = 32100;") != Sqlite.OK)
141+ db.exec ("PRAGMA synchronous = NORMAL; PRAGMA temp_store = MEMORY;");
142+
143+ string basename = Path.get_basename (path);
144+ string[] parts = basename.split (".");
145+ if (!(parts != null && parts[0] != null && parts[1] != null))
146+ throw new DatabaseError.SCHEMA ("Failed to deduce schema filename from %s".printf (path));
147+ string schema_filename = Midori.Paths.get_res_filename (parts[0] + "/Create.sql");
148+ string schema;
149+ try {
150+ FileUtils.get_contents (schema_filename, out schema, null);
151+ } catch (Error error) {
152+ throw new DatabaseError.SCHEMA ("Failed to open schema: %s".printf (schema_filename));
153+ }
154+ if (db.exec (schema) != Sqlite.OK)
155+ throw new DatabaseError.EXECUTE ("Failed to execute schema: %s".printf (schema));
156+
157+ first_use = !exists;
158+ return true;
159+ }
160+
161+ public bool exec (string query) throws DatabaseError {
162+ if (db.exec (query) != Sqlite.OK)
163+ throw new DatabaseError.EXECUTE (db.errmsg ());
164+ return true;
165+ }
166+ }
167+}
168
169=== modified file 'midori/midori-history.c'
170--- midori/midori-history.c 2013-05-19 09:33:02 +0000
171+++ midori/midori-history.c 2013-09-13 21:27:32 +0000
172@@ -30,7 +30,8 @@
173 KatzeArray*
174 midori_history_new (char** errmsg)
175 {
176- gchar* filename;
177+ MidoriHistoryDatabase* database;
178+ GError* error = NULL;
179 sqlite3* db;
180 gboolean has_day = FALSE;
181 sqlite3_stmt* stmt;
182@@ -41,36 +42,16 @@
183
184 g_return_val_if_fail (errmsg != NULL, NULL);
185
186- filename = midori_paths_get_config_filename_for_writing ("history.db");
187- if (sqlite3_open (filename, &db) != SQLITE_OK)
188+ database = midori_history_database_new (NULL, &error);
189+ if (error != NULL)
190 {
191- *errmsg = g_strdup_printf (_("Failed to open database: %s\n"),
192- db ? sqlite3_errmsg (db) : "(db = NULL)");
193- g_free (filename);
194- sqlite3_close (db);
195+ *errmsg = g_strdup (error->message);
196+ g_error_free (error);
197 return NULL;
198 }
199- g_free (filename);
200
201- if (sqlite3_exec (db,
202- "PRAGMA journal_mode = WAL; PRAGMA cache_size = 32100;",
203- NULL, NULL, errmsg) != SQLITE_OK)
204- sqlite3_exec (db, "PRAGMA journal_mode = TRUNCATE;", NULL, NULL, errmsg);
205- sqlite3_exec (db,
206- "PRAGMA synchronous = NORMAL; PRAGMA temp_store = MEMORY;",
207- NULL, NULL, errmsg);
208- if (*errmsg)
209- {
210- g_warning ("Failed to set journal mode: %s", *errmsg);
211- sqlite3_free (*errmsg);
212- }
213- if (sqlite3_exec (db,
214- "CREATE TABLE IF NOT EXISTS "
215- "history (uri text, title text, date integer, day integer);"
216- "CREATE TABLE IF NOT EXISTS "
217- "search (keywords text, uri text, day integer);",
218- NULL, NULL, errmsg) != SQLITE_OK)
219- return NULL;
220+ db = midori_database_get_db (MIDORI_DATABASE (database));
221+ g_return_val_if_fail (db != NULL, NULL);
222
223 sqlite3_prepare_v2 (db, "SELECT day FROM history LIMIT 1", -1, &stmt, NULL);
224 result = sqlite3_step (stmt);
225@@ -93,11 +74,6 @@
226 "COMMIT;",
227 NULL, NULL, errmsg);
228
229- bookmarks_filename = midori_paths_get_config_filename_for_writing ("bookmarks_v2.db");
230- sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename);
231- g_free (bookmarks_filename);
232- sqlite3_exec (db, sql, NULL, NULL, errmsg);
233- g_free (sql);
234 array = katze_array_new (KATZE_TYPE_ARRAY);
235 g_object_set_data (G_OBJECT (array), "db", db);
236 g_signal_connect (array, "clear",
237
238=== modified file 'midori/midori-historycompletion.vala'
239--- midori/midori-historycompletion.vala 2013-07-28 21:20:32 +0000
240+++ midori/midori-historycompletion.vala 2013-09-13 21:27:32 +0000
241@@ -18,8 +18,12 @@
242 }
243
244 public override void prepare (GLib.Object app) {
245- database = new HistoryDatabase (app);
246- return_if_fail (database != null);
247+ try {
248+ database = new HistoryDatabase (app);
249+ }
250+ catch (Error error) {
251+ warning (error.message);
252+ }
253 }
254
255 public override bool can_complete (string text) {
256
257=== modified file 'midori/midori-historydatabase.vala'
258--- midori/midori-historydatabase.vala 2013-07-22 23:05:26 +0000
259+++ midori/midori-historydatabase.vala 2013-09-13 21:27:32 +0000
260@@ -35,15 +35,12 @@
261 public int64 date { get; set; }
262 }
263
264- public class HistoryDatabase : GLib.Object {
265- unowned Sqlite.Database db = null;
266-
267- public HistoryDatabase (GLib.Object app) {
268- GLib.Object history;
269- app.get ("history", out history);
270- return_val_if_fail (history != null, null);
271- db = history.get_data<Sqlite.Database?> ("db");
272- return_val_if_fail (db != null, null);
273+ public class HistoryDatabase : Midori.Database {
274+ public HistoryDatabase (GLib.Object? app) throws DatabaseError {
275+ Object (path: "history.db");
276+ init ();
277+ string bookmarks_filename = Midori.Paths.get_config_filename_for_writing ("bookmarks_v2.db");
278+ exec ("ATTACH DATABASE '%s' AS bookmarks".printf (bookmarks_filename));
279 }
280
281 public async List<HistoryItem>? query (string sqlcmd, string? filter, int day, int max_items, Cancellable cancellable) {
282
283=== modified file 'po/POTFILES.in'
284--- po/POTFILES.in 2013-09-08 16:00:37 +0000
285+++ po/POTFILES.in 2013-09-13 21:27:32 +0000
286@@ -6,6 +6,7 @@
287 midori/midori-app.c
288 midori/midori-array.c
289 midori/midori-browser.c
290+midori/midori-database.vala
291 midori/midori-extension.c
292 midori/midori-locationaction.c
293 midori/midori-panel.c
294
295=== modified file 'tests/completion.vala'
296--- tests/completion.vala 2013-09-08 00:52:09 +0000
297+++ tests/completion.vala 2013-09-13 21:27:32 +0000
298@@ -107,16 +107,12 @@
299 }
300
301 void completion_history () {
302+ Sqlite.Database db;
303+ assert (Sqlite.Database.open_v2 (Midori.Paths.get_config_filename_for_writing ("bookmarks_v2.db"), out db) == Sqlite.OK);
304+ assert (db.exec ("CREATE TABLE bookmarks (uri TEXT, title TEXT, last_visit DATE);") == Sqlite.OK);
305+
306 var completion = new Midori.HistoryCompletion ();
307 var app = new Midori.App ();
308- var history = new Katze.Array (typeof (Katze.Item));
309- app.set ("history", history);
310- Sqlite.Database db;
311- Sqlite.Database.open_v2 (":memory:", out db);
312- db.exec ("CREATE TABLE history (uri TEXT, title TEXT, date INTEGER, day INTEGER);");
313- db.exec ("CREATE TABLE search (uri TEXT, keywords TEXT, day INTEGER);");
314- db.exec ("CREATE TABLE bookmarks (uri TEXT, title TEXT, last_visit DATE);");
315- history.set_data<unowned Sqlite.Database?> ("db", db);
316 completion.prepare (app);
317 foreach (var spec in completions)
318 complete_spec.begin (completion, spec);
319@@ -152,6 +148,7 @@
320 void main (string[] args) {
321 Test.init (ref args);
322 Midori.App.setup (ref args, null);
323+ Midori.Paths.init (Midori.RuntimeMode.NORMAL, null);
324 Test.add_func ("/completion/autocompleter", completion_autocompleter);
325 Test.add_func ("/completion/history", completion_history);
326 Test.add_func ("/completion/location-action", completion_location_action);

Subscribers

People subscribed via source and target branches

to all changes: