/* * unity-webapps-app-db.c * Copyright (C) Canonical LTD 2011 * * Author: Robert Carr * unity-webapps is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * unity-webapps 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see ."; */ #include #include #include #include #include #include #include "context-daemon/util/unity-webapps-dirs.h" #include "unity-webapps-app-db.h" #include "unity-webapps-debug.h" static sqlite3 *app_db = NULL; #define CREATE_RESOURCES_TABLE_SQL "CREATE TABLE IF NOT EXISTS apps(name TEXT, domain TEXT, homepage TEXT, PRIMARY KEY (name, domain));" #define CREATE_ACTIONS_TABLE_SQL "CREATE TABLE IF NOT EXISTS actions(name TEXT, domain TEXT, label TEXT, page TEXT, PRIMARY KEY (name, domain, label));" #define GET_HOMEPAGE_SQL_TEMPLATE "SELECT homepage FROM apps WHERE name=%Q AND domain=%Q;" static sqlite3_stmt * db_get_homepage_prepare_statement (const gchar *name, const gchar *domain) { gchar *statement_sql; sqlite3_stmt *statement; gint rc; statement_sql = sqlite3_mprintf (GET_HOMEPAGE_SQL_TEMPLATE, name, domain); statement = NULL; rc = sqlite3_prepare_v2 (app_db, statement_sql, -1, &statement, NULL); if (rc != SQLITE_OK) { g_critical ("Failed to compile App DB get homepage statement: %s", sqlite3_errmsg (app_db)); } sqlite3_free (statement_sql); return statement; } gchar * unity_webapps_app_db_get_homepage (const gchar *name, const gchar *domain) { sqlite3_stmt *homepage_statement; gchar *homepage; gint rc; if (!app_db) { unity_webapps_app_db_open (); } homepage = NULL; homepage_statement = db_get_homepage_prepare_statement (name, domain); if (homepage_statement == NULL) { return NULL; } rc = sqlite3_step (homepage_statement); if (rc == SQLITE_ROW) { homepage = g_strdup ((const gchar *)sqlite3_column_text (homepage_statement, 0)); } UNITY_WEBAPPS_NOTE (MISC, "Looked up homepage for (%s, %s) got %s", name, domain, homepage); sqlite3_finalize (homepage_statement); return homepage; } #define INSERT_HOMEPAGE_SQL_TEMPLATE "INSERT OR REPLACE INTO apps (name, domain, homepage) VALUES (%Q, %Q, %Q);" static sqlite3_stmt * db_insert_homepage_prepare_statement (const gchar *name, const gchar *domain, const gchar *homepage) { gchar *statement_sql; sqlite3_stmt *statement; gint rc; statement_sql = sqlite3_mprintf (INSERT_HOMEPAGE_SQL_TEMPLATE, name, domain, homepage); statement = NULL; rc = sqlite3_prepare_v2 (app_db, statement_sql, -1, &statement, NULL); if (rc != SQLITE_OK) { g_critical ("Failed to compile App DB insert homepage statement: %s", sqlite3_errmsg (app_db)); } sqlite3_free (statement_sql); return statement; } gboolean unity_webapps_app_db_update_homepage (const gchar *name, const gchar *domain, const gchar *homepage) { sqlite3_stmt *homepage_statement; int rc; gboolean ret = TRUE; if (!app_db) { unity_webapps_app_db_open (); } homepage_statement = db_insert_homepage_prepare_statement (name, domain, homepage); if (homepage_statement == NULL) { return FALSE; } rc = sqlite3_step (homepage_statement); if (rc != SQLITE_DONE) { g_warning ("Error updating homepage in app db: %s", sqlite3_errmsg (app_db)); ret = FALSE; goto out; } out: sqlite3_finalize (homepage_statement); return ret; } static void create_apps_table (const gchar *query) { int rc; gchar *error_message; error_message = NULL; rc = sqlite3_exec (app_db, query, NULL, 0, &error_message); if (rc != SQLITE_OK) { g_critical ("Error creating apps table %s \n", error_message); sqlite3_free (error_message); sqlite3_close (app_db); app_db = NULL; } } gboolean unity_webapps_app_db_open () { const gchar *uw_dir; gchar *database_file; gboolean ret; int rc; ret = TRUE; uw_dir = unity_webapps_dirs_get_user_dir (); database_file = g_build_filename (uw_dir, "apps2.db", NULL); UNITY_WEBAPPS_NOTE (RESOURCE, "Opening App DB (%s)", database_file); rc = sqlite3_open (database_file, &app_db); if (rc != 0) { g_critical ("Failed to open apps database: %s", sqlite3_errmsg(app_db)); sqlite3_close (app_db); ret = FALSE; goto out; } create_apps_table (CREATE_RESOURCES_TABLE_SQL); create_apps_table (CREATE_ACTIONS_TABLE_SQL); out: g_free (database_file); return ret; } #define INSERT_ACTION_SQL_TEMPLATE "INSERT OR REPLACE INTO actions (name, domain, label, page) VALUES (%Q, %Q, %Q, %Q);" gboolean unity_webapps_app_db_add_action (const gchar *name, const gchar *domain, const gchar *label, const gchar *page) { sqlite3_stmt *statement; char *statement_sql; gint rc; gboolean res = TRUE; if (!app_db) { unity_webapps_app_db_open (); } statement_sql = sqlite3_mprintf (INSERT_ACTION_SQL_TEMPLATE, name, domain, label, page); rc = sqlite3_prepare_v2 (app_db, statement_sql, -1, &statement, NULL); if (rc != SQLITE_OK) { g_critical ("Failed to compile Action DB statement: %s", sqlite3_errmsg (app_db)); sqlite3_free (statement_sql); return FALSE; } sqlite3_free (statement_sql); rc = sqlite3_step (statement); if (rc != SQLITE_DONE) { g_warning ("Error inserting action: %s", sqlite3_errmsg (app_db)); res = FALSE; } sqlite3_finalize (statement); return res; } #define DELETE_ALL_ACTIONS_SQL "DELETE FROM actions WHERE name=%Q AND domain=%Q" gboolean unity_webapps_app_db_clear_actions (const gchar *name, const gchar *domain) { sqlite3_stmt *statement; char *statement_sql; gint rc; gboolean res = TRUE; if (!app_db) { unity_webapps_app_db_open (); } statement_sql = sqlite3_mprintf (DELETE_ALL_ACTIONS_SQL, name, domain); rc = sqlite3_prepare_v2 (app_db, statement_sql, -1, &statement, NULL); if (rc != SQLITE_OK) { g_critical ("Failed to compile Action DB statement: %s", sqlite3_errmsg (app_db)); sqlite3_free (statement_sql); return FALSE; } sqlite3_free (statement_sql); rc = sqlite3_step (statement); if (rc != SQLITE_DONE) { g_warning ("Error deleting actions: %s", sqlite3_errmsg (app_db)); res = FALSE; } sqlite3_finalize (statement); return res; } #define MAX_ACTIONS_COUNT 10 #define SELECT_ALL_ACTIONS_SQL "SELECT label, page FROM actions WHERE name=%Q AND domain=%Q" gboolean unity_webapps_app_db_get_actions (const gchar *name, const gchar *domain, gchar ***labels, gchar ***pages) { sqlite3_stmt *statement; char *statement_sql; gint rc, i; gboolean res = TRUE; *labels = NULL; *pages = NULL; if (!app_db) { unity_webapps_app_db_open (); } statement_sql = sqlite3_mprintf (SELECT_ALL_ACTIONS_SQL, name, domain); rc = sqlite3_prepare_v2 (app_db, statement_sql, -1, &statement, NULL); if (rc != SQLITE_OK) { g_critical ("Failed to compile Action DB statement: %s", sqlite3_errmsg (app_db)); sqlite3_free (statement_sql); return FALSE; } sqlite3_free (statement_sql); *labels = g_new (gchar*, MAX_ACTIONS_COUNT + 1); *pages = g_new (gchar*, MAX_ACTIONS_COUNT + 1); for (i = 0, rc = sqlite3_step (statement); i < MAX_ACTIONS_COUNT && rc == SQLITE_ROW; i++, rc = sqlite3_step (statement)) { (*labels)[i] = g_strdup ((const gchar *)sqlite3_column_text (statement, 0)); (*pages)[i] = g_strdup ((const gchar *)sqlite3_column_text (statement, 1)); } (*labels)[i] = NULL; (*pages)[i] = NULL; sqlite3_finalize (statement); return res; }