static QScriptValue qmlsqldatabase_change_version(QScriptContext *context, QScriptEngine *engine) { if (context->argumentCount() < 2) return engine->undefinedValue(); QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject()); QString from_version = context->argument(0).toString(); QString to_version = context->argument(1).toString(); QScriptValue callback = context->argument(2); QScriptValue instance = engine->newObject(); instance.setProperty(QLatin1String("executeSql"), engine->newFunction(qmlsqldatabase_executeSql,1)); QScriptValue tx = engine->newVariant(instance,QVariant::fromValue(db)); QString foundvers = context->thisObject().property(QLatin1String("version")).toString(); if (from_version!=foundvers) { THROW_SQL(VERSION_ERR,QDeclarativeEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(foundvers)); return engine->undefinedValue(); } bool ok = true; if (callback.isFunction()) { ok = false; db.transaction(); callback.call(QScriptValue(), QScriptValueList() << tx); if (engine->hasUncaughtException()) { db.rollback(); } else { if (!db.commit()) { db.rollback(); THROW_SQL(UNKNOWN_ERR,QDeclarativeEngine::tr("SQL transaction failed")); } else { ok = true; } } } if (ok) { context->thisObject().setProperty(QLatin1String("version"), to_version, QScriptValue::ReadOnly); #ifndef QT_NO_SETTINGS QSettings ini(qmlsqldatabase_databaseFile(db.connectionName(),engine) + QLatin1String(".ini"), QSettings::IniFormat); ini.setValue(QLatin1String("Version"), to_version); #endif } return engine->undefinedValue(); }
static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine) { QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject()); QString sql = context->argument(0).toString(); QSqlQuery query(db); bool err = false; QScriptValue result; if (query.prepare(sql)) { if (context->argumentCount() > 1) { QScriptValue values = context->argument(1); if (values.isObject()) { if (values.isArray()) { int size = values.property(QLatin1String("length")).toInt32(); for (int i = 0; i < size; ++i) query.bindValue(i, values.property(i).toVariant()); } else { for (QScriptValueIterator it(values); it.hasNext();) { it.next(); query.bindValue(it.name(),it.value().toVariant()); } } } else { query.bindValue(0,values.toVariant()); } } if (query.exec()) { result = engine->newObject(); QDeclarativeScriptEngine *qmlengine = static_cast<QDeclarativeScriptEngine*>(engine); if (!qmlengine->sqlQueryClass) qmlengine->sqlQueryClass = new QDeclarativeSqlQueryScriptClass(engine); QScriptValue rows = engine->newObject(qmlengine->sqlQueryClass); rows.setData(engine->newVariant(qVariantFromValue(query))); rows.setProperty(QLatin1String("item"), engine->newFunction(qmlsqldatabase_item,1), QScriptValue::SkipInEnumeration); result.setProperty(QLatin1String("rows"),rows); result.setProperty(QLatin1String("rowsAffected"),query.numRowsAffected()); result.setProperty(QLatin1String("insertId"),query.lastInsertId().toString()); } else { err = true; } } else { err = true; } if (err) THROW_SQL(DATABASE_ERR,query.lastError().text()); return result; }
static QScriptValue qmlsqldatabase_transaction_shared(QScriptContext *context, QScriptEngine *engine, bool readOnly) { QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject()); QScriptValue callback = context->argument(0); if (!callback.isFunction()) THROW_SQL(UNKNOWN_ERR,QDeclarativeEngine::tr("transaction: missing callback")); QScriptValue instance = engine->newObject(); instance.setProperty(QLatin1String("executeSql"), engine->newFunction(readOnly ? qmlsqldatabase_executeSql_readonly : qmlsqldatabase_executeSql,1)); QScriptValue tx = engine->newVariant(instance,qVariantFromValue(db)); db.transaction(); callback.call(QScriptValue(), QScriptValueList() << tx); instance.setProperty(QLatin1String("executeSql"), engine->newFunction(qmlsqldatabase_executeSql_outsidetransaction)); if (engine->hasUncaughtException()) { db.rollback(); } else { if (!db.commit()) db.rollback(); } return engine->undefinedValue(); }
/* Currently documented in doc/src/declarative/globalobject.qdoc */ static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEngine *engine) { qmlsqldatabase_initDatabasesPath(engine); QSqlDatabase database; QString dbname = context->argument(0).toString(); QString dbversion = context->argument(1).toString(); QString dbdescription = context->argument(2).toString(); int dbestimatedsize = context->argument(3).toNumber(); QScriptValue dbcreationCallback = context->argument(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()) THROW_SQL(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 THROW_SQL(VERSION_ERR,QDeclarativeEngine::tr("SQL: database version mismatch")); } version = ini.value(QLatin1String("Version")).toString(); } database.setDatabaseName(basename+QLatin1String(".sqlite")); } if (!database.isOpen()) database.open(); } QScriptValue instance = engine->newObject(); instance.setProperty(QLatin1String("transaction"), engine->newFunction(qmlsqldatabase_transaction,1)); instance.setProperty(QLatin1String("readTransaction"), engine->newFunction(qmlsqldatabase_read_transaction,1)); instance.setProperty(QLatin1String("version"), version, QScriptValue::ReadOnly); instance.setProperty(QLatin1String("changeVersion"), engine->newFunction(qmlsqldatabase_change_version,3)); QScriptValue result = engine->newVariant(instance,qVariantFromValue(database)); if (created && dbcreationCallback.isFunction()) { dbcreationCallback.call(QScriptValue(), QScriptValueList() << result); } return result; }
static QScriptValue qmlsqldatabase_executeSql_outsidetransaction(QScriptContext *context, QScriptEngine * /*engine*/) { THROW_SQL(DATABASE_ERR,QDeclarativeEngine::tr("executeSql called outside transaction()")); }