aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Yin <charles.yin@nokia.com>2012-01-24 16:07:24 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-25 06:32:34 +0100
commitb2869013fdfb76d60ce8750e24614111f78fef5c (patch)
treec57ec9c0cfc1226c1ac9d66735ddd267b20cffca
parent149f6afe321ce59aebe4ce2f9dddd1881d0ac22b (diff)
Move sqldatabase into a module API plugin
Change-Id: Icd0bbfe16804abf1bbadbabddf3a30b5b18df30c Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--doc/src/declarative/advtutorial.qdoc2
-rw-r--r--doc/src/declarative/globalobject.qdoc84
-rwxr-xr-xexamples/declarative/samegame/content/samegame.js5
-rw-r--r--examples/declarative/snake/content/HighScoreModel.qml3
-rw-r--r--examples/declarative/sqllocalstorage/hello.qml3
-rwxr-xr-xexamples/declarative/tutorials/samegame/samegame4/content/samegame.js5
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp12
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp63
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase_p.h2
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp4
-rw-r--r--src/declarative/qml/v8/qv8sqlerrors.cpp64
-rw-r--r--src/declarative/qml/v8/qv8sqlerrors_p.h77
-rw-r--r--src/declarative/qml/v8/v8.pri4
-rw-r--r--src/imports/imports.pro4
-rw-r--r--src/imports/localstorage/localstorage.pro15
-rw-r--r--src/imports/localstorage/plugin.cpp668
-rw-r--r--src/imports/localstorage/qmldir1
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/changeversion.js8
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/creation-a.js6
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/creation.js5
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/error-a.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/error-b.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/error-creation.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/error-notransaction.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/error-outsidetransaction.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/iteration-forwardonly.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/iteration.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/readonly-error.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/readonly.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/reopen1.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/reopen2.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/selection-bindnames.js4
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/data/selection.js4
33 files changed, 916 insertions, 171 deletions
diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc
index 47b8e16b06..fb880860bc 100644
--- a/doc/src/declarative/advtutorial.qdoc
+++ b/doc/src/declarative/advtutorial.qdoc
@@ -428,7 +428,7 @@ Here is the \c saveHighScore() function in \c samegame.js:
First we call \c sendHighScore() (explained in the section below) if it is possible to send the high scores to an online database.
-Then, we use the \l{Offline Storage API} to maintain a persistent SQL database unique to this application. We create an offline storage database for the high scores using \c openDatabase() and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrieval, and in the \c db.transaction() call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string.
+Then, we use the \l{Offline Storage API} to maintain a persistent SQL database unique to this application. We create an offline storage database for the high scores using \c openDatabaseSync() and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrieval, and in the \c db.transaction() call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string.
This is one way of storing and displaying high scores locally, but certainly not the only way. A more complex alternative would be to create a high score dialog component, and pass it the results for processing and display (instead of reusing the \c Dialog). This would allow a more themeable dialog that could better present the high scores. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database.
diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc
index 0911784e56..6d501802a8 100644
--- a/doc/src/declarative/globalobject.qdoc
+++ b/doc/src/declarative/globalobject.qdoc
@@ -118,90 +118,6 @@ browser. The following objects and properties are supported by the QML implemen
The \l{declarative/xml/xmlhttprequest}{XMLHttpRequest example} demonstrates how to
use the XMLHttpRequest object to make a request and read the response headers.
-\section1 Offline Storage API
-
-\section2 Database API
-
-The \c openDatabaseSync() and related functions
-provide the ability to access local offline storage in an SQL database.
-
-These databases are user-specific and QML-specific, but accessible to all QML applications.
-They are stored in the \c Databases subdirectory
-of QDeclarativeEngine::offlineStoragePath(), currently as SQLite databases.
-
-Database connections are automatically closed during Javascript garbage collection.
-
-The API can be used from JavaScript functions in your QML:
-
-\snippet declarative/sqllocalstorage/hello.qml 0
-
-The API conforms to the Synchronous API of the HTML5 Web Database API,
-\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
-
-The \l{declarative/sqllocalstorage}{SQL Local Storage example} demonstrates the basics of
-using the Offline Storage API.
-
-\section3 db = openDatabaseSync(identifier, version, description, estimated_size, callback(db))
-
-Returns the database identified by \i identifier. If the database does not already exist, it
-is created, and the function \i callback is called with the database as a parameter. \i description
-and \i estimated_size are written to the INI file (described below), but are otherwise currently
-unused.
-
-May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR.
-
-When a database is first created, an INI file is also created specifying its characteristics:
-
-\table
-\header \o \bold {Key} \o \bold {Value}
-\row \o Name \o The name of the database passed to \c openDatabase()
-\row \o Version \o The version of the database passed to \c openDatabase()
-\row \o Description \o The description of the database passed to \c openDatabase()
-\row \o EstimatedSize \o The estimated size (in bytes) of the database passed to \c openDatabase()
-\row \o Driver \o Currently "QSQLITE"
-\endtable
-
-This data can be used by application tools.
-
-\section3 db.changeVersion(from, to, callback(tx))
-
-This method allows you to perform a \i{Scheme Upgrade}.
-
-If the current version of \i db is not \i from, then an exception is thrown.
-
-Otherwise, a database transaction is created and passed to \i callback. In this function,
-you can call \i executeSql on \i tx to upgrade the database.
-
-May throw exception with code property SQLException.DATABASE_ERR or SQLException.UNKNOWN_ERR.
-
-\section3 db.transaction(callback(tx))
-
-This method creates a read/write transaction and passed to \i callback. In this function,
-you can call \i executeSql on \i tx to read and modify the database.
-
-If the callback throws exceptions, the transaction is rolled back.
-
-\section3 db.readTransaction(callback(tx))
-
-This method creates a read-only transaction and passed to \i callback. In this function,
-you can call \i executeSql on \i tx to read the database (with SELECT statements).
-
-\section3 results = tx.executeSql(statement, values)
-
-This method executes a SQL \i statement, binding the list of \i values to SQL positional parameters ("?").
-
-It returns a results object, with the following properties:
-
-\table
-\header \o \bold {Type} \o \bold {Property} \o \bold {Value} \o \bold {Applicability}
-\row \o int \o rows.length \o The number of rows in the result \o SELECT
-\row \o var \o rows.item(i) \o Function that returns row \i i of the result \o SELECT
-\row \o int \o rowsAffected \o The number of rows affected by a modification \o UPDATE, DELETE
-\row \o string \o insertId \o The id of the row inserted \o INSERT
-\endtable
-
-May throw exception with code property SQLException.DATABASE_ERR, SQLException.SYNTAX_ERR, or SQLException.UNKNOWN_ERR.
-
\section1 Logging
\c console.log(), \c console.debug(), \c console.time(), and \c console.timeEnd() can be used to print information
diff --git a/examples/declarative/samegame/content/samegame.js b/examples/declarative/samegame/content/samegame.js
index 8c15af763a..611767584b 100755
--- a/examples/declarative/samegame/content/samegame.js
+++ b/examples/declarative/samegame/content/samegame.js
@@ -1,5 +1,6 @@
/* This script file handles the game logic */
.pragma library
+.import QtQuick.LocalStorage 2.0 as Sql
var maxColumn = 10;
var maxRow = 15;
@@ -229,7 +230,7 @@ function createBlock(column,row)
function initHighScoreBar()
{
- var db = openDatabaseSync(
+ var db = Sql.openDatabaseSync(
"SameGameScores",
"1.0",
"Local SameGame High Scores",
@@ -254,7 +255,7 @@ function saveHighScore(name)
if (scoresURL != "")
sendHighScore(name);
// Offline storage
- var db = openDatabaseSync(
+ var db = Sql.openDatabaseSync(
"SameGameScores",
"1.0",
"Local SameGame High Scores",
diff --git a/examples/declarative/snake/content/HighScoreModel.qml b/examples/declarative/snake/content/HighScoreModel.qml
index 0a30d7343e..d6ac762859 100644
--- a/examples/declarative/snake/content/HighScoreModel.qml
+++ b/examples/declarative/snake/content/HighScoreModel.qml
@@ -40,6 +40,7 @@
****************************************************************************/
import QtQuick 2.0
+import QtQuick.LocalStorage 2.0 as Sql
// Models a high score table.
//
@@ -84,7 +85,7 @@ ListModel {
function __db()
{
- return openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000);
+ return Sql.openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000);
}
function __ensureTables(tx)
{
diff --git a/examples/declarative/sqllocalstorage/hello.qml b/examples/declarative/sqllocalstorage/hello.qml
index 5290f9c38b..8312e8cabe 100644
--- a/examples/declarative/sqllocalstorage/hello.qml
+++ b/examples/declarative/sqllocalstorage/hello.qml
@@ -39,6 +39,7 @@
****************************************************************************/
//![0]
import QtQuick 2.0
+import QtQuick.LocalStorage 2.0 as LS
Rectangle {
color: "white"
@@ -49,7 +50,7 @@ Rectangle {
text: "?"
anchors.horizontalCenter: parent.horizontalCenter
function findGreetings() {
- var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000);
+ var db = LS.openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000);
db.transaction(
function(tx) {
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
index ccc3f9dae2..7bb7243914 100755
--- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
@@ -1,4 +1,6 @@
/* This script file handles the game logic */
+.import QtQuick.LocalStorage 2.0 as Sql
+
var maxColumn = 10;
var maxRow = 15;
var maxIndex = maxColumn * maxRow;
@@ -191,7 +193,7 @@ function saveHighScore(name) {
if (scoresURL != "")
sendHighScore(name);
- var db = openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100);
+ var db = Sql.openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100);
var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)";
var data = [name, gameCanvas.score, maxColumn + "x" + maxRow, Math.floor(gameDuration / 1000)];
db.transaction(function(tx) {
@@ -222,4 +224,3 @@ function sendHighScore(name) {
postman.send(postData);
}
//![1]
-
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 54f17ca48d..ade01cfe89 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -74,6 +74,9 @@
#include "qdeclarativeincubator.h"
#include <private/qv8profilerservice_p.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qsettings.h>
+
#include <QtCore/qmetaobject.h>
#include <QNetworkAccessManager>
#include <QDebug>
@@ -454,6 +457,11 @@ void QDeclarativeEnginePrivate::init()
QDeclarativeDebugTrace::initialize();
QDebugMessageService::instance();
}
+
+ QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
+ offlineStoragePath = dataLocation.replace(QLatin1Char('/'), QDir::separator()) +
+ QDir::separator() + QLatin1String("QML") +
+ QDir::separator() + QLatin1String("OfflineStorage");
}
QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
@@ -1543,13 +1551,13 @@ bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &ur
void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
{
Q_D(QDeclarativeEngine);
- qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
+ d->offlineStoragePath = dir;
}
QString QDeclarativeEngine::offlineStoragePath() const
{
Q_D(const QDeclarativeEngine);
- return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
+ return d->offlineStoragePath;
}
static void voidptr_destructor(void *v)
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index 5f7100e49b..fd4356efd9 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -59,31 +59,10 @@
#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;
@@ -201,7 +179,7 @@ QDeclarativeSqlDatabaseData::~QDeclarativeSqlDatabaseData()
static QString qmlsqldatabase_databasesPath(QV8Engine *engine)
{
- return QDeclarativeSqlDatabaseData::data(engine)->offlineStoragePath +
+ return engine->engine()->offlineStoragePath() +
QDir::separator() + QLatin1String("Databases");
}
@@ -264,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);
@@ -319,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;
}
@@ -341,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);
@@ -366,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;
}
@@ -394,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]);
@@ -467,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);
@@ -482,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();
}
@@ -517,11 +495,6 @@ static v8::Handle<v8::Value> qmlsqldatabase_open_sync(const v8::Arguments& args)
QDeclarativeSqlDatabaseData::QDeclarativeSqlDatabaseData(QV8Engine *engine)
{
- QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::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);
@@ -559,12 +532,6 @@ 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);
}
@@ -574,16 +541,6 @@ void qt_rem_qmlsqldatabase(QV8Engine * /* engine */, void *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
diff --git a/src/declarative/qml/qdeclarativesqldatabase_p.h b/src/declarative/qml/qdeclarativesqldatabase_p.h
index cf093eefad..a878b38742 100644
--- a/src/declarative/qml/qdeclarativesqldatabase_p.h
+++ b/src/declarative/qml/qdeclarativesqldatabase_p.h
@@ -62,8 +62,6 @@ class QV8Engine;
void *qt_add_qmlsqldatabase(QV8Engine *engine);
void qt_rem_qmlsqldatabase(QV8Engine *engine, void *);
-void qt_qmlsqldatabase_setOfflineStoragePath(QV8Engine *engine, const QString &);
-QString qt_qmlsqldatabase_getOfflineStoragePath(const QV8Engine *);
QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index e7fe2c713d..efb500c5d7 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -58,6 +58,8 @@
#include "qscript_impl_p.h"
#include "qv8domerrors_p.h"
+#include "qv8sqlerrors_p.h"
+
Q_DECLARE_METATYPE(QJSValue)
Q_DECLARE_METATYPE(QList<int>)
@@ -618,6 +620,8 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
qt_add_domexceptions(this);
m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this);
+
+ qt_add_sqlexceptions(this);
m_sqlDatabaseData = qt_add_qmlsqldatabase(this);
{
diff --git a/src/declarative/qml/v8/qv8sqlerrors.cpp b/src/declarative/qml/v8/qv8sqlerrors.cpp
new file mode 100644
index 0000000000..1aa3e771de
--- /dev/null
+++ b/src/declarative/qml/v8/qv8sqlerrors.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv8sqlerrors_p.h"
+#include "qv8engine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+void qt_add_sqlexceptions(QV8Engine *engine)
+{
+ // SQL Exception
+ v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
+
+ v8::Local<v8::Object> sqlexception = v8::Object::New();
+ sqlexception->Set(v8::String::New("UNKNOWN_ERR"), v8::Integer::New(SQLEXCEPTION_UNKNOWN_ERR), attributes);
+ sqlexception->Set(v8::String::New("DATABASE_ERR"), v8::Integer::New(SQLEXCEPTION_DATABASE_ERR), attributes);
+ sqlexception->Set(v8::String::New("VERSION_ERR"), v8::Integer::New(SQLEXCEPTION_VERSION_ERR), attributes);
+ sqlexception->Set(v8::String::New("TOO_LARGE_ERR"), v8::Integer::New(SQLEXCEPTION_TOO_LARGE_ERR), attributes);
+ sqlexception->Set(v8::String::New("QUOTA_ERR"), v8::Integer::New(SQLEXCEPTION_QUOTA_ERR), attributes);
+ sqlexception->Set(v8::String::New("SYNTAX_ERR"), v8::Integer::New(SQLEXCEPTION_SYNTAX_ERR), attributes);
+ sqlexception->Set(v8::String::New("CONSTRAINT_ERR"), v8::Integer::New(SQLEXCEPTION_CONSTRAINT_ERR), attributes);
+ sqlexception->Set(v8::String::New("TIMEOUT_ERR"), v8::Integer::New(SQLEXCEPTION_TIMEOUT_ERR), attributes);
+ engine->global()->Set(v8::String::New("SQLException"), sqlexception);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qv8sqlerrors_p.h b/src/declarative/qml/v8/qv8sqlerrors_p.h
new file mode 100644
index 0000000000..4ca36a8d46
--- /dev/null
+++ b/src/declarative/qml/v8/qv8sqlerrors_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV8SQLERRORS_P_H
+#define QV8SQLERRORS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+#define SQLEXCEPTION_UNKNOWN_ERR 1
+#define SQLEXCEPTION_DATABASE_ERR 2
+#define SQLEXCEPTION_VERSION_ERR 3
+#define SQLEXCEPTION_TOO_LARGE_ERR 4
+#define SQLEXCEPTION_QUOTA_ERR 5
+#define SQLEXCEPTION_SYNTAX_ERR 6
+#define SQLEXCEPTION_CONSTRAINT_ERR 7
+#define SQLEXCEPTION_TIMEOUT_ERR 8
+
+class QV8Engine;
+void qt_add_sqlexceptions(QV8Engine *engine);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QV8SQLERRORS_P_H
diff --git a/src/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri
index 99ecf90983..72416c4dbb 100644
--- a/src/declarative/qml/v8/v8.pri
+++ b/src/declarative/qml/v8/v8.pri
@@ -23,6 +23,7 @@ HEADERS += \
$$PWD/../../../3rdparty/javascriptcore/DateMath.h \
$$PWD/qv8engine_impl_p.h \
$$PWD/qv8domerrors_p.h \
+ $$PWD/qv8sqlerrors_p.h \
$$PWD/qdeclarativebuiltinfunctions_p.h
SOURCES += \
@@ -40,4 +41,5 @@ SOURCES += \
$$PWD/qv8bindings.cpp \
$$PWD/../../../3rdparty/javascriptcore/DateMath.cpp \
$$PWD/qv8domerrors.cpp \
- $$PWD/qdeclarativebuiltinfunctions.cpp
+ $$PWD/qv8sqlerrors.cpp \
+ $$PWD/qdeclarativebuiltinfunctions.cpp \ No newline at end of file
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 18400f86f2..ea8e78d01e 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS += qtquick2 qtquick1 qt47 folderlistmodel particles gestures etcprovider
+SUBDIRS += qtquick2 qtquick1 qt47 folderlistmodel particles gestures etcprovider localstorage
contains(QT_CONFIG, qmltest): SUBDIRS += testlib
-contains(QT_CONFIG, xmlpatterns) : SUBDIRS += xmllistmodel
+contains(QT_CONFIG, xmlpatterns) : SUBDIRS += xmllistmodel \ No newline at end of file
diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro
new file mode 100644
index 0000000000..51a69aac4f
--- /dev/null
+++ b/src/imports/localstorage/localstorage.pro
@@ -0,0 +1,15 @@
+TARGET = qmllocalstorageplugin
+TARGETPATH = QtQuick/LocalStorage
+include(../qimportbase.pri)
+
+QT += sql declarative declarative-private v8-private core-private
+
+SOURCES += plugin.cpp
+
+DESTDIR = $$QT.declarative.imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+INSTALLS += target qmldir \ No newline at end of file
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
new file mode 100644
index 0000000000..dba7340fa3
--- /dev/null
+++ b/src/imports/localstorage/plugin.cpp
@@ -0,0 +1,668 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QStringList>
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+#include <private/qdeclarativeengine_p.h>
+#include <QDebug>
+#include <private/qv8engine_p.h>
+#include <QtSql/qsqldatabase.h>
+#include <QtSql/qsqlquery.h>
+#include <QtSql/qsqlerror.h>
+#include <QtSql/qsqlrecord.h>
+#include <QtSql/qsqlfield.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qsettings.h>
+#include <QtCore/qdir.h>
+#include <private/qv8sqlerrors_p.h>
+
+
+#define V8THROW_SQL(error, desc) \
+{ \
+ v8::Local<v8::Value> v = v8::Exception::Error(engine->toString(desc)); \
+ v->ToObject()->Set(v8::String::New("code"), v8::Integer::New(error)); \
+ v8::ThrowException(v); \
+ return v8::Handle<v8::Value>(); \
+}
+
+#define V8THROW_SQL_VOID(error, desc) \
+{ \
+ v8::Local<v8::Value> v = v8::Exception::Error(engine->toString(desc)); \
+ v->ToObject()->Set(v8::String::New("code"), v8::Integer::New(error)); \
+ v8::ThrowException(v); \
+ return; \
+}
+
+#define V8THROW_REFERENCE(string) { \
+ v8::ThrowException(v8::Exception::ReferenceError(v8::String::New(string))); \
+ return v8::Handle<v8::Value>(); \
+}
+
+#define V8THROW_REFERENCE_VOID(string) { \
+ v8::ThrowException(v8::Exception::ReferenceError(v8::String::New(string))); \
+ return; \
+}
+
+class QDeclarativeSqlDatabaseData : public QV8Engine::Deletable
+{
+public:
+ QDeclarativeSqlDatabaseData(QV8Engine *engine);
+ ~QDeclarativeSqlDatabaseData();
+
+ v8::Persistent<v8::Function> constructor;
+ v8::Persistent<v8::Function> queryConstructor;
+ v8::Persistent<v8::Function> rowsConstructor;
+};
+
+V8_DEFINE_EXTENSION(QDeclarativeSqlDatabaseData, databaseData)
+
+class QV8SqlDatabaseResource : public QV8ObjectResource
+{
+ V8_RESOURCE_TYPE(SQLDatabaseType)
+
+public:
+ enum Type { Database, Query, Rows };
+ QV8SqlDatabaseResource(QV8Engine *e)
+ : QV8ObjectResource(e), type(Database), inTransaction(false), readonly(false), forwardOnly(false) {}
+
+ ~QV8SqlDatabaseResource() {
+ }
+
+ Type type;
+ QSqlDatabase database;
+
+ QString version; // type == Database
+
+ bool inTransaction; // type == Query
+ bool readonly; // type == Query
+
+ QSqlQuery query; // type == Rows
+ bool forwardOnly; // type == Rows
+};
+
+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)
+ V8THROW_REFERENCE("Not a SQLDatabase object");
+
+ return r->engine->toString(r->version);
+}
+
+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)
+ V8THROW_REFERENCE("Not a SQLDatabase::Rows object");
+
+ int s = r->query.size();
+ if (s < 0) {
+ // Inefficient
+ if (r->query.last()) {
+ s = r->query.at() + 1;
+ } else {
+ s = 0;
+ }
+ }
+ return v8::Integer::New(s);
+}
+
+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());
+ if (!r || r->type != QV8SqlDatabaseResource::Rows)
+ V8THROW_REFERENCE("Not a SQLDatabase::Rows object");
+ return v8::Boolean::New(r->query.isForwardOnly());
+}
+
+static void qmlsqldatabase_rows_setForwardOnly(v8::Local<v8::String> /* property */,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info)
+{
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(info.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Rows)
+ V8THROW_REFERENCE_VOID("Not a SQLDatabase::Rows object");
+
+ r->query.setForwardOnly(value->BooleanValue());
+}
+
+QDeclarativeSqlDatabaseData::~QDeclarativeSqlDatabaseData()
+{
+ qPersistentDispose(constructor);
+ qPersistentDispose(queryConstructor);
+ qPersistentDispose(rowsConstructor);
+}
+
+static QString qmlsqldatabase_databasesPath(QV8Engine *engine)
+{
+ return engine->engine()->offlineStoragePath() +
+ QDir::separator() + QLatin1String("Databases");
+}
+
+static void qmlsqldatabase_initDatabasesPath(QV8Engine *engine)
+{
+ QDir().mkpath(qmlsqldatabase_databasesPath(engine));
+}
+
+static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Engine *engine)
+{
+ return qmlsqldatabase_databasesPath(engine) + QDir::separator() + connectionName;
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_rows_index(QV8SqlDatabaseResource *r, uint32_t 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) {
+ 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 {
+ return v8::Undefined();
+ }
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_rows_index(uint32_t index, const v8::AccessorInfo& info)
+{
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(info.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Rows)
+ V8THROW_REFERENCE("Not a SQLDatabase::Rows object");
+
+ return qmlsqldatabase_rows_index(r, index);
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_rows_item(const v8::Arguments& args)
+{
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(args.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Rows)
+ V8THROW_REFERENCE("Not a SQLDatabase::Rows object");
+
+ return qmlsqldatabase_rows_index(r, args.Length()?args[0]->Uint32Value():0);
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_executeSql(const v8::Arguments& args)
+{
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(args.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Query)
+ V8THROW_REFERENCE("Not a SQLDatabase::Query object");
+
+ QV8Engine *engine = r->engine;
+
+ if (!r->inTransaction)
+ 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(SQLEXCEPTION_SYNTAX_ERR, QDeclarativeEngine::tr("Read-only Transaction"));
+ }
+
+ QSqlQuery query(db);
+ bool err = false;
+
+ v8::Handle<v8::Value> result = v8::Undefined();
+
+ if (query.prepare(sql)) {
+ if (args.Length() > 1) {
+ v8::Local<v8::Value> values = args[1];
+ if (values->IsArray()) {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(values);
+ uint32_t size = array->Length();
+ for (uint32_t ii = 0; ii < size; ++ii)
+ query.bindValue(ii, engine->toVariant(array->Get(ii), -1));
+ } else if (values->IsObject() && !values->ToObject()->GetExternalResource()) {
+ v8::Local<v8::Object> object = values->ToObject();
+ v8::Local<v8::Array> names = object->GetPropertyNames();
+ uint32_t size = names->Length();
+ for (uint32_t ii = 0; ii < size; ++ii)
+ query.bindValue(engine->toString(names->Get(ii)),
+ engine->toVariant(object->Get(names->Get(ii)), -1));
+ } else {
+ query.bindValue(0, engine->toVariant(values, -1));
+ }
+ }
+ if (query.exec()) {
+ v8::Handle<v8::Object> rows = databaseData(engine)->rowsConstructor->NewInstance();
+ QV8SqlDatabaseResource *r = new QV8SqlDatabaseResource(engine);
+ r->type = QV8SqlDatabaseResource::Rows;
+ r->database = db;
+ r->query = query;
+ rows->SetExternalResource(r);
+
+ v8::Local<v8::Object> resultObject = v8::Object::New();
+ result = resultObject;
+ // XXX optimize
+ resultObject->Set(v8::String::New("rowsAffected"), v8::Integer::New(query.numRowsAffected()));
+ resultObject->Set(v8::String::New("insertId"), engine->toString(query.lastInsertId().toString()));
+ resultObject->Set(v8::String::New("rows"), rows);
+ } else {
+ err = true;
+ }
+ } else {
+ err = true;
+ }
+ if (err)
+ V8THROW_SQL(SQLEXCEPTION_DATABASE_ERR,query.lastError().text());
+
+ return result;
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_changeVersion(const v8::Arguments& args)
+{
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(args.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Database)
+ V8THROW_REFERENCE("Not a SQLDatabase object");
+
+ QV8Engine *engine = r->engine;
+
+ QSqlDatabase db = r->database;
+ QString from_version = engine->toString(args[0]);
+ QString to_version = engine->toString(args[1]);
+ v8::Handle<v8::Value> callback = args[2];
+
+ if (from_version != 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 = databaseData(engine)->queryConstructor->NewInstance();
+ QV8SqlDatabaseResource *r2 = new QV8SqlDatabaseResource(engine);
+ r2->type = QV8SqlDatabaseResource::Query;
+ r2->database = db;
+ r2->version = r->version;
+ r2->inTransaction = true;
+ instance->SetExternalResource(r2);
+
+ bool ok = true;
+ if (callback->IsFunction()) {
+ ok = false;
+ db.transaction();
+
+ v8::TryCatch tc;
+ v8::Handle<v8::Value> callbackArgs[] = { instance };
+ v8::Handle<v8::Function>::Cast(callback)->Call(engine->global(), 1, callbackArgs);
+
+ if (tc.HasCaught()) {
+ db.rollback();
+ tc.ReThrow();
+ return v8::Handle<v8::Value>();
+ } else if (!db.commit()) {
+ db.rollback();
+ V8THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QDeclarativeEngine::tr("SQL transaction failed"));
+ } else {
+ ok = true;
+ }
+ }
+
+ r2->inTransaction = false;
+
+ if (ok) {
+ r2->version = to_version;
+#ifndef QT_NO_SETTINGS
+ QSettings ini(qmlsqldatabase_databaseFile(db.connectionName(),engine) + QLatin1String(".ini"), QSettings::IniFormat);
+ ini.setValue(QLatin1String("Version"), to_version);
+#endif
+ }
+
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_transaction_shared(const v8::Arguments& args, bool readOnly)
+{
+ QV8SqlDatabaseResource *r = v8_resource_cast<QV8SqlDatabaseResource>(args.This());
+ if (!r || r->type != QV8SqlDatabaseResource::Database)
+ V8THROW_REFERENCE("Not a SQLDatabase object");
+
+ QV8Engine *engine = r->engine;
+
+ if (args.Length() == 0 || !args[0]->IsFunction())
+ 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]);
+
+ v8::Local<v8::Object> instance = databaseData(engine)->queryConstructor->NewInstance();
+ QV8SqlDatabaseResource *q = new QV8SqlDatabaseResource(engine);
+ q->type = QV8SqlDatabaseResource::Query;
+ q->database = db;
+ q->readonly = readOnly;
+ q->inTransaction = true;
+ instance->SetExternalResource(q);
+
+ db.transaction();
+ v8::TryCatch tc;
+ v8::Handle<v8::Value> callbackArgs[] = { instance };
+ callback->Call(engine->global(), 1, callbackArgs);
+
+ q->inTransaction = false;
+
+ if (tc.HasCaught()) {
+ db.rollback();
+ tc.ReThrow();
+ return v8::Handle<v8::Value>();
+ } else if (!db.commit()) {
+ db.rollback();
+ }
+
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_transaction(const v8::Arguments& args)
+{
+ return qmlsqldatabase_transaction_shared(args, false);
+}
+
+static v8::Handle<v8::Value> qmlsqldatabase_read_transaction(const v8::Arguments& args)
+{
+ return qmlsqldatabase_transaction_shared(args, true);
+}
+
+QDeclarativeSqlDatabaseData::QDeclarativeSqlDatabaseData(QV8Engine *engine)
+{
+ {
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->PrototypeTemplate()->Set(v8::String::New("transaction"),
+ V8FUNCTION(qmlsqldatabase_transaction, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("readTransaction"),
+ V8FUNCTION(qmlsqldatabase_read_transaction, engine));
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("version"), qmlsqldatabase_version);
+ ft->PrototypeTemplate()->Set(v8::String::New("changeVersion"),
+ V8FUNCTION(qmlsqldatabase_changeVersion, engine));
+ constructor = qPersistentNew<v8::Function>(ft->GetFunction());
+ }
+
+ {
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->PrototypeTemplate()->Set(v8::String::New("executeSql"),
+ V8FUNCTION(qmlsqldatabase_executeSql, engine));
+ queryConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
+ }
+ {
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->PrototypeTemplate()->Set(v8::String::New("item"), V8FUNCTION(qmlsqldatabase_rows_item, engine));
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("length"), qmlsqldatabase_rows_length);
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("forwardOnly"), qmlsqldatabase_rows_forwardOnly,
+ qmlsqldatabase_rows_setForwardOnly);
+ ft->InstanceTemplate()->SetIndexedPropertyHandler(qmlsqldatabase_rows_index);
+ rowsConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
+ }
+}
+
+/*
+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
+through the data.
+*/
+
+
+/*!
+ \qmlclass LocalStorage QQuickLocalStorage
+ \inqmlmodule QtQuick.LocalStorage 2
+ \since QtQuick 2.0
+
+ \brief The LocalStorage module API provides the ability to access local offline storage in an SQL database.
+
+These databases are user-specific and QML-specific, but accessible to all QML applications.
+They are stored in the \c Databases subdirectory
+of QDeclarativeEngine::offlineStoragePath(), currently as SQLite databases.
+
+Database connections are automatically closed during Javascript garbage collection.
+
+The API can be used from JavaScript functions in your QML:
+
+\snippet declarative/sqllocalstorage/hello.qml 0
+
+The API conforms to the Synchronous API of the HTML5 Web Database API,
+\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
+
+The \l{declarative/sqllocalstorage}{SQL Local Storage example} demonstrates the basics of
+using the Offline Storage API.
+
+\section3 Open or create a databaseData
+\code
+import QtQuick.LocalStorage 2.0 as LS
+
+db = LS.openDatabaseSync(identifier, version, description, estimated_size, callback(db))
+\endcode
+The above code returns the database identified by \i identifier. If the database does not already exist, it
+is created, and the function \i callback is called with the database as a parameter. \i description
+and \i estimated_size are written to the INI file (described below), but are otherwise currently
+unused.
+
+May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR.
+
+When a database is first created, an INI file is also created specifying its characteristics:
+
+\table
+\header \o \bold {Key} \o \bold {Value}
+\row \o Name \o The name of the database passed to \c openDatabase()
+\row \o Version \o The version of the database passed to \c openDatabase()
+\row \o Description \o The description of the database passed to \c openDatabase()
+\row \o EstimatedSize \o The estimated size (in bytes) of the database passed to \c openDatabase()
+\row \o Driver \o Currently "QSQLITE"
+\endtable
+
+This data can be used by application tools.
+
+\section3 db.changeVersion(from, to, callback(tx))
+
+This method allows you to perform a \i{Scheme Upgrade}.
+
+If the current version of \i db is not \i from, then an exception is thrown.
+
+Otherwise, a database transaction is created and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to upgrade the database.
+
+May throw exception with code property SQLException.DATABASE_ERR or SQLException.UNKNOWN_ERR.
+
+\section3 db.transaction(callback(tx))
+
+This method creates a read/write transaction and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to read and modify the database.
+
+If the callback throws exceptions, the transaction is rolled back.
+
+\section3 db.readTransaction(callback(tx))
+
+This method creates a read-only transaction and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to read the database (with SELECT statements).
+
+\section3 results = tx.executeSql(statement, values)
+
+This method executes a SQL \i statement, binding the list of \i values to SQL positional parameters ("?").
+
+It returns a results object, with the following properties:
+
+\table
+\header \o \bold {Type} \o \bold {Property} \o \bold {Value} \o \bold {Applicability}
+\row \o int \o rows.length \o The number of rows in the result \o SELECT
+\row \o var \o rows.item(i) \o Function that returns row \i i of the result \o SELECT
+\row \o int \o rowsAffected \o The number of rows affected by a modification \o UPDATE, DELETE
+\row \o string \o insertId \o The id of the row inserted \o INSERT
+\endtable
+
+May throw exception with code property SQLException.DATABASE_ERR, SQLException.SYNTAX_ERR, or SQLException.UNKNOWN_ERR.
+ */
+class QQuickLocalStorage : public QObject
+{
+ Q_OBJECT
+public:
+ QQuickLocalStorage(QObject *parent=0) : QObject(parent)
+ {
+ }
+ ~QQuickLocalStorage() {
+ }
+
+ Q_INVOKABLE void openDatabaseSync(QDeclarativeV8Function* args);
+};
+
+/*!
+ * \qmlmethod object LocalStorage::openDatabaseSync(string name, string version, string description, int estimated_size, jsobject callback(db))
+ * \brief Open or create a local storage sql database by given parameters.
+ *
+ * \c name is the database name
+ * \c version is the database version
+ * \c description is the database display name
+ * \c estimated_size is the database's estimated size, in bytes
+ * \c callback is an optional parameter, which is invoked if the database has not yet been created.
+ * \return the database object
+ */
+void QQuickLocalStorage::openDatabaseSync(QDeclarativeV8Function *args)
+{
+#ifndef QT_NO_SETTINGS
+ QV8Engine *engine = args->engine();
+ qmlsqldatabase_initDatabasesPath(engine);
+
+ QSqlDatabase database;
+
+ QString dbname = engine->toString((*args)[0]);
+ QString dbversion = engine->toString((*args)[1]);
+ QString dbdescription = engine->toString((*args)[2]);
+ int dbestimatedsize = (*args)[3]->Int32Value();
+ v8::Handle<v8::Value> dbcreationCallback = (*args)[4];
+
+ QCryptographicHash md5(QCryptographicHash::Md5);
+ md5.addData(dbname.toUtf8());
+ QString dbid(QLatin1String(md5.result().toHex()));
+
+ QString basename = qmlsqldatabase_databaseFile(dbid, engine);
+ bool created = false;
+ QString version = dbversion;
+
+ {
+ QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
+
+ if (QSqlDatabase::connectionNames().contains(dbid)) {
+ database = QSqlDatabase::database(dbid);
+ version = ini.value(QLatin1String("Version")).toString();
+ if (version != dbversion && !dbversion.isEmpty() && !version.isEmpty())
+ V8THROW_SQL_VOID(SQLEXCEPTION_VERSION_ERR, QDeclarativeEngine::tr("SQL: database version mismatch"));
+ } else {
+ created = !QFile::exists(basename+QLatin1String(".sqlite"));
+ database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid);
+ if (created) {
+ ini.setValue(QLatin1String("Name"), dbname);
+ if (dbcreationCallback->IsFunction())
+ version = QString();
+ ini.setValue(QLatin1String("Version"), version);
+ ini.setValue(QLatin1String("Description"), dbdescription);
+ ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize);
+ ini.setValue(QLatin1String("Driver"), QLatin1String("QSQLITE"));
+ } else {
+ if (!dbversion.isEmpty() && ini.value(QLatin1String("Version")) != dbversion) {
+ // Incompatible
+ V8THROW_SQL_VOID(SQLEXCEPTION_VERSION_ERR,QDeclarativeEngine::tr("SQL: database version mismatch"));
+ }
+ version = ini.value(QLatin1String("Version")).toString();
+ }
+ database.setDatabaseName(basename+QLatin1String(".sqlite"));
+ }
+ if (!database.isOpen())
+ database.open();
+ }
+
+ v8::Local<v8::Object> instance = databaseData(engine)->constructor->NewInstance();
+
+ QV8SqlDatabaseResource *r = new QV8SqlDatabaseResource(engine);
+ r->database = database;
+ r->version = version;
+ instance->SetExternalResource(r);
+
+ if (created && dbcreationCallback->IsFunction()) {
+ v8::TryCatch tc;
+ v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(dbcreationCallback);
+ v8::Handle<v8::Value> args[] = { instance };
+ callback->Call(engine->global(), 1, args);
+ if (tc.HasCaught()) {
+ tc.ReThrow();
+ return;
+ }
+ }
+
+ args->returnValue(instance);
+#endif // QT_NO_SETTINGS
+}
+
+static QObject *module_api_factory(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+ QQuickLocalStorage *api = new QQuickLocalStorage();
+
+ return api;
+}
+
+class QDeclarativeLocalStoragePlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ QDeclarativeLocalStoragePlugin()
+ {
+ }
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage");
+ qmlRegisterModuleApi(uri, 2, 0, module_api_factory);
+ }
+};
+
+#include "plugin.moc"
+
+Q_EXPORT_PLUGIN2(plugin, QDeclarativeLocalStoragePlugin);
diff --git a/src/imports/localstorage/qmldir b/src/imports/localstorage/qmldir
new file mode 100644
index 0000000000..33288a1afa
--- /dev/null
+++ b/src/imports/localstorage/qmldir
@@ -0,0 +1 @@
+plugin qmllocalstorageplugin \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/changeversion.js b/tests/auto/declarative/qdeclarativesqldatabase/data/changeversion.js
index 680d7a652f..178ff7c4af 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/changeversion.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/changeversion.js
@@ -1,7 +1,9 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000,
+ var db = Sql.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000,
function(db) {
db.changeVersion("","1.0")
db.transaction(function(tx){
@@ -15,7 +17,7 @@ function test() {
});
- db = openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000);
+ db = Sql.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000);
if (db.version == "1.0")
db.changeVersion("1.0","2.0",function(tx)
@@ -35,7 +37,7 @@ function test() {
else
return "db.version should be 1.0, but is " + db.version;
- var db = openDatabaseSync("QmlTestDB-changeversion", "2.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-changeversion", "2.0", "Test database from Qt autotests", 1000000);
db.transaction(function(tx){
var rs = tx.executeSql('SELECT * FROM Utterance');
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/creation-a.js b/tests/auto/declarative/qdeclarativesqldatabase/data/creation-a.js
index bd7d5c5022..25cba05451 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/creation-a.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/creation-a.js
@@ -1,7 +1,9 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
+ var db = Sql.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
function(db) {
db.transaction(function(tx){
tx.executeSql('CREATE TABLE Greeting(salutation TEXT, salutee TEXT)');
@@ -9,7 +11,7 @@ function test() {
})
});
- var db = openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
+ var db = Sql.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
function(db) {
r = "FAILED: should have already been created";
});
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/creation.js b/tests/auto/declarative/qdeclarativesqldatabase/data/creation.js
index 317b4c1564..64eb4c7b92 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/creation.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/creation.js
@@ -1,7 +1,8 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-creation", "1.0", "Test database from Qt autotests", 1000000);
-
+ var db = Sql.openDatabaseSync("QmlTestDB-creation", "1.0", "Test database from Qt autotests", 1000000);
db.transaction(
function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)');
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/error-a.js b/tests/auto/declarative/qdeclarativesqldatabase/data/error-a.js
index 10a23f68f7..d7e9b4fdff 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/error-a.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/error-a.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-error-a", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-error-a", "1.0", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
try {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/error-b.js b/tests/auto/declarative/qdeclarativesqldatabase/data/error-b.js
index 4dd0ecf2af..17e34c989e 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/error-b.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/error-b.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-error-b", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-error-b", "1.0", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
db.transaction(
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/error-creation.js b/tests/auto/declarative/qdeclarativesqldatabase/data/error-creation.js
index 0ab2a3544f..d66977d1e2 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/error-creation.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/error-creation.js
@@ -1,7 +1,9 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
try {
- var db = openDatabaseSync("QmlTestDB-creation", "2.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-creation", "2.0", "Test database from Qt autotests", 1000000);
} catch (err) {
if (err.code != SQLException.VERSION_ERR)
r = "WRONG ERROR CODE="+err.code;
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/error-notransaction.js b/tests/auto/declarative/qdeclarativesqldatabase/data/error-notransaction.js
index b9cc6475a6..2cce3f613c 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/error-notransaction.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/error-notransaction.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
try {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/error-outsidetransaction.js b/tests/auto/declarative/qdeclarativesqldatabase/data/error-outsidetransaction.js
index a7af3bddbc..7af7c1c6a2 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/error-outsidetransaction.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/error-outsidetransaction.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
var v;
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/iteration-forwardonly.js b/tests/auto/declarative/qdeclarativesqldatabase/data/iteration-forwardonly.js
index 45947c08a7..b3df1be113 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/iteration-forwardonly.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/iteration-forwardonly.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-iteration-forwardonly", "", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-iteration-forwardonly", "", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
db.transaction(
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/iteration.js b/tests/auto/declarative/qdeclarativesqldatabase/data/iteration.js
index c34cbbb391..8d96dc2154 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/iteration.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/iteration.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-iteration", "", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-iteration", "", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
db.transaction(
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/readonly-error.js b/tests/auto/declarative/qdeclarativesqldatabase/data/readonly-error.js
index 69ec67fb1a..39eb398004 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/readonly-error.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/readonly-error.js
@@ -1,6 +1,8 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-readonly-error", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-readonly-error", "1.0", "Test database from Qt autotests", 1000000);
db.transaction(
function(tx) {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/readonly.js b/tests/auto/declarative/qdeclarativesqldatabase/data/readonly.js
index 5ee862c083..985c9ecab5 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/readonly.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/readonly.js
@@ -1,6 +1,8 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-readonly", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-readonly", "1.0", "Test database from Qt autotests", 1000000);
db.transaction(
function(tx) {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/reopen1.js b/tests/auto/declarative/qdeclarativesqldatabase/data/reopen1.js
index c1a8157b10..2171fb028e 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/reopen1.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/reopen1.js
@@ -1,6 +1,8 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
db.transaction(
function(tx) {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/reopen2.js b/tests/auto/declarative/qdeclarativesqldatabase/data/reopen2.js
index 4f7248f094..12c6135145 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/reopen2.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/reopen2.js
@@ -1,6 +1,8 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
var r="transaction_not_finished";
- var db = openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
db.transaction(
function(tx) {
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/selection-bindnames.js b/tests/auto/declarative/qdeclarativesqldatabase/data/selection-bindnames.js
index 9786821f47..9333ccfacb 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/selection-bindnames.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/selection-bindnames.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-bindnames", "", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-bindnames", "", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
db.transaction(
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/data/selection.js b/tests/auto/declarative/qdeclarativesqldatabase/data/selection.js
index 4ae40b105f..18d4dce80f 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/data/selection.js
+++ b/tests/auto/declarative/qdeclarativesqldatabase/data/selection.js
@@ -1,5 +1,7 @@
+.import QtQuick.LocalStorage 2.0 as Sql
+
function test() {
- var db = openDatabaseSync("QmlTestDB-selection", "", "Test database from Qt autotests", 1000000);
+ var db = Sql.openDatabaseSync("QmlTestDB-selection", "", "Test database from Qt autotests", 1000000);
var r="transaction_not_finished";
db.transaction(