Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativesqldatabase.cpp
index df072ed..f47fe14 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtDeclarative module of the Qt Toolkit.
 **
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
 
-#include "private/qdeclarativesqldatabase_p.h"
+#include "qdeclarativesqldatabase_p.h"
 
 #include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativerefcount_p.h>
 
 #include <QtCore/qobject.h>
 #include <QtSql/qsqldatabase.h>
 #include <QtSql/qsqlquery.h>
 #include <QtSql/qsqlerror.h>
 #include <QtSql/qsqlrecord.h>
-#include <QtGui/qdesktopservices.h>
+#include <QtSql/qsqlfield.h>
+#include <QtCore/qstandardpaths.h>
 #include <QtCore/qstack.h>
 #include <QtCore/qcryptographichash.h>
 #include <QtCore/qsettings.h>
 #include <QtCore/qdebug.h>
 
 #include <private/qv8engine_p.h>
+#include <private/qv8sqlerrors_p.h>
 
 QT_BEGIN_NAMESPACE
 
-enum SqlException {
-    UNKNOWN_ERR,
-    DATABASE_ERR,
-    VERSION_ERR,
-    TOO_LARGE_ERR,
-    QUOTA_ERR,
-    SYNTAX_ERR,
-    CONSTRAINT_ERR,
-    TIMEOUT_ERR
-};
-
-static const char* sqlerror[] = {
-    "UNKNOWN_ERR",
-    "DATABASE_ERR",
-    "VERSION_ERR",
-    "TOO_LARGE_ERR",
-    "QUOTA_ERR",
-    "SYNTAX_ERR",
-    "CONSTRAINT_ERR",
-    "TIMEOUT_ERR",
-    0
-};
 
 #define THROW_SQL(error, desc)
 
@@ -109,7 +88,6 @@ struct QDeclarativeSqlDatabaseData {
     QDeclarativeSqlDatabaseData(QV8Engine *engine);
     ~QDeclarativeSqlDatabaseData();
 
-    QString offlineStoragePath;
     v8::Persistent<v8::Function> constructor;
     v8::Persistent<v8::Function> queryConstructor;
     v8::Persistent<v8::Function> rowsConstructor;
@@ -144,7 +122,7 @@ public:
     bool forwardOnly; // type == Rows
 };
 
