Merge lp:~aauzi/midori/fix-1179200-7 into lp:midori

Proposed by André Auzi
Status: Superseded
Proposed branch: lp:~aauzi/midori/fix-1179200-7
Merge into: lp:midori
Diff against target: 2304 lines (+1236/-348)
10 files modified
katze/katze-array.c (+29/-48)
katze/katze-array.h (+30/-0)
katze/katze-item.c (+6/-0)
midori/midori-array.c (+11/-1)
midori/midori-bookmarks-db.c (+1019/-196)
midori/midori-bookmarks-db.h (+52/-25)
midori/midori-browser.c (+30/-26)
midori/midori-frontend.c (+4/-4)
panels/midori-bookmarks.c (+27/-25)
tests/bookmarks.c (+28/-23)
To merge this branch: bzr merge lp:~aauzi/midori/fix-1179200-7
Reviewer Review Type Date Requested Status
Midori Devs Pending
Review via email: mp+186168@code.launchpad.net

This proposal has been superseded by a proposal from 2013-09-18.

Description of the change

Seventh step for merge of fix-1179200

Here the database transactions are added in idle time processing to improve the processing speed.

Import bookmarks time is significantly reduced.

To post a comment you must log in.
lp:~aauzi/midori/fix-1179200-7 updated
6404. By Cris Dywan

Use stock as string in liststore

6405. By Cris Dywan

Refactor excuting schema from file into a function

6406. By André Auzi

Introduces KatzeArray::update-item to handle metadata changes

6407. By Cris Dywan

Initialize priv->element to avoid crash when freeing

6408. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6409. By Cris Dywan

Use destructive-action style class in ClearPrivateData

6410. By André Stösel

fix endless loop in Midori.Database.init

6411. By André Stösel

Check if execinfo.h header exists on BSD

6412. By André Stösel

use a separate signal to store the tab title

6413. By André Stösel

don't change uri/title if the tab isn't loaded

6414. By André Stösel

fix for proxy item ownership in delayed load extension

6415. By Olivier Duchateau

Install mo files in locale dir

6416. By Olivier Duchateau

Add CMakeLists.txt for config directory

6417. By André Auzi

fix bookmarks test regression after fix-1179200-4

6418. By Cris Dywan

Rasterize SVG to PNG with rsvg-convert

6419. By Cris Dywan

Add USE_APIDOCS to build API docs with CMake

6420. By Cris Dywan

Add missing PO_FILES argument to GETTEXT_PROCESS_PO_FILES

6421. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6422. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6423. By Paweł Forysiuk

Install config files to /etc when install prefix is /usr

6424. By Paweł Forysiuk

Allow running test under debug tools with cmake

6425. By Cris Dywan

Untangle implicit GTK+3 for Granite and WebKit2

6426. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6427. By André Stösel

add tab sorting

6428. By André Stösel

handle tab movement

6429. By Matthew Boevink <email address hidden>

Fixes bug where certificate Security overlay failed to close

6430. By Matthew Boevink <email address hidden>

midori_panel_action_activate_cb forgot to update the action group

6431. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6432. By Paweł Forysiuk

Drop waf build system and provide cmake-based "configure" script

6433. By André Auzi

Make tabby compile with Webkit2

6434. By André Stösel

handle urls as argument when starting midori

6435. By Paweł Forysiuk

Only install config files to /etc if prefix equals /usr

6436. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6437. By gue5t <email address hidden>

Use tabby sorting increment when importing session.xbel tabs

6438. By gue5t <email address hidden>

Ensure tab spinners update as often as the menubar spinner to avoid desync

6439. By André Auzi

Implement MidoriBookmarksDatabase class by inheritence from MidoriDatabase

6440. By André Stösel

option to modify the number of tabs which will be restored in each idle callback

6441. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6442. By Cris Dywan

Re-arrange data file installing to be more explicit

  Skip .ico, .res and .swf.
  And don't ignore files unwanted on Win32 otherwise they
  will be installed in the fallback.

6443. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6444. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6445. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6446. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6447. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6448. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6449. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6450. By Cris Dywan

Enable old target policy on cmake < 2.8.8

6451. By André Stösel

allow "view source" on about pages

6452. By André Auzi

Cache bookmark items to avoid their recreation on database reads

6453. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6454. By Paweł Forysiuk

Build fix: found undeclared in midori_bookmarks_db_remove_item_recursive

6455. By Paweł Forysiuk

Correct view source assertions in tab unit test

6456. By Paweł Forysiuk

Try to handle previous runs of cmake in configure wrapper

6457. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6458. By Paweł Forysiuk

Update win32-release script for cmake, move unused docs/scripts to old folder

6459. By Paweł Forysiuk

Resolve compiler warnings in current trunk

Add EXTRA_WARNINGS flag to increase verbosity
Respect VALAC for the Vala compiler if defined
Sort out Vala 0.16 build issues
Make warnings fatal for bzr builds

6460. By André Stösel

remove unused variable

6461. By André Stösel

add function to view dom source

6462. By Cris Dywan

Use font-set signal and font family for GTK+ 3.2 font chooser

6463. By Cris Dywan

Cast WebKitDOMHtmlElement for getting source content

6464. By André Stösel

restore the last closed sessions if no session is opened

6465. By Cris Dywan

Check path being NULL in export before trying to inspect it

6466. By André Stösel

bugfix: it should be possible to use exension.set_.. api within hidden extensions

6467. By André Auzi

Reset item ids when re-importing bookmarks

6468. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6469. By Paweł Forysiuk

Fix building on Ubuntu 12.04

6470. By Cris Dywan

Don't use context-menu signal in WebKitGTK+ < 1.10.0

6471. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6472. By gue5t <email address hidden>

Fix autoscrolling if page contains a frame with our custom error page

6473. By Cris Dywan

Fix check for found valac and mention VALAC variable

6474. By Paweł Forysiuk

Provide sensible default font suggestions on Win32

6475. By André Stösel

removed unused preference dialog and related code

6476. By André Stösel

Check all browsers for opened sessions and whether they're popups

6477. By André Stösel

Remove stored popup sessions from the database

6478. By Cris Dywan

Hide WEbGL preference if it is unavailable

6479. By gue5t <email address hidden>

Use correct signal when clearing the trash

6480. By Cris Dywan

Swap NULL-check with main frame check

6481. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6482. By gue5t <email address hidden>

Tweak searching for resources when running from build folder

6483. By Paweł Forysiuk

Add copyright note to appdata file

6484. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6485. By André Stösel

handle tab duplication

6486. By André Stösel

Open speed dial or homepage according to preference

6487. By Paweł Forysiuk

makedist: Try to use system defaults

6488. By André Stösel

instead of creating devpet status icon on extension load, create it only to show new messages

6489. By Cris Dywan

Bump version to 0.5.6

6490. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6491. By Isaac Smith

Allow printing without confirmation dialog on kiosk setups

6492. By Matthew Boevink <email address hidden>

Add close tabs to right feature

6493. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6494. By gue5t <email address hidden>

Change preferences to refer to proxy address as a "URI" (not "hostname")

6495. By gue5t <email address hidden>

Correctly disable favicon database in app and private mode

6496. By gue5t <email address hidden>

Fix build with WebKit2 since 6491

6497. By gue5t <email address hidden>

Give NextForward its own label for toolbar editor

6498. By gue5t <email address hidden>

Introduce and use Midori.URI.get_hostname_for_display

6499. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6500. By Cris Dywan

Set minimum value of 0 on spin button for maximum cache size

6501. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6502. By Cody Garver

Move Preferences menu entry above About

6503. By gue5t <email address hidden>

Enable sidepanel in private mode

6504. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6505. By Paweł Forysiuk

Adjust CMakeList .ico check to not skip nojs icons

6506. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6507. By Cris Dywan

NULL-check treeview in midori_search_action_get_editor

6508. By Paweł Forysiuk

Work around symbol relocation issue old version of gcc present on Ubuntu LTS

6509. By Cris Dywan

Introduce notebook class converging separate implementations

6510. By Cris Dywan

Drop deprecated StaticNotebook used in KatzePreferences

6511. By Cris Dywan

Drop uncommented contractor support

6512. By Cris Dywan

Drop unused GraniteClutter-based animation support

6513. By André Stösel

New extension Flummi for running commands once or repeatedly on startup

6514. By Cris Dywan

Introduce high-level prepare/ DatabaseStatement API

6515. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6516. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6517. By André Stösel

execute commands given at start time

6518. By André Stösel

handle url arguments for blank sessions

6519. By Paweł Forysiuk

Don't try to create formhistory database if config_dir is NULL

6520. By Cris Dywan

Add flummi to POTFILES.in

6521. By Cris Dywan

Skip folders starting with _ from license and potfiles checks

6522. By Cris Dywan

Use int64 arguments in HistoryDatabase.query

6523. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6524. By Launchpad Translations on behalf of midori

Launchpad automatic translations update.

6525. By André Auzi

improve bookmarks import performance using db transactions

6526. By André Auzi

merge lp:~aauzi/midori/fix-1179200-7

Unmerged revisions

6526. By André Auzi

merge lp:~aauzi/midori/fix-1179200-7

6525. By André Auzi

