browsercore/appfw/Api/Managers/geolocationManager.cpp
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
permissions -rw-r--r--
201041

/*
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * This program 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, version 2.1 of the License.
 * 
 * This program 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 "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
 *
 * Description: This implements the geolocation database API's.
 *
 */

#include<QString>
#include<QFile>
#include<QFileInfo>
#include<QDebug>
#include<QSqlQuery>
#include<QSqlError>
#include<QWidget>
#include<QDateTime>
#include<QtGui>

#include "geolocationManager.h"

/* Declare the user defined meta type for use with QVariant in geolocation. */
Q_DECLARE_METATYPE(QWebPage::PermissionPolicy);

GeolocationManager* GeolocationManager::getSingleton() 
{
    static GeolocationManager* s_instance;
    if(!s_instance) {
        s_instance = new GeolocationManager();
    }
    Q_ASSERT(s_instance);
    return s_instance;    
}

GeolocationManager::GeolocationManager(QWidget *parent) :
    QObject(parent)
{
    setObjectName("geolocationManager");
    
    /* Register user defined Meta Types used in geolocation API. */
    qRegisterMetaType<QWebPage::PermissionPolicy>("QWebPage::PermissionPolicy");
    
    m_geo = QSqlDatabase::database(GEOLOCATION_DB_NAME);
    if (!m_geo.isValid()) {
        m_geo = QSqlDatabase::addDatabase("QSQLITE", GEOLOCATION_DB_NAME);
        m_geo.setDatabaseName(GEOLOCATION_DB_FILE);
    }
    if (m_geo.open()) {
        if(!doesTableExist(GEOLOCATION_TABLE_NAME)) {
            createGeolocationSchema();
        }
    }
}

GeolocationManager::~GeolocationManager()
{
    m_geo.close();
    QSqlDatabase::removeDatabase(GEOLOCATION_DB_NAME);
}

bool GeolocationManager::doesTableExist(QString tableName)
{
    bool retVal = false;
       
    if (!m_geo.isValid() || !m_geo.isOpen())
         return false;
       
    QSqlQuery query(m_geo);
    query.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name=:tableName");
    query.bindValue(":tableName", QVariant(tableName));
    if (query.exec()) {
        if (query.next()) 
            retVal = true;
        query.finish();
    }
    return retVal;
}
   
void GeolocationManager::createGeolocationSchema()
{
    if (!doQuery("CREATE TABLE IF NOT EXISTS geolocationdata("
        "domain text PRIMARY KEY,"
        "creationtime int, "
        "permission text)")) {
        // TODO: do some error handling here!
        return;
    }
    // We do lookups by domain
    if (!doQuery("CREATE INDEX IF NOT EXISTS geo_domain_idx ON geolocationdata(domain ASC)")) {
        // TODO: do some error handling here!
        return;
    }
}

// TODO refactor this - nothing except the schema creation can use it as is
bool GeolocationManager::doQuery(QString query)
{
    QSqlQuery db_query(m_geo);
    bool ok = db_query.exec(query);
    if (!ok) {
        qDebug() << "GeolocationManager::doQuery" << QString("ERR: %1 %2").arg(
                db_query.lastError().type()).arg(db_query.lastError().text())
                << " Query: " << db_query.lastQuery();
    }
    return ok;
}

/**===================================================================================
 * Description: Converts database permission string into enum
 * Returns: permission enum
 ======================================================================================*/
QWebPage::PermissionPolicy GeolocationManager::convertStringIntoPermission(QString permission)
{
    QWebPage::PermissionPolicy permissionPolicy = QWebPage::PermissionUnknown;
    	
    if (permission == "G") 
        permissionPolicy = QWebPage::PermissionGranted;
    else if (permission == "D") 
        permissionPolicy = QWebPage::PermissionDenied;
    else if (permission == "U") 
        permissionPolicy = QWebPage::PermissionUnknown;
    
    return permissionPolicy;
}

/**===================================================================================
 * Description: Converts permission enum into database string
 * Returns: String
 ======================================================================================*/
QString GeolocationManager::convertPermissionIntoString(QWebPage::PermissionPolicy permission)
{
    QString retVal;

    switch (permission) {
      case QWebPage::PermissionGranted:
         retVal = "G";
         break;
      case QWebPage::PermissionDenied:
         retVal = "D";
         break;
      case QWebPage::PermissionUnknown:
         retVal = "U";
         break;
      default:
         retVal = "";    
    }
    
    return retVal;
}

