diff options
Diffstat (limited to 'WebCore/storage/IDBFactoryBackendImpl.cpp')
-rw-r--r-- | WebCore/storage/IDBFactoryBackendImpl.cpp | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/WebCore/storage/IDBFactoryBackendImpl.cpp b/WebCore/storage/IDBFactoryBackendImpl.cpp index 7bdd70d..905726f 100644 --- a/WebCore/storage/IDBFactoryBackendImpl.cpp +++ b/WebCore/storage/IDBFactoryBackendImpl.cpp @@ -30,7 +30,10 @@ #include "IDBFactoryBackendImpl.h" #include "DOMStringList.h" +#include "FileSystem.h" #include "IDBDatabaseBackendImpl.h" +#include "IDBDatabaseException.h" +#include "SQLiteDatabase.h" #include "SecurityOrigin.h" #include <wtf/Threading.h> #include <wtf/UnusedParam.h> @@ -39,31 +42,74 @@ namespace WebCore { -PassRefPtr<IDBFactoryBackendImpl> IDBFactoryBackendImpl::create() +IDBFactoryBackendImpl::IDBFactoryBackendImpl() { - return adoptRef(new IDBFactoryBackendImpl); } -IDBFactoryBackendImpl::IDBFactoryBackendImpl() +IDBFactoryBackendImpl::~IDBFactoryBackendImpl() { } -IDBFactoryBackendImpl::~IDBFactoryBackendImpl() +static PassOwnPtr<SQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOrigin, String name) { + String pathBase = "/tmp/temporary-indexed-db-files"; // FIXME: Write a PageGroupSettings class and have this value come from that. + if (!makeAllDirectories(pathBase)) { + // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out. + LOG_ERROR("Unabled to create LocalStorage database path %s", pathBase.utf8().data()); + return 0; + } + + String databaseIdentifier = securityOrigin->databaseIdentifier(); + String santizedName = encodeForFileName(name); + String path = pathByAppendingComponent(pathBase, databaseIdentifier + "_" + santizedName + ".indexeddb"); + + OwnPtr<SQLiteDatabase> sqliteDatabase = adoptPtr(new SQLiteDatabase()); + if (!sqliteDatabase->open(path)) { + // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out. + LOG_ERROR("Failed to open database file %s for IndexedDB", path.utf8().data()); + return 0; + } + + return sqliteDatabase.release(); } -void IDBFactoryBackendImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin>, Frame*) +static bool createTables(SQLiteDatabase* sqliteDatabase) +{ + static const char* commands[] = { + "CREATE TABLE IF NOT EXISTS MetaData (name TEXT, description TEXT, version TEXT)" + }; + + for (size_t i = 0; i < arraysize(commands); ++i) { + if (!sqliteDatabase->executeCommand(commands[i])) { + // FIXME: We should try to recover from this situation. Maybe nuke the database and start over? + LOG_ERROR("Failed to run the following command for IndexedDB: %s", commands[i]); + return false; + } + } + return true; +} + +void IDBFactoryBackendImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*) { - RefPtr<IDBDatabaseBackendInterface> databaseBackend; IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(name); - if (it == m_databaseBackendMap.end()) { - // FIXME: What should the version be? The spec doesn't define it yet. - databaseBackend = IDBDatabaseBackendImpl::create(name, description, ""); - m_databaseBackendMap.set(name, databaseBackend); - } else - databaseBackend = it->second; - - callbacks->onSuccess(databaseBackend.release()); + if (it != m_databaseBackendMap.end()) { + if (!description.isNull()) + it->second->setDescription(description); // The description may have changed. + callbacks->onSuccess(it->second.get()); + return; + } + + // FIXME: Everything from now on should be done on another thread. + + OwnPtr<SQLiteDatabase> sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), name); + if (!sqliteDatabase || !createTables(sqliteDatabase.get())) { + callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); + return; + } + + RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.release()); + callbacks->onSuccess(databaseBackend.get()); + m_databaseBackendMap.set(name, databaseBackend.release()); } } // namespace WebCore |