1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef UniqueIDBDatabase_h 27#define UniqueIDBDatabase_h 28 29#if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS) 30 31#include "IDBIdentifier.h" 32#include "UniqueIDBDatabaseIdentifier.h" 33#include <WebCore/IDBDatabaseBackend.h> 34#include <WebCore/IndexedDB.h> 35#include <functional> 36#include <wtf/Deque.h> 37#include <wtf/HashSet.h> 38#include <wtf/PassRefPtr.h> 39#include <wtf/RefCounted.h> 40#include <wtf/text/WTFString.h> 41 42namespace WebCore { 43class SharedBuffer; 44 45struct IDBDatabaseMetadata; 46struct IDBKeyData; 47} 48 49namespace WebKit { 50 51class AsyncRequest; 52class AsyncTask; 53class DatabaseProcessIDBConnection; 54class UniqueIDBDatabaseBackingStore; 55 56struct SecurityOriginData; 57 58enum class UniqueIDBDatabaseShutdownType { 59 NormalShutdown, 60 DeleteShutdown 61}; 62 63class UniqueIDBDatabase : public ThreadSafeRefCounted<UniqueIDBDatabase> { 64public: 65 static PassRefPtr<UniqueIDBDatabase> create(const UniqueIDBDatabaseIdentifier& identifier) 66 { 67 return adoptRef(new UniqueIDBDatabase(identifier)); 68 } 69 70 ~UniqueIDBDatabase(); 71 72 static String calculateAbsoluteDatabaseFilename(const String& absoluteDatabaseDirectory); 73 74 const UniqueIDBDatabaseIdentifier& identifier() const { return m_identifier; } 75 76 void registerConnection(DatabaseProcessIDBConnection&); 77 void unregisterConnection(DatabaseProcessIDBConnection&); 78 79 void deleteDatabase(std::function<void(bool)> successCallback); 80 81 void getOrEstablishIDBDatabaseMetadata(std::function<void(bool, const WebCore::IDBDatabaseMetadata&)> completionCallback); 82 83 void openTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode, std::function<void(bool)> successCallback); 84 void beginTransaction(const IDBIdentifier& transactionIdentifier, std::function<void(bool)> successCallback); 85 void commitTransaction(const IDBIdentifier& transactionIdentifier, std::function<void(bool)> successCallback); 86 void resetTransaction(const IDBIdentifier& transactionIdentifier, std::function<void(bool)> successCallback); 87 void rollbackTransaction(const IDBIdentifier& transactionIdentifier, std::function<void(bool)> successCallback); 88 89 void changeDatabaseVersion(const IDBIdentifier& transactionIdentifier, uint64_t newVersion, std::function<void(bool)> successCallback); 90 void createObjectStore(const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, std::function<void(bool)> successCallback); 91 void deleteObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, std::function<void(bool)> successCallback); 92 void clearObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, std::function<void(bool)> successCallback); 93 void createIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata&, std::function<void(bool)> successCallback); 94 void deleteIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, std::function<void(bool)> successCallback); 95 96 void putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyData&, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys, std::function<void(const WebCore::IDBKeyData&, uint32_t, const String&)> callback); 97 void getRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType, std::function<void(const WebCore::IDBGetResult&, uint32_t, const String&)> callback); 98 99 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<void(int64_t, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback); 100 void cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function<void(const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback); 101 void cursorIterate(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, std::function<void(const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback); 102 103 void count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, std::function<void(int64_t, uint32_t, const String&)> callback); 104 void deleteRange(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&, std::function<void(uint32_t, const String&)> callback); 105 106private: 107 UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&); 108 109 UniqueIDBDatabaseIdentifier m_identifier; 110 111 bool m_inMemory; 112 String m_databaseRelativeDirectory; 113 114 HashSet<RefPtr<DatabaseProcessIDBConnection>> m_connections; 115 HashMap<uint64_t, RefPtr<AsyncRequest>> m_databaseRequests; 116 117 String absoluteDatabaseDirectory() const; 118 119 enum class DatabaseTaskType { 120 Normal, 121 Shutdown 122 }; 123 void postDatabaseTask(std::unique_ptr<AsyncTask>, DatabaseTaskType = DatabaseTaskType::Normal); 124 125 void shutdown(UniqueIDBDatabaseShutdownType); 126 127 // Method that attempts to make legal filenames from all legal database names 128 String filenameForDatabaseName() const; 129 130 // Returns a string that is appropriate for use as a unique filename 131 String databaseFilenameIdentifier(const SecurityOriginData&) const; 132 133 // Returns true if this origin can use the same databases as the given origin. 134 bool canShareDatabases(const SecurityOriginData&, const SecurityOriginData&) const; 135 136 void postTransactionOperation(const IDBIdentifier& transactionIdentifier, std::unique_ptr<AsyncTask>, std::function<void(bool)> successCallback); 137 138 // To be called from the database workqueue thread only 139 void performNextDatabaseTask(); 140 void postMainThreadTask(std::unique_ptr<AsyncTask>, DatabaseTaskType = DatabaseTaskType::Normal); 141 void openBackingStoreAndReadMetadata(const UniqueIDBDatabaseIdentifier&, const String& databaseDirectory); 142 void openBackingStoreTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode); 143 void beginBackingStoreTransaction(const IDBIdentifier&); 144 void commitBackingStoreTransaction(const IDBIdentifier&); 145 void resetBackingStoreTransaction(const IDBIdentifier&); 146 void rollbackBackingStoreTransaction(const IDBIdentifier&); 147 148 void changeDatabaseVersionInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, uint64_t newVersion); 149 void createObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&); 150 void deleteObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID); 151 void clearObjectStoreInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID); 152 153 void createIndexInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata&); 154 void deleteIndexInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID); 155 156 void putRecordInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, const WebCore::IDBKeyData&, const Vector<uint8_t>& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys); 157 void getRecordFromBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType); 158 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&); 159 void advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count); 160 void iterateCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&); 161 void countInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&); 162 void deleteRangeInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&); 163 164 void shutdownBackingStore(UniqueIDBDatabaseShutdownType, const String& databaseDirectory); 165 166 // Callbacks from the database workqueue thread, to be performed on the main thread only 167 void performNextMainThreadTask(); 168 bool performNextMainThreadTaskWithoutAdoptRef(); 169 void didOpenBackingStoreAndReadMetadata(const WebCore::IDBDatabaseMetadata&, bool success); 170 void didCompleteTransactionOperation(const IDBIdentifier& transactionIdentifier, bool success); 171 void didChangeDatabaseVersion(uint64_t requestID, bool success); 172 void didCreateObjectStore(uint64_t requestID, bool success); 173 void didDeleteObjectStore(uint64_t requestID, bool success); 174 void didClearObjectStore(uint64_t requestID, bool success); 175 void didCreateIndex(uint64_t requestID, bool success); 176 void didDeleteIndex(uint64_t requestID, bool success); 177 void didPutRecordInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage); 178 void didGetRecordFromBackingStore(uint64_t requestID, const WebCore::IDBGetResult&, uint32_t errorCode, const String& errorMessage); 179 void didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<uint8_t>&, uint32_t errorCode, const String& errorMessage); 180 void didAdvanceCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<uint8_t>&, uint32_t errorCode, const String& errorMessage); 181 void didIterateCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<uint8_t>&, uint32_t errorCode, const String& errorMessage); 182 void didCountInBackingStore(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage); 183 void didDeleteRangeInBackingStore(uint64_t requestID, uint32_t errorCode, const String& errorMessage); 184 185 void didShutdownBackingStore(UniqueIDBDatabaseShutdownType); 186 void didCompleteBoolRequest(uint64_t requestID, bool success); 187 188 void didEstablishTransaction(const IDBIdentifier& transactionIdentifier, bool success); 189 void didResetTransaction(const IDBIdentifier& transactionIdentifier, bool success); 190 void resetAllTransactions(const DatabaseProcessIDBConnection&); 191 void finalizeRollback(const IDBIdentifier& transactionId); 192 193 bool m_acceptingNewRequests; 194 195 HashMap<const DatabaseProcessIDBConnection*, HashSet<IDBIdentifier>> m_establishedTransactions; 196 Deque<RefPtr<AsyncRequest>> m_pendingMetadataRequests; 197 HashMap<IDBIdentifier, RefPtr<AsyncRequest>> m_pendingTransactionRequests; 198 HashSet<IDBIdentifier> m_pendingTransactionRollbacks; 199 HashMap<uint64_t, RefPtr<AsyncRequest>> m_pendingDatabaseTasks; 200 RefPtr<AsyncRequest> m_pendingShutdownTask; 201 202 std::unique_ptr<WebCore::IDBDatabaseMetadata> m_metadata; 203 bool m_didGetMetadataFromBackingStore; 204 205 RefPtr<UniqueIDBDatabaseBackingStore> m_backingStore; 206 207 Deque<std::unique_ptr<AsyncTask>> m_databaseTasks; 208 Mutex m_databaseTaskMutex; 209 210 Deque<std::unique_ptr<AsyncTask>> m_mainThreadTasks; 211 Mutex m_mainThreadTaskMutex; 212}; 213 214} // namespace WebKit 215 216#endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS) 217#endif // UniqueIDBDatabase_h 218