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, QQmlEngine::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,QQmlEngine::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 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(); }
/* 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; }
void QQuickLocalStorage::openDatabaseSync(QQmlV8Function *args) { #ifndef QT_NO_SETTINGS QV8Engine *engine = args->engine(); if (engine->engine()->offlineStoragePath().isEmpty()) V8THROW_SQL_VOID(SQLEXCEPTION_DATABASE_ERR, QQmlEngine::tr("SQL: can't create database, offline storage is disabled.")); 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, QQmlEngine::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,QQmlEngine::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 }