/**===================================================================================
 * Description: Delete the geolocation item.
 * Returns: SUCCESS(0) or Failure(-1 or -2)
 ======================================================================================*/
int GeolocationManager::deleteGeodomain(QString domain)
{
   int retVal = SUCCESS;
       
    if (domain.isEmpty())
        retVal = FAILURE;
       
    if (retVal == SUCCESS) {
        if (m_geo.isOpen()) {
        QSqlQuery query(m_geo);
               
        query.prepare("DELETE FROM geolocationdata WHERE domain=:geodomain");
        query.bindValue(":geodomain", domain);
        if (!query.exec()) {
            lastErrMsg(query);
            retVal = DATABASEERROR;
        }
        } else 
               retVal = FAILURE;
    }
       
    return retVal;
}
 
/**===================================================================================
 * Description: Delete all records from the geolocation table.
 * Returns: SUCCESS(0) or FAILURE(-1 or -2)
 ======================================================================================*/
int GeolocationManager::clearAllGeodata()
{
    int retVal = SUCCESS;
    
    if (m_geo.isOpen()) {
        QSqlQuery query(m_geo);
        
        if (!query.exec("DELETE FROM geolocationdata")) {
            lastErrMsg(query);
            retVal = DATABASEERROR;
        }
    } else
        retVal = FAILURE;
    
    return retVal;
}



/**================================================================
 * Description: Adds a domain to the database. 
 * Returns: SUCCESS(0) or FAILURE (-1 or -2)
 ==================================================================*/
int GeolocationManager::addGeodomain(QString domainToAdd, QWebPage::PermissionPolicy permission)
{
    int retVal = SUCCESS;
    
    if (domainToAdd.isEmpty() || permission == QWebPage::PermissionUnknown)
        retVal = FAILURE;
    
    if (retVal == SUCCESS) {
        QString permissionPolicy(convertPermissionIntoString(permission));
        
        QDateTime dt  = QDateTime::currentDateTime();
        int timestamp = dt.toTime_t();
    
        if (m_geo.isOpen()) {
            QSqlQuery query(m_geo);
            m_geo.transaction();
            query.prepare("SELECT domain FROM geolocationdata WHERE domain=:domain");
            query.bindValue(":domain",domainToAdd);
            if (!query.exec()) {
                 lastErrMsg(query);
                 m_geo.rollback();
                return DATABASEERROR;
            }
            if(!query.next()) {
                QSqlQuery query2(m_geo);
                query2.prepare("INSERT INTO geolocationdata (domain, creationtime, permission) "
                        "VALUES (:domain, :ctime, :ppermisson)");
                query2.bindValue(":domain", QVariant(domainToAdd));
                query2.bindValue(":ctime", QVariant(timestamp));
                query2.bindValue(":ppermission", QVariant(permissionPolicy));
                if (!query2.exec()) {
                    lastErrMsg(query);
                    m_geo.rollback();
                    retVal = DATABASEERROR;
                }
            }
            query.finish();
            if (!m_geo.commit()) {
                 qDebug() << m_geo.lastError().text();
                 m_geo.rollback();
                 return DATABASEERROR;
            }
        } else
            retVal = FAILURE;
    }
    
    return retVal;
}

/**==============================================================
 * Description: Finds attributes (row) including permission policy for a domain.
 * Returns: empty list (not found) or list of attributes
 ===============================================================*/
QList<QVariant> GeolocationManager::findGeodomain(QString domainToFind)
{ 
    QList<QVariant> retValue;
    
    if (m_geo.isOpen()) {
        QSqlQuery query(m_geo);
        query.prepare(
                "SELECT permission FROM geolocationdata WHERE domain=:domain");
        query.bindValue(":domain",domainToFind);
        if (query.exec()) {
            if (query.next()) {
                QWebPage::PermissionPolicy permission = convertStringIntoPermission(query.value(0).toString());
                QVariant v;
                v.setValue(permission);
                retValue << v;
                return retValue;
            }
        } else {
            lastErrMsg(query);
        }
    }
    
    return retValue;
}

/**==============================================================
 * Description: Prints a last error message from the query.
 * Returns: Nothing.
 ===============================================================*/
void GeolocationManager::lastErrMsg(QSqlQuery& query)
{
    qDebug() << "GeolocationManager::lastErrMsg" << QString("ERR: %1 %2").arg(
            query.lastError().type()).arg(query.lastError().text())
            << " Query: " << query.lastQuery();
}