The new format uses bookmarks_v2.db.
We require sqlite 3.6.19 now due to foreign keys.
Fixes: https://bugs.launchpad.net/midori/+bug/836707
static gboolean
midori_history_initialize (KatzeArray* array,
const gchar* filename,
- const gchar* bookmarks_filename,
char** errmsg)
{
sqlite3* db;
sqlite3_stmt* stmt;
gint result;
gchar* sql;
+ gchar* bookmarks_filename;
+
+ g_return_val_if_fail (errmsg != NULL, FALSE);
if (sqlite3_open (filename, &db) != SQLITE_OK)
{
"COMMIT;",
NULL, NULL, errmsg);
+ bookmarks_filename = build_config_filename ("bookmarks_v2.db");
sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename);
+ g_free (bookmarks_filename);
sqlite3_exec (db, sql, NULL, NULL, errmsg);
g_free (sql);
g_object_set_data (G_OBJECT (array), "db", db);
gchar** extensions;
MidoriWebSettings* settings;
gchar* config_file;
- gchar* bookmarks_file;
GKeyFile* speeddial;
- gboolean bookmarks_exist;
MidoriStartup load_on_startup;
KatzeArray* search_engines;
KatzeArray* bookmarks;
midori_startup_timer ("Search read: \t%f");
bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
- bookmarks_file = g_build_filename (config, "bookmarks.db", NULL);
- bookmarks_exist = g_access (bookmarks_file, F_OK) == 0;
errmsg = NULL;
- if ((db = midori_bookmarks_initialize (bookmarks, bookmarks_file, &errmsg)) == NULL)
+ if ((db = midori_bookmarks_initialize (bookmarks, &errmsg)) == NULL)
{
g_string_append_printf (error_messages,
_("Bookmarks couldn't be loaded: %s\n"), errmsg);
katze_assign (config_file, g_build_filename (config, "history.db", NULL));
errmsg = NULL;
- if (!midori_history_initialize (history, config_file, bookmarks_file, &errmsg))
+ if (!midori_history_initialize (history, config_file, &errmsg))
{
g_string_append_printf (error_messages,
_("The history couldn't be loaded: %s\n"), errmsg);
errmsg = NULL;
}
- g_free (bookmarks_file);
midori_startup_timer ("History read: \t%f");
error = NULL;
item->added = date;
}
else if (g_str_equal (name, "day") || g_str_equal (name, "app")
- || g_str_equal (name, "toolbar"))
+ || g_str_equal (name, "toolbar") || g_str_equal (name, "id")
+ || g_str_equal (name, "parentid") || g_str_equal (name, "seq")
+ || g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar"))
{
gint value;
value = sqlite3_column_int64 (stmt, column);
katze_item_set_meta_integer (item, name, value);
}
- else if (g_str_equal (name, "folder"))
- {
- const unsigned char* folder;
- folder = sqlite3_column_text (stmt, column);
- katze_item_set_meta_string (item, name, (gchar*)folder);
- }
else if (g_str_equal (name, "desc"))
{
const unsigned char* text;
text = sqlite3_column_text (stmt, column);
item->text = g_strdup ((gchar*)text);
}
+ else if (g_str_equal (name, "sql"))
+ {
+ const unsigned char* sql;
+ sql = sqlite3_column_text (stmt, column);
+ katze_item_set_meta_string (item, name, (gchar*)sql);
+ }
else
g_warn_if_reached ();
}
return NULL;
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
- "ORDER BY title DESC", fields, condition);
+ "ORDER BY (uri='') ASC, title DESC", fields, condition);
if (strstr (condition, "%q"))
{
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
{
if (KATZE_ITEM_IS_FOLDER (item))
{
+ gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
+ katze_item_get_meta_integer (item, "id"));
KatzeArray* subarray = midori_array_query_recursive (bookmarks,
- fields, "folder='%q'", item->name, TRUE);
+ fields, "parentid=%q", parentid, TRUE);
katze_item_set_name (KATZE_ITEM (subarray), item->name);
katze_array_add_item (array, subarray);
+
+ g_free (parentid);
}
}
g_list_free (list);
#include "midori-bookmarks.h"
#include "panels/midori-bookmarks.h"
#include "midori-array.h"
+#include "sokoke.h"
+#include <glib/gstdio.h>
#include <glib/gi18n.h>
#ifdef G_ENABLE_DEBUG
sqlite3* db)
{
midori_bookmarks_insert_item_db (db, item,
- katze_item_get_meta_string (item, "folder"));
+ katze_item_get_meta_integer (item, "parentid"));
}
void
gchar* sqlcmd;
char* errmsg = NULL;
- if (KATZE_ITEM_IS_BOOKMARK (item))
- sqlcmd = sqlite3_mprintf (
- "DELETE FROM bookmarks WHERE uri = '%q' "
- " AND folder = '%q'",
- katze_item_get_uri (item),
- katze_str_non_null (katze_item_get_meta_string (item, "folder")));
- else
- sqlcmd = sqlite3_mprintf (
- "DELETE FROM bookmarks WHERE title = '%q'"
- " AND folder = '%q'",
- katze_item_get_name (item),
- katze_str_non_null (katze_item_get_meta_string (item, "folder")));
+ sqlcmd = sqlite3_mprintf (
+ "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";",
+ katze_item_get_meta_integer (item, "id"));
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
{
sqlite3_free (sqlcmd);
}
+#define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \
+ do { \
+ if (sql_errmsg) \
+ { \
+ g_string_append_printf (errmsg_str, "%s : %s\n", custom_errmsg, sql_errmsg); \
+ sqlite3_free (sql_errmsg); \
+ } \
+ else \
+ g_string_append (errmsg_str, custom_errmsg); \
+ } while (0)
+
+gboolean
+midori_bookmarks_import_from_old_db (sqlite3* db,
+ const gchar* oldfile,
+ gchar** errmsg)
+{
+ gint sql_errcode;
+ gboolean failure = FALSE;
+ gchar* sql_errmsg = NULL;
+ GString* errmsg_str = g_string_new (NULL);
+ gchar* attach_stmt = sqlite3_mprintf ("ATTACH DATABASE %Q AS old_db;", oldfile);
+ const gchar* convert_stmts =
+ "BEGIN TRANSACTION;"
+ "INSERT INTO main.bookmarks (parentid, title, uri, desc, app, toolbar) "
+ "SELECT NULL AS parentid, title, uri, desc, app, toolbar "
+ "FROM old_db.bookmarks;"
+ "UPDATE main.bookmarks SET parentid = ("
+ "SELECT id FROM main.bookmarks AS b1 WHERE b1.title = ("
+ "SELECT folder FROM old_db.bookmarks WHERE title = main.bookmarks.title));"
+ "COMMIT;";
+ const gchar* detach_stmt = "DETACH DATABASE old_db;";
+
+ *errmsg = NULL;
+ sql_errcode = sqlite3_exec (db, attach_stmt, NULL, NULL, &sql_errmsg);
+ sqlite3_free (attach_stmt);
+
+ if (sql_errcode != SQLITE_OK)
+ {
+ _APPEND_TO_SQL_ERRORMSG (_("failed to ATTACH old db"));
+ goto convert_failed;
+ }
+
+ if (sqlite3_exec (db, convert_stmts, NULL, NULL, &sql_errmsg) != SQLITE_OK)
+ {
+ failure = TRUE;
+ _APPEND_TO_SQL_ERRORMSG (_("failed to import from old db"));
+
+ /* try to get back to previous state */
+ if (sqlite3_exec (db, "ROLLBACK TRANSACTION;", NULL, NULL, &sql_errmsg) != SQLITE_OK)
+ _APPEND_TO_SQL_ERRORMSG (_("failed to rollback the transaction"));
+ }
+
+ if (sqlite3_exec (db, detach_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
+ _APPEND_TO_SQL_ERRORMSG (_("failed to DETACH "));
+
+ if (failure)
+ {
+ convert_failed:
+ *errmsg = g_string_free (errmsg_str, FALSE);
+ g_print ("ERRORR: %s\n", errmsg_str->str);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#undef _APPEND_TO_SQL_ERRORMSG
+
sqlite3*
midori_bookmarks_initialize (KatzeArray* array,
- const gchar* filename,
char** errmsg)
{
sqlite3* db;
+ gchar* oldfile;
+ gchar* newfile;
+ gboolean newfile_did_exist, oldfile_exists;
+ const gchar* create_stmt;
+ gchar* sql_errmsg = NULL;
+ gchar* import_errmsg = NULL;
- if (sqlite3_open (filename, &db) != SQLITE_OK)
+ g_return_val_if_fail (errmsg != NULL, NULL);
+
+ oldfile = g_build_filename (sokoke_set_config_dir (NULL), "bookmarks.db", NULL);
+ oldfile_exists = g_access (oldfile, F_OK) == 0;
+ newfile = g_build_filename (sokoke_set_config_dir (NULL), "bookmarks_v2.db", NULL);
+ newfile_did_exist = g_access (newfile, F_OK) == 0;
+
+ /* sqlite3_open will create the file if it did not exists already */
+ if (sqlite3_open (newfile, &db) != SQLITE_OK)
{
- if (errmsg)
- *errmsg = g_strdup_printf (_("Failed to open database: %s\n"),
- sqlite3_errmsg (db));
- sqlite3_close (db);
- return NULL;
+ if (db)
+ *errmsg = g_strdup_printf (_("failed to open database: %s\n"),
+ sqlite3_errmsg (db));
+ else
+ *errmsg = g_strdup (_("failed to open database\n"));
+
+ goto init_failed;
}
#ifdef G_ENABLE_DEBUG
sqlite3_trace (db, midori_bookmarks_dbtracer, NULL);
#endif
- if (sqlite3_exec (db,
- "CREATE TABLE IF NOT EXISTS "
- "bookmarks (uri text, title text, folder text, "
- "desc text, app integer, toolbar integer);",
- NULL, NULL, errmsg) != SQLITE_OK)
+ create_stmt = /* Table structure */
+ "CREATE TABLE IF NOT EXISTS bookmarks "
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "parentid INTEGER DEFAULT NULL, "
+ "title TEXT, uri TEXT, desc TEXT, app INTEGER, toolbar INTEGER, "
+ "pos_panel INTEGER, pos_bar INTEGER, "
+ "created DATE DEFAULT CURRENT_TIMESTAMP, "
+ "last_visit DATE, visit_count INTEGER DEFAULT 0, "
+ "nick TEXT, "
+ "FOREIGN KEY(parentid) REFERENCES bookmarks(id) "
+ "ON DELETE CASCADE); PRAGMA foreign_keys = ON;"
+
+ /* trigger: insert panel position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosPanel "
+ "AFTER INSERT ON bookmarks FOR EACH ROW "
+ "BEGIN UPDATE bookmarks SET pos_panel = ("
+ "SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks WHERE "
+ "(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
+ "OR (NEW.parentid IS NULL AND parentid IS NULL)) "
+ "WHERE id = NEW.id; END;"
+
+ /* trigger: insert Bookmarkbar position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosBar "
+ "AFTER INSERT ON bookmarks FOR EACH ROW WHEN NEW.toolbar=1 "
+ "BEGIN UPDATE bookmarks SET pos_bar = ("
+ "SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
+ "((NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
+ "OR (NEW.parentid IS NULL AND parentid IS NULL)) AND toolbar=1) "
+ "WHERE id = NEW.id; END;"
+
+ /* trigger: update panel position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosPanel "
+ "BEFORE UPDATE OF parentid ON bookmarks FOR EACH ROW "
+ "WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
+ "AND NEW.parentid IS NOT OLD.parentid) OR "
+ "((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
+ "AND NEW.parentid!=OLD.parentid) "
+ "BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
+ "WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
+ "OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; "
+ "UPDATE bookmarks SET pos_panel = ("
+ "SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks "
+ "WHERE (NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
+ "OR (NEW.parentid IS NULL AND parentid IS NULL)) "
+ "WHERE id = OLD.id; END;"
+
+ /* trigger: update Bookmarkbar position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar0 "
+ "AFTER UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
+ "WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
+ "AND NEW.parentid IS NOT OLD.parentid) "
+ "OR ((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
+ "AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=1 AND NEW.toolbar=0) "
+ "BEGIN UPDATE bookmarks SET pos_bar = NULL WHERE id = NEW.id; "
+ "UPDATE bookmarks SET pos_bar = pos_bar-1 "
+ "WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
+ "OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;"
+
+ /* trigger: update Bookmarkbar position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar1 "
+ "BEFORE UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
+ "WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
+ "AND NEW.parentid IS NOT OLD.parentid) OR "
+ "((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
+ "AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=0 AND NEW.toolbar=1) "
+ "BEGIN UPDATE bookmarks SET pos_bar = ("
+ "SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
+ "(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
+ "OR (NEW.parentid IS NULL AND parentid IS NULL)) "
+ "WHERE id = OLD.id; END;"
+
+ /* trigger: delete panel position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosPanel "
+ "AFTER DELETE ON bookmarks FOR EACH ROW "
+ "BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
+ "WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
+ "OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; END;"
+
+ /* trigger: delete Bookmarkbar position */
+ "CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosBar "
+ "AFTER DELETE ON bookmarks FOR EACH ROW WHEN OLD.toolbar=1 "
+ "BEGIN UPDATE bookmarks SET pos_bar = pos_bar-1 "
+ "WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
+ "OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;";
+
+
+ if (newfile_did_exist)
+ {
+ /* we are done */
+ goto init_success;
+ }
+ else
+ {
+ /* initial creation */
+ if (sqlite3_exec (db, create_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
+ {
+
+ if (errmsg)
+ {
+ if (sql_errmsg)
+ {
+ *errmsg = g_strdup_printf (_("could not create bookmarks table: %s\n"), sql_errmsg);
+ sqlite3_free (sql_errmsg);
+ }
+ else
+ *errmsg = g_strdup (_("could not create bookmarks table"));
+ }
+
+ /* we can as well remove the new file */
+ g_unlink (newfile);
+ goto init_failed;
+ }
+
+ }
+
+ if (oldfile_exists)
+ /* import from old db */
+ if (!midori_bookmarks_import_from_old_db (db, oldfile, &import_errmsg))
+ {
+ if (errmsg)
+ {
+ if (import_errmsg)
+ {
+ *errmsg = g_strdup_printf (_("could not import from old database: %s\n"), import_errmsg);
+ g_free (import_errmsg);
+ }
+ else
+ *errmsg = g_strdup_printf (_("could not import from old database"));
+ }
+ }
+
+ init_success:
+ g_free (newfile);
+ g_free (oldfile);
+ g_signal_connect (array, "add-item",
+ G_CALLBACK (midori_bookmarks_add_item_cb), db);
+ g_signal_connect (array, "remove-item",
+ G_CALLBACK (midori_bookmarks_remove_item_cb), db);
+
+ return db;
+
+ init_failed:
+ g_free (newfile);
+ g_free (oldfile);
+
+ if (db)
+ sqlite3_close (db);
+
return NULL;
- g_signal_connect (array, "add-item",
- G_CALLBACK (midori_bookmarks_add_item_cb), db);
- g_signal_connect (array, "remove-item",
- G_CALLBACK (midori_bookmarks_remove_item_cb), db);
- return db;
}
void
g_error_free (error);
return;
}
- midori_bookmarks_import_array_db (db, bookmarks, "");
+ midori_bookmarks_import_array_db (db, bookmarks, 0);
}
sqlite3*
midori_bookmarks_initialize (KatzeArray* array,
- const gchar* filename,
char** errmsg);
void
void
midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array,
- gchar* folder);
+ gint64 parentid);
+
+gboolean
+midori_bookmarks_update_item_db (sqlite3* db,
+ KatzeItem* item);
void
midori_browser_open_bookmark (MidoriBrowser* browser,
}
static GtkWidget*
-midori_bookmark_folder_button_new (KatzeArray* array,
- gboolean new_bookmark,
- const gchar* selected)
+midori_bookmark_folder_button_new (KatzeArray* array,
+ gboolean new_bookmark,
+ gint64 selected,
+ gint64 parentid)
{
GtkListStore* model;
GtkWidget* combo;
sqlite3* db;
sqlite3_stmt* statement;
gint result;
- const gchar* sqlcmd = "SELECT title from bookmarks where uri=''";
+ const gchar* sqlcmd = "SELECT title, id FROM bookmarks WHERE uri='' ORDER BY title ASC";
- model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT64);
combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "ellipsize", 1);
gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
- 0, _("Toplevel folder"), 1, PANGO_ELLIPSIZE_END, -1);
+ 0, _("Toplevel folder"), 1, PANGO_ELLIPSIZE_END, 2, (gint64)0, -1);
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
db = g_object_get_data (G_OBJECT (array), "db");
while ((result = sqlite3_step (statement)) == SQLITE_ROW)
{
const unsigned char* name = sqlite3_column_text (statement, 0);
- gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
- 0, name, 1, PANGO_ELLIPSIZE_END, -1);
- if (!new_bookmark && !g_strcmp0 (selected, (gchar*)name))
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), n);
- n++;
+ gint64 id = sqlite3_column_int64 (statement, 1);
+
+ /* do not show the folder itself */
+ if (id != selected)
+ {
+ gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
+ 0, name, 1, PANGO_ELLIPSIZE_END, 2, id, -1);
+
+ if (!new_bookmark && id == parentid)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), n);
+ n++;
+ }
}
if (n < 2)
gtk_widget_set_sensitive (combo, FALSE);
return combo;
}
-static gchar*
+static gint64
midori_bookmark_folder_button_get_active (GtkWidget* combo)
{
- gchar* selected = NULL;
+ gint64 id;
GtkTreeIter iter;
- g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), NULL);
+ g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), 0);
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
{
+ gchar* selected = NULL;
GtkTreeModel* model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &selected, -1);
+ gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &selected, 2, &id, -1);
+
if (g_str_equal (selected, _("Toplevel folder")))
- katze_assign (selected, g_strdup (""));
+ id = 0;
+
+ g_free (selected);
}
- return selected;
+ return id;
}
static void
gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
combo_folder = midori_bookmark_folder_button_new (browser->bookmarks,
- new_bookmark, katze_item_get_meta_string (bookmark, "folder"));
+ new_bookmark, katze_item_get_meta_integer (bookmark, "id"),
+ katze_item_get_meta_integer (bookmark, "parentid"));
gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
- gchar* selected;
-
- if (!new_bookmark)
- katze_array_remove_item (browser->bookmarks, bookmark);
+ gint64 selected;
katze_item_set_name (bookmark,
gtk_entry_get_text (GTK_ENTRY (entry_title)));
}
selected = midori_bookmark_folder_button_get_active (combo_folder);
- katze_item_set_meta_string (bookmark, "folder", selected);
- katze_array_add_item (browser->bookmarks, bookmark);
+ katze_item_set_meta_integer (bookmark, "parentid", selected);
+
+ if (new_bookmark)
+ katze_array_add_item (browser->bookmarks, bookmark);
+ else
+ midori_bookmarks_update_item_db (db, bookmark);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar)))
if (!gtk_widget_get_visible (browser->bookmarkbar))
_action_set_active (browser, "Bookmarkbar", TRUE);
- g_free (selected);
return_status = TRUE;
}
if (gtk_widget_get_visible (browser->bookmarkbar))
KatzeArray* folder,
MidoriBrowser* browser)
{
- const gchar* folder_name;
+ gint64 id;
KatzeArray* bookmarks;
GtkWidget* menuitem;
- folder_name = katze_item_get_name (KATZE_ITEM (folder));
- if (!(bookmarks = midori_array_query (browser->bookmarks,
- "uri, title, app, folder", "folder = '%q'", folder_name)))
- return FALSE;
+ id = katze_item_get_meta_integer (KATZE_ITEM (folder), "id");
+
+ if (id == -1)
+ {
+ if (!(bookmarks = midori_array_query (browser->bookmarks,
+ "id, title, parentid, uri, app, pos_panel, pos_bar", "parentid is NULL", NULL)))
+ {
+ g_warning ("midori_array_query returned NULL)");
+ return FALSE;
+ }
+ }
+ else
+ {
+ gchar *parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id);
+
+ if (!(bookmarks = midori_array_query (browser->bookmarks,
+ "id, title, parentid, uri, app, pos_panel, pos_bar", "parentid = %q", parentid)))
+ {
+ g_warning ("midori_array_query returned NULL (id='%s')", parentid);
+ g_free (parentid);
+ return FALSE;
+ }
+
+ g_free (parentid);
+ }
/* Clear items from dummy array here */
gtk_container_foreach (GTK_CONTAINER (menu),
gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks,
- FALSE, NULL);
+ FALSE, 0, 0);
gtk_box_pack_start (GTK_BOX (hbox), combobox_folder, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox);
{
GtkTreeIter iter;
gchar* path = NULL;
- gchar* selected = NULL;
+ gint64 selected;
GError* error;
sqlite3* db = g_object_get_data (G_OBJECT (browser->bookmarks), "db");
midori_bookmarks_import_array_db (db, bookmarks, selected);
katze_array_update (browser->bookmarks);
g_object_unref (bookmarks);
- g_free (selected);
g_free (path);
}
else
error = NULL;
bookmarks = midori_array_query_recursive (browser->bookmarks,
- "*", "folder='%q'", "", TRUE);
+ "*", "parentid IS NULL", NULL, TRUE);
if (!midori_array_to_file (bookmarks, path, format, &error))
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
gtk_separator_tool_item_new (), -1);
array = midori_array_query (browser->bookmarks,
- "uri, title, desc, app, folder, toolbar", "toolbar = 1", NULL);
+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL);
if (!array)
{
+ g_warning ("midori_array_query returned NULL");
_action_set_sensitive (browser, "BookmarkAdd", FALSE);
_action_set_sensitive (browser, "BookmarkFolderAdd", FALSE);
return;
midori_bookmarkbar_insert_item (browser->bookmarkbar, item);
else
{
+ gint64 id = katze_item_get_meta_integer (item, "id");
+ gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id);
KatzeArray* subfolder = midori_array_query (browser->bookmarks,
- "uri, title, desc, app", "folder = '%q' AND uri != ''", katze_item_get_name (item));
- katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item));
- midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder));
+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q AND uri != ''",
+ parentid);
+
+ if (subfolder)
+ {
+ katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item));
+ katze_item_set_meta_integer (KATZE_ITEM (subfolder), "id", id);
+ midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder));
+ }
+ else
+ g_warning ("midori_array_query returned NULL (id='%s')", parentid);
+
+ g_free (parentid);
}
}
_action_set_sensitive (browser, "BookmarkAdd", TRUE);
return STOCK_BOOKMARKS;
}
+/* TODO: Function never used */
void
-midori_bookmarks_export_array_db (sqlite3* db,
- KatzeArray* array,
- const gchar* folder)
+midori_bookmarks_export_array_db (sqlite3* db,
+ KatzeArray* array,
+ gint64 parentid)
{
KatzeArray* root_array;
KatzeArray* subarray;
KatzeItem* item;
GList* list;
+ gchar* parent_id;
- if (!(root_array = midori_array_query (array, "*", "folder='%q'", folder)))
+ parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
+ if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id)))
+ {
+ g_free (parent_id);
return;
+ }
KATZE_ARRAY_FOREACH_ITEM_L (item, root_array, list)
{
if (KATZE_ITEM_IS_FOLDER (item))
{
subarray = katze_array_new (KATZE_TYPE_ARRAY);
katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item));
- midori_bookmarks_export_array_db (db, subarray, katze_item_get_name (item));
+ midori_bookmarks_export_array_db (db, subarray,
+ katze_item_get_meta_integer (item, "parentid"));
katze_array_add_item (array, subarray);
}
else
katze_array_add_item (array, item);
}
+
+ g_free (parent_id);
g_list_free (list);
}
void
-midori_bookmarks_import_array_db (sqlite3* db,
- KatzeArray* array,
- const gchar* folder)
+midori_bookmarks_import_array_db (sqlite3* db,
+ KatzeArray* array,
+ gint64 parentid)
{
GList* list;
KatzeItem* item;
+ gint64 id;
if (!db)
return;
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
{
+ id = midori_bookmarks_insert_item_db (db, item, parentid);
if (KATZE_IS_ARRAY (item))
- midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), folder);
- midori_bookmarks_insert_item_db (db, item, folder);
+ midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), id);
}
g_list_free (list);
}
static KatzeArray*
midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks,
- const gchar* folder,
+ gint64 parentid,
const gchar* keyword)
{
KatzeArray* array;
if (keyword && *keyword)
array = midori_array_query (bookmarks->array,
- "uri, title, desc, app, toolbar, folder", "title LIKE '%%%q%%'", keyword);
+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword);
else
- array = midori_array_query (bookmarks->array,
- "uri, title, desc, app, toolbar, folder", "folder = '%q'", folder);
+ {
+ if (parentid > 0)
+ {
+ gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
+ array = midori_array_query (bookmarks->array,
+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id);
+
+ g_free (parent_id);
+ }
+ else
+ array = midori_array_query (bookmarks->array,
+ "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL);
+ }
return array ? array : katze_array_new (KATZE_TYPE_ITEM);
}
midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
GtkTreeStore* model,
GtkTreeIter* parent,
- const gchar* folder,
+ gint64 parentid,
const gchar* keyword)
{
KatzeArray* array;
KatzeItem* item;
GtkTreeIter child;
- array = midori_bookmarks_read_from_db (bookmarks, folder, keyword);
+ array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword);
katze_bookmark_populate_tree_view (array, model, parent);
/* Remove invisible dummy row */
last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent);
g_object_unref (item);
}
-void
-midori_bookmarks_insert_item_db (sqlite3* db,
- KatzeItem* item,
- const gchar* folder)
+gint64
+midori_bookmarks_insert_item_db (sqlite3* db,
+ KatzeItem* item,
+ gint64 parentid)
{
gchar* sqlcmd;
char* errmsg = NULL;
KatzeItem* old_parent;
- const gchar* parent;
+ gchar* new_parentid;
+ gchar* id = NULL;
const gchar* uri = NULL;
const gchar* desc = NULL;
+ gint64 seq = 0;
/* Bookmarks must have a name, import may produce invalid items */
- g_return_if_fail (katze_item_get_name (item));
+ g_return_val_if_fail (katze_item_get_name (item), seq);
if (!db)
- return;
+ return seq;
+
+ if (katze_item_get_meta_integer (item, "id") > 0)
+ id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id"));
+ else
+ id = g_strdup_printf ("NULL");
if (KATZE_ITEM_IS_BOOKMARK (item))
uri = katze_item_get_uri (item);
/* Use folder, otherwise fallback to parent folder */
old_parent = katze_item_get_parent (item);
- if (folder && *folder)
- parent = folder;
- else if (old_parent && katze_item_get_name (old_parent))
- parent = katze_item_get_name (old_parent);
+ if (parentid > 0)
+ new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
+ else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0)
+ new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id"));
else
- parent = "";
+ new_parentid = g_strdup_printf ("NULL");
sqlcmd = sqlite3_mprintf (
- "INSERT into bookmarks (uri, title, desc, folder, toolbar, app) values"
- " ('%q', '%q', '%q', '%q', %d, %d)",
- uri ? uri : "",
+ "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
+ "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
+ id,
+ new_parentid,
katze_item_get_name (item),
- desc ? desc : "",
- parent,
+ katze_str_non_null (uri),
+ katze_str_non_null (desc),
katze_item_get_meta_boolean (item, "toolbar"),
katze_item_get_meta_boolean (item, "app"));
- if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
+ if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
+ {
+ /* Get insert id */
+ if (g_str_equal (id, "NULL"))
+ {
+ KatzeArray* seq_array;
+
+ sqlite3_free (sqlcmd);
+ sqlcmd = sqlite3_mprintf (
+ "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
+
+ seq_array = katze_array_from_sqlite (db, sqlcmd);
+ if (katze_array_get_nth_item (seq_array, 0))
+ {
+ KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0);
+
+ seq = katze_item_get_meta_integer (seq_item, "seq");
+ katze_item_set_meta_integer (item, "id", seq);
+ }
+ g_object_unref (seq_array);
+ }
+ }
+ else
{
g_printerr (_("Failed to add bookmark item: %s\n"), errmsg);
sqlite3_free (errmsg);
}
sqlite3_free (sqlcmd);
+ g_free (new_parentid);
+ g_free (id);
+
+ return seq;
}
static void
{
GtkTreeModel* model;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
- if (!g_strcmp0 (katze_item_get_meta_string (item, "folder"), ""))
- gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
- NULL, NULL, G_MAXINT, 0, item, -1);
- else
- {
- gtk_tree_store_clear (GTK_TREE_STORE (model));
- midori_bookmarks_read_from_db_to_model (bookmarks,
- GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
- }
+ gtk_tree_store_clear (GTK_TREE_STORE (model));
+ midori_bookmarks_read_from_db_to_model (bookmarks,
+ GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
static void
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
- GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
+ GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
static void
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
- GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
+ GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
KatzeItem* item;
GtkTreeIter parent;
KatzeItem* new_parent = NULL;
- const gchar* parent_name;
+ gint64 parentid;
gtk_tree_model_get (model, iter, 0, &item, -1);
/* Bookmarks must not be moved into non-folder items */
if (!KATZE_ITEM_IS_FOLDER (new_parent))
- parent_name = "";
+ parentid = 0;
else
- parent_name = katze_item_get_name (new_parent);
+ parentid = katze_item_get_meta_integer (new_parent, "id");
}
else
- parent_name = "";
+ parentid = 0;
katze_array_remove_item (bookmarks->array, item);
- katze_item_set_meta_string (item, "folder", parent_name);
+ katze_item_set_meta_integer (item, "parentid", parentid);
katze_array_add_item (bookmarks->array, item);
g_object_unref (item);
{
KatzeItem* item;
MidoriBrowser* browser;
+ gint64 parentid;
gtk_tree_model_get (model, &iter, 0, &item, -1);
g_assert (!KATZE_ITEM_IS_SEPARATOR (item));
browser = midori_browser_get_for_widget (bookmarks->treeview);
+ parentid = katze_item_get_meta_integer (item, "parentid");
midori_browser_edit_bookmark_dialog_new (
browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL);
+
+ if (katze_item_get_meta_integer (item, "parentid") != parentid)
+ {
+ gtk_tree_store_clear (GTK_TREE_STORE (model));
+ midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
+ NULL, 0, NULL);
+ }
+
g_object_unref (item);
}
}
gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);
}
+gboolean
+midori_bookmarks_update_item_db (sqlite3* db,
+ KatzeItem* item)
+{
+ gchar* sqlcmd;
+ char* errmsg = NULL;
+ gchar* parentid;
+ gboolean updated;
+
+ if (katze_item_get_meta_integer (item, "parentid") > 0)
+ parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
+ katze_item_get_meta_integer (item, "parentid"));
+ else
+ parentid = g_strdup_printf ("NULL");
+
+ sqlcmd = sqlite3_mprintf (
+ "UPDATE bookmarks SET "
+ "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
+ "WHERE id = %" G_GINT64_FORMAT ";",
+ parentid,
+ katze_item_get_name (item),
+ katze_str_non_null (katze_item_get_uri (item)),
+ katze_str_non_null (katze_item_get_meta_string (item, "desc")),
+ katze_item_get_meta_boolean (item, "toolbar"),
+ katze_item_get_meta_boolean (item, "app"),
+ katze_item_get_meta_integer (item, "id"));
+
+ updated = TRUE;
+ if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
+ {
+ updated = FALSE;
+ g_printerr (_("Failed to update bookmark : %s\n"), errmsg);
+ sqlite3_free (errmsg);
+ }
+
+ sqlite3_free (sqlcmd);
+ g_free (parentid);
+
+ return updated;
+}
+
static void
midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem,
MidoriBookmarks* bookmarks)
g_object_ref (app);
bookmarks->array = katze_object_get_object (app, "bookmarks");
- midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, "", NULL);
- g_signal_connect (bookmarks->array, "add-item",
+ midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL);
+ g_signal_connect_after (bookmarks->array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
g_signal_connect (bookmarks->array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
KatzeItem* child;
KatzeArray* array;
- array = midori_bookmarks_read_from_db (bookmarks, katze_item_get_name (item), NULL);
+ array = midori_bookmarks_read_from_db (bookmarks,
+ katze_item_get_meta_integer (item, "parentid"), NULL);
+
g_return_if_fail (KATZE_IS_ARRAY (array));
KATZE_ARRAY_FOREACH_ITEM (child, array)
{
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_tree_model_get (model, iter, 0, &item, -1);
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
- iter, katze_item_get_name (item), NULL);
+ iter, katze_item_get_meta_integer (item, "id"), NULL);
g_object_unref (item);
}
gtk_tree_store_clear (treestore);
midori_bookmarks_read_from_db_to_model (bookmarks,
- treestore, NULL, NULL, bookmarks->filter);
+ treestore, NULL, 0, bookmarks->filter);
return FALSE;
}
GtkWidget*
midori_bookmarks_new (void);
-void
-midori_bookmarks_insert_item_db (sqlite3* db,
- KatzeItem* item,
- const gchar* folder);
+gint64
+midori_bookmarks_insert_item_db (sqlite3* db,
+ KatzeItem* item,
+ gint64 parentid);
void
-midori_bookmarks_import_array_db (sqlite3* db,
- KatzeArray* array,
- const gchar* folder);
+midori_bookmarks_import_array_db (sqlite3* db,
+ KatzeArray* array,
+ gint64 parentid);
+
+gboolean
+midori_bookmarks_update_item_db (sqlite3* db,
+ KatzeItem* item);
G_END_DECLS
if check_version (conf.env['LIBSOUP_VERSION'], 2, 37, 1):
conf.define ('HAVE_LIBSOUP_2_37_1', 1)
check_pkg ('libxml-2.0', '2.6')
- check_pkg ('sqlite3', '3.0', True, var='SQLITE')
+ check_pkg ('sqlite3', '3.6.19', True, var='SQLITE')
if option_enabled ('hildon'):
if check_pkg ('hildon-1', mandatory=False, var='HILDON'):