/*
    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;
}
Example #2
0
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
}