activityfw/activityserviceplugin/win/activitydatabase_p.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:16:09 +0300
changeset 61 8e5041d13c84
child 66 32469d7d46ff
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/
#include "activitydatabase_p.h"

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QStringList>
#include <QSettings>

#include <hsactivitydbclient.h>

const char KConnectionName[] = "ActivityDatabase";

ActivityDatabasePrivate::ActivityDatabasePrivate()
{
    // determine database localization
    QSettings settings("nokia", "activities");
    if (!settings.contains("activitydatabase")) {
        settings.setValue("activitydatabase", "C:\\activitydatabase.db");
    }
    QString databaseFile = settings.value("activitydatabase").toString();

    QSqlDatabase database;
    if (QSqlDatabase::contains(KConnectionName)) {
        database = QSqlDatabase::database(KConnectionName);
    } else {   
        database = QSqlDatabase::addDatabase("QSQLITE", KConnectionName);
        database.setDatabaseName(databaseFile);    
        if (!database.open()) {
            qFatal(qPrintable(database.lastError().text()));
        }
    }    
    
    if (!checkTables()) {
        recreateTables();
    }
}

ActivityDatabasePrivate::~ActivityDatabasePrivate()
{
    QSqlDatabase::database(KConnectionName).close();
}

void ActivityDatabasePrivate::saveActivity(const QString &applicationName, const QString &activityName, const QVariantHash &activityMetadata) 
{
    if (applicationName.isEmpty() || activityName.isEmpty() || activityMetadata.value("screenshot").isNull()) {
        qWarning("Activity entry is invalid, aborting save");
        return;
    }
    
    QVariantHash activityData(activityMetadata);
    activityData.insert(ActivityApplicationKeyword, applicationName);
    activityData.insert(ActivityActivityKeyword, activityName);    
    
    // stream whole entry to bytearray
    QByteArray streamedData;
    {
        QDataStream stream(&streamedData, QIODevice::WriteOnly);
        stream << activityData;
    }  

    QSqlDatabase database = QSqlDatabase::database(KConnectionName);
    
    if (!database.transaction()) {
        qFatal(qPrintable(database.lastError().text()));
    }
        
    // update or insert data
    {
        QSqlQuery query(database);
        if (!query.exec(QString("SELECT ApplicationName FROM Activities WHERE ApplicationName = '%1' AND ActivityName = '%2'").arg(applicationName).arg(activityName))) {
            qFatal(qPrintable(query.lastError().text()));
        }

        if (query.next()) {
            if (!query.prepare("UPDATE Activities SET Data = :Data WHERE ApplicationName = :ApplicationName AND ActivityName = :ActivityName")) {
                qFatal(qPrintable(query.lastError().text()));
            }
            query.bindValue(":Data", streamedData);
            query.bindValue(":ApplicationName", applicationName);
            query.bindValue(":ActivityName", activityName);
            if (!query.exec()) {
                qFatal(qPrintable(query.lastError().text()));
            }
        } else {
            if (!query.prepare("INSERT INTO Activities(ApplicationName, ActivityName, Data) VALUES(:ApplicationName, :ActivityName, :Data)")) {
                qFatal(qPrintable(query.lastError().text()));
            }
            query.bindValue(":ApplicationName", applicationName);
            query.bindValue(":ActivityName", activityName);
            query.bindValue(":Data", streamedData);
            if (!query.exec()) {
                qFatal(qPrintable(query.lastError().text()));
            }        
        }
    }
    
    if (!database.commit()) {
        qFatal(qPrintable(database.lastError().text()));
    } 
}

void ActivityDatabasePrivate::deleteActivity(const QString &applicationName, const QString &activityName)
{
    QString sqlCommand = QString("DELETE FROM Activities WHERE ApplicationName = '%1' AND ActivityName = '%2'").arg(applicationName).arg(activityName);
    QSqlQuery query(QSqlDatabase::database(KConnectionName));
    if (!query.exec(sqlCommand)) {
        qFatal(qPrintable(query.lastError().text()));
    }
}

void ActivityDatabasePrivate::deleteApplicationActivities(const QString &applicationName)
{
    QString sqlCommand = QString("DELETE FROM Activities WHERE ApplicationName = '%1'").arg(applicationName);
    QSqlQuery query(QSqlDatabase::database(KConnectionName));
    if (!query.exec(sqlCommand)) {
        qFatal(qPrintable(query.lastError().text()));
    }
}