-static v8::Handle<v8::Value> qmlsqldatabase_version(v8::Local<v8::String> property, const v8::AccessorInfo& info)
+static v8::Handle<v8::Value> qmlsqldatabase_version(v8::Local<v8::String> /* property */, const v8::AccessorInfo& info)
 {
     QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(info.This());
     if (!r || r->type != QV8SqlDatabaseResource::Database)
@@ -153,7 +131,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_version(v8::Local<v8::String> proper
     return r->engine->toString(r->version);
 }
 
-static v8::Handle<v8::Value> qmlsqldatabase_rows_length(v8::Local<v8::String> property, const v8::AccessorInfo& info)
+static v8::Handle<v8::Value> qmlsqldatabase_rows_length(v8::Local<v8::String> /* property */, const v8::AccessorInfo& info)
 {
     QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(info.This());
     if (!r || r->type != QV8SqlDatabaseResource::Rows)
@@ -171,7 +149,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_rows_length(v8::Local<v8::String> pr
     return v8::Integer::New(s);
 }
 
-static v8::Handle<v8::Value> qmlsqldatabase_rows_forwardOnly(v8::Local<v8::String> property, 
+static v8::Handle<v8::Value> qmlsqldatabase_rows_forwardOnly(v8::Local<v8::String> /* property */,
                                                              const v8::AccessorInfo& info)
 {
     QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(info.This());
@@ -181,7 +159,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_rows_forwardOnly(v8::Local<v8::Strin
     return v8::Boolean::New(r->query.isForwardOnly());
 }
 
-static void qmlsqldatabase_rows_setForwardOnly(v8::Local<v8::String> property,
+static void qmlsqldatabase_rows_setForwardOnly(v8::Local<v8::String> /* property */,
                                                v8::Local<v8::Value> value,
                                                const v8::AccessorInfo& info)
 {
@@ -196,11 +174,12 @@ QDeclarativeSqlDatabaseData::~QDeclarativeSqlDatabaseData()
 {
     qPersistentDispose(constructor);
     qPersistentDispose(queryConstructor);
+    qPersistentDispose(rowsConstructor);
 }
 
 static QString qmlsqldatabase_databasesPath(QV8Engine *engine)
 {
-    return QDeclarativeSqlDatabaseData::data(engine)->offlineStoragePath +
+    return engine->engine()->offlineStoragePath() +
            QDir::separator() + QLatin1String("Databases");
 }
 
@@ -216,14 +195,19 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Eng
 
 static v8::Handle<v8::Value> qmlsqldatabase_rows_index(QV8SqlDatabaseResource *r, uint32_t index)
 {
-    if (r->query.at() == index || r->query.seek(index)) {
+    if (r->query.at() == (int)index || r->query.seek(index)) {
 
         QSqlRecord record = r->query.record();
         // XXX optimize
         v8::Local<v8::Object> row = v8::Object::New();
         for (int ii = 0; ii < record.count(); ++ii) {
-            row->Set(r->engine->toString(record.fieldName(ii)), 
-                     r->engine->toString(record.value(ii).toString()));
+            QVariant v = record.value(ii);
+            if (v.isNull()) {
+                row->Set(r->engine->toString(record.fieldName(ii)), v8::Null());
+            } else {
+                row->Set(r->engine->toString(record.fieldName(ii)),
+                         r->engine->fromVariant(v));
+            }
         }
         return row;
     } else {
@@ -258,14 +242,14 @@ static v8::Handle<v8::Value> qmlsqldatabase_executeSql(const v8::Arguments& args
     QV8Engine *engine = r->engine;
 
     if (!r->inTransaction)
-        V8THROW_SQL(DATABASE_ERR,QDeclarativeEngine::tr("executeSql called outside transaction()"));
+        V8THROW_SQL(SQLEXCEPTION_DATABASE_ERR,QDeclarativeEngine::tr("executeSql called outside transaction()"));
 
     QSqlDatabase db = r->database;
 
     QString sql = engine->toString(args[0]);
 
     if (r->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
-        V8THROW_SQL(SYNTAX_ERR, QDeclarativeEngine::tr("Read-only Transaction"));
+        V8THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QDeclarativeEngine::tr("Read-only Transaction"));
     }
 
     QSqlQuery query(db);
@@ -313,7 +297,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_executeSql(const v8::Arguments& args
         err = true;
     }
     if (err)
-        V8THROW_SQL(DATABASE_ERR,query.lastError().text());
+        V8THROW_SQL(SQLEXCEPTION_DATABASE_ERR,query.lastError().text());
 
     return result;
 }
@@ -335,7 +319,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_changeVersion(const v8::Arguments& a
     v8::Handle<v8::Value> callback = args[2];
 
     if (from_version != r->version) 
-        V8THROW_SQL(VERSION_ERR, QDeclarativeEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(r->version));
+        V8THROW_SQL(SQLEXCEPTION_VERSION_ERR, QDeclarativeEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(r->version));
 
     v8::Local<v8::Object> instance = QDeclarativeSqlDatabaseData::data(engine)->queryConstructor->NewInstance();
     QV8SqlDatabaseResource *r2 = new QV8SqlDatabaseResource(engine);
@@ -360,7 +344,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_changeVersion(const v8::Arguments& a
             return v8::Handle<v8::Value>();
         } else if (!db.commit()) {
             db.rollback();
-            V8THROW_SQL(UNKNOWN_ERR,QDeclarativeEngine::tr("SQL transaction failed"));
+            V8THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QDeclarativeEngine::tr("SQL transaction failed"));
         } else {
             ok = true;
         }
@@ -388,7 +372,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_transaction_shared(const v8::Argumen
     QV8Engine *engine = r->engine;
 
     if (args.Length() == 0 || !args[0]->IsFunction())
-        V8THROW_SQL(UNKNOWN_ERR,QDeclarativeEngine::tr("transaction: missing callback"));
+        V8THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QDeclarativeEngine::tr("transaction: missing callback"));
     
     QSqlDatabase db = r->database;
     v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(args[0]);
@@ -461,7 +445,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_open_sync(const v8::Arguments& args)
             database = QSqlDatabase::database(dbid);
             version = ini.value(QLatin1String("Version")).toString();
             if (version != dbversion && !dbversion.isEmpty() && !version.isEmpty())
-                V8THROW_SQL(VERSION_ERR, QDeclarativeEngine::tr("SQL: database version mismatch"));
+                V8THROW_SQL(SQLEXCEPTION_VERSION_ERR, QDeclarativeEngine::tr("SQL: database version mismatch"));
         } else {
             created = !QFile::exists(basename+QLatin1String(".sqlite"));
             database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid);
@@ -476,7 +460,7 @@ static v8::Handle<v8::Value> qmlsqldatabase_open_sync(const v8::Arguments& args)
             } else {
                 if (!dbversion.isEmpty() && ini.value(QLatin1String("Version")) != dbversion) {
                     // Incompatible
-                    V8THROW_SQL(VERSION_ERR,QDeclarativeEngine::tr("SQL: database version mismatch"));
+                    V8THROW_SQL(SQLEXCEPTION_VERSION_ERR,QDeclarativeEngine::tr("SQL: database version mismatch"));
                 }
                 version = ini.value(QLatin1String("Version")).toString();
             }
@@ -511,11 +495,6 @@ static v8::Handle<v8::Value> qmlsqldatabase_open_sync(const v8::Arguments& args)
 
 QDeclarativeSqlDatabaseData::QDeclarativeSqlDatabaseData(QV8Engine *engine)
 {
-    QString dataLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
-    offlineStoragePath = dataLocation.replace(QLatin1Char('/'), QDir::separator()) +
-                         QDir::separator() + QLatin1String("QML") +
-                         QDir::separator() + QLatin1String("OfflineStorage");
-
     {
     v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
     ft->InstanceTemplate()->SetHasExternalResource(true);
@@ -553,31 +532,15 @@ void *qt_add_qmlsqldatabase(QV8Engine *engine)
     v8::Local<v8::Function> openDatabase = V8FUNCTION(qmlsqldatabase_open_sync, engine);
     engine->global()->Set(v8::String::New("openDatabaseSync"), openDatabase);
 
-    v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
-    v8::Local<v8::Object> sqlExceptionPrototype = v8::Object::New();
-    for (int i=0; sqlerror[i]; ++i)
-        sqlExceptionPrototype->Set(v8::String::New(sqlerror[i]), v8::Integer::New(i), attributes);
-    engine->global()->Set(v8::String::New("SQLException"), sqlExceptionPrototype);
-
     return (void *)new QDeclarativeSqlDatabaseData(engine);
 }
 
-void qt_rem_qmlsqldatabase(QV8Engine *engine, void *d)
+void qt_rem_qmlsqldatabase(QV8Engine * /* engine */, void *d)
 {
     QDeclarativeSqlDatabaseData *data = (QDeclarativeSqlDatabaseData *)d;
     delete data;
 }
 
-void qt_qmlsqldatabase_setOfflineStoragePath(QV8Engine *engine, const QString &path)
-{
-    QDeclarativeSqlDatabaseData::data(engine)->offlineStoragePath = path;
-}
-
-QString qt_qmlsqldatabase_getOfflineStoragePath(const QV8Engine *engine)
-{
-    return QDeclarativeSqlDatabaseData::data(const_cast<QV8Engine *>(engine))->offlineStoragePath;
-}
-
 /*
 HTML5 "spec" says "rs.rows[n]", but WebKit only impelments "rs.rows.item(n)". We do both (and property iterator).
 We add a "forwardOnly" property that stops Qt caching results (code promises to only go forward