homescreenapp/hsdomainmodel/src/hsdatabase.cpp
changeset 36 cdae8c6c3876
parent 35 f9ce957a272c
child 39 4e8ebe173323
--- a/homescreenapp/hsdomainmodel/src/hsdatabase.cpp	Fri Mar 19 09:27:44 2010 +0200
+++ b/homescreenapp/hsdomainmodel/src/hsdatabase.cpp	Fri Apr 16 14:54:01 2010 +0300
@@ -11,727 +11,714 @@
 *
 * Contributors:
 *
-* Description:  Implementation for SQLlite content store.
+* Description:
 *
 */
 
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlRecord>
+#include <QVariantHash>
+#include <QDir>
+
 #include "hsdatabase.h"
-#include "hsscenedata.h"
-#include "hspagedata.h"
-#include "hswidgetdata.h"
-#include "hswidgetpresentationdata.h"
-#include "hstest_global.h"
-
-namespace 
-{
-    const char DATABASE_CONNECTION_NAME[] = "hsdb.connection";
-}
+#include "hsdomainmodeldatastructures.h"
 
-#ifdef Q_OS_SYMBIAN
-QString HsDatabase::mDatabaseName("c:\\private\\20022f35\\homescreendb");
-#else
-QString HsDatabase::mDatabaseName("homescreendb");
-#endif //Q_OS_SYMBIAN
-
-QScopedPointer<HsDatabase> HsDatabase::mInstance(0);
+namespace
+{
+    template<class T>
+    QVariantList toVariantList(const QList<T> &list)
+    {
+        QVariantList vlist;
+        foreach (T item, list) {
+            vlist << item;
+        }
+        return vlist;
+    }
 
-/*!
-    Utility to create variant list from given \a list
-*/
-template<class T>
-QVariantList toVariantList(const QList<T> &list)
-{
-    QVariantList vlist;
-    foreach (T item, list) {
-        vlist << item;
+    template<class T>
+    QVariantList toVariantList(const T &item, int count)
+    {
+        QVariantList vlist;
+        for (int i = 0; i < count; ++i) {
+            vlist << item;
+        }
+        return vlist;
     }
-    return vlist;
 }
 
 /*!
-    Utility to insert given \a item to variant list \a count times
-*/
-template<class T>
-QVariantList toVariantList(const T &item, int count)
-{
-    QVariantList vlist;
-    for (int i = 0; i < count; ++i) {
-        vlist << item;
-    }
-    return vlist;
-}
-/*!
-    Set name of the database to use
+    Constructs a new database with the given \a parent object.
 */
- void HsDatabase::setDatabaseName(const QString& dbName)
- {
-    mDatabaseName = QDir::toNativeSeparators(dbName);
- }
-
-/*!
-    \class HsDatabase
-    \ingroup group_hsdatamodel
-    \brief Implementation for SQLlite content store.
-
-    Home screen content store that uses an SQLite database
-    as the data store.
-
-*/
-
-/*!
-    Singleton. 
-*/
-HsDatabase *HsDatabase::instance()
+HsDatabase::HsDatabase(QObject *parent)
+  : QObject(parent)
 {
-    if (mInstance.isNull()) {
-        mInstance.reset(new HsDatabase());
-        if(!mInstance->openDatabase(mDatabaseName)){
-            mInstance.reset();  
-        }
-    }
-    return mInstance.data();
-}
-
-/*!
-    Closes database and removes it.
-*/
-HsDatabase::~HsDatabase()
-{
-    // Database calls must be in scope, see info from
-    // QSqlDatabase::removeDatabase() documentation.
-    {
-        QSqlDatabase db = database();
-        db.close();
-    }
-
-    QSqlDatabase::removeDatabase(DATABASE_CONNECTION_NAME);
-}
-
-bool HsDatabase::transaction()
-{
-    return database().transaction();
-}
-
-bool HsDatabase::rollback()
-{
-    return database().rollback();
-}
-
-bool HsDatabase::commit()
-{
-    return database().commit();
 }
 
 /*!
-    Returns scene data in \a scene
+    Destroys this database.
 */
-bool HsDatabase::scene(HsSceneData &scene)
-{   
-    HsSceneData temp;
-
-    QSqlDatabase db = database();        
-    QSqlQuery query(db);
-
-    query.prepare("SELECT * FROM Scene");
-
-    if (!query.exec() || !query.next()) {
-        return false;
-    }
-    
-    temp.setId(columnValue(query, "Id").toInt());
-    temp.setPortraitWallpaper(columnValue(query, "PortraitWallpaper").toString());
-    temp.setLandscapeWallpaper(columnValue(query, "LandscapeWallpaper").toString());
-        
-    int defaultPageId = columnValue(query, "DefaultPageId").toInt();
-
-    query.prepare("SELECT * FROM Pages WHERE Id = ?");
-    query.addBindValue(defaultPageId);
-    
-    if (!query.exec() || !query.next()) {
-        return false;
-    }
-    
-    HsPageData page;    
-    if (!parsePage(query, true, page)) {
-        return false;
-    }
-    temp.setDefaultPage(page);
-
-    scene = temp;
-
-    return true;
+HsDatabase::~HsDatabase()
+{
+    close();
 }
 
 /*!
-    Updates the scene with \a scene.
+    Sets the connection name to \a name.
 */
-bool HsDatabase::updateScene(const HsSceneData &scene)
+void HsDatabase::setConnectionName(const QString &name)
 {
-    QSqlDatabase db = database();
-
-    QString queryString = "UPDATE Scene "
-                          "SET PortraitWallpaper = ?, LandscapeWallpaper = ? "
-                          "WHERE Id = ?";
-
-  
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(scene.portraitWallpaper());
-    query.addBindValue(scene.landscapeWallpaper());    
-    query.addBindValue(scene.id());
-
-    return query.exec();
+    mConnectionName = name;
+}
+ 
+/*!
+    Returns the connection name.
+*/
+QString HsDatabase::connectionName() const
+{
+    return mConnectionName;
 }
 
 /*!
-    Returns page data in \a pages list
+    Sets the database name to \a name.
 */
-bool HsDatabase::pages(QList<HsPageData> &pages)
+void HsDatabase::setDatabaseName(const QString &name)
 {
-    QList<HsPageData> temp;
-
-    QSqlDatabase db = database();           
-    QSqlQuery query(db);
-
-    query.prepare("SELECT * FROM Pages ORDER BY PageIndex");
-    
-    if (!query.exec()) {
-        return false;
-    }
-    
-    while (query.next()) {
-        HsPageData page;
-        if (!parsePage(query, true, page)) {
-            return false;
-        }
-        temp << page;
-    }
-
-    pages = temp;
-
-    return true;
+    mDatabaseName = QDir::toNativeSeparators(name);
 }
-
+ 
 /*!
-    Returns a\ page data for the page with given \a id. Includes children
-    data if \a getChildren is true
+    Returns the database name.
 */
-bool HsDatabase::page(int id, HsPageData &page, bool getChildren)
+QString HsDatabase::databaseName() const
 {
-    QSqlDatabase db = database();           
-    QSqlQuery query(db);
-
-    QString queryString = "SELECT * FROM Pages "
-                          "WHERE Id = ?";
-
-    query.prepare(queryString);
-    query.addBindValue(id);
-    
-    if (!query.exec() || !query.next()) {
-        return false;
-    }
-    
-    return parsePage(query, getChildren, page);
+    return mDatabaseName;
 }
 
 /*!
-    Insert page based on given \a page data 
-*/
-bool HsDatabase::insertPage(HsPageData &page)
+    Opens the database connection using the current connection
+    values. Returns true on success, otherwise returns false.
+*/  
+bool HsDatabase::open()
 {
-    QSqlDatabase db = database();
-
-    QString queryString = "INSERT INTO Pages "
-                          "(PageIndex) "
-                          "VALUES(?)";
-
-    QSqlQuery query(db);
-
-    query.prepare(queryString);    
-    query.addBindValue(page.index());
-    
-    if (!query.exec()) {
+    QSqlDatabase database;
+    if (QSqlDatabase::contains(mConnectionName)) {
+        database = QSqlDatabase::database(mConnectionName);
+    } else {
+        database = QSqlDatabase::addDatabase("QSQLITE", mConnectionName);
+        database.setDatabaseName(mDatabaseName);
+    }
+    if (!database.isValid()) {
+        close();
         return false;
     }
-
-    page.setId(query.lastInsertId().toInt());
-
-    QList<HsWidgetData> &widgets = page.widgets();
-    for (int i = 0; i < widgets.count(); ++i) {
-        widgets[i].setPageId(page.id());
-        if (!insertWidget(widgets[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-
-/*!
-    Updates a page based on given \a page data. Includes children
-    data if \a getChildren is true
-*/
-bool HsDatabase::updatePage(const HsPageData &page, bool updateChildren)
-{
-    QSqlDatabase db = database();
-
-    QString queryString = "UPDATE Pages "
-                          "SET PageIndex = ? "
-                          "WHERE Id = ?";
-
-  
-    QSqlQuery query(db);
-
-    query.prepare(queryString);    
-    query.addBindValue(page.index());    
-    query.addBindValue(page.id());
-
-    if (!query.exec()) {
-        return false;
-    }
-
-    if (!updateChildren) {
-        return true;
-    }
-
-    QList<HsWidgetData> widgets = page.widgets();
-    for (int i = 0; i < widgets.count(); ++i) {
-        if (!updateWidget(widgets[i])) {
+    if (!database.isOpen()) {
+        if (!database.open()) {
+            close();
             return false;
         }
     }
     return true;
 }
+ 
+/*!
+    Closes the database connection.
+*/
+void HsDatabase::close()
+{
+    {
+        QSqlDatabase database = QSqlDatabase::database(mConnectionName);
+        if (database.isValid() && database.isOpen()) {
+            database.close();
+        }
+    }
+    QSqlDatabase::removeDatabase(mConnectionName);
+}
 
 /*!
-    Deletes page with given \a id
+    Begins a transaction on the database if the driver 
+    supports transactions. Returns true if the operation 
+    succeeded. Otherwise returns false.
+*/
+bool HsDatabase::transaction()
+{
+    return QSqlDatabase::database(mConnectionName).transaction();
+}
+ 
+/*!
+    Rolls back a transaction on the database, if the driver 
+    supports transactions and a transaction() has been started.
+    Returns true if the operation succeeded. Otherwise returns
+    false.
 */
-bool HsDatabase::deletePage(int id)
+bool HsDatabase::rollback()
 {
-    HsPageData pageToBeDeleted;
+    return QSqlDatabase::database(mConnectionName).rollback();
+}
+ 
+/*!
+    Commits a transaction to the database if the driver supports 
+    transactions and a transaction() has been started. Returns 
+    true if the operation succeeded. Otherwise returns false.
+*/
+bool HsDatabase::commit()
+{
+    return QSqlDatabase::database(mConnectionName).commit();
+}
 
-    if (!page(id, pageToBeDeleted, false)) {
-        return false;
-    }
-   
-    QSqlDatabase db = database();
-              
-    QString queryString = "DELETE FROM Pages "
-                          "WHERE Id = ?";
+/*!
 
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(id);
-    
-    if (!query.exec()) {
+*/
+bool HsDatabase::scene(HsSceneData &data)
+{
+    if (!checkConnection()) {
         return false;
     }
 
-    //update other indexes
-    QList<HsPageData> allPages;
-    if (!pages(allPages)) {
-        return false;    
-    }
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    HsPageData page;
-    foreach (page, allPages) {
-        if (page.index() > pageToBeDeleted.index()) {
-            page.setIndex(page.index() - 1);
-            if (!updatePage(page, false)) {
-                return false;   
-            }
-        }
+    QString statement =
+        "SELECT id, portraitWallpaper, landscapeWallpaper, defaultPageId, maximumPageCount "
+        "FROM Scene";
+    
+    if (query.prepare(statement) && query.exec() && query.next()) {        
+        data.id                 = query.value(0).toInt();
+        data.portraitWallpaper  = query.value(1).toString();
+        data.landscapeWallpaper = query.value(2).toString();
+        data.defaultPageId      = query.value(3).toInt();
+        data.maximumPageCount   = query.value(4).toInt();
+        return true;
     }
-
-    return true;
-
+    
+    return false;
 }
 
 /*!
-    Returns widget data for the widget with given id. Includes children
-    data if \a getChildren is true
+
 */
-bool HsDatabase::widget(int id, HsWidgetData &widget, bool getChildren)
+bool HsDatabase::updateScene(const HsSceneData &data)
 {
-    QSqlDatabase db = database();
-    QSqlQuery query(db);
-
-    QString queryString = "SELECT * FROM Widgets "
-                          "WHERE Id = ?";
-    
-    query.prepare(queryString);
-    query.addBindValue(id);
-
-    if (!query.exec() || !query.next()) {
+    if (!checkConnection()) {
         return false;
     }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "UPDATE Scene "
+        "SET portraitWallpaper = ?, landscapeWallpaper = ? "
+        "WHERE id = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(data.portraitWallpaper);
+        query.addBindValue(data.landscapeWallpaper);    
+        query.addBindValue(data.id);
+        return  query.exec();
+    }
     
-    return parseWidget(query, getChildren, widget);
+    return false;
 }
 
 /*!
-    Insert widget based on given \a widget data
+
 */
-bool HsDatabase::insertWidget(HsWidgetData &widget)
-{    
-    QSqlDatabase db = database();
+bool HsDatabase::pages(QList<HsPageData> &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT id, indexPosition "
+        "FROM Pages "
+        "ORDER BY indexPosition";
 
-    QString queryString = "INSERT INTO Widgets "
-                          "(Uri, PageId) "
-                          "VALUES(?, ?)";
-
-    QSqlQuery query(db);
+    if (query.prepare(statement) && query.exec()) {
+        data.clear();
+        while (query.next()) {
+            HsPageData d;
+            d.id            = query.value(0).toInt();
+            d.indexPosition = query.value(1).toInt();
+            data.append(d);
+        }
+        return true;
+    }
 
-    query.prepare(queryString);
-    query.addBindValue(widget.uri());
-    query.addBindValue(widget.pageId());
+    return false;
+}
+
+/*!
 
-    if (!query.exec()) {
+*/
+bool HsDatabase::page(HsPageData &data)
+{
+    if (!checkConnection()) {
         return false;
     }
 
-    widget.setId(query.lastInsertId().toInt());
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    QList<HsWidgetPresentationData> &presentations = widget.presentations();
-    for (int i = 0; i < presentations.count(); ++i) {
-        presentations[i].setWidgetId(widget.id());
-        if (!insertWidgetPresentation(presentations[i])) {
-            return false;
+    QString statement =
+        "SELECT indexPosition "
+        "FROM Pages "
+        "WHERE id = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(data.id);
+        if (query.exec() && query.next()) {
+            data.indexPosition = query.value(0).toInt();
+            return true;
         }
     }
 
-    return true;
+    return false;
+}
+
+/*!
+
+*/
+bool HsDatabase::insertPage(HsPageData &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "INSERT INTO Pages "
+        "(indexPosition) "
+        "VALUES "
+        "(?)";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(data.indexPosition);
+        if (query.exec()) {
+            data.id = query.lastInsertId().toInt();
+            return true;
+        }
+    }
+
+    return false;
 }
 
 /*!
-    Insert widget based on given \a widget data. Widget \a databaseId
-    is written on return.
+
 */
-bool HsDatabase::insertWidget(const HsWidgetData &widget,
-                              int &databaseId)
+bool HsDatabase::updatePage(const HsPageData &data)
 {
-    QSqlDatabase db = database();
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "UPDATE Pages "
+        "SET indexPosition = ? "
+        "WHERE id = ?";
 
-    QString queryString = "INSERT INTO Widgets "
-                          "(Uri, PageId) "
-                          "VALUES(?, ?)";
-
-    QSqlQuery query(db);
+    if (query.prepare(statement)) {
+        query.addBindValue(data.indexPosition);
+        query.addBindValue(data.id);
+        return query.exec();
+    }
 
-    query.prepare(queryString);
-    query.addBindValue(widget.uri());
-    query.addBindValue(widget.pageId());
+    return false;
+}
+
+/*!
 
-    if (!query.exec()) {
-        QSqlError err = query.lastError();
+*/
+bool HsDatabase::deletePage(int id)
+{
+    if (!checkConnection()) {
         return false;
     }
 
-    databaseId = query.lastInsertId().toInt();
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "DELETE FROM Pages "
+        "WHERE id = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(id);
+        return query.exec();
+    }
+
+    return false;
+}
+
+/*!
 
-    QList<HsWidgetPresentationData> presentations = widget.presentations();
-    for (int i = 0; i < presentations.count(); ++i) {
-        presentations[i].setWidgetId(databaseId);
-        if (!insertWidgetPresentation(presentations[i])) {
-            return false;
+*/
+bool HsDatabase::widgets(int pageId, QList<HsWidgetData> &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT id, uri "
+        "FROM Widgets "
+        "WHERE pageId = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(pageId);
+        if (query.exec()) {
+            data.clear();
+            while (query.next()) {
+                HsWidgetData d;
+                d.id     = query.value(0).toInt();
+                d.uri    = query.value(1).toString();
+                d.pageId = pageId;
+                data.append(d);
+            }
+            return true;
         }
     }
 
-    return true;
+    return false;
 }
 
 /*!
-    Updates a widget based on given \a widget data. Includes children
-    if \a getChildren is true
+
 */
-bool HsDatabase::updateWidget(const HsWidgetData &widget, 
-                              bool updateChildren)
+bool HsDatabase::widgets(const QString &uri, QList<HsWidgetData> &data)
 {
-    QSqlDatabase db = database();
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT id, pageId "
+        "FROM Widgets "
+        "WHERE uri = ?";
 
-    QString queryString = "UPDATE Widgets "
-                          "SET Uri = ?";
-
-    if (widget.pageId() != -1) {
-        queryString += ", PageId = ?";
+    if (query.prepare(statement)) {
+        query.addBindValue(uri);
+        if (query.exec()) {
+            data.clear();
+            while (query.next()) {
+                HsWidgetData d;
+                d.id     = query.value(0).toInt();
+                d.uri    = uri;
+                d.pageId = query.value(1).toInt();
+                data.append(d);
+            }
+            return true;
+        }
     }
 
-    queryString += " WHERE Id = ?";
+    return false;
+}
+
+/*!
 
-  
-    QSqlQuery query(db);
+*/
+bool HsDatabase::widget(HsWidgetData &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT uri, pageId "
+        "FROM Widgets "
+        "WHERE id = ?";
 
-    query.prepare(queryString);
-    query.addBindValue(widget.uri());
-    if (widget.pageId() != -1) {
-        query.addBindValue(widget.pageId());
+    if (query.prepare(statement)) {
+        query.addBindValue(data.id);
+        if (query.exec() && query.next()) {
+            data.uri    = query.value(0).toString();
+            data.pageId = query.value(1).toInt();
+            return true;
+        }
     }
-    query.addBindValue(widget.id());
+
+    return false;
+}
 
-    if (!query.exec()) {
+/*!
+
+*/
+bool HsDatabase::insertWidget(HsWidgetData &data)
+{
+    if (!checkConnection()) {
         return false;
     }
 
-    if (!updateChildren) {
-        return true;
-    }
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    QList<HsWidgetPresentationData> presentations = widget.presentations();
-    for (int i = 0; i < presentations.count(); ++i) {
-        if (!updateWidgetPresentation(presentations[i])) {
-            return false;
+    QString statement =
+        "INSERT INTO Widgets "
+        "(uri, pageId) "
+        "VALUES "
+        "(?, ?)";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(data.uri);
+        query.addBindValue(data.pageId);
+        if (query.exec()) {
+            data.id = query.lastInsertId().toInt();
+            return true;
         }
     }
 
-    return true;
+    return false;
 }
 
 /*!
-    Deletes widget with given \a widget id
+
+*/
+bool HsDatabase::updateWidget(const HsWidgetData &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "UPDATE Widgets "
+        "SET uri = ?, pageId = ? "
+        "WHERE id = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(data.uri);
+        query.addBindValue(data.pageId);
+        query.addBindValue(data.id);
+        return query.exec();
+    }
+
+    return false;
+}
+
+/*!
+
 */
 bool HsDatabase::deleteWidget(int id)
 {
-    QSqlDatabase db = database();
-       
-    QString queryString = "DELETE FROM Widgets "
-                          "WHERE Id = ?";
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    QSqlQuery query(db);
+    QString statement =
+        "DELETE FROM Widgets "
+        "WHERE id = ?";
 
-    query.prepare(queryString);
-    query.addBindValue(id);
+    if (query.prepare(statement)) {
+        query.addBindValue(id);
+        return query.exec();
+    }
 
-    return query.exec();
+    return false;
 }
 
 /*!
-    Deletes all widgets with given \a uri
+
 */
 bool HsDatabase::deleteWidgets(const QString &uri)
 {
-    QSqlDatabase db = database();
-       
-    QString queryString = "DELETE FROM Widgets "
-                          "WHERE Uri = ?";
-
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(uri);
-
-    return query.exec();
-}
-
-/*!
-    Returns widget \a presentation data for the widget with given \a widgetId. 
-    Presentations can be distinguished by given \a key.
-*/
-bool HsDatabase::widgetPresentation(int widgetId, 
-                                    const QString &key, 
-                                    HsWidgetPresentationData &presentation)
-{
-    Q_UNUSED(key);
-
-    QSqlDatabase db = database();
-    QSqlQuery query(db);
-    
-    QString queryString = "SELECT * FROM WidgetPresentations "
-                          "WHERE WidgetId = ? "
-                          "AND Key = ?";
-    
-    query.prepare(queryString);
-    query.addBindValue(widgetId);
-    query.addBindValue(key);
-    
-    if (!query.exec() || !query.next()) {
+    if (!checkConnection()) {
         return false;
     }
 
-    return parseWidgetPresentation(query, presentation);
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "DELETE FROM Widgets "
+        "WHERE uri = ?";
+
+    if (query.prepare(statement)) {
+        query.addBindValue(uri);
+        return query.exec();
+    }
+
+    return false;
 }
 
 /*!
-    Inserts a widget \a presentation. 
+
 */
-bool HsDatabase::insertWidgetPresentation(HsWidgetPresentationData &presentation)
+bool HsDatabase::widgetPresentation(HsWidgetPresentationData &data)
 {
-    QSqlDatabase db = database();
- 
-    QString queryString = "INSERT INTO WidgetPresentations "
-                          "(Key, Height, Width, YPosition, XPosition, ZValue, WidgetId) "
-                          "VALUES(?, ?, ?, ?, ?, ?, ?)";
-
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(presentation.key());
-    query.addBindValue(presentation.size().height());
-    query.addBindValue(presentation.size().width());
-    query.addBindValue(presentation.position().y());
-    query.addBindValue(presentation.position().x());
-    query.addBindValue(presentation.zValue()); 
-    query.addBindValue(presentation.widgetId());
-
-    if (!query.exec()) {
+    if (!checkConnection()) {
         return false;
     }
 
-    presentation.setId(query.lastInsertId().toInt());
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT x, y, width, height, zValue "
+        "FROM WidgetPresentations "
+        "WHERE key = ? AND widgetId = ?";
 
-    return true;
+    if (query.prepare(statement)) {
+        query.addBindValue(data.key);
+        query.addBindValue(data.widgetId);
+        if (query.exec() && query.next()) {
+            data.x      = query.value(0).toReal();
+            data.y      = query.value(1).toReal();
+            data.width  = query.value(2).toReal();
+            data.height = query.value(3).toReal();
+            data.zValue = query.value(4).toReal();
+            return true;
+        }
+    }
+
+    return false;
 }
 
 /*!
-    Update a widget \a presentation. 
-*/
-bool HsDatabase::updateWidgetPresentation(const HsWidgetPresentationData &presentation)
-{
-    QSqlDatabase db = database();
 
-    QString queryString = "UPDATE WidgetPresentations "
-                          "SET Key = ?, Height = ?, Width = ?, YPosition = ?, XPosition = ?, ZValue = ?";
-    
-    if (presentation.widgetId() != -1) {
-        queryString += ", WidgetId = ?";
+*/
+bool HsDatabase::setWidgetPresentation(const HsWidgetPresentationData &data)
+{
+    if (!checkConnection()) {
+        return false;
     }
-     
-    queryString += " WHERE Id = ?";
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    QSqlQuery query(db);
+    QString statement =
+        "REPLACE INTO WidgetPresentations "
+        "(key, x, y, width, height, zValue, widgetId) "
+        "VALUES (?, ?, ?, ?, ?, ?, ?)";
 
-    query.prepare(queryString);
-    query.addBindValue(presentation.key());
-    query.addBindValue(presentation.size().height());
-    query.addBindValue(presentation.size().width());
-    query.addBindValue(presentation.position().y());
-    query.addBindValue(presentation.position().x());
-    query.addBindValue(presentation.zValue()); 
-    if (presentation.widgetId() != -1) {
-        query.addBindValue(presentation.widgetId());
-    }    
-    query.addBindValue(presentation.id());
+    if (query.prepare(statement)) {
+        query.addBindValue(data.key);
+        query.addBindValue(data.x);
+        query.addBindValue(data.y);
+        query.addBindValue(data.width);
+        query.addBindValue(data.height);
+        query.addBindValue(data.zValue);
+        query.addBindValue(data.widgetId);
+        return query.exec();
+    }
 
-    return query.exec();
+    return false;
 }
 
 /*!
-    Delete widget \a presentation width given \a id. 
+
 */
-bool HsDatabase::deleteWidgetPresentation(int id)
+bool HsDatabase::deleteWidgetPresentation(int widgetId, const QString &key)
 {
-    QSqlDatabase db = database();
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    QString queryString = "DELETE FROM WidgetPresentations "
-                          "WHERE Id = ?";
-
-    QSqlQuery query(db);
+    QString statement =
+        "DELETE FROM WidgetPresentations "
+        "WHERE key = ? AND widgetId = ?";
 
-    query.prepare(queryString);
-    query.addBindValue(id);
+    if (query.prepare(statement)) {
+        query.addBindValue(key);
+        query.addBindValue(widgetId);
+        return query.exec();
+    }
 
-    return query.exec();
+    return false;
 }
 
 /*!
-    Set widget preference \a value for given \a key for widget with given \a widgetId 
+
 */
-bool HsDatabase::setWidgetPreferenceForKey(int widgetId, 
-                                           const QString &key, 
-                                           const QString &value)
+bool HsDatabase::widgetPreferences(int widgetId, QVariantHash &data)
 {
-    QSqlDatabase db = database();
-
-    QString queryString = "SELECT COUNT() "
-                          "FROM WidgetPreferences "
-                          "WHERE WidgetId = ? "
-                          "AND Key = ?";
-
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(widgetId);
-    query.addBindValue(key);
-
-    if (!query.exec() || !query.next()) {
+    if (!checkConnection()) {
         return false;
     }
 
-    int count = query.value(0).toInt();
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QString statement =
+        "SELECT key, value "
+        "FROM WidgetPreferences "
+        "WHERE widgetId = ?";
 
-    if (count) {
-        queryString = "UPDATE WidgetPreferences "
-                      "SET Value = :value "
-                      "WHERE WidgetId = :widgetId "
-                      "AND Key = :key";
-    } else {
-        queryString = "INSERT INTO WidgetPreferences "
-                      "(WidgetId, Key, Value) "
-                      "VALUES(:widgetId, :key, :value)";
+    if (query.prepare(statement)) {
+        query.addBindValue(widgetId);
+        if (query.exec()) {
+            data.clear();
+            while (query.next()) {
+                data.insert(query.value(0).toString(), 
+                            query.value(1));
+            }
+            return true;
+        }
     }
 
-    query.prepare(queryString);
-    query.bindValue(":widgetId", widgetId);
-    query.bindValue(":value", value);
-    query.bindValue(":key", key);
-
-    return query.exec();
+    return false;
 }
 
 /*!
-    Returns widget preference \a value for given \a key for widget with given \a widgetId 
+
 */
-bool HsDatabase::widgetPreferenceForKey(int widgetId, 
-                                        const QString &key, 
-                                        QString &value)
+bool HsDatabase::widgetPreference(int widgetId, const QString &key, QVariant &value)
 {
-    QSqlDatabase db = database();
-
-    QString queryString = "SELECT Value "
-                          "FROM WidgetPreferences "
-                          "WHERE WidgetId = ? "
-                          "AND Key = ?";
-
-    QSqlQuery query(db);
-
-    query.prepare(queryString);
-    query.addBindValue(widgetId);
-    query.addBindValue(key);
-
-    if (!query.exec() || !query.next()) {
+    if (!checkConnection()) {
         return false;
     }
 
-    value = query.value(0).toString();
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
 
-    return true;
-}
+    QString statement =
+        "SELECT value "
+        "FROM WidgetPreferences "
+        "WHERE key = ? AND widgetId = ?";
 
-/*!
-    Store widget \a preferences for given \a widgetId. Returns true
-    if successfull.
-*/
-bool HsDatabase::setWidgetPreferences(int widgetId, const QVariantMap &preferences)
-{
-    QSqlDatabase db = database();
-    QSqlQuery query(db);
-
-    QList<QString> deleteNames = preferences.keys(QVariant());
-    QVariantMap insertOrReplaceMap(preferences);
-    foreach (QString deleteName, deleteNames) {
-        insertOrReplaceMap.remove(deleteName);
+    if (query.prepare(statement)) {
+        query.addBindValue(key);
+        query.addBindValue(widgetId);
+        if (query.exec() && query.next()) {
+            value = query.value(0);
+            return true;
+        }
     }
 
-    if (!deleteNames.isEmpty()) {
-        QString queryString = "DELETE FROM WidgetPreferences "
-                              "WHERE WidgetId = ? "
-                              "AND Key = ?";
+    return false;
+}
+ 
+/*!
+
+*/
+bool HsDatabase::setWidgetPreferences(int widgetId, const QVariantHash &data)
+{
+    if (!checkConnection()) {
+        return false;
+    }
+
+    QSqlQuery query(QSqlDatabase::database(mConnectionName));
+
+    QList<QString> deleteKeys = data.keys(QVariant());
+    QVariantHash insertOrReplaceData(data);
+    foreach (QString key, deleteKeys) {
+        insertOrReplaceData.remove(key);
+    }
+
+    if (!deleteKeys.isEmpty()) {
+        QString statement = 
+            "DELETE FROM WidgetPreferences "
+            "WHERE key = ? AND widgetId = ?";
         
-        if (query.prepare(queryString)) {
-            query.addBindValue(toVariantList(widgetId, deleteNames.count()));
-            query.addBindValue(toVariantList(deleteNames));
+        if (query.prepare(statement)) {
+            query.addBindValue(toVariantList(deleteKeys));
+            query.addBindValue(toVariantList(widgetId, deleteKeys.count()));
             if (!query.execBatch()) {
                 return false;
             }
@@ -740,15 +727,16 @@
         }
     }
 
-    if (!insertOrReplaceMap.isEmpty()) {
-        QString queryString = "REPLACE INTO WidgetPreferences "
-                              "(WidgetId, Key, Value) "
-                              "VALUES (?, ?, ?)";
+    if (!insertOrReplaceData.isEmpty()) {
+        QString statement = 
+            "REPLACE INTO WidgetPreferences "
+            "(key, value, widgetId) "
+            "VALUES (?, ?, ?)";
             
-        if (query.prepare(queryString)) {
-            query.addBindValue(toVariantList(widgetId, insertOrReplaceMap.count()));
-            query.addBindValue(toVariantList(insertOrReplaceMap.keys()));
-            query.addBindValue(toVariantList(insertOrReplaceMap.values()));
+        if (query.prepare(statement)) {
+            query.addBindValue(toVariantList(insertOrReplaceData.keys()));
+            query.addBindValue(toVariantList(insertOrReplaceData.values()));
+            query.addBindValue(toVariantList(widgetId, insertOrReplaceData.count()));
             if (!query.execBatch()) {
                 return false;
             }
@@ -759,198 +747,44 @@
 
     return true;
 }
-
+ 
 /*!
-    Fetch widget \a preferences based on given \a widgetId. Returns
-    true if successfull.
+    Sets the database instance. The existing instance
+    will be deleted.
 */
-bool HsDatabase::widgetPreferences(int widgetId, QVariantMap &preferences)
+void HsDatabase::setInstance(HsDatabase *instance)
 {
-    QSqlDatabase db = database();
-    QSqlQuery query(db);
-    
-    QString queryString = "SELECT Key, Value "
-                          "FROM WidgetPreferences "
-                          "WHERE WidgetId = ?";
-
-    query.prepare(queryString);
-    query.addBindValue(widgetId);
-  
-    if (query.exec()) {
-        while (query.next()) {
-            preferences.insert(query.value(0).toString(), 
-                               query.value(1));
-        }
-    } else {
-        return false;
-    }
-    return true;
+    mInstance.reset(instance);
 }
 
 /*!
-    Returns instance \a ids of the widget identified by the given \a uri
+    Returns the database instance.
 */
-bool HsDatabase::widgetIds(const QString &uri, QList<int> &ids)
+HsDatabase *HsDatabase::instance()
 {
-    QSqlDatabase db = database();
-    QSqlQuery query(db);
-
-    QString queryString = "SELECT Id "
-                          "FROM Widgets "
-                          "WHERE Uri = ?";
-    
-    query.prepare(queryString);
-    query.addBindValue(uri);
-
-    if (!query.exec() || !query.next()) {
-        return false;
-    }
-
-    ids << query.value(0).toInt();
-    while (query.next()) {
-        ids << query.value(0).toInt();        
-    }
-
-    return true;
-}
-
-/*!
-    Constructor
-*/
-HsDatabase::HsDatabase()
-    : QObject()
-{
-}
-/*!
-    Open database from given \a databaseName
-*/
-bool HsDatabase::openDatabase(const QString &databaseName)
-{
-    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", DATABASE_CONNECTION_NAME);
-    db.setDatabaseName(databaseName);
-    if (!db.open()) {
-        HSDEBUG( db.lastError().text().toLatin1() );
-        return false;
-    }
-    return true;
+    return mInstance.data();
 }
 
 /*!
-    Parses \a page data from given \a query. Include child 
-    data when \a getChildren is set to true.
+    Returns the current database instance. Callers of this 
+    function take ownership of the instance. The current 
+    database instance will be reset to null.    
 */
-bool HsDatabase::parsePage(const QSqlQuery &query, 
-                           bool getChildren, 
-                           HsPageData &page)
+HsDatabase *HsDatabase::takeInstance()
 {
-    HsPageData temp;
-
-    temp.setId(columnValue(query, "Id").toInt());    
-    temp.setIndex(columnValue(query, "PageIndex").toInt());    
-        
-    if (getChildren) {
-        QSqlDatabase db = database();
-        QSqlQuery q(db);        
-        
-        QString queryString = "SELECT * "
-                              "FROM Widgets "
-                              "WHERE PageId = ?";
-        
-        q.prepare(queryString);
-        q.addBindValue(temp.id());
-
-        if (!q.exec()) {
-            return false;
-        }
-
-        while (q.next()) {
-            HsWidgetData widget;
-            if (!parseWidget(q, true, widget)) {
-                return false;
-            }
-            temp.widgets() << widget;
-        }
-    }
-
-    page = temp;
-
-    return true;
+    return mInstance.take();
+}
+  
+/*!
+    Checks the connection validity. Returns true if the 
+    connection is valid.
+*/
+bool HsDatabase::checkConnection() const
+{
+    return QSqlDatabase::database(mConnectionName).isValid();
 }
 
 /*!
-    Parses \a widget data from given \a query. Include child data 
-    when \a getChildren is set to true.
+    Points to the database instance.
 */
-bool HsDatabase::parseWidget(const QSqlQuery &query, 
-                             bool getChildren, 
-                             HsWidgetData &widget)
-{
-    HsWidgetData temp;
-
-    temp.setId(columnValue(query, "Id").toInt());
-    temp.setUri(columnValue(query, "Uri").toString());
-    temp.setPageId(columnValue(query, "PageId").toInt());
-
-    if (getChildren) {
-        QSqlDatabase db = database();
-        QSqlQuery q(db);
-        
-        QString queryString = "SELECT * "
-                              "FROM WidgetPresentations "
-                              "WHERE WidgetId = ?";
-
-        q.prepare(queryString);
-        q.addBindValue(temp.id());
-
-        if (!q.exec()) {
-            return false;
-        }
-
-        while (q.next()) {
-            HsWidgetPresentationData presentation;
-            if (!parseWidgetPresentation(q, presentation)) {
-                return false;
-            }
-            temp.presentations() << presentation;
-        }
-    }
-
-    widget = temp;
-
-    return true;
-}
-
-/*!
-    Parses widget \a presentation data from given SQL \a query.
-*/
-bool HsDatabase::parseWidgetPresentation(const QSqlQuery &query, 
-                                         HsWidgetPresentationData &presentation)
-{
-    presentation.setId(columnValue(query, "Id").toInt());
-    presentation.setKey(columnValue(query, "Key").toString());
-    presentation.setPosition(QPointF(columnValue(query, "XPosition").toDouble(),
-                                     columnValue(query, "YPosition").toDouble()));
-    presentation.setSize(QSizeF(columnValue(query, "Width").toDouble(),
-                                columnValue(query, "Height").toDouble()));    
-    presentation.setZValue(columnValue(query, "ZValue").toDouble());
-    presentation.setWidgetId(columnValue(query, "WidgetId").toInt());
-
-    return true;
-}
-
-/*!
-    Parses column value with given \a columnName from given SQL \a query.
-*/
-QVariant HsDatabase::columnValue(const QSqlQuery &query, 
-                                 const QString &columnName) const
-{
-    return query.value(query.record().indexOf(columnName));
-}
-
-/*!
-    Returns database connection
-*/
-QSqlDatabase HsDatabase::database() const
-{
-    return QSqlDatabase::database(DATABASE_CONNECTION_NAME);
-}
+QScopedPointer<HsDatabase> HsDatabase::mInstance(0);