QList<QVariantHash> ActivityDatabasePrivate::allActivitiesList()
{
    return activitiesList("SELECT Data FROM Activities");
}

QList<QVariantHash> ActivityDatabasePrivate::applicationActivitiesList(const QString &applicationName)
{
    return activitiesList(QString("SELECT Data FROM Activities WHERE ApplicationName = '%1'").arg(applicationName));
}

QList<QVariantHash> ActivityDatabasePrivate::activitiesList(const QString& sqlCommand)
{   
    QSqlQuery query(QSqlDatabase::database(KConnectionName));
    if (!query.exec(sqlCommand)) {
        qFatal(qPrintable(query.lastError().text()));
    }
    
    QList<QVariantHash> result;
    while (query.next()) {
        QVariantHash activityEntry;
        {
            QByteArray data(query.value(0).toByteArray());
            QDataStream stream(&data, QIODevice::ReadOnly);
            stream >> activityEntry;
        }
        result.append(activityEntry);
    }   
    return result;
}

QString ActivityDatabasePrivate::requestedActivityName(const QString &applicationName)
{
    QSqlQuery query(QSqlDatabase::database(KConnectionName));
    if (!query.exec(QString("SELECT ActivityName FROM Activities WHERE ApplicationName = '%1' AND RequestFlag").arg(applicationName))) {
        qFatal(qPrintable(query.lastError().text()));
    }
    
    QString result;
    if (query.next()) {
        result = query.value(0).toString();
    }   
    return result;
}

void ActivityDatabasePrivate::setActivityRequestFlag(const QString &applicationName, const QString &activityName)
{
    QSqlQuery query(QSqlDatabase::database(KConnectionName));
    
    // clear old requests for given application
    if (!query.exec(QString("UPDATE Activities SET RequestFlag=0 WHERE ApplicationName = '%1'").arg(applicationName))) {
        qFatal(qPrintable(query.lastError().text()));
    }
    
    // set new request
    if (!query.exec(QString("UPDATE Activities SET RequestFlag=1 WHERE ApplicationName = '%1' AND ActivityName = '%2'").arg(applicationName).arg(activityName))) {
        qFatal(qPrintable(query.lastError().text()));
    }
}

void ActivityDatabasePrivate::clearActivityRequestFlag(const QString &applicationName, const QString &activityName)
{
    QSqlQuery query(QSqlDatabase::database(KConnectionName));

    // just clear the given request
    if (!query.exec(QString("UPDATE Activities SET RequestFlag=0 WHERE ApplicationName = '%1' AND ActivityName = '%2'").arg(applicationName).arg(activityName))) {
        qFatal(qPrintable(query.lastError().text()));
    }
}

bool ActivityDatabasePrivate::checkTables()
{
    QStringList expectedTables("Activities");
    QStringList actualTables = QSqlDatabase::database(KConnectionName).tables();
    return (expectedTables == actualTables); 
}

void ActivityDatabasePrivate::recreateTables()
{
    QSqlDatabase database = QSqlDatabase::database(KConnectionName);
    
    if (!database.transaction()) {
        qFatal(qPrintable(database.lastError().text()));
    }
    
    // drop any existing tables
    {
        QSqlQuery dropQuery(database);
        foreach(const QString &tableName, database.tables()) {
            if (!dropQuery.exec(QString("DROP TABLE %1").arg(tableName))) {
                qFatal(qPrintable(dropQuery.lastError().text()));
            }
        }
    }

    // create new table
    {
        QSqlQuery createQuery(database);
        QString statement(
            "CREATE TABLE Activities("
            "ApplicationName TEXT NOT NULL,"
            "ActivityName TEXT NOT NULL,"
            "RequestFlag BOOL NOT NULL DEFAULT FALSE,"
            "Data BLOB NOT NULL,"
            "PRIMARY KEY(ActivityName, ApplicationName))");
        
        if (!createQuery.exec(statement)) {
            qFatal(qPrintable(createQuery.lastError().text()));
        }
    }
    
    if (!database.commit()) {
        qFatal(qPrintable(database.lastError().text()));
    }  
}