summaryrefslogtreecommitdiffstats
path: root/WebCore/storage/IDBFactoryBackendImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/storage/IDBFactoryBackendImpl.cpp')
-rw-r--r--WebCore/storage/IDBFactoryBackendImpl.cpp74
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