/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UniqueIDBDatabase_h #define UniqueIDBDatabase_h #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS) #include "IDBIdentifier.h" #include "UniqueIDBDatabaseIdentifier.h" #include #include #include #include #include #include #include #include namespace WebCore { class SharedBuffer; struct IDBDatabaseMetadata; struct IDBKeyData; } namespace WebKit { class AsyncRequest; class AsyncTask; class DatabaseProcessIDBConnection; class UniqueIDBDatabaseBackingStore; struct SecurityOriginData; enum class UniqueIDBDatabaseShutdownType { NormalShutdown, DeleteShutdown }; class UniqueIDBDatabase : public ThreadSafeRefCounted { public: static PassRefPtr create(const UniqueIDBDatabaseIdentifier& identifier) { return adoptRef(new UniqueIDBDatabase(identifier)); } ~UniqueIDBDatabase(); static String calculateAbsoluteDatabaseFilename(const String& absoluteDatabaseDirectory); const UniqueIDBDatabaseIdentifier& identifier() const { return m_identifier; } void registerConnection(DatabaseProcessIDBConnection&); void unregisterConnection(DatabaseProcessIDBConnection&); void deleteDatabase(std::function successCallback); void getOrEstablishIDBDatabaseMetadata(std::function completionCallback); void openTransaction(const IDBIdentifier& transactionIdentifier, const Vector& objectStoreIDs, WebCore::IndexedDB::TransactionMode, std::function successCallback); void beginTransaction(const IDBIdentifier& transactionIdentifier, std::function successCallback); void commitTransaction(const IDBIdentifier& transactionIdentifier, std::function successCallback); void resetTransaction(const IDBIdentifier& transactionIdentifier, std::function successCallback); void rollbackTransaction(const IDBIdentifier& transactionIdentifier, std::function successCallback); void changeDatabaseVersion(const IDBIdentifier& transactionIdentifier, uint64_t newVersion, std::function successCallback); void createObjectStore(const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, std::function successCallback); void deleteObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, std::function successCallback); void clearObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, std::function successCallback); void createIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata&, std::function successCallback); void deleteIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, std::function successCallback); void putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyData&, const IPC::DataReference& value, int64_t putMode, const Vector& indexIDs, const Vector>& indexKeys, std::function callback); void getRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType, std::function callback); void openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, std::function, const WebCore::IDBKeyData&, uint32_t, const String&)> callback); void cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function, const WebCore::IDBKeyData&, uint32_t, const String&)> callback); void cursorIterate(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, std::function, const WebCore::IDBKeyData&, uint32_t, const String&)> callback); void count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, std::function callback); void deleteRange(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&, std::function callback); private: UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&); UniqueIDBDatabaseIdentifier m_identifier; bool m_inMemory; String m_databaseRelativeDirectory; HashSet> m_connections; HashMap> m_databaseRequests; String absoluteDatabaseDirectory() const; enum class DatabaseTaskType { Normal, Shutdown }; void postDatabaseTask(std::unique_ptr, DatabaseTaskType = DatabaseTaskType::Normal); void shutdown(UniqueIDBDatabaseShutdownType); // Method that attempts to make legal filenames from all legal database names String filenameForDatabaseName() const; // Returns a string that is appropriate for use as a unique filename String databaseFilenameIdentifier(const SecurityOriginData&) const; // Returns true if this origin can use the same databases as the given origin. bool canShareDatabases(const SecurityOriginData&, const SecurityOriginData&) const; void postTransactionOperation(const IDBIdentifier& transactionIdentifier, std::unique_ptr, std::function successCallback); // To be called from the database workqueue thread only void performNextDatabaseTask(); void postMainThreadTask(std::unique_ptr, DatabaseTaskType = DatabaseTaskType::Normal); void openBackingStoreAndReadMetadata(const UniqueIDBDatabaseIdentifier&, const String& databaseDirectory); void openBackingStoreTransaction(const IDBIdentifier& transactionIdentifier, const Vector& objectStoreIDs, WebCore::IndexedDB::TransactionMode); void beginBackingStoreTransaction(const IDBIdentifier&); void commitBackingStoreTransaction(const IDBIdentifier&); void resetBackingStoreTransaction(const IDBIdentifier&); void rollbackBackingStoreTransaction(const IDBIdentifier&); void changeDatabaseVersionInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, uint64_t newVersion); void createObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&); void deleteObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID); void clearObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID); void createIndexInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata&); void deleteIndexInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID); void putRecordInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, const WebCore::IDBKeyData&, const Vector& value, int64_t putMode, const Vector& indexIDs, const Vector>& indexKeys); void getRecordFromBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType); void openCursorInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&); void advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count); void iterateCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&); void countInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&); void deleteRangeInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&); void shutdownBackingStore(UniqueIDBDatabaseShutdownType, const String& databaseDirectory); // Callbacks from the database workqueue thread, to be performed on the main thread only void performNextMainThreadTask(); void didOpenBackingStoreAndReadMetadata(const WebCore::IDBDatabaseMetadata&, bool success); void didCompleteTransactionOperation(const IDBIdentifier& transactionIdentifier, bool success); void didChangeDatabaseVersion(uint64_t requestID, bool success); void didCreateObjectStore(uint64_t requestID, bool success); void didDeleteObjectStore(uint64_t requestID, bool success); void didClearObjectStore(uint64_t requestID, bool success); void didCreateIndex(uint64_t requestID, bool success); void didDeleteIndex(uint64_t requestID, bool success); void didPutRecordInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage); void didGetRecordFromBackingStore(uint64_t requestID, const WebCore::IDBGetResult&, uint32_t errorCode, const String& errorMessage); void didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage); void didAdvanceCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage); void didIterateCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage); void didCountInBackingStore(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage); void didDeleteRangeInBackingStore(uint64_t requestID, uint32_t errorCode, const String& errorMessage); void didShutdownBackingStore(UniqueIDBDatabaseShutdownType); void didCompleteBoolRequest(uint64_t requestID, bool success); bool m_acceptingNewRequests; Deque> m_pendingMetadataRequests; HashMap> m_pendingTransactionRequests; HashMap> m_pendingDatabaseTasks; RefPtr m_pendingShutdownTask; std::unique_ptr m_metadata; bool m_didGetMetadataFromBackingStore; RefPtr m_backingStore; Deque> m_databaseTasks; Mutex m_databaseTaskMutex; Deque> m_mainThreadTasks; Mutex m_mainThreadTaskMutex; }; } // namespace WebKit #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS) #endif // UniqueIDBDatabase_h