improve bookmarks import performance using db transactions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'katze/katze-array.c'
2--- katze/katze-array.c 2012-08-08 23:02:56 +0000
3+++ katze/katze-array.c 2013-09-17 21:46:23 +0000
4@@ -25,38 +25,14 @@
5 * #KatzeArray is a type aware container for items.
6 */
7
8-struct _KatzeArray
9+G_DEFINE_TYPE (KatzeArray, katze_array, KATZE_TYPE_ITEM);
10+
11+struct _KatzeArrayPrivate
12 {
13- KatzeItem parent_instance;
14-
15 GType type;
16 GList* items;
17 };
18
19-struct _KatzeArrayClass
20-{
21- KatzeItemClass parent_class;
22-
23- /* Signals */
24- void
25- (*add_item) (KatzeArray* array,
26- gpointer item);
27- void
28- (*remove_item) (KatzeArray* array,
29- gpointer item);
30- void
31- (*move_item) (KatzeArray* array,
32- gpointer item,
33- gint index);
34- void
35- (*clear) (KatzeArray* array);
36-
37- void
38- (*update) (KatzeArray* array);
39-};
40-
41-G_DEFINE_TYPE (KatzeArray, katze_array, KATZE_TYPE_ITEM);
42-
43 enum {
44 ADD_ITEM,
45 REMOVE_ITEM,
46@@ -90,7 +66,7 @@
47 if (g_type_is_a (type, KATZE_TYPE_ITEM))
48 katze_item_set_parent (item, array);
49
50- array->items = g_list_append (array->items, item);
51+ array->priv->items = g_list_append (array->priv->items, item);
52 _katze_array_update (array);
53 }
54
55@@ -98,7 +74,7 @@
56 _katze_array_remove_item (KatzeArray* array,
57 gpointer item)
58 {
59- array->items = g_list_remove (array->items, item);
60+ array->priv->items = g_list_remove (array->priv->items, item);
61
62 if (KATZE_IS_ITEM (item))
63 katze_item_set_parent (item, NULL);
64@@ -111,8 +87,8 @@
65 gpointer item,
66 gint position)
67 {
68- array->items = g_list_remove (array->items, item);
69- array->items = g_list_insert (array->items, item, position);
70+ array->priv->items = g_list_remove (array->priv->items, item);
71+ array->priv->items = g_list_insert (array->priv->items, item, position);
72 _katze_array_update (array);
73 }
74
75@@ -121,10 +97,10 @@
76 {
77 GObject* item;
78
79- while ((item = g_list_nth_data (array->items, 0)))
80+ while ((item = g_list_nth_data (array->priv->items, 0)))
81 g_signal_emit (array, signals[REMOVE_ITEM], 0, item);
82- g_list_free (array->items);
83- array->items = NULL;
84+ g_list_free (array->priv->items);
85+ array->priv->items = NULL;
86 _katze_array_update (array);
87 }
88
89@@ -217,13 +193,18 @@
90 class->move_item = _katze_array_move_item;
91 class->clear = _katze_array_clear;
92 class->update = _katze_array_update;
93+
94+ g_type_class_add_private (class, sizeof (KatzeArrayPrivate));
95 }
96
97 static void
98 katze_array_init (KatzeArray* array)
99 {
100- array->type = G_TYPE_OBJECT;
101- array->items = NULL;
102+ array->priv = G_TYPE_INSTANCE_GET_PRIVATE (array,
103+ KATZE_TYPE_ARRAY, KatzeArrayPrivate);
104+
105+ array->priv->type = G_TYPE_OBJECT;
106+ array->priv->items = NULL;
107 }
108
109 static void
110@@ -232,9 +213,9 @@
111 KatzeArray* array = KATZE_ARRAY (object);
112 GList* items;
113
114- for (items = array->items; items; items = g_list_next (items))
115+ for (items = array->priv->items; items; items = g_list_next (items))
116 g_object_unref (items->data);
117- g_list_free (array->items);
118+ g_list_free (array->priv->items);
119
120 G_OBJECT_CLASS (katze_array_parent_class)->finalize (object);
121 }
122@@ -258,7 +239,7 @@
123 g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL);
124
125 array = g_object_new (KATZE_TYPE_ARRAY, NULL);
126- array->type = type;
127+ array->priv->type = type;
128
129 return array;
130 }
131@@ -279,7 +260,7 @@
132 {
133 g_return_val_if_fail (KATZE_IS_ARRAY (array), FALSE);
134
135- return g_type_is_a (array->type, is_a_type);
136+ return g_type_is_a (array->priv->type, is_a_type);
137 }
138
139 /**
140@@ -333,7 +314,7 @@
141 {
142 g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
143
144- return g_list_nth_data (array->items, n);
145+ return g_list_nth_data (array->priv->items, n);
146 }
147
148 /**
149@@ -349,7 +330,7 @@
150 {
151 g_return_val_if_fail (KATZE_IS_ARRAY (array), TRUE);
152
153- return !g_list_nth_data (array->items, 0);
154+ return !g_list_nth_data (array->priv->items, 0);
155 }
156
157 /**
158@@ -367,7 +348,7 @@
159 {
160 g_return_val_if_fail (KATZE_IS_ARRAY (array), -1);
161
162- return g_list_index (array->items, item);
163+ return g_list_index (array->priv->items, item);
164 }
165
166 /**
167@@ -401,7 +382,7 @@
168 if (token_length < 1)
169 token_length = strlen (token);
170
171- for (items = array->items; items; items = g_list_next (items))
172+ for (items = array->priv->items; items; items = g_list_next (items))
173 {
174 const gchar* found_token = ((KatzeItem*)items->data)->token;
175 if (found_token != NULL)
176@@ -439,7 +420,7 @@
177 g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
178 g_return_val_if_fail (uri != NULL, NULL);
179
180- for (items = array->items; items; items = g_list_next (items))
181+ for (items = array->priv->items; items; items = g_list_next (items))
182 {
183 const gchar* found_uri = ((KatzeItem*)items->data)->uri;
184 if (found_uri != NULL && !strcmp (found_uri, uri))
185@@ -461,7 +442,7 @@
186 {
187 g_return_val_if_fail (KATZE_IS_ARRAY (array), 0);
188
189- return g_list_length (array->items);
190+ return g_list_length (array->priv->items);
191 }
192
193 /**
194@@ -499,7 +480,7 @@
195 {
196 g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
197
198- return g_list_copy (array->items);
199+ return g_list_copy (array->priv->items);
200 }
201
202 GList*
203@@ -507,7 +488,7 @@
204 {
205 g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
206
207- return array->items;
208+ return array->priv->items;
209 }
210
211 /**
212
213=== modified file 'katze/katze-array.h'
214--- katze/katze-array.h 2011-01-19 20:58:26 +0000
215+++ katze/katze-array.h 2013-09-17 21:46:23 +0000
216@@ -31,6 +31,36 @@
217
218 typedef struct _KatzeArray KatzeArray;
219 typedef struct _KatzeArrayClass KatzeArrayClass;
220+typedef struct _KatzeArrayPrivate KatzeArrayPrivate;
221+
222+struct _KatzeArray
223+{
224+ KatzeItem parent_instance;
225+
226+ KatzeArrayPrivate* priv;
227+};
228+
229+struct _KatzeArrayClass
230+{
231+ KatzeItemClass parent_class;
232+
233+ /* Signals */
234+ void
235+ (*add_item) (KatzeArray* array,
236+ gpointer item);
237+ void
238+ (*remove_item) (KatzeArray* array,
239+ gpointer item);
240+ void
241+ (*move_item) (KatzeArray* array,
242+ gpointer item,
243+ gint index);
244+ void
245+ (*clear) (KatzeArray* array);
246+
247+ void
248+ (*update) (KatzeArray* array);
249+};
250
251 GType
252 katze_array_get_type (void) G_GNUC_CONST;
253
254=== modified file 'katze/katze-item.c'
255--- katze/katze-item.c 2013-07-27 12:35:55 +0000
256+++ katze/katze-item.c 2013-09-17 21:46:23 +0000
257@@ -314,6 +314,9 @@
258 {
259 g_return_if_fail (KATZE_IS_ITEM (item));
260
261+ if (!g_strcmp0 (item->name, name))
262+ return;
263+
264 katze_assign (item->name, g_strdup (name));
265 if (item->parent)
266 katze_array_update ((KatzeArray*)item->parent);
267@@ -418,6 +421,9 @@
268 {
269 g_return_if_fail (KATZE_IS_ITEM (item));
270
271+ if (!g_strcmp0 (katze_item_get_meta_string (item, "icon"), icon))
272+ return;
273+
274 katze_item_set_meta_string (item, "icon", icon);
275 if (item->parent)
276 katze_array_update ((KatzeArray*)item->parent);
277
278=== modified file 'midori/midori-array.c'
279--- midori/midori-array.c 2013-08-05 12:50:34 +0000
280+++ midori/midori-array.c 2013-09-17 21:46:23 +0000
281@@ -986,7 +986,17 @@
282 return FALSE;
283 }
284
285-static void
286+/**
287+ * katze_item_set_value_from_columne:
288+ * @stmt: prepared statement
289+ * @column: column to read
290+ * @item: #KatzeItem to populate
291+ *
292+ * Stores the column in the given #KatzeItem.
293+ *
294+ * Since: 0.2.7
295+ **/
296+void
297 katze_item_set_value_from_column (sqlite3_stmt* stmt,
298 gint column,
299 KatzeItem* item)
300
301=== modified file 'midori/midori-bookmarks-db.c'
302--- midori/midori-bookmarks-db.c 2013-09-08 10:53:32 +0000
303+++ midori/midori-bookmarks-db.c 2013-09-17 21:46:23 +0000
304@@ -25,14 +25,622 @@
305 #include <unistd.h>
306 #endif
307
308-static gboolean
309-midori_bookmarks_update_item_db (sqlite3* db,
310- KatzeItem* item);
311-
312-gint64
313-midori_bookmarks_insert_item_db (sqlite3* db,
314- KatzeItem* item,
315- gint64 parentid)
316+/**
317+ * SECTION:midory-bookmarks-db
318+ * @short_description: A #KatzeArray connected to a database
319+ * @see_also: #KatzeArray
320+ *
321+ * #MidoriBookmarksDb is a #KatzeArray specialized for database
322+ * interraction.
323+ */
324+
325+struct _MidoriBookmarksDb
326+{
327+ KatzeArray parent_instance;
328+
329+ sqlite3* db;
330+ GList* pending_inserts;
331+ GHashTable* pending_updates;
332+ GHashTable* pending_deletes;
333+ GHashTable* all_items;
334+ gboolean in_idle_func;
335+};
336+
337+struct _MidoriBookmarksDbClass
338+{
339+ KatzeArrayClass parent_class;
340+
341+ /* Signals */
342+ void
343+ (*update_item) (MidoriBookmarksDb* bookmarks,
344+ gpointer item);
345+};
346+
347+G_DEFINE_TYPE (MidoriBookmarksDb, midori_bookmarks_db, KATZE_TYPE_ARRAY);
348+
349+enum {
350+ UPDATE_ITEM,
351+
352+ LAST_SIGNAL
353+};
354+
355+static guint signals[LAST_SIGNAL];
356+
357+static void
358+_midori_bookmarks_db_add_item (KatzeArray* array,
359+ gpointer item);
360+
361+static void
362+_midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks,
363+ gpointer item);
364+
365+static void
366+_midori_bookmarks_db_remove_item (KatzeArray* array,
367+ gpointer item);
368+
369+static void
370+_midori_bookmarks_db_move_item (KatzeArray* array,
371+ gpointer item,
372+ gint position);
373+
374+static void
375+_midori_bookmarks_db_clear (KatzeArray* array);
376+
377+static void
378+midori_bookmarks_db_force_idle (MidoriBookmarksDb* bookmarks);
379+
380+static void
381+midori_bookmarks_db_finalize (GObject* object);
382+
383+static gint64
384+midori_bookmarks_db_insert_item_db (sqlite3* db,
385+ KatzeItem* item,
386+ gint64 parentid);
387+
388+static gboolean
389+midori_bookmarks_db_update_item_db (sqlite3* db,
390+ KatzeItem* item);
391+
392+static gboolean
393+midori_bookmarks_db_remove_item_db (sqlite3* db,
394+ KatzeItem* item);
395+
396+static guint
397+item_hash (gconstpointer item)
398+{
399+ gint64 id = katze_item_get_meta_integer (KATZE_ITEM (item), "id");
400+ return g_int64_hash (&id);
401+}
402+
403+static gboolean
404+item_equal (gconstpointer item_a, gconstpointer item_b)
405+{
406+ gint64 id_a = katze_item_get_meta_integer (KATZE_ITEM (item_a), "id");
407+ gint64 id_b = katze_item_get_meta_integer (KATZE_ITEM (item_b), "id");
408+ return (id_a == id_b)? TRUE : FALSE;
409+}
410+
411+static void
412+midori_bookmarks_db_class_init (MidoriBookmarksDbClass* class)
413+{
414+ GObjectClass* gobject_class;
415+ KatzeArrayClass* katze_array_class;
416+
417+ gobject_class = G_OBJECT_CLASS (class);
418+ gobject_class->finalize = midori_bookmarks_db_finalize;
419+
420+ signals[UPDATE_ITEM] = g_signal_new (
421+ "update-item",
422+ G_TYPE_FROM_CLASS (class),
423+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
424+ G_STRUCT_OFFSET (MidoriBookmarksDbClass, update_item),
425+ 0,
426+ NULL,
427+ g_cclosure_marshal_VOID__POINTER,
428+ G_TYPE_NONE, 1,
429+ G_TYPE_POINTER);
430+
431+ katze_array_class = KATZE_ARRAY_CLASS (class);
432+
433+ katze_array_class->add_item = _midori_bookmarks_db_add_item;
434+ katze_array_class->remove_item = _midori_bookmarks_db_remove_item;
435+ katze_array_class->move_item = _midori_bookmarks_db_move_item;
436+ katze_array_class->clear = _midori_bookmarks_db_clear;
437+
438+ class->update_item = _midori_bookmarks_db_update_item;
439+}
440+
441+static void
442+midori_bookmarks_db_init (MidoriBookmarksDb* bookmarks)
443+{
444+ bookmarks->db = NULL;
445+ bookmarks->pending_inserts = NULL;
446+ bookmarks->pending_updates = g_hash_table_new (item_hash, item_equal);
447+ bookmarks->pending_deletes = g_hash_table_new (item_hash, item_equal);
448+ bookmarks->all_items = g_hash_table_new (item_hash, item_equal);
449+
450+ bookmarks->in_idle_func = FALSE;
451+
452+ katze_item_set_meta_integer (KATZE_ITEM (bookmarks), "id", 0);
453+ katze_item_set_name (KATZE_ITEM (bookmarks), _("Bookmarks"));
454+ g_hash_table_insert (bookmarks->all_items, bookmarks, bookmarks);
455+ /* g_object_ref (bookmarks); */
456+}
457+
458+static void
459+midori_bookmarks_db_finalize (GObject* object)
460+{
461+ MidoriBookmarksDb* bookmarks = MIDORI_BOOKMARKS_DB (object);
462+
463+ if (bookmarks->db)
464+ {
465+ midori_bookmarks_db_force_idle (bookmarks);
466+ sqlite3_close (bookmarks->db);
467+ }
468+
469+ g_list_free (bookmarks->pending_inserts);
470+ g_hash_table_unref (bookmarks->pending_updates);
471+ g_hash_table_unref (bookmarks->pending_deletes);
472+ g_hash_table_unref (bookmarks->all_items);
473+
474+ G_OBJECT_CLASS (midori_bookmarks_db_parent_class)->finalize (object);
475+}
476+
477+/**
478+ * midori_bookmarks_db_get_item_parent:
479+ * @bookmarks: the main bookmarks array
480+ * @item: a #KatzeItem
481+ *
482+ * Internal function that find the parent of the @item thanks to its %parentid
483+ **/
484+static KatzeArray*
485+midori_bookmarks_db_get_item_parent (MidoriBookmarksDb* bookmarks,
486+ gpointer item)
487+{
488+ KatzeArray* parent;
489+ gint64 parentid;
490+
491+ parentid = katze_item_get_meta_integer (KATZE_ITEM (item), "parentid");
492+
493+ if (parentid == 0)
494+ {
495+ parent = KATZE_ARRAY (bookmarks);
496+ }
497+ else
498+ {
499+ KatzeItem *search = katze_item_new ();
500+
501+ katze_item_set_meta_integer(search, "id", parentid);
502+
503+ parent = KATZE_ARRAY (g_hash_table_lookup (bookmarks->all_items, search));
504+
505+ g_object_unref (search);
506+ }
507+
508+ return parent;
509+}
510+
511+/**
512+ * _midori_bookmarks_db_add_item:
513+ * @array: the main bookmarks array
514+ * @item: a #KatzeItem
515+ *
516+ * Internal function that overloads the #KatzeArray %katze_array_add_item().
517+ * It relays the add item to the appropriate #KatzeArray.
518+ **/
519+static void
520+_midori_bookmarks_db_add_item (KatzeArray* array,
521+ gpointer item)
522+{
523+ MidoriBookmarksDb *bookmarks;
524+ KatzeArray* parent;
525+ KatzeArray* db_parent;
526+
527+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
528+ g_return_if_fail (KATZE_IS_ITEM (item));
529+
530+ bookmarks = MIDORI_BOOKMARKS_DB (array);
531+ g_return_if_fail (bookmarks->in_idle_func);
532+
533+ parent = katze_item_get_parent (KATZE_ITEM (item));
534+
535+ db_parent = midori_bookmarks_db_get_item_parent (bookmarks, item);
536+
537+ g_return_if_fail (db_parent);
538+
539+ if (parent == db_parent)
540+ {
541+ if (IS_MIDORI_BOOKMARKS_DB (parent))
542+ KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->update (parent);
543+ else
544+ katze_array_update (parent);
545+ return;
546+ }
547+
548+ if (IS_MIDORI_BOOKMARKS_DB (parent))
549+ KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->add_item (parent, item);
550+ else if (KATZE_IS_ARRAY (parent))
551+ katze_array_add_item (parent, item);
552+}
553+
554+/**
555+ * _midori_bookmarks_db_update_item:
556+ * @array: the main bookmarks array
557+ * @item: a #KatzeItem
558+ *
559+ * Internal function that implements the %midori_bookmarks_db_update_item() post-processing.
560+ * It relays an update to the appropriate #KatzeArray.
561+ **/
562+static void
563+_midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks,
564+ gpointer item)
565+{
566+ KatzeArray* parent;
567+
568+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
569+ g_return_if_fail (KATZE_IS_ITEM (item));
570+
571+ g_return_if_fail (bookmarks->in_idle_func);
572+
573+ parent = katze_item_get_parent (KATZE_ITEM (item));
574+
575+ g_return_if_fail (parent);
576+
577+ katze_array_update (parent);
578+}
579+
580+/**
581+ * _midori_bookmarks_db_remove_item:
582+ * @array: the main bookmarks array
583+ * @item: a #KatzeItem
584+ *
585+ * Internal function that overloads the #KatzeArray %katze_array_remove_item().
586+ * It relays the remove item to the appropriate #KatzeArray.
587+ **/
588+static void
589+_midori_bookmarks_db_remove_item (KatzeArray* array,
590+ gpointer item)
591+{
592+ MidoriBookmarksDb *bookmarks;
593+ KatzeArray* parent;
594+
595+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
596+ g_return_if_fail (KATZE_IS_ITEM (item));
597+
598+ bookmarks = MIDORI_BOOKMARKS_DB (array);
599+ g_return_if_fail (bookmarks->in_idle_func);
600+
601+ parent = katze_item_get_parent (KATZE_ITEM (item));
602+
603+ g_return_if_fail (parent);
604+
605+ if (IS_MIDORI_BOOKMARKS_DB (parent))
606+ KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->remove_item (parent, item);
607+ else if (KATZE_IS_ARRAY (parent))
608+ katze_array_remove_item (parent, item);
609+}
610+
611+/**
612+ * _midori_bookmarks_db_move_item:
613+ * @array: the main bookmarks array
614+ * @item: a #KatzeItem
615+ * @position: the new @item position
616+ *
617+ * Internal function that overloads the #KatzeArray %katze_array_move_item().
618+ * It relays the move @item to the appropriate #KatzeArray.
619+ **/
620+static void
621+_midori_bookmarks_db_move_item (KatzeArray* array,
622+ gpointer item,
623+ gint position)
624+{
625+ MidoriBookmarksDb *bookmarks;
626+ KatzeArray* parent;
627+
628+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
629+ g_return_if_fail (KATZE_IS_ITEM (item));
630+
631+ parent = katze_item_get_parent (KATZE_ITEM (item));
632+
633+ g_return_if_fail (parent);
634+
635+ KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->move_item (parent, item, position);
636+}
637+
638+/**
639+ * _midori_bookmarks_db_clear:
640+ * @array: the main bookmarks array
641+ *
642+ * Internal function that overloads the #KatzeArray %katze_array_clear().
643+ * It deletes the whole bookmarks data.
644+ **/
645+static void
646+_midori_bookmarks_db_clear (KatzeArray* array)
647+{
648+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
649+
650+ g_critical ("_midori_bookmarks_db_clear: not implemented\n");
651+}
652+
653+/**
654+ * midori_bookmarks_db_signal_update_item:
655+ * @array: a #KatzeArray
656+ * @item: an item
657+ *
658+ * Notify an update of the item of the array.
659+ *
660+ **/
661+static void
662+midori_bookmarks_db_signal_update_item (MidoriBookmarksDb* array,
663+ gpointer item)
664+{
665+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
666+
667+ g_signal_emit (array, signals[UPDATE_ITEM], 0, item);
668+}
669+
670+/**
671+ * midori_bookmarks_db_begin_transaction:
672+ * @db: the removed #KatzeItem
673+ *
674+ * Internal function that starts an SQL transaction.
675+ **/
676+static gboolean
677+midori_bookmarks_db_begin_transaction (sqlite3* db)
678+{
679+ char* errmsg = NULL;
680+
681+ if (sqlite3_exec (db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg) != SQLITE_OK)
682+ {
683+ g_printerr (_("Failed to begin transaction: %s\n"), errmsg);
684+ sqlite3_free (errmsg);
685+ return FALSE;
686+ }
687+
688+ return TRUE;
689+}
690+
691+/**
692+ * midori_bookmarks_db_end_transaction:
693+ * @db: the removed #KatzeItem
694+ * @commit : boolean
695+ *
696+ * Internal function that ends an SQL transaction.
697+ * If @commit is %TRUE, the transaction is ended by a COMMIT.
698+ * It is ended by a ROLLBACK otherwise.
699+ **/
700+static void
701+midori_bookmarks_db_end_transaction (sqlite3* db, gboolean commit)
702+{
703+ char* errmsg = NULL;
704+ if (sqlite3_exec (db, (commit ? "COMMIT;" : "ROLLBACK;"), NULL, NULL, &errmsg) != SQLITE_OK)
705+ {
706+ if (commit)
707+ g_printerr (_("Failed to end transaction: %s\n"), errmsg);
708+ else
709+ g_printerr (_("Failed to cancel transaction: %s\n"), errmsg);
710+ sqlite3_free (errmsg);
711+ }
712+}
713+
714+/**
715+ * midori_bookmarks_db_add_item_recursive:
716+ * @item: the removed #KatzeItem
717+ * @bookmarks : the main bookmarks array
718+ *
719+ * Internal function that creates memory records of the added @item.
720+ * If @item is a #KatzeArray, the function recursiveley adds records
721+ * of all its childs.
722+ **/
723+static gint
724+midori_bookmarks_db_add_item_recursive (MidoriBookmarksDb* bookmarks,
725+ KatzeItem* item)
726+{
727+ GList* list;
728+ KatzeArray* array;
729+ gint64 id = 0;
730+ gint count = 0;
731+ gint64 parentid = katze_item_get_meta_integer (item, "parentid");
732+
733+ id = midori_bookmarks_db_insert_item_db (bookmarks->db, item, parentid);
734+ count++;
735+
736+ g_object_ref (item);
737+ g_hash_table_insert (bookmarks->all_items, item, item);
738+
739+ if (!KATZE_IS_ARRAY (item))
740+ return count;
741+
742+ array = KATZE_ARRAY (item);
743+
744+ KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
745+ {
746+ katze_item_set_meta_integer (item, "parentid", id);
747+ count += midori_bookmarks_db_add_item_recursive (bookmarks, item);
748+ }
749+
750+ g_list_free (list);
751+ return count;
752+}
753+
754+/**
755+ * midori_bookmarks_db_remove_item_recursive:
756+ * @item: the removed #KatzeItem
757+ * @bookmarks : the main bookmarks array
758+ *
759+ * Internal function that removes memory records of the removed @item.
760+ * If @item is a #KatzeArray, the function recursiveley removes records
761+ * of all its childs.
762+ **/
763+static void
764+midori_bookmarks_db_remove_item_recursive (KatzeItem* item,
765+ MidoriBookmarksDb* bookmarks)
766+{
767+ GHashTableIter hash_iter;
768+ gpointer key, value;
769+ gpointer found;
770+ KatzeArray* array;
771+ KatzeItem* child;
772+ GList* list;
773+
774+ if (NULL != (found = g_list_find (bookmarks->pending_inserts, item)))
775+ {
776+ g_object_unref (((GList*)found)->data);
777+ bookmarks->pending_inserts = g_list_delete_link (bookmarks->pending_inserts,
778+ ((GList*)found));
779+ }
780+
781+ if (NULL != (found = g_hash_table_lookup (bookmarks->pending_updates, item)))
782+ {
783+ g_hash_table_remove (bookmarks->pending_updates, found);
784+ g_object_unref (found);
785+ }
786+
787+ if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item)))
788+ {
789+ g_hash_table_remove (bookmarks->all_items, found);
790+ g_object_unref (found);
791+ }
792+
793+ if (!KATZE_IS_ARRAY (item))
794+ return;
795+
796+ array = KATZE_ARRAY (item);
797+
798+ KATZE_ARRAY_FOREACH_ITEM_L (child, array, list)
799+ {
800+ midori_bookmarks_db_remove_item_recursive (child, bookmarks);
801+ }
802+
803+ g_list_free (list);
804+}
805+
806+/**
807+ * midori_bookmarks_db_idle_func:
808+ * @data: the main bookmark array
809+ *
810+ * Internal function executed during idle time that Packs pending database
811+ * operations in one transaction.
812+ *
813+ * Pending operations are either:
814+ * a. a list of pending add items,
815+ * all child #KatzeItem of a #KatzeArray are recursively added.
816+ * Each added #KatzeItem is memorized for future use.
817+ * (See %midori_bookmarks_db_array_from_statement())
818+ * b. a hash table of items to update,
819+ * c. or a hash table of items to remove
820+ * the database CASCADE on delete takes care of removal of the childs
821+ * #KatzeItem of a #KatzeArray in the database
822+ *
823+ * When database operations are done, the #KatzeArray equivalent operations
824+ * are called to:
825+ * 1. update the #KatzeArray tree content
826+ * 2. signal the client views of the #KatzeArray tree content change.
827+ **/
828+static gboolean
829+midori_bookmarks_db_idle_func (gpointer data)
830+{
831+ GTimer *timer = g_timer_new();
832+ gint count = 0;
833+ gulong microseconds;
834+ gboolean with_transaction;
835+ MidoriBookmarksDb* bookmarks = MIDORI_BOOKMARKS_DB (data);
836+ GList* list_iter;
837+ GHashTableIter hash_iter;
838+ gpointer key, value;
839+
840+ bookmarks->in_idle_func = TRUE;
841+
842+ g_timer_start (timer);
843+
844+ with_transaction = midori_bookmarks_db_begin_transaction (bookmarks->db);
845+
846+ for (list_iter = bookmarks->pending_inserts; list_iter; list_iter = g_list_next (list_iter))
847+ {
848+ KatzeItem *item = KATZE_ITEM (list_iter->data);
849+
850+ count += midori_bookmarks_db_add_item_recursive (bookmarks, item);
851+ katze_array_add_item (KATZE_ARRAY (bookmarks), item);
852+
853+ g_object_unref (item);
854+ }
855+
856+ g_hash_table_iter_init (&hash_iter, bookmarks->pending_updates);
857+
858+ while (g_hash_table_iter_next (&hash_iter, &key, &value))
859+ {
860+ KatzeItem *item = KATZE_ITEM (value);
861+
862+ midori_bookmarks_db_update_item_db (bookmarks->db, item);
863+ midori_bookmarks_db_signal_update_item (bookmarks, item);
864+ g_object_unref (item);
865+ count++;
866+ }
867+
868+ g_hash_table_iter_init (&hash_iter, bookmarks->pending_deletes);
869+
870+ while (g_hash_table_iter_next (&hash_iter, &key, &value))
871+ {
872+ KatzeItem *item = KATZE_ITEM (value);
873+
874+ midori_bookmarks_db_remove_item_db (bookmarks->db, item);
875+ katze_array_remove_item (KATZE_ARRAY (bookmarks), item);
876+ g_object_unref (item);
877+ count++;
878+ }
879+
880+ if (with_transaction)
881+ midori_bookmarks_db_end_transaction (bookmarks->db, TRUE);
882+
883+ g_timer_elapsed (timer, &microseconds);
884+ g_print ("midori_bookmarks_db_idle: %d DB operation(s) in %lu micro-seconds\n",
885+ count, microseconds);
886+
887+ g_timer_destroy (timer);
888+
889+ g_hash_table_remove_all (bookmarks->pending_deletes);
890+ g_hash_table_remove_all (bookmarks->pending_updates);
891+ g_list_free (bookmarks->pending_inserts);
892+ bookmarks->pending_inserts = NULL;
893+
894+ bookmarks->in_idle_func = FALSE;
895+
896+ return FALSE;
897+}
898+
899+/**
900+ * midori_bookmarks_db_idle_start:
901+ * @bookmarks: the main bookmark array
902+ *
903+ * Internal function that checks whether idle processing is pending,
904+ * if not, add a new one.
905+ **/
906+static void
907+midori_bookmarks_db_idle_start (MidoriBookmarksDb* bookmarks)
908+{
909+ g_return_if_fail (bookmarks->db != NULL);
910+
911+ if (bookmarks->pending_inserts
912+ || g_hash_table_size (bookmarks->pending_updates)
913+ || g_hash_table_size (bookmarks->pending_deletes))
914+ return;
915+
916+ g_idle_add (midori_bookmarks_db_idle_func, bookmarks);
917+}
918+
919+/**
920+ * midori_bookmarks_db_insert_item_db:
921+ * @db: the #sqlite3
922+ * @item: #KatzeItem the item to insert
923+ *
924+ * Internal function that does the actual SQL INSERT of the @item in @db.
925+ *
926+ * Since: 0.5.2
927+ **/
928+static gint64
929+midori_bookmarks_db_insert_item_db (sqlite3* db,
930+ KatzeItem* item,
931+ gint64 parentid)
932 {
933 gchar* sqlcmd;
934 char* errmsg = NULL;
935@@ -70,15 +678,15 @@
936 new_parentid = g_strdup_printf ("NULL");
937
938 sqlcmd = sqlite3_mprintf (
939- "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
940- "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
941- id,
942- new_parentid,
943- katze_item_get_name (item),
944- katze_str_non_null (uri),
945- katze_str_non_null (desc),
946- katze_item_get_meta_boolean (item, "toolbar"),
947- katze_item_get_meta_boolean (item, "app"));
948+ "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
949+ "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
950+ id,
951+ new_parentid,
952+ katze_item_get_name (item),
953+ katze_str_non_null (uri),
954+ katze_str_non_null (desc),
955+ katze_item_get_meta_boolean (item, "toolbar"),
956+ katze_item_get_meta_boolean (item, "app"));
957
958 if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
959 {
960@@ -89,7 +697,7 @@
961
962 sqlite3_free (sqlcmd);
963 sqlcmd = sqlite3_mprintf (
964- "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
965+ "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
966
967 seq_array = katze_array_from_sqlite (db, sqlcmd);
968 if (katze_array_get_nth_item (seq_array, 0))
969@@ -115,8 +723,17 @@
970 return seq;
971 }
972
973-gboolean
974-midori_bookmarks_update_item_db (sqlite3* db,
975+/**
976+ * midori_bookmarks_db_update_item_db:
977+ * @db: the #sqlite3
978+ * @item: #KatzeItem the item to update
979+ *
980+ * Internal function that does the actual SQL UPDATE of the @item in @db.
981+ *
982+ * Since: 0.5.2
983+ **/
984+static gboolean
985+midori_bookmarks_db_update_item_db (sqlite3* db,
986 KatzeItem* item)
987 {
988 gchar* sqlcmd;
989@@ -126,7 +743,7 @@
990 gchar* id;
991
992 id = g_strdup_printf ("%" G_GINT64_FORMAT,
993- katze_item_get_meta_integer (item, "id"));
994+ katze_item_get_meta_integer (item, "id"));
995
996 if (katze_item_get_meta_integer (item, "parentid") > 0)
997 parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
998@@ -135,16 +752,16 @@
999 parentid = g_strdup_printf ("NULL");
1000
1001 sqlcmd = sqlite3_mprintf (
1002- "UPDATE bookmarks SET "
1003- "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
1004- "WHERE id = %q ;",
1005- parentid,
1006- katze_item_get_name (item),
1007- katze_str_non_null (katze_item_get_uri (item)),
1008- katze_str_non_null (katze_item_get_meta_string (item, "desc")),
1009- katze_item_get_meta_boolean (item, "toolbar"),
1010- katze_item_get_meta_boolean (item, "app"),
1011- id);
1012+ "UPDATE bookmarks SET "
1013+ "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
1014+ "WHERE id = %q ;",
1015+ parentid,
1016+ katze_item_get_name (item),
1017+ katze_str_non_null (katze_item_get_uri (item)),
1018+ katze_str_non_null (katze_item_get_meta_string (item, "desc")),
1019+ katze_item_get_meta_boolean (item, "toolbar"),
1020+ katze_item_get_meta_boolean (item, "app"),
1021+ id);
1022
1023 updated = TRUE;
1024 if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
1025@@ -162,68 +779,128 @@
1026 }
1027
1028 /**
1029+ * midori_bookmarks_db_remove_item_db:
1030+ * @db: the #sqlite3
1031+ * @item: #KatzeItem the item to delete
1032+ *
1033+ * Internal function that does the actual SQL DELETE of the @item in @db.
1034+ *
1035+ * Since: 0.5.2
1036+ **/
1037+static gboolean
1038+midori_bookmarks_db_remove_item_db (sqlite3* db,
1039+ KatzeItem* item)
1040+{
1041+ char* errmsg = NULL;
1042+ gchar* sqlcmd;
1043+ gboolean removed = TRUE;
1044+ gchar* id;
1045+
1046+ id = g_strdup_printf ("%" G_GINT64_FORMAT,
1047+ katze_item_get_meta_integer (item, "id"));
1048+
1049+ sqlcmd = sqlite3_mprintf ("DELETE FROM bookmarks WHERE id = %q", id);
1050+
1051+ if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
1052+ {
1053+ g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg);
1054+ sqlite3_free (errmsg);
1055+ removed = FALSE;
1056+ }
1057+
1058+ sqlite3_free (sqlcmd);
1059+ g_free (id);
1060+ return removed;
1061+}
1062+
1063+/**
1064+ * midori_bookmarks_db_add_item:
1065+ * @bookmarks: the main bookmark array
1066+ * @item: #KatzeItem the item to update
1067+ *
1068+ * Adds the @item in the bookmark data base.
1069+ *
1070+ * Since: 0.5.2
1071+ **/
1072+void
1073+midori_bookmarks_db_add_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
1074+{
1075+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
1076+ g_return_if_fail (KATZE_IS_ITEM (item));
1077+
1078+ /* Force NULL id for database addition */
1079+ if (NULL != katze_item_get_meta_string (item, "id"))
1080+ {
1081+ katze_item_set_meta_string (item, "id", NULL);
1082+ }
1083+
1084+ gpointer found = g_list_find (bookmarks->pending_inserts, item);
1085+
1086+ if (found)
1087+ return;
1088+
1089+ midori_bookmarks_db_idle_start (bookmarks);
1090+
1091+ g_object_ref (item);
1092+ bookmarks->pending_inserts = g_list_append (bookmarks->pending_inserts, item);
1093+}
1094+
1095+/**
1096 * midori_bookmarks_db_update_item:
1097 * @bookmarks: the main bookmark array
1098 * @item: #KatzeItem the item to update
1099 *
1100 * Updates the @item in the bookmark data base.
1101 *
1102- * Since: 0.5.5
1103- **/
1104-void
1105-midori_array_update_item (KatzeArray* bookmarks,
1106- KatzeItem* item)
1107-{
1108- g_return_if_fail (KATZE_IS_ARRAY (bookmarks));
1109- g_return_if_fail (KATZE_IS_ITEM (item));
1110- g_return_if_fail (katze_item_get_meta_string (item, "id"));
1111- g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
1112-
1113- sqlite3* db = g_object_get_data (G_OBJECT (bookmarks), "db");
1114-
1115- g_return_if_fail (db);
1116-
1117- midori_bookmarks_update_item_db (db, item);
1118-}
1119-
1120-void
1121-midori_bookmarks_dbtracer (void* dummy,
1122- const char* query)
1123-{
1124- g_printerr ("%s\n", query);
1125-}
1126-
1127-static void
1128-midori_bookmarks_add_item_cb (KatzeArray* array,
1129- KatzeItem* item,
1130- sqlite3* db)
1131-{
1132- midori_bookmarks_insert_item_db (db, item,
1133- katze_item_get_meta_integer (item, "parentid"));
1134-}
1135-
1136-static void
1137-midori_bookmarks_remove_item_cb (KatzeArray* array,
1138- KatzeItem* item,
1139- sqlite3* db)
1140-{
1141- gchar* sqlcmd;
1142- char* errmsg = NULL;
1143- gchar* id;
1144-
1145- id = g_strdup_printf ("%" G_GINT64_FORMAT,
1146- katze_item_get_meta_integer (item, "id"));
1147-
1148- sqlcmd = sqlite3_mprintf ("DELETE FROM bookmarks WHERE id = %q", id);
1149-
1150- if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
1151- {
1152- g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg);
1153- sqlite3_free (errmsg);
1154- }
1155-
1156- sqlite3_free (sqlcmd);
1157- g_free (id);
1158+ * Since: 0.5.2
1159+ **/
1160+void
1161+midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
1162+{
1163+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
1164+ g_return_if_fail (KATZE_IS_ITEM (item));
1165+ g_return_if_fail (katze_item_get_meta_string (item, "id"));
1166+ g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
1167+
1168+ gpointer found = g_hash_table_lookup (bookmarks->pending_updates, item);
1169+
1170+ if (found)
1171+ return;
1172+
1173+ midori_bookmarks_db_idle_start (bookmarks);
1174+
1175+ g_object_ref (item);
1176+ g_hash_table_insert (bookmarks->pending_updates, item, item);
1177+}
1178+
1179+/**
1180+ * midori_bookmarks_db_remove_item:
1181+ * @bookmarks: the main bookmark array
1182+ * @item: #KatzeItem the item to remove
1183+ *
1184+ * Removes the @item from the bookmark data base.
1185+ *
1186+ * Since: 0.5.2
1187+ **/
1188+void
1189+midori_bookmarks_db_remove_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
1190+{
1191+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
1192+ g_return_if_fail (KATZE_IS_ITEM (item));
1193+ g_return_if_fail (katze_item_get_meta_string (item, "id"));
1194+ g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
1195+
1196+ gpointer found = g_hash_table_lookup (bookmarks->pending_deletes, item);
1197+
1198+ if (found)
1199+ return;
1200+
1201+ midori_bookmarks_db_idle_start (bookmarks);
1202+
1203+ midori_bookmarks_db_remove_item_recursive (item, bookmarks);
1204+
1205+ g_object_ref (item);
1206+ g_hash_table_insert (bookmarks->pending_deletes, item, item);
1207 }
1208
1209 #define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \
1210@@ -237,8 +914,8 @@
1211 g_string_append (errmsg_str, custom_errmsg); \
1212 } while (0)
1213
1214-gboolean
1215-midori_bookmarks_import_from_old_db (sqlite3* db,
1216+static gboolean
1217+midori_bookmarks_db_import_from_old_db (sqlite3* db,
1218 const gchar* oldfile,
1219 gchar** errmsg)
1220 {
1221@@ -293,8 +970,24 @@
1222 }
1223 #undef _APPEND_TO_SQL_ERRORMSG
1224
1225-KatzeArray*
1226-midori_bookmarks_new (char** errmsg)
1227+static void
1228+midori_bookmarks_db_dbtracer (void* dummy,
1229+ const char* query)
1230+{
1231+ g_printerr ("%s\n", query);
1232+}
1233+
1234+/**
1235+ * midori_bookmarks_db_new:
1236+ *
1237+ * Initializes the bookmark data base.
1238+ *
1239+ * Returns: the main bookmarks array
1240+ *
1241+ * Since: 0.5.2
1242+ **/
1243+MidoriBookmarksDb*
1244+midori_bookmarks_db_new (char** errmsg)
1245 {
1246 sqlite3* db;
1247 gchar* oldfile;
1248@@ -304,6 +997,7 @@
1249 gchar* sql_errmsg = NULL;
1250 gchar* import_errmsg = NULL;
1251 KatzeArray* array;
1252+ MidoriBookmarksDb* bookmarks;
1253
1254 g_return_val_if_fail (errmsg != NULL, NULL);
1255
1256@@ -321,7 +1015,7 @@
1257 }
1258
1259 if (midori_debug ("bookmarks"))
1260- sqlite3_trace (db, midori_bookmarks_dbtracer, NULL);
1261+ sqlite3_trace (db, midori_bookmarks_db_dbtracer, NULL);
1262
1263 create_stmt = /* Table structure */
1264 "CREATE TABLE IF NOT EXISTS bookmarks "
1265@@ -442,7 +1136,7 @@
1266
1267 if (oldfile_exists)
1268 /* import from old db */
1269- if (!midori_bookmarks_import_from_old_db (db, oldfile, &import_errmsg))
1270+ if (!midori_bookmarks_db_import_from_old_db (db, oldfile, &import_errmsg))
1271 {
1272 *errmsg = g_strdup_printf (_("Couldn't import from old database: %s\n"),
1273 import_errmsg ? import_errmsg : "(err = NULL)");
1274@@ -452,13 +1146,11 @@
1275 init_success:
1276 g_free (newfile);
1277 g_free (oldfile);
1278- array = katze_array_new (KATZE_TYPE_ARRAY);
1279- g_signal_connect (array, "add-item",
1280- G_CALLBACK (midori_bookmarks_add_item_cb), db);
1281- g_signal_connect (array, "remove-item",
1282- G_CALLBACK (midori_bookmarks_remove_item_cb), db);
1283- g_object_set_data (G_OBJECT (array), "db", db);
1284- return array;
1285+ bookmarks = MIDORI_BOOKMARKS_DB (g_object_new (TYPE_MIDORI_BOOKMARKS_DB, NULL));
1286+ bookmarks->db = db;
1287+
1288+ g_object_set_data (G_OBJECT (bookmarks), "db", db);
1289+ return bookmarks;
1290
1291 init_failed:
1292 g_free (newfile);
1293@@ -470,40 +1162,176 @@
1294 return NULL;
1295 }
1296
1297+/**
1298+ * midori_bookmarks_db_on_quit:
1299+ * @bookmarks: the main bookmark array
1300+ *
1301+ * Delete the main bookmark array.
1302+ *
1303+ * Since: 0.5.2
1304+ **/
1305 void
1306-midori_bookmarks_on_quit (KatzeArray* array)
1307+midori_bookmarks_db_on_quit (MidoriBookmarksDb* bookmarks)
1308 {
1309- g_return_if_fail (KATZE_IS_ARRAY (array));
1310+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
1311
1312- sqlite3* db = g_object_get_data (G_OBJECT (array), "db");
1313- g_return_if_fail (db != NULL);
1314- sqlite3_close (db);
1315+ g_object_unref (bookmarks);
1316 }
1317
1318+/**
1319+ * midori_bookmarks_db_import_array:
1320+ * @array: the main bookmark array
1321+ * @array: #KatzeArray containing the items to import
1322+ * @parentid: the id of folder
1323+ *
1324+ * Imports the items of @array as childs of the folder
1325+ * identfied by @parentid.
1326+ *
1327+ * Since: 0.5.2
1328+ **/
1329 void
1330-midori_bookmarks_import_array (KatzeArray* bookmarks,
1331+midori_bookmarks_db_import_array (MidoriBookmarksDb* bookmarks,
1332 KatzeArray* array,
1333 gint64 parentid)
1334 {
1335 GList* list;
1336 KatzeItem* item;
1337
1338- if (!bookmarks)
1339- return;
1340+ g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
1341+ g_return_if_fail (KATZE_IS_ARRAY (array));
1342
1343 KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
1344 {
1345 katze_item_set_meta_integer (item, "parentid", parentid);
1346- katze_array_add_item (bookmarks, item);
1347- if (KATZE_IS_ARRAY (item))
1348- midori_bookmarks_import_array (bookmarks, KATZE_ARRAY (item),
1349- katze_item_get_meta_integer(item, "id"));
1350+ midori_bookmarks_db_add_item (bookmarks, item);
1351 }
1352+
1353 g_list_free (list);
1354 }
1355
1356 /**
1357- * midori_array_query_recursive:
1358+ * midori_bookmarks_db_force_idle:
1359+ * @array: the main bookmark array
1360+ *
1361+ * Internal function that checks if idle processing is pending.
1362+ * If it is the case, removes it from idle time processing and
1363+ * executes it immediately.
1364+ **/
1365+static void
1366+midori_bookmarks_db_force_idle (MidoriBookmarksDb* bookmarks)
1367+{
1368+ if (bookmarks->in_idle_func)
1369+ return;
1370+
1371+ if (g_idle_remove_by_data (bookmarks))
1372+ midori_bookmarks_db_idle_func (bookmarks);
1373+}
1374+
1375+/**
1376+ * midori_bookmarks_db_array_from_statement:
1377+ * @stmt: the sqlite returned statement
1378+ * @bookmarks: the database controller
1379+ *
1380+ * Internal function that populate a #KatzeArray by processing the @stmt
1381+ * rows identifying:
1382+ * a- if the item is already in memory
1383+ * in this case the item data is updated with retreived database content
1384+ * and the already existing item is populated in the returned #KatzeArray
1385+ * b- if the data is a folder
1386+ * a new #KatzeArray item is populated in the returned #KatzeArray and
1387+ * memorized for future use.
1388+ * c- if the data is a bookmark
1389+ * a new #KatzeItem item is populated in the returned #KatzeArray and
1390+ * memorized for furure use.
1391+ *
1392+ * Return value: the populated #KatzeArray
1393+ **/
1394+static KatzeArray*
1395+midori_bookmarks_db_array_from_statement (sqlite3_stmt* stmt,
1396+ MidoriBookmarksDb* bookmarks)
1397+{
1398+ KatzeArray *array;
1399+ gint result;
1400+ gint cols;
1401+
1402+ array = katze_array_new (KATZE_TYPE_ITEM);
1403+ cols = sqlite3_column_count (stmt);
1404+
1405+ while ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1406+ {
1407+ gint i;
1408+ KatzeItem* item;
1409+ KatzeItem* found;
1410+
1411+ item = katze_item_new ();
1412+ for (i = 0; i < cols; i++)
1413+ katze_item_set_value_from_column (stmt, i, item);
1414+
1415+ if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item)))
1416+ {
1417+ for (i = 0; i < cols; i++)
1418+ katze_item_set_value_from_column (stmt, i, found);
1419+
1420+ g_object_unref (item);
1421+
1422+ item = found;
1423+ }
1424+ else if (KATZE_ITEM_IS_FOLDER (item))
1425+ {
1426+ g_object_unref (item);
1427+
1428+ item = KATZE_ITEM (katze_array_new (KATZE_TYPE_ITEM));
1429+
1430+ for (i = 0; i < cols; i++)
1431+ katze_item_set_value_from_column (stmt, i, item);
1432+
1433+ g_object_ref (item);
1434+ g_hash_table_insert (bookmarks->all_items, item, item);
1435+ }
1436+ else
1437+ {
1438+ g_object_ref (item);
1439+ g_hash_table_insert (bookmarks->all_items, item, item);
1440+ }
1441+
1442+ katze_array_add_item (array, item);
1443+ }
1444+
1445+ sqlite3_clear_bindings (stmt);
1446+ sqlite3_reset (stmt);
1447+ return array;
1448+}
1449+
1450+/**
1451+ * midori_bookmarks_db_array_from_sqlite:
1452+ * @array: the main bookmark array
1453+ * @sqlcmd: the sqlcmd to execute
1454+ *
1455+ * Internal function that first forces pending idle processing to update the
1456+ * database then process the requested @sqlcmd.
1457+ *
1458+ * Return value: a #KatzeArray on success, %NULL otherwise
1459+ **/
1460+static KatzeArray*
1461+midori_bookmarks_db_array_from_sqlite (MidoriBookmarksDb* bookmarks,
1462+ const gchar* sqlcmd)
1463+{
1464+ sqlite3_stmt* stmt;
1465+ gint result;
1466+
1467+ g_return_val_if_fail (bookmarks->db != NULL, NULL);
1468+
1469+ midori_bookmarks_db_force_idle (bookmarks);
1470+
1471+ result = sqlite3_prepare_v2 (bookmarks->db, sqlcmd, -1, &stmt, NULL);
1472+ if (result != SQLITE_OK)
1473+ return NULL;
1474+
1475+ return midori_bookmarks_db_array_from_statement (stmt, bookmarks);
1476+}
1477+
1478+/**
1479+ * midori_bookmarks_db_query_recursive:
1480 * @array: the main bookmark array
1481 * @fields: comma separated list of fields
1482 * @condition: condition, like "folder = '%q'"
1483@@ -514,38 +1342,35 @@
1484 *
1485 * Return value: a #KatzeArray on success, %NULL otherwise
1486 *
1487- * Since: 0.4.4
1488+ * Since: 0.5.2
1489 **/
1490 KatzeArray*
1491-midori_array_query_recursive (KatzeArray* bookmarks,
1492- const gchar* fields,
1493- const gchar* condition,
1494- const gchar* value,
1495- gboolean recursive)
1496+midori_bookmarks_db_query_recursive (MidoriBookmarksDb* bookmarks,
1497+ const gchar* fields,
1498+ const gchar* condition,
1499+ const gchar* value,
1500+ gboolean recursive)
1501 {
1502- sqlite3* db;
1503 gchar* sqlcmd;
1504 char* sqlcmd_value;
1505 KatzeArray* array;
1506 KatzeItem* item;
1507 GList* list;
1508
1509- g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
1510+ g_return_val_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks), NULL);
1511 g_return_val_if_fail (fields, NULL);
1512 g_return_val_if_fail (condition, NULL);
1513- db = g_object_get_data (G_OBJECT (bookmarks), "db");
1514- g_return_val_if_fail (db != NULL, NULL);
1515
1516 sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
1517 "ORDER BY (uri='') ASC, title DESC", fields, condition);
1518 if (strstr (condition, "%q"))
1519 {
1520 sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
1521- array = katze_array_from_sqlite (db, sqlcmd_value);
1522+ array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd_value);
1523 sqlite3_free (sqlcmd_value);
1524 }
1525 else
1526- array = katze_array_from_sqlite (db, sqlcmd);
1527+ array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd);
1528 g_free (sqlcmd);
1529
1530 if (!recursive)
1531@@ -556,9 +1381,9 @@
1532 if (KATZE_ITEM_IS_FOLDER (item))
1533 {
1534 gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
1535- katze_item_get_meta_integer (item, "id"));
1536- KatzeArray* subarray = midori_array_query_recursive (bookmarks,
1537- fields, "parentid=%q", parentid, TRUE);
1538+ katze_item_get_meta_integer (item, "id"));
1539+ KatzeArray* subarray = midori_bookmarks_db_query_recursive (bookmarks,
1540+ fields, "parentid=%q", parentid, TRUE);
1541 KatzeItem* subitem;
1542 GList* sublist;
1543
1544@@ -576,21 +1401,21 @@
1545 }
1546
1547 static gint64
1548-count_from_sqlite (sqlite3* db,
1549- const gchar* sqlcmd)
1550+midori_bookmarks_db_count_from_sqlite (sqlite3* db,
1551+ const gchar* sqlcmd)
1552 {
1553 gint64 count = -1;
1554 sqlite3_stmt* stmt;
1555 gint result;
1556-
1557+
1558 result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL);
1559 if (result != SQLITE_OK)
1560 return -1;
1561
1562 g_assert (sqlite3_column_count (stmt) == 1);
1563-
1564+
1565 if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1566- count = sqlite3_column_int64(stmt, 0);
1567+ count = sqlite3_column_int64(stmt, 0);
1568
1569 sqlite3_clear_bindings (stmt);
1570 sqlite3_reset (stmt);
1571@@ -599,14 +1424,13 @@
1572 }
1573
1574 static gint64
1575-midori_array_count_recursive_by_id (KatzeArray* bookmarks,
1576- const gchar* condition,
1577- const gchar* value,
1578- gint64 id,
1579- gboolean recursive)
1580+midori_bookmarks_db_count_recursive_by_id (MidoriBookmarksDb* bookmarks,
1581+ const gchar* condition,
1582+ const gchar* value,
1583+ gint64 id,
1584+ gboolean recursive)
1585 {
1586 gint64 count = -1;
1587- sqlite3* db;
1588 gchar* sqlcmd;
1589 char* sqlcmd_value;
1590 sqlite3_stmt* stmt;
1591@@ -615,30 +1439,29 @@
1592 GList* iter_ids;
1593
1594 g_return_val_if_fail (condition, -1);
1595- g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1);
1596- db = g_object_get_data (G_OBJECT (bookmarks), "db");
1597- g_return_val_if_fail (db != NULL, -1);
1598+ g_return_val_if_fail (MIDORI_BOOKMARKS_DB (bookmarks), -1);
1599+ g_return_val_if_fail (bookmarks->db != NULL, -1);
1600
1601 g_assert(!strstr("parentid", condition));
1602
1603 if (id > 0)
1604- sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1605- "WHERE parentid = %" G_GINT64_FORMAT " AND %s",
1606- id,
1607- condition);
1608+ sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1609+ "WHERE parentid = %" G_GINT64_FORMAT " AND %s",
1610+ id,
1611+ condition);
1612 else
1613- sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1614- "WHERE parentid IS NULL AND %s ",
1615- condition);
1616+ sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1617+ "WHERE parentid IS NULL AND %s ",
1618+ condition);
1619
1620 if (strstr (condition, "%q"))
1621 {
1622 sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
1623- count = count_from_sqlite (db, sqlcmd_value);
1624+ count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd_value);
1625 sqlite3_free (sqlcmd_value);
1626 }
1627 else
1628- count = count_from_sqlite (db, sqlcmd);
1629+ count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd);
1630
1631 g_free (sqlcmd);
1632
1633@@ -648,28 +1471,28 @@
1634 ids = NULL;
1635
1636 if (id > 0)
1637- sqlcmd_value = sqlite3_mprintf (
1638- "SELECT id FROM bookmarks "
1639- "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
1640+ sqlcmd_value = sqlite3_mprintf (
1641+ "SELECT id FROM bookmarks "
1642+ "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
1643 else
1644- sqlcmd_value = sqlite3_mprintf (
1645- "SELECT id FROM bookmarks "
1646- "WHERE parentid IS NULL AND uri = ''");
1647+ sqlcmd_value = sqlite3_mprintf (
1648+ "SELECT id FROM bookmarks "
1649+ "WHERE parentid IS NULL AND uri = ''");
1650
1651- if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
1652+ if (sqlite3_prepare_v2 (bookmarks->db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
1653 {
1654- g_assert (sqlite3_column_count (stmt) == 1);
1655-
1656- if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1657- {
1658- gint64* pid = g_new (gint64, 1);
1659-
1660- *pid = sqlite3_column_int64(stmt, 0);
1661- ids = g_list_append (ids, pid);
1662- }
1663-
1664- sqlite3_clear_bindings (stmt);
1665- sqlite3_reset (stmt);
1666+ g_assert (sqlite3_column_count (stmt) == 1);
1667+
1668+ if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1669+ {
1670+ gint64* pid = g_new (gint64, 1);
1671+
1672+ *pid = sqlite3_column_int64(stmt, 0);
1673+ ids = g_list_append (ids, pid);
1674+ }
1675+
1676+ sqlite3_clear_bindings (stmt);
1677+ sqlite3_reset (stmt);
1678 }
1679
1680 sqlite3_free (sqlcmd_value);
1681@@ -677,29 +1500,29 @@
1682 iter_ids = ids;
1683 while (iter_ids)
1684 {
1685- gint64 sub_count = midori_array_count_recursive_by_id (bookmarks,
1686- condition,
1687- value,
1688- *(gint64*)(iter_ids->data),
1689- recursive);
1690-
1691- if (sub_count < 0)
1692- {
1693- g_list_free_full (ids, g_free);
1694- return -1;
1695- }
1696-
1697- count += sub_count;
1698- iter_ids = g_list_next (iter_ids);
1699+ gint64 sub_count = midori_bookmarks_db_count_recursive_by_id (bookmarks,
1700+ condition,
1701+ value,
1702+ *(gint64*)(iter_ids->data),
1703+ recursive);
1704+
1705+ if (sub_count < 0)
1706+ {
1707+ g_list_free_full (ids, g_free);
1708+ return -1;
1709+ }
1710+
1711+ count += sub_count;
1712+ iter_ids = g_list_next (iter_ids);
1713 }
1714-
1715+
1716 g_list_free_full (ids, g_free);
1717 return count;
1718 }
1719
1720 /**
1721- * midori_array_count_recursive:
1722- * @array: the main bookmark array
1723+ * midori_bookmarks_db_count_recursive:
1724+ * @bookmarks: the main bookmark array
1725 * @condition: condition, like "folder = '%q'"
1726 * @value: a value to be inserted if @condition contains %q
1727 * @recursive: if %TRUE include children
1728@@ -709,19 +1532,19 @@
1729 * Since: 0.5.2
1730 **/
1731 gint64
1732-midori_array_count_recursive (KatzeArray* bookmarks,
1733- const gchar* condition,
1734- const gchar* value,
1735- KatzeItem* folder,
1736- gboolean recursive)
1737+midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks,
1738+ const gchar* condition,
1739+ const gchar* value,
1740+ KatzeItem* folder,
1741+ gboolean recursive)
1742 {
1743 gint64 id = -1;
1744
1745 g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1);
1746-
1747+
1748 id = folder ? katze_item_get_meta_integer (folder, "id") : 0;
1749
1750- return midori_array_count_recursive_by_id (bookmarks, condition,
1751- value, id,
1752- recursive);
1753+ return midori_bookmarks_db_count_recursive_by_id (bookmarks, condition,
1754+ value, id,
1755+ recursive);
1756 }
1757
1758=== modified file 'midori/midori-bookmarks-db.h'
1759--- midori/midori-bookmarks-db.h 2013-09-08 10:53:32 +0000
1760+++ midori/midori-bookmarks-db.h 2013-09-17 21:46:23 +0000
1761@@ -16,33 +16,60 @@
1762 #include <sqlite3.h>
1763 #include <katze/katze.h>
1764
1765-KatzeArray*
1766-midori_bookmarks_new (char** errmsg);
1767-
1768-void
1769-midori_bookmarks_on_quit (KatzeArray* array);
1770-
1771-void
1772-midori_array_update_item (KatzeArray* bookmarks, KatzeItem* item);
1773-
1774-void
1775-midori_bookmarks_import_array (KatzeArray* bookmarks,
1776- KatzeArray* array,
1777- gint64 parentid);
1778-
1779-KatzeArray*
1780-midori_array_query_recursive (KatzeArray* bookmarks,
1781- const gchar* fields,
1782- const gchar* condition,
1783- const gchar* value,
1784- gboolean recursive);
1785+G_BEGIN_DECLS
1786+
1787+#define TYPE_MIDORI_BOOKMARKS_DB \
1788+ (midori_bookmarks_db_get_type ())
1789+#define MIDORI_BOOKMARKS_DB(obj) \
1790+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDb))
1791+#define MIDORI_BOOKMARKS_DB_CLASS(klass) \
1792+ (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDbClass))
1793+#define IS_MIDORI_BOOKMARKS_DB(obj) \
1794+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MIDORI_BOOKMARKS_DB))
1795+#define IS_MIDORI_BOOKMARKS_DB_CLASS(klass) \
1796+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MIDORI_BOOKMARKS_DB))
1797+#define MIDORI_BOOKMARKS_DB_GET_CLASS(obj) \
1798+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MIDORI_BOOKMARKS_DB, MidoriBookmarksDbClass))
1799+
1800+typedef struct _MidoriBookmarksDb MidoriBookmarksDb;
1801+typedef struct _MidoriBookmarksDbClass MidoriBookmarksDbClass;
1802+
1803+GType
1804+midori_bookmarks_db_get_type (void) G_GNUC_CONST;
1805+
1806+MidoriBookmarksDb*
1807+midori_bookmarks_db_new (char** errmsg);
1808+
1809+void
1810+midori_bookmarks_db_on_quit (MidoriBookmarksDb* array);
1811+
1812+void
1813+midori_bookmarks_db_add_item (MidoriBookmarksDb* bookmarks, KatzeItem* item);
1814+
1815+void
1816+midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks, KatzeItem* item);
1817+
1818+void
1819+midori_bookmarks_db_remove_item (MidoriBookmarksDb* bookmarks, KatzeItem* item);
1820+
1821+void
1822+midori_bookmarks_db_import_array (MidoriBookmarksDb* bookmarks,
1823+ KatzeArray* array,
1824+ gint64 parentid);
1825+
1826+KatzeArray*
1827+midori_bookmarks_db_query_recursive (MidoriBookmarksDb* bookmarks,
1828+ const gchar* fields,
1829+ const gchar* condition,
1830+ const gchar* value,
1831+ gboolean recursive);
1832
1833 gint64
1834-midori_array_count_recursive (KatzeArray* bookmarks,
1835- const gchar* condition,
1836- const gchar* value,
1837- KatzeItem* folder,
1838- gboolean recursive);
1839+midori_bookmarks_db_count_recursive (MidoriBookmarksDb* bookmarks,
1840+ const gchar* condition,
1841+ const gchar* value,
1842+ KatzeItem* folder,
1843+ gboolean recursive);
1844
1845 gint64
1846 midori_bookmarks_insert_item_db (sqlite3* db,
1847
1848=== modified file 'midori/midori-browser.c'
1849--- midori/midori-browser.c 2013-09-16 22:00:41 +0000
1850+++ midori/midori-browser.c 2013-09-17 21:46:23 +0000
1851@@ -87,7 +87,7 @@
1852
1853 MidoriWebSettings* settings;
1854 KatzeArray* proxy_array;
1855- KatzeArray* bookmarks;
1856+ MidoriBookmarksDb* bookmarks;
1857 KatzeArray* trash;
1858 KatzeArray* search_engines;
1859 KatzeArray* history;
1860@@ -195,8 +195,8 @@
1861 GtkToolbarStyle style);
1862
1863 static void
1864-midori_browser_set_bookmarks (MidoriBrowser* browser,
1865- KatzeArray* bookmarks);
1866+midori_browser_set_bookmarks (MidoriBrowser* browser,
1867+ MidoriBookmarksDb* bookmarks);
1868
1869 static void
1870 midori_browser_add_speed_dial (MidoriBrowser* browser);
1871@@ -863,7 +863,7 @@
1872 }
1873
1874 static GtkWidget*
1875-midori_bookmark_folder_button_new (KatzeArray* array,
1876+midori_bookmark_folder_button_new (MidoriBookmarksDb* array,
1877 gint64 selected_parentid)
1878 {
1879 GtkTreeStore* model;
1880@@ -1231,18 +1231,9 @@
1881 katze_item_set_meta_integer (bookmark, "parentid", selected);
1882
1883 if (new_bookmark)
1884- katze_array_add_item (browser->bookmarks, bookmark);
1885+ midori_bookmarks_db_add_item (browser->bookmarks, bookmark);
1886 else
1887- {
1888- midori_array_update_item (browser->bookmarks, bookmark);
1889- midori_browser_update_history (bookmark, "bookmark", "modify");
1890-
1891- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar)))
1892- if (!gtk_widget_get_visible (browser->bookmarkbar))
1893- _action_set_active (browser, "Bookmarkbar", TRUE);
1894- if (gtk_widget_get_visible (browser->bookmarkbar))
1895- midori_bookmarkbar_populate (browser);
1896- }
1897+ midori_bookmarks_db_update_item (browser->bookmarks, bookmark);
1898
1899 return_status = TRUE;
1900 }
1901@@ -2545,7 +2536,7 @@
1902 "bookmarks",
1903 "Bookmarks",
1904 "The bookmarks folder, containing all bookmarks",
1905- KATZE_TYPE_ARRAY,
1906+ TYPE_MIDORI_BOOKMARKS_DB,
1907 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1908
1909 /**
1910@@ -3273,8 +3264,8 @@
1911 else
1912 condition = "parentid = %q";
1913
1914- bookmarks = midori_array_query_recursive (browser->bookmarks,
1915- "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, FALSE);
1916+ bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks,
1917+ "id, title, parentid, uri, app, pos_panel, pos_bar", condition, id, FALSE);
1918 if (!bookmarks)
1919 return FALSE;
1920
1921@@ -4308,7 +4299,7 @@
1922 KatzeItem* item;
1923
1924 item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
1925- katze_array_remove_item (browser->bookmarks, item);
1926+ midori_bookmarks_db_remove_item (browser->bookmarks, item);
1927 }
1928
1929 static void
1930@@ -4320,7 +4311,7 @@
1931 MidoriContextAction* menu = midori_context_action_new ("BookmarkContextMenu", NULL, NULL, NULL);
1932 if (KATZE_ITEM_IS_FOLDER (item))
1933 {
1934- gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
1935+ gint child_bookmarks_count = midori_bookmarks_db_count_recursive (browser->bookmarks,
1936 "uri <> ''", NULL, item, FALSE);
1937
1938 GtkAction* action = gtk_action_new ("BookmarkOpenAllTabs", _("Open all in _Tabs"), NULL, STOCK_TAB_NEW);
1939@@ -4590,8 +4581,7 @@
1940 if (error)
1941 g_error_free (error);
1942 }
1943- midori_bookmarks_import_array (browser->bookmarks, bookmarks, selected);
1944-
1945+ midori_bookmarks_db_import_array (browser->bookmarks, bookmarks, selected);
1946 g_object_unref (bookmarks);
1947 g_free (path);
1948 }
1949@@ -4645,7 +4635,7 @@
1950 return;
1951
1952 error = NULL;
1953- bookmarks = midori_array_query_recursive (browser->bookmarks,
1954+ bookmarks = midori_bookmarks_db_query_recursive (browser->bookmarks,
1955 "*", "parentid IS NULL", NULL, TRUE);
1956 if (!midori_array_to_file (bookmarks, path, format, &error))
1957 {
1958@@ -7060,6 +7050,16 @@
1959 }
1960
1961 static void
1962+midori_bookmarkbar_update_item_cb (KatzeArray* bookmarks,
1963+ KatzeItem* item,
1964+ MidoriBrowser* browser)
1965+{
1966+ if (gtk_widget_get_visible (browser->bookmarkbar))
1967+ midori_bookmarkbar_populate (browser);
1968+ midori_browser_update_history (item, "bookmark", "modify");
1969+}
1970+
1971+static void
1972 midori_bookmarkbar_remove_item_cb (KatzeArray* bookmarks,
1973 KatzeItem* item,
1974 MidoriBrowser* browser)
1975@@ -7091,8 +7091,8 @@
1976 gtk_toolbar_insert (GTK_TOOLBAR (browser->bookmarkbar),
1977 gtk_separator_tool_item_new (), -1);
1978
1979- array = midori_array_query_recursive (browser->bookmarks,
1980- "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, FALSE);
1981+ array = midori_bookmarks_db_query_recursive (browser->bookmarks,
1982+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL, FALSE);
1983 if (!array)
1984 {
1985 _action_set_sensitive (browser, "BookmarkAdd", FALSE);
1986@@ -7132,7 +7132,7 @@
1987
1988 static void
1989 midori_browser_set_bookmarks (MidoriBrowser* browser,
1990- KatzeArray* bookmarks)
1991+ MidoriBookmarksDb* bookmarks)
1992 {
1993 MidoriWebSettings* settings;
1994
1995@@ -7141,6 +7141,8 @@
1996 g_signal_handlers_disconnect_by_func (browser->bookmarks,
1997 midori_bookmarkbar_add_item_cb, browser);
1998 g_signal_handlers_disconnect_by_func (browser->bookmarks,
1999+ midori_bookmarkbar_update_item_cb, browser);
2000+ g_signal_handlers_disconnect_by_func (browser->bookmarks,
2001 midori_bookmarkbar_remove_item_cb, browser);
2002 }
2003
2004@@ -7174,6 +7176,8 @@
2005 g_object_notify (G_OBJECT (settings), "show-bookmarkbar");
2006 g_signal_connect_after (bookmarks, "add-item",
2007 G_CALLBACK (midori_bookmarkbar_add_item_cb), browser);
2008+ g_signal_connect_after (bookmarks, "update-item",
2009+ G_CALLBACK (midori_bookmarkbar_update_item_cb), browser);
2010 g_signal_connect_after (bookmarks, "remove-item",
2011 G_CALLBACK (midori_bookmarkbar_remove_item_cb), browser);
2012 }
2013
2014=== modified file 'midori/midori-frontend.c'
2015--- midori/midori-frontend.c 2013-09-08 11:09:40 +0000
2016+++ midori/midori-frontend.c 2013-09-17 21:46:23 +0000
2017@@ -487,9 +487,9 @@
2018 }
2019 g_free (uri);
2020
2021- KatzeArray* bookmarks;
2022+ MidoriBookmarksDb* bookmarks;
2023 gchar* errmsg = NULL;
2024- if (!(bookmarks = midori_bookmarks_new (&errmsg)))
2025+ if (!(bookmarks = midori_bookmarks_db_new (&errmsg)))
2026 {
2027 g_string_append_printf (error_messages,
2028 _("Bookmarks couldn't be loaded: %s\n"), errmsg);
2029@@ -596,11 +596,11 @@
2030 midori_normal_app_on_quit (MidoriApp* app)
2031 {
2032 MidoriWebSettings* settings = katze_object_get_object (app, "settings");
2033- KatzeArray* bookmarks = katze_object_get_object (app, "bookmarks");
2034+ MidoriBookmarksDb* bookmarks = katze_object_get_object (app, "bookmarks");
2035 KatzeArray* history = katze_object_get_object (app, "history");
2036
2037 g_object_notify (G_OBJECT (settings), "load-on-startup");
2038- midori_bookmarks_on_quit (bookmarks);
2039+ midori_bookmarks_db_on_quit (bookmarks);
2040 midori_history_on_quit (history, settings);
2041 midori_private_data_on_quit (settings);
2042
2043
2044=== modified file 'panels/midori-bookmarks.c'
2045--- panels/midori-bookmarks.c 2013-09-08 11:09:40 +0000
2046+++ panels/midori-bookmarks.c 2013-09-17 21:46:23 +0000
2047@@ -45,7 +45,7 @@
2048 GtkWidget* delete;
2049 GtkWidget* treeview;
2050 MidoriApp* app;
2051- KatzeArray* array;
2052+ MidoriBookmarksDb* bookmarks_db;
2053
2054 gint filter_timeout;
2055 gchar* filter;
2056@@ -125,6 +125,7 @@
2057 return STOCK_BOOKMARKS;
2058 }
2059
2060+#if 0 /* Make sure the following function is never used */
2061 /* TODO: Function never used */
2062 void
2063 midori_bookmarks_export_array_db (sqlite3* db,
2064@@ -138,7 +139,7 @@
2065 gchar* parent_id;
2066
2067 parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
2068- if (!(root_array = midori_array_query_recursive (array, "*", "parentid = %q", parent_id, FALSE)))
2069+ if (!(root_array = midori_bookmarks_db_query_recursive (array, "*", "parentid = %q", parent_id, FALSE)))
2070 {
2071 g_free (parent_id);
2072 return;
2073@@ -160,6 +161,7 @@
2074 g_free (parent_id);
2075 g_list_free (list);
2076 }
2077+#endif /* 0 */
2078
2079 static KatzeArray*
2080 midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks,
2081@@ -169,21 +171,21 @@
2082 KatzeArray* array;
2083
2084 if (keyword && *keyword)
2085- array = midori_array_query_recursive (bookmarks->array,
2086- "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, FALSE);
2087+ array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db,
2088+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword, FALSE);
2089 else
2090 {
2091 if (parentid > 0)
2092 {
2093 gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
2094- array = midori_array_query_recursive (bookmarks->array,
2095- "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, FALSE);
2096+ array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db,
2097+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id, FALSE);
2098
2099 g_free (parent_id);
2100 }
2101 else
2102- array = midori_array_query_recursive (bookmarks->array,
2103- "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, FALSE);
2104+ array = midori_bookmarks_db_query_recursive (bookmarks->bookmarks_db,
2105+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL, FALSE);
2106 }
2107 return array ? array : katze_array_new (KATZE_TYPE_ITEM);
2108 }
2109@@ -274,9 +276,9 @@
2110 else
2111 parentid = 0;
2112
2113- katze_array_remove_item (bookmarks->array, item);
2114 katze_item_set_meta_integer (item, "parentid", parentid);
2115- katze_array_add_item (bookmarks->array, item);
2116+
2117+ midori_bookmarks_db_update_item (bookmarks->bookmarks_db, item);
2118
2119 g_object_unref (item);
2120 if (new_parent)
2121@@ -416,9 +418,9 @@
2122
2123 if (KATZE_ITEM_IS_FOLDER (item))
2124 {
2125- gint child_folders_count = midori_array_count_recursive (bookmarks->array,
2126+ gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db,
2127 "uri = ''", NULL, item, FALSE);
2128- gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
2129+ gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db,
2130 "uri <> ''", NULL, item, FALSE);
2131 gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count);
2132 gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
2133@@ -451,9 +453,9 @@
2134 }
2135 else
2136 {
2137- gint child_folders_count = midori_array_count_recursive (bookmarks->array,
2138+ gint child_folders_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db,
2139 "uri = ''", NULL, NULL, FALSE);
2140- gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
2141+ gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db,
2142 "uri <> ''", NULL, NULL, FALSE);
2143 gchar* child_folders_str = midori_bookmarks_statusbar_subfolders_str (child_folders_count);
2144 gchar* child_bookmarks_str = midori_bookmarks_statusbar_bookmarks_str (child_bookmarks_count);
2145@@ -499,10 +501,10 @@
2146
2147 /* Manually remove the iter and block clearing the treeview */
2148 gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
2149- g_signal_handlers_block_by_func (bookmarks->array,
2150+ g_signal_handlers_block_by_func (bookmarks->bookmarks_db,
2151 midori_bookmarks_remove_item_cb, bookmarks);
2152- katze_array_remove_item (bookmarks->array, item);
2153- g_signal_handlers_unblock_by_func (bookmarks->array,
2154+ midori_bookmarks_db_remove_item (bookmarks->bookmarks_db, item);
2155+ g_signal_handlers_unblock_by_func (bookmarks->bookmarks_db,
2156 midori_bookmarks_remove_item_cb, bookmarks);
2157 g_object_unref (item);
2158 }
2159@@ -585,9 +587,9 @@
2160 GtkTreeModel* model;
2161
2162 model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
2163- if (bookmarks->array)
2164+ if (bookmarks->bookmarks_db)
2165 {
2166- g_object_unref (bookmarks->array);
2167+ g_object_unref (bookmarks->bookmarks_db);
2168 gtk_tree_store_clear (GTK_TREE_STORE (model));
2169 }
2170 katze_assign (bookmarks->app, app);
2171@@ -595,13 +597,13 @@
2172 return;
2173
2174 g_object_ref (app);
2175- bookmarks->array = katze_object_get_object (app, "bookmarks");
2176+ bookmarks->bookmarks_db = katze_object_get_object (app, "bookmarks");
2177 midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL);
2178- g_signal_connect_after (bookmarks->array, "add-item",
2179- G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
2180- g_signal_connect (bookmarks->array, "remove-item",
2181+ g_signal_connect_after (bookmarks->bookmarks_db, "add-item",
2182+ G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
2183+ g_signal_connect (bookmarks->bookmarks_db, "remove-item",
2184 G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
2185- g_signal_connect (bookmarks->array, "update",
2186+ g_signal_connect (bookmarks->bookmarks_db, "update",
2187 G_CALLBACK (midori_bookmarks_update_cb), bookmarks);
2188 g_signal_connect_after (model, "row-changed",
2189 G_CALLBACK (midori_bookmarks_row_changed_cb),
2190@@ -835,7 +837,7 @@
2191 menu = gtk_menu_new ();
2192 if (KATZE_ITEM_IS_FOLDER (item))
2193 {
2194- gint child_bookmarks_count = midori_array_count_recursive (bookmarks->array,
2195+ gint child_bookmarks_count = midori_bookmarks_db_count_recursive (bookmarks->bookmarks_db,
2196 "uri <> ''", NULL, item, FALSE);
2197
2198 midori_bookmarks_popup_item (menu,
2199
2200=== modified file 'tests/bookmarks.c'
2201--- tests/bookmarks.c 2012-11-25 15:37:41 +0000
2202+++ tests/bookmarks.c 2013-09-17 21:46:23 +0000
2203@@ -10,11 +10,11 @@
2204 */
2205
2206 #include "midori.h"
2207-#include "panels/midori-bookmarks.h"
2208+#include "midori-bookmarks-db.h"
2209
2210 typedef struct
2211 {
2212- KatzeArray* db_bookmarks;
2213+ MidoriBookmarksDb* db_bookmarks;
2214 KatzeArray* test_bookmarks;
2215 } BookmarksFixture;
2216
2217@@ -37,7 +37,7 @@
2218 KatzeArray* folder;
2219 gchar *errmsg = NULL;
2220
2221- if (!(fixture->db_bookmarks = midori_bookmarks_new (&errmsg)))
2222+ if (!(fixture->db_bookmarks = midori_bookmarks_db_new (&errmsg)))
2223 g_error ("Bookmarks couldn't be loaded: %s\n", errmsg);
2224 g_assert (errmsg == NULL);
2225 g_assert (g_object_get_data (G_OBJECT (fixture->db_bookmarks), "db"));
2226@@ -84,8 +84,8 @@
2227 fixture_teardown (BookmarksFixture* fixture,
2228 const TestParameters *params)
2229 {
2230- midori_bookmarks_on_quit (fixture->db_bookmarks);
2231- g_object_unref (fixture->db_bookmarks);
2232+ midori_bookmarks_db_on_quit (fixture->db_bookmarks);
2233+ /* g_object_unref (fixture->db_bookmarks); */
2234 g_object_unref (fixture->test_bookmarks);
2235 }
2236
2237@@ -112,7 +112,7 @@
2238 /* NB: assumes "title" is unique in a set */
2239 static void
2240 compare_test_and_db (KatzeArray* test_bookmarks,
2241- KatzeArray* db_bookmarks,
2242+ MidoriBookmarksDb* db_bookmarks,
2243 gboolean verbose)
2244 {
2245 KatzeArray* db_items;
2246@@ -127,7 +127,7 @@
2247 g_print ("----------\n");
2248 }
2249
2250- db_items = midori_array_query_recursive (db_bookmarks,
2251+ db_items = midori_bookmarks_db_query_recursive (db_bookmarks,
2252 "*", "title='%q'", katze_item_get_name (test_item), FALSE);
2253
2254 /* FIXME g_assert_cmpint (katze_array_get_length (db_items), ==, 1); */
2255@@ -142,28 +142,33 @@
2256 }
2257
2258 static void
2259+print_bookmarks (KatzeArray* test_bookmarks)
2260+{
2261+ KatzeItem* item;
2262+ GList* list;
2263+ KATZE_ARRAY_FOREACH_ITEM_L (item, test_bookmarks, list)
2264+ {
2265+ print_bookmark (item);
2266+ g_print ("----------\n");
2267+
2268+ if (KATZE_ITEM_IS_FOLDER(item))
2269+ print_bookmarks (KATZE_ARRAY (item));
2270+ }
2271+ g_list_free (list);
2272+}
2273+
2274+static void
2275 insert_bookmarks (KatzeArray* test_bookmarks,
2276- KatzeArray* db_bookmarks,
2277+ MidoriBookmarksDb* db_bookmarks,
2278 gboolean verbose)
2279 {
2280- KatzeItem* item;
2281- GList* list;
2282- sqlite3 *db = g_object_get_data (G_OBJECT (db_bookmarks), "db");
2283
2284- KATZE_ARRAY_FOREACH_ITEM_L (item, test_bookmarks, list)
2285+ if (verbose)
2286 {
2287- if (verbose)
2288- {
2289- print_bookmark (item);
2290- g_print ("----------\n");
2291- }
2292-
2293- midori_bookmarks_insert_item_db (db, item, 0);
2294-
2295- if (KATZE_ITEM_IS_FOLDER(item))
2296- insert_bookmarks (KATZE_ARRAY (item), db_bookmarks, verbose);
2297+ print_bookmarks (test_bookmarks);
2298 }
2299- g_list_free (list);
2300+
2301+ midori_bookmarks_db_import_array (db_bookmarks, test_bookmarks, 0);
2302 }
2303
2304 static void

Subscribers

People subscribed via source and target branches

to all changes: