qtmobility/src/serviceframework/servicedatabase.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 8 71781823f776
--- a/qtmobility/src/serviceframework/servicedatabase.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/serviceframework/servicedatabase.cpp	Mon May 03 13:18:40 2010 +0300
@@ -39,7 +39,7 @@
 **
 ****************************************************************************/
 
-//#define QT_SFW_SERVICEDATABASE_DEBUG
+// #define QT_SFW_SERVICEDATABASE_DEBUG
 
 #include "servicedatabase_p.h"
 #include <QDir>
@@ -166,8 +166,8 @@
             m_lastError.setError(DBError::SqlError, database.lastError().text());
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
             qWarning() << "ServiceDatabase::open():-"
-                        << "Problem:" << "Could not open database"
-                        << "\nReason:" << m_lastError.text();
+                        << "Problem:" << "Could not open database. "
+                        << "Reason:" << m_lastError.text();
 #endif
             close();
             return false;
@@ -220,6 +220,17 @@
 {
 #ifndef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
     Q_UNUSED(securityToken);
+#else
+    if (securityToken.isEmpty()) {
+        QString errorText("Access denied, no security token provided (for registering service: \"%1\")");
+        m_lastError.setError(DBError::NoWritePermissions, errorText.arg(service.name));
+#ifdef QT_SFW_SERVICEDATABASE_DEBUG
+        qWarning() << "ServiceDatabase::registerService():-"
+                << "Problem: Unable to register service,"
+                << "reason:" << qPrintable(m_lastError.text());
+#endif
+        return false;
+    }
 #endif
 
     if(!checkConnection()) {
@@ -236,8 +247,8 @@
     if (!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::registerService():-"
-                    << "Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Unable to begin transaction,"
+                    << "reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -274,38 +285,44 @@
     }
 
 #ifdef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
-    statement = "SELECT Value FROM ServiceProperty WHERE ServiceID = ? AND Key = ?";
+    // If service(s) have already been registered with same name, they must all come from
+    // same application. Fetch a service with given name and if such exists, check that its
+    // security ID equals to the security ID of the current registrar.
+    // One application may register multiple services with same name (different location),
+    // hence the keyword DISTINCT.
+    statement = "SELECT DISTINCT ServiceProperty.Value FROM Service, ServiceProperty "
+                "WHERE Service.ID = ServiceProperty.ServiceID "
+                "AND ServiceProperty.Key = ? "
+                "AND Service.Name = ?";
     bindValues.clear();
+    bindValues.append(SECURITY_TOKEN_KEY);
     bindValues.append(service.name);
-    bindValues.append(SECURITY_TOKEN_KEY);
-    
-    if(!executeQuery(&query, statement, bindValues)) {
+    if (!executeQuery(&query, statement, bindValues)) {
         rollbackTransaction(&query);
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::registerService():-"
-                    << qPrintable(m_lastError.text());
+                   << qPrintable(m_lastError.text());
 #endif
         return false;
     }
-
-    QStringList securityTokens;
-    while(query.next()) {
-        securityTokens << query.value(EBindIndex).toString();
+    QString existingSecurityToken;
+    if (query.next()) {
+        existingSecurityToken = query.value(EBindIndex).toString();
     }
-    
-    if (!securityTokens.isEmpty() && securityTokens.first() != securityToken) {
+    if (!existingSecurityToken.isEmpty() && (existingSecurityToken != securityToken)) {
         QString errorText("Access denied: \"%1\"");
-             m_lastError.setError(DBError::NoWritePermissions, errorText.arg(service.name));
-             rollbackTransaction(&query);
-     #ifdef QT_SFW_SERVICEDATABASE_DEBUG
-             qWarning() << "ServiceDatabase::registerService():-"
-                         << "Problem: Unable to register service"
-                         << "\nReason:" << qPrintable(m_lastError.text());
-     #endif    
-             return false;
+        m_lastError.setError(DBError::NoWritePermissions, errorText.arg(service.name));
+        rollbackTransaction(&query);
+#ifdef QT_SFW_SERVICEDATABASE_DEBUG
+        qWarning() << "ServiceDatabase::registerService():-"
+                << "Problem: Unable to register service,"
+                << "reason:" << qPrintable(m_lastError.text());
+#endif
+        return false;
     }
-#endif
+#endif // QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
 
+    // Checks done, create new rows into tables.
     statement = "INSERT INTO Service(ID,Name,Location) VALUES(?,?,?)";
     QString serviceID = QUuid::createUuid().toString();
 
@@ -342,23 +359,22 @@
     }
     
 #ifdef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
-    if (securityTokens.isEmpty()) {
-        statement = "INSERT INTO ServiceProperty(ServiceID,Key,Value) VALUES(?,?,?)";
-        bindValues.clear();
-        bindValues.append(service.name);
-        bindValues.append(SECURITY_TOKEN_KEY);
-        bindValues.append(securityToken);
+    // Insert a security token for the particular service
+    statement = "INSERT INTO ServiceProperty(ServiceID,Key,Value) VALUES(?,?,?)";
+    bindValues.clear();
+    bindValues.append(serviceID);
+    bindValues.append(SECURITY_TOKEN_KEY);
+    bindValues.append(securityToken);
     
-        if (!executeQuery(&query, statement, bindValues)) {
-            rollbackTransaction(&query);
+    if (!executeQuery(&query, statement, bindValues)) {
+        rollbackTransaction(&query);
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
-            qWarning() << "ServiceDatabase::registerService():-"
-                        << qPrintable(m_lastError.text());
+        qWarning() << "ServiceDatabase::registerService():-"
+                << qPrintable(m_lastError.text());
 #endif
-            return false;
-        }
+        return false;
     }
-#endif
+#endif // QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
     
     QList <QServiceInterfaceDescriptor> interfaces = service.interfaces;
     QString interfaceID;;
@@ -569,9 +585,9 @@
 
     if (!query->next()) {
          QString errorText("No Interface Descriptor found with "
-                            "\nService name: %1 "
-                            "\nInterface name: %2 "
-                            "\nVersion: %3.%4");
+                            "Service name: %1 "
+                            "Interface name: %2 "
+                            "Version: %3.%4");
         m_lastError.setError(DBError::NotFound, errorText.arg(interface.serviceName())
                                                         .arg(interface.interfaceName())
                                                         .arg(interface.majorVersion())
@@ -716,8 +732,8 @@
         if (!success) {
             QString errorText;
             errorText = "Problem: Could not %1 statement: %2"
-                "\nReason: %3"
-                "\nParameters: %4\n";
+                "Reason: %3"
+                "Parameters: %4\n";
             QString parameters;
             if (bindValues.count() > 0) {
                 for(int i = 0; i < bindValues.count(); ++i) {
@@ -791,8 +807,8 @@
     if (!beginTransaction(&query, Read)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::getInterfaces():-"
-                    << "Unable to begin transaction:"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return interfaces;
     }
@@ -945,8 +961,8 @@
     if (!beginTransaction(&query, Read)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::getInterface():-"
-                    << "Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return interface;
     }
@@ -1106,8 +1122,8 @@
     if (!inTransaction && !beginTransaction(&query, Read)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::interfaceDefault(QString, QString):-"
-                    << "Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return interface;
     }
@@ -1234,8 +1250,8 @@
     if(!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::setInterfaceDefault(QServiceInterfaceDescriptor):-"
-            << "Problem: Unable to begin transaction"
-            << "\nReason:" << qPrintable(m_lastError.text());
+            << "Problem: Unable to begin transaction."
+            << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -1276,8 +1292,8 @@
             rollbackTransaction(&query);
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
             qWarning() << "ServiceDatbase::setInterfaceDefault(QServiceInterfaceDescriptor):-"
-                << "Problem: Unable to set default service"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                << "Problem: Unable to set default service. "
+                << "Reason:" << qPrintable(m_lastError.text());
 #endif
             return false;
         }
@@ -1357,10 +1373,22 @@
    DBError::InvalidDatabaseFile
 */
 bool ServiceDatabase::unregisterService(const QString &serviceName, const QString &securityToken)
-{
+{    
 #ifndef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
     Q_UNUSED(securityToken);
+#else
+    if (securityToken.isEmpty()) {
+        QString errorText("Access denied, no security token provided (for unregistering service: \"%1\")");
+        m_lastError.setError(DBError::NoWritePermissions, errorText.arg(serviceName));
+#ifdef QT_SFW_SERVICEDATABASE_DEBUG
+        qWarning() << "ServiceDatabase::unregisterService():-"
+                << "Problem: Unable to unregister service. "
+                << "Reason:" << qPrintable(m_lastError.text());
 #endif
+        return false;
+    }
+#endif
+
 
     if (!checkConnection()) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
@@ -1376,8 +1404,8 @@
     if(!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::unregisterService():-"
-                    << "Problem: Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Problem: Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -1399,39 +1427,43 @@
         serviceIDs << query.value(EBindIndex).toString();
     }
 
+#ifdef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
+    // Only the application that registered the service is allowed to unregister that
+    // service. Fetch a security ID of a service (with given name) and verify that it matches
+    // with current apps security id. Only one application is allowed to register services with
+    // same name, hence a distinct (just any of the) security token will do because they are identical.
+    if (!serviceIDs.isEmpty()) {
+        statement = "SELECT DISTINCT Value FROM ServiceProperty WHERE ServiceID = ? AND Key = ?";
+        bindValues.clear();
+        bindValues.append(serviceIDs.first());
+        bindValues.append(SECURITY_TOKEN_KEY);
 
-#ifdef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
-    statement = "SELECT Value FROM ServiceProperty WHERE ServiceID = ? AND Key = ?";
-    bindValues.clear();
-    bindValues.append(serviceName);
-    bindValues.append(SECURITY_TOKEN_KEY);
-    if(!executeQuery(&query, statement, bindValues)) {
-        rollbackTransaction(&query);
+        if (!executeQuery(&query, statement, bindValues)) {
+            rollbackTransaction(&query);
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
-        qWarning() << "ServiceDatabase::unregisterService():-"
+            qWarning() << "ServiceDatabase::unregisterService():-"
                     << qPrintable(m_lastError.text());
 #endif
-        return false;
-    }
-
-    QStringList securityTokens;
-    while(query.next()) {
-        securityTokens << query.value(EBindIndex).toString();
+            return false;
+        }
+        QString existingSecurityToken;
+        if (query.next()) {
+            existingSecurityToken = query.value(EBindIndex).toString();
+        }
+        if (existingSecurityToken != securityToken) {
+            QString errorText("Access denied: \"%1\"");
+            m_lastError.setError(DBError::NoWritePermissions, errorText.arg(serviceName));
+            rollbackTransaction(&query);
+#ifdef QT_SFW_SERVICEDATABASE_DEBUG
+            qWarning() << "ServiceDatabase::unregisterService():-"
+                    << "Problem: Unable to unregister service"
+                    << "Reason:" << qPrintable(m_lastError.text());
+#endif
+            return false;
+        }
     }
-    
-    if (!securityTokens.isEmpty() && (securityTokens.first() != securityToken)) {
-        QString errorText("Access denied: \"%1\"");
-             m_lastError.setError(DBError::NoWritePermissions, errorText.arg(serviceName));
-             rollbackTransaction(&query);
-     #ifdef QT_SFW_SERVICEDATABASE_DEBUG
-             qWarning() << "ServiceDatabase::unregisterService():-"
-                         << "Problem: Unable to unregister service"
-                         << "\nReason:" << qPrintable(m_lastError.text());
-     #endif    
-    }
-    
-#endif
-    
+#endif // QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
+
     statement = "SELECT Interface.ID from Interface, Service "
                 "WHERE Interface.ServiceID = Service.ID "
                     "AND Service.Name =? COLLATE NOCASE";
@@ -1458,7 +1490,7 @@
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::unregisterService():-"
                     << "Problem: Unable to unregister service"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -1511,19 +1543,11 @@
         }
     }
 
-#ifndef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
     statement = "DELETE FROM ServiceProperty WHERE ServiceID = ?";
-#else
-    statement = "DELETE FROM ServiceProperty WHERE ServiceID = ? AND Key <> ?";
-#endif
-
     
     foreach(const QString &serviceID, serviceIDs) {
         bindValues.clear();
         bindValues.append(serviceID);
-#ifdef QT_SFW_SERVICEDATABASE_USE_SECURITY_TOKEN
-        bindValues.append(SECURITY_TOKEN_KEY);
-#endif
         if (!executeQuery(&query, statement, bindValues)) {
             rollbackTransaction(&query);
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
@@ -1645,6 +1669,18 @@
 {
     QString path;
     if(m_databasePath.isEmpty()) {
+#if (defined(Q_OS_SYMBIAN) && defined(__WINS__))
+        // On Symbian, database location never changes. On emulator it is fixed
+        // and on hardware it is relative to the db managers private directory.
+        path = QDir::toNativeSeparators("C:\\Data\\temp\\QtServiceFW");
+#elif defined(Q_OS_SYMBIAN)
+        QString qtVersion(qVersion());
+        qtVersion = qtVersion.left(qtVersion.size() -2); //strip off patch version
+        path = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() +
+                                        "\\Nokia\\" + "QtServiceFramework_" +
+                                        qtVersion + "_system" +
+                                        QLatin1String(".db"));
+#else
         QSettings settings(QSettings::SystemScope, "Nokia", "Services");
         path = settings.value("ServicesDB/Path").toString();
         if (path.isEmpty()) {
@@ -1655,6 +1691,7 @@
             path.append(RESOLVERDATABASE);
         }
         path = QDir::toNativeSeparators(path);
+#endif
     } else {
         path = m_databasePath;
     }
@@ -1681,8 +1718,8 @@
     if (!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::createTables():-"
-                    << "Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -1803,8 +1840,8 @@
     if (!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
         qWarning() << "ServiceDatabase::removeExternalDefaultServiceInterface():-"
-                    << "Problem: Unable to begin transaction"
-                    << "\nReason:" << qPrintable(m_lastError.text());
+                    << "Problem: Unable to begin transaction. "
+                    << "Reason:" << qPrintable(m_lastError.text());
 #endif
         return false;
     }
@@ -1878,14 +1915,14 @@
         if (!beginTransaction(&query, Write)) {
 #ifdef QT_SFW_SERVICEDATABASE_DEBUG
             qWarning() << "ServiceDatabase::dropTables():-"
-                        << "Unable to begin transaction"
-                        << "\nReason:" << qPrintable(m_lastError.text());
+                        << "Unable to begin transaction. "
+                        << "Reason:" << qPrintable(m_lastError.text());
 #endif
             return false;
         }
         QStringList actualTables = database.tables();
 
-        foreach(QString expectedTable, expectedTables) {
+        foreach(const QString expectedTable, expectedTables) {
             if ((actualTables.contains(expectedTable))
                 && (!executeQuery(&query, QString("DROP TABLE ") + expectedTable))) {
                 rollbackTransaction(&query);