25
25
#include <unistd.h>
29
midori_bookmarks_update_item_db (sqlite3* db,
33
midori_bookmarks_insert_item_db (sqlite3* db,
29
* SECTION:midory-bookmarks-db
30
* @short_description: A #KatzeArray connected to a database
31
* @see_also: #KatzeArray
33
* #MidoriBookmarksDb is a #KatzeArray specialized for database
37
struct _MidoriBookmarksDb
39
KatzeArray parent_instance;
44
struct _MidoriBookmarksDbClass
46
KatzeArrayClass parent_class;
50
(*update_item) (MidoriBookmarksDb* bookmarks,
54
G_DEFINE_TYPE (MidoriBookmarksDb, midori_bookmarks_db, KATZE_TYPE_ARRAY);
62
static guint signals[LAST_SIGNAL];
65
_midori_bookmarks_db_add_item (KatzeArray* array,
69
_midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks,
73
_midori_bookmarks_db_remove_item (KatzeArray* array,
77
_midori_bookmarks_db_move_item (KatzeArray* array,
82
_midori_bookmarks_db_clear (KatzeArray* array);
85
midori_bookmarks_db_finalize (GObject* object);
88
midori_bookmarks_db_insert_item_db (sqlite3* db,
93
midori_bookmarks_db_update_item_db (sqlite3* db,
97
midori_bookmarks_db_remove_item_db (sqlite3* db,
101
midori_bookmarks_db_class_init (MidoriBookmarksDbClass* class)
103
GObjectClass* gobject_class;
104
KatzeArrayClass* katze_array_class;
106
gobject_class = G_OBJECT_CLASS (class);
107
gobject_class->finalize = midori_bookmarks_db_finalize;
109
signals[UPDATE_ITEM] = g_signal_new (
111
G_TYPE_FROM_CLASS (class),
112
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
113
G_STRUCT_OFFSET (MidoriBookmarksDbClass, update_item),
116
g_cclosure_marshal_VOID__POINTER,
120
katze_array_class = KATZE_ARRAY_CLASS (class);
122
katze_array_class->add_item = _midori_bookmarks_db_add_item;
123
katze_array_class->remove_item = _midori_bookmarks_db_remove_item;
124
katze_array_class->move_item = _midori_bookmarks_db_move_item;
125
katze_array_class->clear = _midori_bookmarks_db_clear;
127
class->update_item = _midori_bookmarks_db_update_item;
131
midori_bookmarks_db_init (MidoriBookmarksDb* bookmarks)
133
bookmarks->db = NULL;
135
katze_item_set_meta_integer (KATZE_ITEM (bookmarks), "id", 0);
136
katze_item_set_name (KATZE_ITEM (bookmarks), _("Bookmarks"));
137
/* g_object_ref (bookmarks); */
141
midori_bookmarks_db_finalize (GObject* object)
143
MidoriBookmarksDb* bookmarks = MIDORI_BOOKMARKS_DB (object);
147
sqlite3_close (bookmarks->db);
150
G_OBJECT_CLASS (midori_bookmarks_db_parent_class)->finalize (object);
154
* midori_bookmarks_db_get_item_parent:
155
* @bookmarks: the main bookmarks array
156
* @item: a #KatzeItem
158
* Internal function that find the parent of the @item thanks to its %parentid
161
midori_bookmarks_db_get_item_parent (MidoriBookmarksDb* bookmarks,
167
parentid = katze_item_get_meta_integer (KATZE_ITEM (item), "parentid");
171
parent = KATZE_ARRAY (bookmarks);
182
* _midori_bookmarks_db_add_item:
183
* @array: the main bookmarks array
184
* @item: a #KatzeItem
186
* Internal function that overloads the #KatzeArray %katze_array_add_item().
187
* It relays the add item to the appropriate #KatzeArray.
190
_midori_bookmarks_db_add_item (KatzeArray* array,
193
MidoriBookmarksDb *bookmarks;
195
KatzeArray* db_parent;
197
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
198
g_return_if_fail (KATZE_IS_ITEM (item));
200
bookmarks = MIDORI_BOOKMARKS_DB (array);
202
parent = katze_item_get_parent (KATZE_ITEM (item));
204
db_parent = midori_bookmarks_db_get_item_parent (bookmarks, item);
206
g_return_if_fail (db_parent);
208
if (parent == db_parent)
210
if (IS_MIDORI_BOOKMARKS_DB (parent))
211
KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->update (parent);
213
katze_array_update (parent);
217
if (IS_MIDORI_BOOKMARKS_DB (parent))
218
KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->add_item (parent, item);
220
katze_array_add_item (parent, item);
224
* _midori_bookmarks_db_update_item:
225
* @array: the main bookmarks array
226
* @item: a #KatzeItem
228
* Internal function that implements the %midori_bookmarks_db_update_item() post-processing.
229
* It relays an update to the appropriate #KatzeArray.
232
_midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks,
237
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
238
g_return_if_fail (KATZE_IS_ITEM (item));
240
parent = katze_item_get_parent (KATZE_ITEM (item));
242
g_return_if_fail (parent);
244
katze_array_update (parent);
248
* _midori_bookmarks_db_remove_item:
249
* @array: the main bookmarks array
250
* @item: a #KatzeItem
252
* Internal function that overloads the #KatzeArray %katze_array_remove_item().
253
* It relays the remove item to the appropriate #KatzeArray.
256
_midori_bookmarks_db_remove_item (KatzeArray* array,
261
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
262
g_return_if_fail (KATZE_IS_ITEM (item));
264
parent = katze_item_get_parent (KATZE_ITEM (item));
266
g_return_if_fail (parent);
268
if (IS_MIDORI_BOOKMARKS_DB (parent))
269
KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->remove_item (parent, item);
271
katze_array_remove_item (parent, item);
275
* _midori_bookmarks_db_move_item:
276
* @array: the main bookmarks array
277
* @item: a #KatzeItem
278
* @position: the new @item position
280
* Internal function that overloads the #KatzeArray %katze_array_move_item().
281
* It relays the move @item to the appropriate #KatzeArray.
284
_midori_bookmarks_db_move_item (KatzeArray* array,
288
MidoriBookmarksDb *bookmarks;
291
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
292
g_return_if_fail (KATZE_IS_ITEM (item));
294
parent = katze_item_get_parent (KATZE_ITEM (item));
296
g_return_if_fail (parent);
298
KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->move_item (parent, item, position);
302
* _midori_bookmarks_db_clear:
303
* @array: the main bookmarks array
305
* Internal function that overloads the #KatzeArray %katze_array_clear().
306
* It deletes the whole bookmarks data.
309
_midori_bookmarks_db_clear (KatzeArray* array)
311
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
313
g_critical ("_midori_bookmarks_db_clear: not implemented\n");
317
* midori_bookmarks_db_signal_update_item:
318
* @array: a #KatzeArray
321
* Notify an update of the item of the array.
325
midori_bookmarks_db_signal_update_item (MidoriBookmarksDb* array,
328
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (array));
330
g_signal_emit (array, signals[UPDATE_ITEM], 0, item);
334
* midori_bookmarks_db_insert_item_db:
336
* @item: #KatzeItem the item to insert
338
* Internal function that does the actual SQL INSERT of the @item in @db.
343
midori_bookmarks_db_insert_item_db (sqlite3* db,
38
348
char* errmsg = NULL;
70
380
new_parentid = g_strdup_printf ("NULL");
72
382
sqlcmd = sqlite3_mprintf (
73
"INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
74
"VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
77
katze_item_get_name (item),
78
katze_str_non_null (uri),
79
katze_str_non_null (desc),
80
katze_item_get_meta_boolean (item, "toolbar"),
81
katze_item_get_meta_boolean (item, "app"));
383
"INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
384
"VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
387
katze_item_get_name (item),
388
katze_str_non_null (uri),
389
katze_str_non_null (desc),
390
katze_item_get_meta_boolean (item, "toolbar"),
391
katze_item_get_meta_boolean (item, "app"));
83
393
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
135
454
parentid = g_strdup_printf ("NULL");
137
456
sqlcmd = sqlite3_mprintf (
138
"UPDATE bookmarks SET "
139
"parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
142
katze_item_get_name (item),
143
katze_str_non_null (katze_item_get_uri (item)),
144
katze_str_non_null (katze_item_get_meta_string (item, "desc")),
145
katze_item_get_meta_boolean (item, "toolbar"),
146
katze_item_get_meta_boolean (item, "app"),
457
"UPDATE bookmarks SET "
458
"parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
461
katze_item_get_name (item),
462
katze_str_non_null (katze_item_get_uri (item)),
463
katze_str_non_null (katze_item_get_meta_string (item, "desc")),
464
katze_item_get_meta_boolean (item, "toolbar"),
465
katze_item_get_meta_boolean (item, "app"),
150
469
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
484
* midori_bookmarks_db_remove_item_db:
486
* @item: #KatzeItem the item to delete
488
* Internal function that does the actual SQL DELETE of the @item in @db.
493
midori_bookmarks_db_remove_item_db (sqlite3* db,
498
gboolean removed = TRUE;
501
id = g_strdup_printf ("%" G_GINT64_FORMAT,
502
katze_item_get_meta_integer (item, "id"));
504
sqlcmd = sqlite3_mprintf ("DELETE FROM bookmarks WHERE id = %q", id);
506
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
508
g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg);
509
sqlite3_free (errmsg);
513
sqlite3_free (sqlcmd);
519
* midori_bookmarks_db_add_item:
520
* @bookmarks: the main bookmark array
521
* @item: #KatzeItem the item to update
523
* Adds the @item in the bookmark data base.
528
midori_bookmarks_db_add_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
530
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
531
g_return_if_fail (KATZE_IS_ITEM (item));
532
g_return_if_fail (NULL == katze_item_get_meta_string (item, "id"));
534
midori_bookmarks_db_insert_item_db (bookmarks->db, item,
535
katze_item_get_meta_integer (item, "parentid"));
537
katze_array_add_item (KATZE_ARRAY (bookmarks), item);
165
541
* midori_bookmarks_db_update_item:
166
542
* @bookmarks: the main bookmark array
167
543
* @item: #KatzeItem the item to update
169
545
* Updates the @item in the bookmark data base.
174
midori_array_update_item (KatzeArray* bookmarks,
177
g_return_if_fail (KATZE_IS_ARRAY (bookmarks));
178
g_return_if_fail (KATZE_IS_ITEM (item));
179
g_return_if_fail (katze_item_get_meta_string (item, "id"));
180
g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
182
sqlite3* db = g_object_get_data (G_OBJECT (bookmarks), "db");
184
g_return_if_fail (db);
186
midori_bookmarks_update_item_db (db, item);
190
midori_bookmarks_dbtracer (void* dummy,
193
g_printerr ("%s\n", query);
197
midori_bookmarks_add_item_cb (KatzeArray* array,
201
midori_bookmarks_insert_item_db (db, item,
202
katze_item_get_meta_integer (item, "parentid"));
206
midori_bookmarks_remove_item_cb (KatzeArray* array,
214
id = g_strdup_printf ("%" G_GINT64_FORMAT,
215
katze_item_get_meta_integer (item, "id"));
217
sqlcmd = sqlite3_mprintf ("DELETE FROM bookmarks WHERE id = %q", id);
219
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
221
g_printerr (_("Failed to remove bookmark item: %s\n"), errmsg);
222
sqlite3_free (errmsg);
225
sqlite3_free (sqlcmd);
550
midori_bookmarks_db_update_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
552
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
553
g_return_if_fail (KATZE_IS_ITEM (item));
554
g_return_if_fail (katze_item_get_meta_string (item, "id"));
555
g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
557
midori_bookmarks_db_update_item_db (bookmarks->db, item);
559
midori_bookmarks_db_signal_update_item (bookmarks, item);
563
* midori_bookmarks_db_remove_item:
564
* @bookmarks: the main bookmark array
565
* @item: #KatzeItem the item to remove
567
* Removes the @item from the bookmark data base.
572
midori_bookmarks_db_remove_item (MidoriBookmarksDb* bookmarks, KatzeItem* item)
574
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
575
g_return_if_fail (KATZE_IS_ITEM (item));
576
g_return_if_fail (katze_item_get_meta_string (item, "id"));
577
g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
579
midori_bookmarks_db_remove_item_db (bookmarks->db, item);
581
katze_array_remove_item (KATZE_ARRAY (bookmarks), item);
229
584
#define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \
844
* midori_bookmarks_db_on_quit:
845
* @bookmarks: the main bookmark array
847
* Delete the main bookmark array.
474
midori_bookmarks_on_quit (KatzeArray* array)
852
midori_bookmarks_db_on_quit (MidoriBookmarksDb* bookmarks)
476
g_return_if_fail (KATZE_IS_ARRAY (array));
854
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
478
sqlite3* db = g_object_get_data (G_OBJECT (array), "db");
479
g_return_if_fail (db != NULL);
856
g_object_unref (bookmarks);
860
* midori_bookmarks_db_import_array:
861
* @array: the main bookmark array
862
* @array: #KatzeArray containing the items to import
863
* @parentid: the id of folder
865
* Imports the items of @array as childs of the folder
866
* identfied by @parentid.
484
midori_bookmarks_import_array (KatzeArray* bookmarks,
871
midori_bookmarks_db_import_array (MidoriBookmarksDb* bookmarks,
485
872
KatzeArray* array,
878
g_return_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks));
879
g_return_if_fail (KATZE_IS_ARRAY (array));
494
881
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
496
883
katze_item_set_meta_integer (item, "parentid", parentid);
497
katze_array_add_item (bookmarks, item);
884
midori_bookmarks_db_add_item (bookmarks, item);
498
885
if (KATZE_IS_ARRAY (item))
499
midori_bookmarks_import_array (bookmarks, KATZE_ARRAY (item),
500
katze_item_get_meta_integer(item, "id"));
886
midori_bookmarks_db_import_array (bookmarks, KATZE_ARRAY (item),
887
katze_item_get_meta_integer(item, "id"));
502
889
g_list_free (list);
506
* midori_array_query_recursive:
893
* midori_bookmarks_db_array_from_statement:
894
* @stmt: the sqlite returned statement
895
* @bookmarks: the database controller
897
* Internal function that populate a #KatzeArray by processing the @stmt
899
* a- if the item is already in memory
900
* in this case the item data is updated with retreived database content
901
* and the already existing item is populated in the returned #KatzeArray
902
* b- if the data is a folder
903
* a new #KatzeArray item is populated in the returned #KatzeArray and
904
* memorized for future use.
905
* c- if the data is a bookmark
906
* a new #KatzeItem item is populated in the returned #KatzeArray and
907
* memorized for furure use.
909
* Return value: the populated #KatzeArray
912
midori_bookmarks_db_array_from_statement (sqlite3_stmt* stmt,
913
MidoriBookmarksDb* bookmarks)
919
array = katze_array_new (KATZE_TYPE_ITEM);
920
cols = sqlite3_column_count (stmt);
922
while ((result = sqlite3_step (stmt)) == SQLITE_ROW)
928
item = katze_item_new ();
929
for (i = 0; i < cols; i++)
930
katze_item_set_value_from_column (stmt, i, item);
932
if (KATZE_ITEM_IS_FOLDER (item))
934
g_object_unref (item);
936
item = KATZE_ITEM (katze_array_new (KATZE_TYPE_ITEM));
938
for (i = 0; i < cols; i++)
939
katze_item_set_value_from_column (stmt, i, item);
942
katze_array_add_item (array, item);
945
sqlite3_clear_bindings (stmt);
946
sqlite3_reset (stmt);
951
* midori_bookmarks_db_array_from_sqlite:
952
* @array: the main bookmark array
953
* @sqlcmd: the sqlcmd to execute
955
* Internal function that process the requested @sqlcmd.
957
* Return value: a #KatzeArray on success, %NULL otherwise
960
midori_bookmarks_db_array_from_sqlite (MidoriBookmarksDb* bookmarks,
966
g_return_val_if_fail (bookmarks->db != NULL, NULL);
968
result = sqlite3_prepare_v2 (bookmarks->db, sqlcmd, -1, &stmt, NULL);
969
if (result != SQLITE_OK)
972
return midori_bookmarks_db_array_from_statement (stmt, bookmarks);
976
* midori_bookmarks_db_query_recursive:
507
977
* @array: the main bookmark array
508
978
* @fields: comma separated list of fields
509
979
* @condition: condition, like "folder = '%q'"
515
985
* Return value: a #KatzeArray on success, %NULL otherwise
520
midori_array_query_recursive (KatzeArray* bookmarks,
522
const gchar* condition,
990
midori_bookmarks_db_query_recursive (MidoriBookmarksDb* bookmarks,
992
const gchar* condition,
528
997
char* sqlcmd_value;
529
998
KatzeArray* array;
533
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
1002
g_return_val_if_fail (IS_MIDORI_BOOKMARKS_DB (bookmarks), NULL);
534
1003
g_return_val_if_fail (fields, NULL);
535
1004
g_return_val_if_fail (condition, NULL);
536
db = g_object_get_data (G_OBJECT (bookmarks), "db");
537
g_return_val_if_fail (db != NULL, NULL);
539
1006
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
540
1007
"ORDER BY (uri='') ASC, title DESC", fields, condition);
541
1008
if (strstr (condition, "%q"))
543
1010
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
544
array = katze_array_from_sqlite (db, sqlcmd_value);
1011
array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd_value);
545
1012
sqlite3_free (sqlcmd_value);
548
array = katze_array_from_sqlite (db, sqlcmd);
1015
array = midori_bookmarks_db_array_from_sqlite (bookmarks, sqlcmd);
549
1016
g_free (sqlcmd);
615
1081
GList* iter_ids;
617
1083
g_return_val_if_fail (condition, -1);
618
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1);
619
db = g_object_get_data (G_OBJECT (bookmarks), "db");
620
g_return_val_if_fail (db != NULL, -1);
1084
g_return_val_if_fail (MIDORI_BOOKMARKS_DB (bookmarks), -1);
1085
g_return_val_if_fail (bookmarks->db != NULL, -1);
622
1087
g_assert(!strstr("parentid", condition));
625
sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
626
"WHERE parentid = %" G_GINT64_FORMAT " AND %s",
1090
sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1091
"WHERE parentid = %" G_GINT64_FORMAT " AND %s",
630
sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
631
"WHERE parentid IS NULL AND %s ",
1095
sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
1096
"WHERE parentid IS NULL AND %s ",
634
1099
if (strstr (condition, "%q"))
636
1101
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
637
count = count_from_sqlite (db, sqlcmd_value);
1102
count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd_value);
638
1103
sqlite3_free (sqlcmd_value);
641
count = count_from_sqlite (db, sqlcmd);
1106
count = midori_bookmarks_db_count_from_sqlite (bookmarks->db, sqlcmd);
643
1108
g_free (sqlcmd);
651
sqlcmd_value = sqlite3_mprintf (
652
"SELECT id FROM bookmarks "
653
"WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
1116
sqlcmd_value = sqlite3_mprintf (
1117
"SELECT id FROM bookmarks "
1118
"WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
655
sqlcmd_value = sqlite3_mprintf (
656
"SELECT id FROM bookmarks "
657
"WHERE parentid IS NULL AND uri = ''");
1120
sqlcmd_value = sqlite3_mprintf (
1121
"SELECT id FROM bookmarks "
1122
"WHERE parentid IS NULL AND uri = ''");
659
if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
1124
if (sqlite3_prepare_v2 (bookmarks->db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
661
g_assert (sqlite3_column_count (stmt) == 1);
663
if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
665
gint64* pid = g_new (gint64, 1);
667
*pid = sqlite3_column_int64(stmt, 0);
668
ids = g_list_append (ids, pid);
671
sqlite3_clear_bindings (stmt);
672
sqlite3_reset (stmt);
1126
g_assert (sqlite3_column_count (stmt) == 1);
1128
if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
1130
gint64* pid = g_new (gint64, 1);
1132
*pid = sqlite3_column_int64(stmt, 0);
1133
ids = g_list_append (ids, pid);
1136
sqlite3_clear_bindings (stmt);
1137
sqlite3_reset (stmt);
675
1140
sqlite3_free (sqlcmd_value);