]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/databases/BookmarksDatabase.cpp
Partial bookmark implementation. https://redmine.stoutner.com/issues/968
[PrivacyBrowserPC.git] / src / databases / BookmarksDatabase.cpp
diff --git a/src/databases/BookmarksDatabase.cpp b/src/databases/BookmarksDatabase.cpp
new file mode 100644 (file)
index 0000000..c290682
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2023 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ *
+ * Privacy Browser PC is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser PC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser PC.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Application headers.
+#include "BookmarksDatabase.h"
+
+// Define the private static schema constants.
+const int BookmarksDatabase::SCHEMA_VERSION = 0;
+
+// Define the public static constants.
+const QString BookmarksDatabase::CONNECTION_NAME = "bookmarks_database";
+const QString BookmarksDatabase::BOOKMARK_NAME = "bookmark_name";
+const QString BookmarksDatabase::BOOKMARKS_TABLE = "bookmarks";
+const QString BookmarksDatabase::BOOKMARK_URL = "bookmark_url";
+const QString BookmarksDatabase::DISPLAY_ORDER = "display_order";
+const QString BookmarksDatabase::FAVORITE_ICON = "favorite_icon";
+const QString BookmarksDatabase::FOLDER_ID = "folder_id";
+const QString BookmarksDatabase::ID = "_id";
+const QString BookmarksDatabase::IS_FOLDER = "is_folder";
+const QString BookmarksDatabase::PARENT_FOLDER_ID = "parent_folder_id";
+
+// Construct the class.
+BookmarksDatabase::BookmarksDatabase() {}
+
+void BookmarksDatabase::addDatabase()
+{
+    // Add the bookmarks database.
+    QSqlDatabase bookmarksDatabase = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), CONNECTION_NAME);
+
+    // Set the database name.
+    bookmarksDatabase.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/bookmarks.db");
+
+    // Open the database.
+    if (bookmarksDatabase.open())  // Opening the database succeeded.
+    {
+        // Check to see if the bookmarks table already exists.
+        if (bookmarksDatabase.tables().contains(BOOKMARKS_TABLE))  // The bookmarks table already exists.
+        {
+            // Query the database schema version.
+            QSqlQuery schemaVersionQuery = bookmarksDatabase.exec(QStringLiteral("PRAGMA user_version"));
+
+            // Move to the first record.
+            schemaVersionQuery.first();
+
+            // Get the current schema version.
+            int currentSchemaVersion = schemaVersionQuery.value(0).toInt();
+
+            // Check to see if the schema has been updated.
+            if (currentSchemaVersion < SCHEMA_VERSION)
+            {
+                // Run the schema update code.
+
+                // Update the schema version.
+                bookmarksDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION));
+            }
+        }
+        else  // The bookmarks table does not exist.
+        {
+            // Instantiate a create table query.
+            QSqlQuery createTableQuery(bookmarksDatabase);
+
+            // Populate the create table query.
+            createTableQuery.prepare("CREATE TABLE " + BOOKMARKS_TABLE + "(" +
+                                      ID + " INTEGER PRIMARY KEY, " +
+                                      BOOKMARK_NAME + " TEXT, " +
+                                      BOOKMARK_URL + " TEXT, " +
+                                      PARENT_FOLDER_ID + " INTEGER DEFAULT 0, " +
+                                      DISPLAY_ORDER + " INTEGER DEFAULT 0, " +
+                                      IS_FOLDER + " BOOLEAN DEFAULT FALSE, " +
+                                      FOLDER_ID + " INTEGER DEFAULT 0, " +
+                                      FAVORITE_ICON + " BLOB)");
+
+            // Execute the query.
+            if (!createTableQuery.exec())
+            {
+                // Log any errors.
+                qDebug().noquote().nospace() << "Error creating table:  " << bookmarksDatabase.lastError();
+            }
+
+            // Set the schema version.
+            bookmarksDatabase.exec("PRAGMA user_version = " + QString::number(SCHEMA_VERSION));
+        }
+    }
+    else  // Opening the database failed.
+    {
+        // Write the last database error message to the debug output.
+        qDebug().noquote().nospace() << "Error opening database:  " << bookmarksDatabase.lastError();
+    }
+};
+
+void BookmarksDatabase::addBookmark(const QString &bookmarkName, const QString &bookmarkUrl, const QIcon &favoriteIcon)
+{
+    // Get a handle for the bookmarks database.
+    QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+    // Get a favorite icon pixmap.
+    QPixmap favoriteIconPixmap = favoriteIcon.pixmap(32, 32);
+
+    // Create a favorite icon byte array.
+    QByteArray favoriteIconByteArray;
+
+    // Create a favorite icon buffer.
+    QBuffer favoriteIconBuffer(&favoriteIconByteArray);
+
+    // Open the buffer.
+    favoriteIconBuffer.open(QIODevice::WriteOnly);
+
+    // Convert the favorite icon pixmap into a byte array in PNG format.
+    favoriteIconPixmap.save(&favoriteIconBuffer, "PNG");
+
+    // Close the buffer.
+    favoriteIconBuffer.close();
+
+    // Convert the favorite icon byte array to a base 64 string.
+    QString favoriteIconBase64String = favoriteIconByteArray.toBase64();
+
+    // Instantiate an add bookmark query.
+    QSqlQuery addBookmarkQuery(bookmarksDatabase);
+
+    // Prepare the add bookmark query.
+    addBookmarkQuery.prepare("INSERT INTO " + BOOKMARKS_TABLE + " (" +
+                              BOOKMARK_NAME + ", " +
+                              BOOKMARK_URL + ", " +
+                              FAVORITE_ICON + ") "
+                              "VALUES (:bookmark_name, :bookmark_url, :favorite_icon)"
+    );
+
+    // Bind the values.
+    addBookmarkQuery.bindValue(":bookmark_name", bookmarkName);
+    addBookmarkQuery.bindValue(":bookmark_url", bookmarkUrl);
+    addBookmarkQuery.bindValue(":favorite_icon", favoriteIconBase64String);
+
+    // Execute the query.
+    addBookmarkQuery.exec();
+}
+
+std::list<BookmarkStruct>* BookmarksDatabase::getBookmarks()
+{
+    // Get a handle for the bookmarks database.
+    QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+    // Instantiate a bookmarks query.
+    QSqlQuery bookmarksQuery(bookmarksDatabase);
+
+    // Set the query to be forward only, which is more performant.
+    bookmarksQuery.setForwardOnly(true);
+
+    // Prepare the bookmarks query.
+    bookmarksQuery.prepare("SELECT * FROM " + BOOKMARKS_TABLE);
+
+    // Execute the query.
+    bookmarksQuery.exec();
+
+    // Create a bookmark list.
+    std::list<BookmarkStruct> *bookmarkListPointer = new std::list<BookmarkStruct>;
+
+    // Populate the bookmark list.
+    while (bookmarksQuery.next())
+    {
+        // Create a bookmark struct.
+        struct BookmarkStruct bookmarkStruct;
+
+        // Get the favorite icon base 64 bute array.
+        QByteArray favoriteIconByteArray = QByteArray::fromBase64(bookmarksQuery.value(FAVORITE_ICON).toByteArray());
+
+        // Create a favorite icon pixmap.
+        QPixmap favoriteIconPixmap;
+
+        // Load the pixmap from byte array.
+        favoriteIconPixmap.loadFromData(favoriteIconByteArray);
+
+        // Populate the bookmark struct.
+        bookmarkStruct.id = bookmarksQuery.value(ID).toInt();
+        bookmarkStruct.bookmarkName = bookmarksQuery.value(BOOKMARK_NAME).toString();
+        bookmarkStruct.bookmarkUrl = bookmarksQuery.value(BOOKMARK_URL).toString();
+        bookmarkStruct.favoriteIcon = QIcon(favoriteIconPixmap);
+
+        // Add the bookmark to the list.
+        bookmarkListPointer->push_back(bookmarkStruct);
+    }
+
+    // Return the bookmark list.
+    return bookmarkListPointer;
+}
+
+void BookmarksDatabase::updateBookmarkName(const int bookmarkId, const QString &bookmarkName)
+{
+    // Get a handle for the bookmarks database.
+    QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+    // Instantiate an update bookmark name query.
+    QSqlQuery updateBookmarkNameQuery(bookmarksDatabase);
+
+    // Prepare the update bookmark name query.
+    updateBookmarkNameQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
+                                    " SET " + BOOKMARK_NAME + " = :bookmark_name " +
+                                    "WHERE " + ID + " = :id");
+
+    // Bind the values.
+    updateBookmarkNameQuery.bindValue(":bookmark_name", bookmarkName);
+    updateBookmarkNameQuery.bindValue(":id", bookmarkId);
+
+    // Execute the query.
+    updateBookmarkNameQuery.exec();
+}
+
+void BookmarksDatabase::updateBookmarkUrl(const int bookmarkId, const QString &bookmarkUrl)
+{
+    // Get a handle for the bookmarks database.
+    QSqlDatabase bookmarksDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+    // Instantiate an update bookmark URL query.
+    QSqlQuery updateBookmarkUrlQuery(bookmarksDatabase);
+
+    // Prepare the update bookmark URL query.
+    updateBookmarkUrlQuery.prepare("UPDATE " + BOOKMARKS_TABLE +
+                                   " SET " + BOOKMARK_URL + " = :bookmark_url " +
+                                   "WHERE " + ID + " = :id");
+
+    // Bind the values.
+    updateBookmarkUrlQuery.bindValue(":bookmark_url", bookmarkUrl);
+    updateBookmarkUrlQuery.bindValue(":id", bookmarkId);
+
+    // Execute the query.
+    updateBookmarkUrlQuery.exec();
+}