void IDBFactoryBackendImpl::open(const String& name, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*, const String& dataDir, int64_t maximumSize, BackingStoreType backingStoreType) { ASSERT(backingStoreType != DefaultBackingStore); const String fileIdentifier = computeFileIdentifier(securityOrigin.get(), backingStoreType); const String uniqueIdentifier = computeUniqueIdentifier(name, securityOrigin.get(), backingStoreType); IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier); if (it != m_databaseBackendMap.end()) { callbacks->onSuccess(it->second); return; } // FIXME: Everything from now on should be done on another thread. #if ENABLE(LEVELDB) if (backingStoreType == LevelDBBackingStore) { bool hasSQLBackingStore = IDBSQLiteBackingStore::backingStoreExists(securityOrigin.get(), name, dataDir); // LayoutTests: SQLite backing store may not exist on disk but may exist in cache. String cachedSqliteBackingStoreIdentifier = computeFileIdentifier(securityOrigin.get(), SQLiteBackingStore); if (!hasSQLBackingStore && (m_backingStoreMap.end() != m_backingStoreMap.find(cachedSqliteBackingStoreIdentifier))) hasSQLBackingStore = true; if (hasSQLBackingStore) { bool migrationSucceeded = migrateFromSQLiteToLevelDB(name, securityOrigin.get(), dataDir, maximumSize); UNUSED_PARAM(migrationSucceeded); // FIXME: When migration is actually implemented, we need error handling here. } } #endif RefPtr<IDBBackingStore> backingStore; IDBBackingStoreMap::iterator it2 = m_backingStoreMap.find(fileIdentifier); if (it2 != m_backingStoreMap.end() && (backingStoreType == it2->second->backingStoreType())) backingStore = it2->second; else { if (backingStoreType == SQLiteBackingStore) backingStore = IDBSQLiteBackingStore::open(securityOrigin.get(), dataDir, maximumSize, fileIdentifier, this); #if ENABLE(LEVELDB) else if (backingStoreType == LevelDBBackingStore) backingStore = IDBLevelDBBackingStore::open(securityOrigin.get(), dataDir, maximumSize, fileIdentifier, this); #endif if (!backingStore) { callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); return; } } RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, backingStore.get(), m_transactionCoordinator.get(), this, uniqueIdentifier); callbacks->onSuccess(databaseBackend.get()); m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get()); }
PassRefPtr<IDBBackingStore> IDBFactoryBackendLevelDB::openBackingStore(PassRefPtr<SecurityOrigin> securityOrigin, const String& dataDirectory) { const String fileIdentifier = computeFileIdentifier(securityOrigin.get()); const bool openInMemory = dataDirectory.isEmpty(); IDBBackingStoreMap::iterator it2 = m_backingStoreMap.find(fileIdentifier); if (it2 != m_backingStoreMap.end() && it2->value.get()) return it2->value.get(); RefPtr<IDBBackingStore> backingStore; if (openInMemory) backingStore = IDBBackingStore::openInMemory(securityOrigin.get(), fileIdentifier); else backingStore = IDBBackingStore::open(securityOrigin.get(), dataDirectory, fileIdentifier); if (backingStore) { cleanWeakMap(m_backingStoreMap); m_backingStoreMap.set(fileIdentifier, backingStore->createWeakPtr()); // If an in-memory database, bind lifetime to this factory instance. if (openInMemory) m_sessionOnlyBackingStores.add(backingStore); // All backing stores associated with this factory should be of the same type. ASSERT(m_sessionOnlyBackingStores.isEmpty() || openInMemory); return backingStore.release(); } return 0; }
PassRefPtr<IDBBackingStore> IDBFactoryBackendImpl::openBackingStore(PassRefPtr<SecurityOrigin> securityOrigin, const String& dataDirectory) { const String fileIdentifier = computeFileIdentifier(securityOrigin.get()); RefPtr<IDBBackingStore> backingStore; IDBBackingStoreMap::iterator it2 = m_backingStoreMap.find(fileIdentifier); if (it2 != m_backingStoreMap.end()) backingStore = it2->value; else { backingStore = IDBBackingStore::open(securityOrigin.get(), dataDirectory, fileIdentifier, this); } if (backingStore) return backingStore.release(); return 0; }
PassRefPtr<IDBBackingStore> IDBFactoryBackendImpl::openBackingStore(PassRefPtr<SecurityOrigin> securityOrigin, const String& dataDirectory) { const String fileIdentifier = computeFileIdentifier(securityOrigin.get()); RefPtr<IDBBackingStore> backingStore; IDBBackingStoreMap::iterator it2 = m_backingStoreMap.find(fileIdentifier); if (it2 != m_backingStoreMap.end()) backingStore = it2->second; else { #if USE(LEVELDB) backingStore = IDBLevelDBBackingStore::open(securityOrigin.get(), dataDirectory, fileIdentifier, this); #else UNUSED_PARAM(dataDirectory); ASSERT_NOT_REACHED(); #endif } if (backingStore) return backingStore.release(); return 0; }
static String computeUniqueIdentifier(const String& name, SecurityOrigin* securityOrigin) { return computeFileIdentifier(securityOrigin) + name; }
static String computeUniqueIdentifier(const String& name, SecurityOrigin* securityOrigin, IDBFactoryBackendInterface::BackingStoreType type) { return computeFileIdentifier(securityOrigin, type) + name; }
bool IDBFactoryBackendImpl::migrateFromSQLiteToLevelDB(const String& name, SecurityOrigin* securityOrigin, const String& dataDir, int64_t maximumSize) { #if ENABLE(LEVELDB) String fromUniqueIdentifier = computeUniqueIdentifier(name, securityOrigin, SQLiteBackingStore); String fromFileIdentifier = computeFileIdentifier(securityOrigin, SQLiteBackingStore); String toUniqueIdentifier = computeUniqueIdentifier(name, securityOrigin, LevelDBBackingStore); String toFileIdentifier = computeFileIdentifier(securityOrigin, LevelDBBackingStore); RefPtr<IDBTransactionCoordinator> transactionCoordinator = IDBTransactionCoordinator::create(); RefPtr<IDBBackingStore> fromBackingStore; RefPtr<IDBDatabaseBackendImpl> fromDatabaseBackend; RefPtr<IDBBackingStore> toBackingStore; // Open "From" backing store and backend. When running LayoutTests, the // "from" database may be cached in this class instance, so look for it there first. IDBBackingStoreMap::iterator it = m_backingStoreMap.find(fromFileIdentifier); if (it != m_backingStoreMap.end()) fromBackingStore = it->second; else fromBackingStore = IDBSQLiteBackingStore::open(securityOrigin, dataDir, maximumSize, fromFileIdentifier, this); if (!fromBackingStore) return false; IDBDatabaseBackendMap::iterator it2 = m_databaseBackendMap.find(fromUniqueIdentifier); if (it2 != m_databaseBackendMap.end()) fromDatabaseBackend = it2->second; else { fromDatabaseBackend = IDBDatabaseBackendImpl::create(name, fromBackingStore.get(), transactionCoordinator.get(), this, fromUniqueIdentifier); m_databaseBackendMap.set(fromUniqueIdentifier, fromDatabaseBackend.get()); } if (!fromDatabaseBackend) return false; // Open "To" database. First find out if it already exists -- this will determine if // it is safe to call IDBLevelDBBackingStore::extractIDBDatabaseMetaData. it = m_backingStoreMap.find(toFileIdentifier); if (it != m_backingStoreMap.end()) toBackingStore = it->second; else toBackingStore = IDBLevelDBBackingStore::open(securityOrigin, dataDir, maximumSize, toFileIdentifier, this); if (!toBackingStore) return false; String toDatabaseName = fromDatabaseBackend->name(); String toDatabaseVersion = fromDatabaseBackend->version(); int64_t toDatabaseId = -1; if (!toBackingStore->extractIDBDatabaseMetaData(toDatabaseName, toDatabaseVersion, toDatabaseId)) { if (!toBackingStore->setIDBDatabaseMetaData(toDatabaseName, toDatabaseVersion, toDatabaseId, true)) return false; } return migrateObjectStores(fromBackingStore, fromDatabaseBackend->id(), toBackingStore, toDatabaseId); #endif // ENABLE(LEVELDB) return false; }