summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-09-16 08:21:12 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-09-16 08:21:12 (GMT)
commit5d35dbc3552f722cf4de220d8737e8201e4f61e5 (patch)
tree382aa85b2b63c109b0307f327e6cf4befb7a40d9 /src/declarative/qml
parent4937e80baf3cce7444a007f5b3fa4979ea93f3fc (diff)
downloadQt-5d35dbc3552f722cf4de220d8737e8201e4f61e5.zip
Qt-5d35dbc3552f722cf4de220d8737e8201e4f61e5.tar.gz
Qt-5d35dbc3552f722cf4de220d8737e8201e4f61e5.tar.bz2
Better SQL database performance / memory usage.
Rows accessible incrementally. Rows.forwardOnly for optimization.
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qmlengine.cpp4
-rw-r--r--src/declarative/qml/qmlengine_p.h2
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp100
3 files changed, 93 insertions, 13 deletions
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index efe1a89..c0dd1a8 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -111,7 +111,7 @@ QScriptValue desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
: rootContext(0), currentExpression(0),
isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0),
- nodeListClass(0), namedNodeMapClass(0), scriptEngine(this), rootComponent(0),
+ nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), scriptEngine(this), rootComponent(0),
networkAccessManager(0), typeManager(e), uniqueId(1)
{
QScriptValue qtObject =
@@ -156,6 +156,8 @@ QmlEnginePrivate::~QmlEnginePrivate()
nodeListClass = 0;
delete namedNodeMapClass;
namedNodeMapClass = 0;
+ delete sqlQueryClass;
+ sqlQueryClass = 0;
for(int ii = 0; ii < bindValues.count(); ++ii)
clear(bindValues[ii]);
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 15ab40d..0eeae0c 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -154,6 +154,8 @@ public:
// Used by DOM Core 3 API
QScriptClass *nodeListClass;
QScriptClass *namedNodeMapClass;
+ // Used by SQL database API
+ QScriptClass *sqlQueryClass;
struct QmlScriptEngine : public QScriptEngine
{
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
index 90d6e3e..4a7c3a3 100644
--- a/src/declarative/qml/qmlsqldatabase.cpp
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -65,6 +65,84 @@
#endif
Q_DECLARE_METATYPE(QSqlDatabase)
+Q_DECLARE_METATYPE(QSqlQuery)
+
+class QmlSqlQueryScriptClass: public QScriptClass {
+public:
+ QmlSqlQueryScriptClass(QScriptEngine *engine) : QScriptClass(engine)
+ {
+ str_length = engine->toStringHandle(QLatin1String("length"));
+ str_forwardOnly = engine->toStringHandle(QLatin1String("forwardOnly")); // not in HTML5 (optimization)
+ }
+
+ QueryFlags queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags, uint *id)
+ {
+ if (flags & HandlesReadAccess) {
+ if (name == str_length) {
+ return HandlesReadAccess;
+ } else if (name == str_forwardOnly) {
+ return flags;
+ } else {
+ bool ok;
+ qint32 pos = name.toString().toInt(&ok);
+ if (pos < 0 || !ok)
+ return 0;
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ *id = pos;
+ if (*id < (uint)query.size())
+ return HandlesReadAccess;
+ }
+ }
+ if (flags & HandlesWriteAccess)
+ if (name == str_forwardOnly)
+ return flags;
+ return 0;
+ }
+
+ QScriptValue property(const QScriptValue &object,
+ const QScriptString &name, uint id)
+ {
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ if (name == str_length) {
+ int s = query.size();
+ if (s<0) {
+ // Inefficient.
+ query.last();
+ return query.at()+1;
+ } else {
+ return s;
+ }
+ } else if (name == str_forwardOnly) {
+ return query.isForwardOnly();
+ } else {
+ if (query.at() == id || query.seek(id)) { // Qt 4.6 doesn't optimize at()==id
+ QSqlRecord r = query.record();
+ QScriptValue row = engine()->newArray(r.count());
+ for (int j=0; j<r.count(); ++j) {
+ // XXX only strings
+ row.setProperty(j, QScriptValue(engine(),r.value(j).toString()));
+ }
+ return row;
+ }
+ }
+ return engine()->undefinedValue();
+ }
+
+ void setProperty(QScriptValue &object,
+ const QScriptString &name, uint, const QScriptValue & value)
+ {
+ if (name == str_forwardOnly) {
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ query.setForwardOnly(value.toBool());
+ }
+ }
+
+private:
+ QScriptString str_length;
+ QScriptString str_forwardOnly;
+};
static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine)
{
@@ -85,18 +163,14 @@ static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEn
query.bindValue(0,values.toVariant());
}
if (query.exec()) {
- QScriptValue rows = engine->newArray();
- int i=0;
- for (; query.next(); ++i) {
- QSqlRecord r = query.record();
- QScriptValue row = engine->newArray(r.count());
- for (int j=0; j<r.count(); ++j) {
- row.setProperty(j, QScriptValue(engine,r.value(j).toString()));
- }
- rows.setProperty(i, row);
- }
QScriptValue rs = engine->newObject();
- rs.setProperty(QLatin1String("rows"), rows);
+ if (!QmlEnginePrivate::get(engine)->sqlQueryClass)
+ QmlEnginePrivate::get(engine)->sqlQueryClass= new QmlSqlQueryScriptClass(engine);
+ QScriptValue rows = engine->newObject(QmlEnginePrivate::get(engine)->sqlQueryClass);
+ rows.setData(engine->newVariant(qVariantFromValue(query)));
+ rs.setProperty(QLatin1String("rows"),rows);
+ rs.setProperty(QLatin1String("rowsAffected"),query.numRowsAffected());
+ rs.setProperty(QLatin1String("insertId"),query.lastInsertId().toString()); // XXX only string
cb.call(QScriptValue(), QScriptValueList() << context->thisObject() << rs);
} else {
err = true;
@@ -142,7 +216,7 @@ static QScriptValue qmlsqldatabase_transaction(QScriptContext *context, QScriptE
return engine->undefinedValue();
}
-// XXX Something like this belongs in Qt.
+// XXX Something like this should be exported by Qt.
static QString userLocalDataPath(const QString& app)
{
QString result;
@@ -196,6 +270,8 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *
md5.addData(dbversion.utf8());
QString dbid(QLatin1String(md5.result().toHex()));
+ // Uses SQLLITE (like HTML5), but any could be used.
+
if (QSqlDatabase::connectionNames().contains(dbid)) {
database = QSqlDatabase::database(dbid);
} else {