Changeset 138900 in webkit
- Timestamp:
- Jan 5, 2013 12:42:38 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r138899 r138900 1 2013-01-05 Alec Flett <alecflett@chromium.org> 2 3 IndexedDB: Migrate backend ObjectStore calls to use transaction id 4 https://bugs.webkit.org/show_bug.cgi?id=102741 5 6 Reviewed by Tony Chang. 7 8 Add additional count() tests for multi-entry indexes, not previously 9 covered. 10 11 * storage/indexeddb/index-multientry-expected.txt: 12 * storage/indexeddb/resources/index-multientry.js: 13 (.transaction.oncomplete): 14 (verifyCount.request.onsuccess.request.onsuccess): 15 (verifyCount.request.onsuccess): 16 (verifyCount): 17 1 18 2013-01-05 Robert Hogan <robert@webkit.org> 2 19 -
trunk/LayoutTests/storage/indexeddb/index-multientry-expected.txt
r134661 r138900 83 83 cursor = event.target.result 84 84 PASS expected.length is 0 85 transaction = db.transaction(['store']) 86 transaction.objectStore('store').index('index') 87 index.count() 88 PASS event.target.result is 9 89 index.count(7) 90 PASS event.target.result is 1 85 91 86 92 Verifying unique constraint on multiEntry index … … 163 169 cursor = event.target.result 164 170 PASS expected.length is 0 171 transaction = db.transaction(['store']) 172 transaction.objectStore('store').index('index') 173 index.count() 174 PASS event.target.result is 9 175 index.count(7) 176 PASS event.target.result is 1 165 177 PASS successfullyParsed is true 166 178 -
trunk/LayoutTests/storage/indexeddb/resources/index-multientry.js
r134661 r138900 46 46 transaction = evalAndLog("transaction = db.transaction(['store'], 'readonly')"); 47 47 transaction.onabort = unexpectedAbortCallback; 48 transaction.oncomplete = callback;48 transaction.oncomplete = function() { verifyCount(callback); }; 49 49 50 50 expected = [ … … 105 105 } 106 106 107 function verifyCount(callback) { 108 evalAndLog("transaction = db.transaction(['store'])"); 109 110 transaction.onabort = unexpectedAbortCallback; 111 transaction.oncomplete = callback; 112 113 index = evalAndLog("transaction.objectStore('store').index('index')"); 114 request = evalAndLog("index.count()"); 115 request.onsuccess = function(event) { 116 117 shouldBe("event.target.result", "9"); 118 119 request = evalAndLog("index.count(7)"); 120 request.onsuccess = function(event) { 121 shouldBe("event.target.result", "1"); 122 }; 123 }; 124 125 } 126 107 127 function createIndexOnStoreWithData() 108 128 { -
trunk/Source/WebCore/ChangeLog
r138899 r138900 1 2013-01-05 Alec Flett <alecflett@chromium.org> 2 3 IndexedDB: Migrate backend ObjectStore calls to use transaction id 4 https://bugs.webkit.org/show_bug.cgi?id=102741 5 6 Reviewed by Tony Chang. 7 8 Fully migrate 8 core data calls (get, put, setIndexKeys, setIndexesReady, 9 openCursor, count, deleteRange, and clear) into IDBDatabaseBackendImpl, 10 combining common code from IDBObjectStoreBackendImpl and IDBIndexBackendImpl 11 in order to simplify the backend interface. These calls are now 12 implemented in terms of an int64_t-based transactionId rather than 13 an IDBTransactionBackendInterface, which simplifies the ownership model 14 between the frontend and the backend. 15 16 In addition, remove references to IDBObjectStoreBackend* from IDBIndex, 17 as it is no longer needed. 18 19 A few duplicate IDB_TRACE methods have been removed from wrapper methods 20 that call another method that already have IDB_TRACE's. 21 22 Finally, IDBCursorBackendImpl now no longer holds onto an 23 IDBObjectStoreBackendImpl*, so its destruction and member variables are 24 simplified, and reordered to match proper destruction order. 25 26 * Modules/indexeddb/IDBCursorBackendImpl.cpp: Reordered to account for proper destruction. 27 (WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl): 28 (WebCore::IDBCursorBackendImpl::~IDBCursorBackendImpl): 29 (WebCore::IDBCursorBackendImpl::deleteFunction): 30 * Modules/indexeddb/IDBCursorBackendImpl.h: 31 (WebCore::IDBCursorBackendImpl::create): 32 (IDBCursorBackendImpl): 33 * Modules/indexeddb/IDBDatabase.h: 34 (WebCore::IDBDatabase::backend): 35 (IDBDatabase): 36 * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: 37 (GetOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*RetrievalOperation 38 (WebCore::GetOperation::create): 39 (WebCore::GetOperation::GetOperation): 40 (WebCore): 41 (PutOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*StorageOperation. 42 (WebCore::PutOperation::create): 43 (WebCore::PutOperation::PutOperation): 44 (SetIndexesReadyOperation): Moved from IDBObjectStoreBackendImpl::IndexesReadyOperation 45 (WebCore::SetIndexesReadyOperation::create): 46 (WebCore::SetIndexesReadyOperation::SetIndexesReadyOperation): 47 (OpenCursorOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::Open*CursorOperation 48 (WebCore::OpenCursorOperation::create): 49 (WebCore::OpenCursorOperation::OpenCursorOperation): 50 (CountOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::CountOperation 51 (WebCore::CountOperation::create): 52 (WebCore::CountOperation::CountOperation): 53 (DeleteRangeOperation): Moved from IDBObjectStoreBackendImpl::DeleteOperation 54 (WebCore::DeleteRangeOperation::create): 55 (WebCore::DeleteRangeOperation::DeleteRangeOperation): 56 (ClearOperation): Moved from IDBObjectStoreBackendImpl::ClearOperation 57 (WebCore::ClearOperation::create): 58 (WebCore::ClearOperation::ClearOperation): 59 (WebCore::IDBDatabaseBackendImpl::get): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::get* 60 (WebCore::GetOperation::perform): 61 (WebCore::IDBDatabaseBackendImpl::put): Moved from IDBObjectStoreBackendImpl::put 62 (WebCore::PutOperation::perform): 63 (WebCore::IDBDatabaseBackendImpl::setIndexKeys): Moved from IDBObjectStoreBackendImpl::setIndexKeys 64 (WebCore::IDBDatabaseBackendImpl::setIndexesReady): 65 (WebCore::SetIndexesReadyOperation::perform): 66 (WebCore::IDBDatabaseBackendImpl::openCursor): 67 (WebCore::IDBDatabaseBackendImpl::count): 68 (WebCore::CountOperation::perform): 69 (WebCore::IDBDatabaseBackendImpl::deleteRange): 70 (WebCore::DeleteRangeOperation::perform): 71 (WebCore::IDBDatabaseBackendImpl::clear): 72 (WebCore::ClearOperation::perform): 73 (WebCore::OpenCursorOperation::perform): 74 * Modules/indexeddb/IDBIndex.cpp: 75 (WebCore::IDBIndex::IDBIndex): 76 (WebCore::IDBIndex::openCursor): 77 (WebCore::IDBIndex::count): 78 (WebCore::IDBIndex::openKeyCursor): 79 (WebCore::IDBIndex::get): 80 (WebCore::IDBIndex::getKey): 81 (WebCore::IDBIndex::backendDB): 82 (WebCore): 83 * Modules/indexeddb/IDBIndex.h: 84 (WebCore::IDBIndex::create): 85 (IDBIndex): 86 * Modules/indexeddb/IDBIndexBackendImpl.cpp: 87 (WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl): 88 * Modules/indexeddb/IDBIndexBackendImpl.h: 89 (WebCore::IDBIndexBackendImpl::create): 90 (WebCore::IDBIndexBackendImpl::openCursor): 91 (WebCore::IDBIndexBackendImpl::count): 92 (WebCore::IDBIndexBackendImpl::openKeyCursor): 93 (WebCore::IDBIndexBackendImpl::get): 94 (WebCore::IDBIndexBackendImpl::getKey): 95 (IDBIndexBackendImpl): 96 * Modules/indexeddb/IDBObjectStore.cpp: 97 (WebCore::IDBObjectStore::get): 98 (WebCore::IDBObjectStore::put): 99 (WebCore::IDBObjectStore::deleteFunction): 100 (WebCore::IDBObjectStore::clear): 101 (WebCore): 102 (WebCore::IDBObjectStore::createIndex): 103 (WebCore::IDBObjectStore::index): 104 (WebCore::IDBObjectStore::openCursor): 105 (WebCore::IDBObjectStore::count): 106 (WebCore::IDBObjectStore::backendDB): 107 * Modules/indexeddb/IDBObjectStore.h: 108 (WebCore::IDBObjectStore::id): 109 (IDBObjectStore): 110 * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: 111 (WebCore::IDBObjectStoreBackendImpl::createIndex): 112 (WebCore::IDBObjectStoreBackendImpl::loadIndexes): 113 (WebCore::IDBObjectStoreBackendImpl::generateKey): 114 (WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator): 115 * Modules/indexeddb/IDBObjectStoreBackendImpl.h: 116 (WebCore::IDBObjectStoreBackendImpl::get): 117 (WebCore::IDBObjectStoreBackendImpl::put): 118 (WebCore::IDBObjectStoreBackendImpl::deleteFunction): 119 (WebCore::IDBObjectStoreBackendImpl::clear): 120 (WebCore::IDBObjectStoreBackendImpl::setIndexKeys): 121 (WebCore::IDBObjectStoreBackendImpl::setIndexesReady): 122 (WebCore::IDBObjectStoreBackendImpl::openCursor): 123 (WebCore::IDBObjectStoreBackendImpl::count): 124 (IDBObjectStoreBackendImpl): 125 * Modules/indexeddb/IDBTransactionBackendImpl.h: 126 (WebCore::IDBTransactionBackendImpl::database): 127 (IDBTransactionBackendImpl): 128 1 129 2013-01-05 Robert Hogan <robert@webkit.org> 2 130 -
trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp
r138716 r138900 102 102 }; 103 103 104 IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore) 105 : m_cursor(cursor) 106 , m_taskType(taskType) 104 IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId) 105 : m_taskType(taskType) 107 106 , m_cursorType(cursorType) 107 , m_database(transaction->database()) 108 108 , m_transaction(transaction) 109 , m_objectStore(objectStore) 109 , m_objectStoreId(objectStoreId) 110 , m_cursor(cursor) 110 111 , m_closed(false) 111 112 { … … 116 117 { 117 118 m_transaction->unregisterOpenCursor(this); 118 // Order is important, the cursors have to be destructed before the objectStore.119 m_cursor.clear();120 m_savedCursor.clear();121 122 m_objectStore.clear();123 119 } 124 120 … … 171 167 ASSERT(!ec); 172 168 173 m_objectStore->deleteFunction(keyRange.release(), prpCallbacks, m_transaction.get(), ec); 174 ASSERT(!ec); 169 m_database->deleteRange(m_transaction->id(), m_objectStoreId, keyRange.release(), prpCallbacks); 175 170 } 176 171 -
trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h
r138290 r138900 48 48 class IDBCursorBackendImpl : public IDBCursorBackendInterface { 49 49 public: 50 static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)50 static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId) 51 51 { 52 return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, IDBTransactionBackendInterface::NormalTask, transaction, objectStore ));52 return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, IDBTransactionBackendInterface::NormalTask, transaction, objectStoreId)); 53 53 } 54 static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)54 static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId) 55 55 { 56 return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, taskType, transaction, objectStore ));56 return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, taskType, transaction, objectStoreId)); 57 57 } 58 58 virtual ~IDBCursorBackendImpl(); … … 72 72 73 73 private: 74 IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendImpl*, IDBObjectStoreBackendImpl*);74 IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendImpl*, int64_t objectStoreId); 75 75 76 76 class CursorIterationOperation; … … 78 78 class CursorPrefetchIterationOperation; 79 79 80 RefPtr<IDBBackingStore::Cursor> m_cursor;81 RefPtr<IDBBackingStore::Cursor> m_savedCursor;82 80 IDBTransactionBackendInterface::TaskType m_taskType; 83 81 CursorType m_cursorType; 84 RefPtr<IDBTransactionBackendImpl> m_transaction; 85 RefPtr<IDBObjectStoreBackendImpl> m_objectStore; 82 const RefPtr<IDBDatabaseBackendImpl> m_database; 83 const RefPtr<IDBTransactionBackendImpl> m_transaction; 84 const int64_t m_objectStoreId; 85 86 RefPtr<IDBBackingStore::Cursor> m_cursor; // Must be destroyed before m_transaction. 87 RefPtr<IDBBackingStore::Cursor> m_savedCursor; // Must be destroyed before m_transaction. 86 88 87 89 bool m_closed; -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h
r138674 r138900 104 104 } 105 105 106 IDBDatabaseBackendInterface* backend() const { return m_backend.get(); } 107 106 108 static int64_t nextTransactionId(); 107 109 -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp
r138666 r138900 30 30 31 31 #include "IDBBackingStore.h" 32 #include "IDBCursorBackendImpl.h" 32 33 #include "IDBDatabaseException.h" 33 34 #include "IDBFactoryBackendImpl.h" 35 #include "IDBIndexBackendImpl.h" 34 36 #include "IDBObjectStoreBackendImpl.h" 35 37 #include "IDBTracing.h" … … 155 157 }; 156 158 159 class GetOperation : public IDBTransactionBackendImpl::Operation { 160 public: 161 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, const IDBDatabaseMetadata& metadata, int64 objectStoreId, int64 indexId, PassRefPtr<IDBKeyRange> keyRange, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks) 162 { 163 return adoptPtr(new GetOperation(backingStore, metadata, objectStoreId, indexId, keyRange, cursorType, callbacks)); 164 } 165 virtual void perform(IDBTransactionBackendImpl*); 166 private: 167 GetOperation(PassRefPtr<IDBBackingStore> backingStore, const IDBDatabaseMetadata& metadata, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks) 168 : m_backingStore(backingStore) 169 , m_databaseId(metadata.id) 170 , m_objectStoreId(objectStoreId) 171 , m_indexId(indexId) 172 , m_keyPath(metadata.objectStores.get(objectStoreId).keyPath) 173 , m_autoIncrement(metadata.objectStores.get(objectStoreId).autoIncrement) 174 , m_keyRange(keyRange) 175 , m_cursorType(cursorType) 176 , m_callbacks(callbacks) 177 { 178 ASSERT(metadata.objectStores.get(objectStoreId).id == objectStoreId); 179 } 180 181 const RefPtr<IDBBackingStore> m_backingStore; 182 const int64_t m_databaseId; 183 const int64_t m_objectStoreId; 184 const int64_t m_indexId; 185 const IDBKeyPath m_keyPath; 186 const bool m_autoIncrement; 187 const RefPtr<IDBKeyRange> m_keyRange; 188 const IDBCursorBackendInterface::CursorType m_cursorType; 189 const RefPtr<IDBCallbacks> m_callbacks; 190 }; 191 192 class PutOperation : public IDBTransactionBackendImpl::Operation { 193 public: 194 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, Vector<uint8_t>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackendInterface::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IDBDatabaseBackendInterface::IndexKeys>& indexKeys) 195 { 196 return adoptPtr(new PutOperation(backingStore, databaseId, objectStore, value, key, putMode, callbacks, indexIds, indexKeys)); 197 } 198 virtual void perform(IDBTransactionBackendImpl*); 199 private: 200 PutOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, Vector<uint8_t>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackendInterface::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IDBDatabaseBackendInterface::IndexKeys>& indexKeys) 201 : m_backingStore(backingStore) 202 , m_databaseId(databaseId) 203 , m_objectStore(objectStore) 204 , m_key(key) 205 , m_putMode(putMode) 206 , m_callbacks(callbacks) 207 , m_indexIds(indexIds) 208 , m_indexKeys(indexKeys) 209 { 210 m_value.swap(value); 211 } 212 213 const RefPtr<IDBBackingStore> m_backingStore; 214 const int64_t m_databaseId; 215 const IDBObjectStoreMetadata m_objectStore; 216 Vector<uint8_t> m_value; 217 const RefPtr<IDBKey> m_key; 218 const IDBDatabaseBackendInterface::PutMode m_putMode; 219 const RefPtr<IDBCallbacks> m_callbacks; 220 const Vector<int64_t> m_indexIds; 221 const Vector<IDBDatabaseBackendInterface::IndexKeys> m_indexKeys; 222 }; 223 224 class SetIndexesReadyOperation : public IDBTransactionBackendImpl::Operation { 225 public: 226 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(size_t indexCount) 227 { 228 return adoptPtr(new SetIndexesReadyOperation(indexCount)); 229 } 230 virtual void perform(IDBTransactionBackendImpl*); 231 private: 232 SetIndexesReadyOperation(size_t indexCount) 233 : m_indexCount(indexCount) 234 { 235 } 236 237 const size_t m_indexCount; 238 }; 239 240 class OpenCursorOperation : public IDBTransactionBackendImpl::Operation { 241 public: 242 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, IDBDatabaseBackendInterface::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks) 243 { 244 return adoptPtr(new OpenCursorOperation(backingStore, databaseId, objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks)); 245 } 246 virtual void perform(IDBTransactionBackendImpl*); 247 private: 248 OpenCursorOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, IDBDatabaseBackendInterface::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks) 249 : m_backingStore(backingStore) 250 , m_databaseId(databaseId) 251 , m_objectStoreId(objectStoreId) 252 , m_indexId(indexId) 253 , m_keyRange(keyRange) 254 , m_direction(direction) 255 , m_cursorType(cursorType) 256 , m_taskType(taskType) 257 , m_callbacks(callbacks) 258 { 259 } 260 261 const RefPtr<IDBBackingStore> m_backingStore; 262 const int64_t m_databaseId; 263 const int64_t m_objectStoreId; 264 const int64_t m_indexId; 265 const PassRefPtr<IDBKeyRange> m_keyRange; 266 const unsigned short m_direction; 267 const IDBCursorBackendInterface::CursorType m_cursorType; 268 const IDBDatabaseBackendInterface::TaskType m_taskType; 269 const RefPtr<IDBCallbacks> m_callbacks; 270 }; 271 272 class CountOperation : public IDBTransactionBackendImpl::Operation { 273 public: 274 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 275 { 276 return adoptPtr(new CountOperation(backingStore, databaseId, objectStoreId, indexId, keyRange, callbacks)); 277 } 278 virtual void perform(IDBTransactionBackendImpl*); 279 private: 280 CountOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 281 : m_backingStore(backingStore) 282 , m_databaseId(databaseId) 283 , m_objectStoreId(objectStoreId) 284 , m_indexId(indexId) 285 , m_keyRange(keyRange) 286 , m_callbacks(callbacks) 287 { 288 } 289 290 const RefPtr<IDBBackingStore> m_backingStore; 291 const int64_t m_databaseId; 292 const int64_t m_objectStoreId; 293 const int64_t m_indexId; 294 const RefPtr<IDBKeyRange> m_keyRange; 295 const RefPtr<IDBCallbacks> m_callbacks; 296 }; 297 298 class DeleteRangeOperation : public IDBTransactionBackendImpl::Operation { 299 public: 300 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 301 { 302 return adoptPtr(new DeleteRangeOperation(backingStore, databaseId, objectStoreId, keyRange, callbacks)); 303 } 304 virtual void perform(IDBTransactionBackendImpl*); 305 private: 306 DeleteRangeOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 307 : m_backingStore(backingStore) 308 , m_databaseId(databaseId) 309 , m_objectStoreId(objectStoreId) 310 , m_keyRange(keyRange) 311 , m_callbacks(callbacks) 312 { 313 } 314 315 const RefPtr<IDBBackingStore> m_backingStore; 316 const int64_t m_databaseId; 317 const int64_t m_objectStoreId; 318 const RefPtr<IDBKeyRange> m_keyRange; 319 const RefPtr<IDBCallbacks> m_callbacks; 320 }; 321 322 class ClearOperation : public IDBTransactionBackendImpl::Operation { 323 public: 324 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks) 325 { 326 return adoptPtr(new ClearOperation(backingStore, databaseId, objectStoreId, callbacks)); 327 } 328 virtual void perform(IDBTransactionBackendImpl*); 329 private: 330 ClearOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks) 331 : m_backingStore(backingStore) 332 , m_databaseId(databaseId) 333 , m_objectStoreId(objectStoreId) 334 , m_callbacks(callbacks) 335 { 336 } 337 338 const RefPtr<IDBBackingStore> m_backingStore; 339 const int64_t m_databaseId; 340 const int64_t m_objectStoreId; 341 const RefPtr<IDBCallbacks> m_callbacks; 342 }; 157 343 158 344 class IDBDatabaseBackendImpl::PendingOpenCall { … … 317 503 } 318 504 319 void IDBDatabaseBackendImpl::get(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, bool keyOnly, PassRefPtr<IDBCallbacks>) 320 { 321 ASSERT_NOT_REACHED(); 322 } 323 324 void IDBDatabaseBackendImpl::put(int64_t transactionId, int64_t objectStoreId, Vector<uint8_t>* value, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, const Vector<int64_t>& indexIds, const Vector<IndexKeys>&) 325 { 326 ASSERT_NOT_REACHED(); 327 } 328 329 void IDBDatabaseBackendImpl::setIndexKeys(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>&) 330 { 331 ASSERT_NOT_REACHED(); 505 void IDBDatabaseBackendImpl::get(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, bool keyOnly, PassRefPtr<IDBCallbacks> callbacks) 506 { 507 IDB_TRACE("IDBDatabaseBackendImpl::get"); 508 ASSERT(m_transactions.contains(transactionId)); 509 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 510 511 transaction->scheduleTask(GetOperation::create(m_backingStore, metadata(), objectStoreId, indexId, keyRange, keyOnly ? IDBCursorBackendInterface::KeyOnly : IDBCursorBackendInterface::KeyAndValue, callbacks)); 512 } 513 514 void GetOperation::perform(IDBTransactionBackendImpl* transaction) 515 { 516 IDB_TRACE("GetOperation"); 517 518 RefPtr<IDBKey> key; 519 520 if (m_keyRange->isOnlyKey()) 521 key = m_keyRange->lower(); 522 else { 523 RefPtr<IDBBackingStore::Cursor> backingStoreCursor; 524 if (m_indexId == IDBIndexMetadata::InvalidId) { 525 ASSERT(m_cursorType != IDBCursorBackendInterface::KeyOnly); 526 // ObjectStore Retrieval Operation 527 backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT); 528 } else { 529 if (m_cursorType == IDBCursorBackendInterface::KeyOnly) 530 // Index Value Retrieval Operation 531 backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT); 532 else 533 // Index Referenced Value Retrieval Operation 534 backingStoreCursor = m_backingStore->openIndexCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT); 535 } 536 537 if (!backingStoreCursor) { 538 m_callbacks->onSuccess(); 539 return; 540 } 541 542 key = backingStoreCursor->key(); 543 } 544 545 RefPtr<IDBKey> primaryKey; 546 bool ok; 547 if (m_indexId == IDBIndexMetadata::InvalidId) { 548 // Object Store Retrieval Operation 549 Vector<uint8_t> value; 550 ok = m_backingStore->getRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, *key, value); 551 if (!ok) { 552 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord.")); 553 return; 554 } 555 556 if (value.isEmpty()) { 557 m_callbacks->onSuccess(); 558 return; 559 } 560 561 if (m_autoIncrement && !m_keyPath.isNull()) { 562 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), key, m_keyPath); 563 return; 564 } 565 566 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value)); 567 return; 568 569 } 570 571 // From here we are dealing only with indexes. 572 ok = m_backingStore->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, *key, primaryKey); 573 if (!ok) { 574 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex.")); 575 return; 576 } 577 if (m_cursorType == IDBCursorBackendInterface::KeyOnly) { 578 // Index Value Retrieval Operation 579 m_callbacks->onSuccess(primaryKey.get()); 580 return; 581 } 582 583 // Index Referenced Value Retrieval Operation 584 Vector<uint8_t> value; 585 ok = m_backingStore->getRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, *primaryKey, value); 586 if (!ok) { 587 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord.")); 588 return; 589 } 590 591 if (value.isEmpty()) { 592 m_callbacks->onSuccess(); 593 return; 594 } 595 if (m_autoIncrement && !m_keyPath.isNull()) { 596 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), primaryKey, m_keyPath); 597 return; 598 } 599 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value)); 600 } 601 602 void IDBDatabaseBackendImpl::put(int64_t transactionId, int64_t objectStoreId, Vector<uint8_t>* value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys) 603 { 604 IDB_TRACE("IDBDatabaseBackendImpl::put"); 605 606 ASSERT(m_transactions.contains(transactionId)); 607 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 608 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY); 609 610 const IDBObjectStoreMetadata objectStoreMetadata = metadata().objectStores.get(objectStoreId); 611 612 ASSERT(objectStoreMetadata.autoIncrement || key.get()); 613 614 transaction->scheduleTask(PutOperation::create(m_backingStore, id(), objectStoreMetadata, *value, key, putMode, callbacks, indexIds, indexKeys)); 615 } 616 617 void PutOperation::perform(IDBTransactionBackendImpl* transaction) 618 { 619 IDB_TRACE("PutOperation"); 620 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY); 621 ASSERT(m_indexIds.size() == m_indexKeys.size()); 622 bool keyWasGenerated = false; 623 624 RefPtr<IDBKey> key; 625 if (m_putMode != IDBDatabaseBackendInterface::CursorUpdate && m_objectStore.autoIncrement && !m_key) { 626 RefPtr<IDBKey> autoIncKey = IDBObjectStoreBackendImpl::generateKey(m_backingStore, transaction, m_databaseId, m_objectStore.id); 627 keyWasGenerated = true; 628 if (!autoIncKey->isValid()) { 629 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached.")); 630 return; 631 } 632 key = autoIncKey; 633 } else 634 key = m_key; 635 636 ASSERT(key && key->isValid()); 637 638 IDBBackingStore::RecordIdentifier recordIdentifier; 639 if (m_putMode == IDBDatabaseBackendInterface::AddOnly) { 640 bool found = false; 641 bool ok = m_backingStore->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id, *key, &recordIdentifier, found); 642 if (!ok) { 643 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence.")); 644 return; 645 } 646 if (found) { 647 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store.")); 648 return; 649 } 650 } 651 652 Vector<OwnPtr<IDBObjectStoreBackendImpl::IndexWriter> > indexWriters; 653 String errorMessage; 654 bool obeysConstraints = false; 655 bool backingStoreSuccess = IDBObjectStoreBackendImpl::makeIndexWriters(transaction, m_backingStore.get(), m_databaseId, m_objectStore, key, keyWasGenerated, m_indexIds, m_indexKeys, &indexWriters, &errorMessage, obeysConstraints); 656 if (!backingStoreSuccess) { 657 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys.")); 658 return; 659 } 660 if (!obeysConstraints) { 661 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage)); 662 return; 663 } 664 665 // Before this point, don't do any mutation. After this point, rollback the transaction in case of error. 666 backingStoreSuccess = m_backingStore->putRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id, *key, m_value, &recordIdentifier); 667 if (!backingStoreSuccess) { 668 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add.")); 669 return; 670 } 671 672 for (size_t i = 0; i < indexWriters.size(); ++i) { 673 IDBObjectStoreBackendImpl::IndexWriter* indexWriter = indexWriters[i].get(); 674 indexWriter->writeIndexKeys(recordIdentifier, *m_backingStore, transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id); 675 } 676 677 if (m_objectStore.autoIncrement && m_putMode != IDBDatabaseBackendInterface::CursorUpdate && key->type() == IDBKey::NumberType) { 678 bool ok = IDBObjectStoreBackendImpl::updateKeyGenerator(m_backingStore, transaction, m_databaseId, m_objectStore.id, key.get(), !keyWasGenerated); 679 if (!ok) { 680 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator.")); 681 return; 682 } 683 } 684 685 m_callbacks->onSuccess(key.release()); 686 } 687 688 689 void IDBDatabaseBackendImpl::setIndexKeys(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys) 690 { 691 IDB_TRACE("IDBDatabaseBackendImpl::setIndexKeys"); 692 if (!m_transactions.contains(transactionId)) 693 return; 694 695 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 696 if (transaction->isFinished()) 697 return; 698 699 RefPtr<IDBKey> primaryKey = prpPrimaryKey; 700 RefPtr<IDBBackingStore> store = backingStore(); 701 // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity. 702 IDBBackingStore::RecordIdentifier recordIdentifier; 703 bool found = false; 704 bool ok = store->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_metadata.id, objectStoreId, *primaryKey, &recordIdentifier, found); 705 if (!ok) { 706 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error setting index keys.")); 707 return; 708 } 709 if (!found) { 710 RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error setting index keys for object store.")); 711 transaction->abort(error.release()); 712 return; 713 } 714 715 Vector<OwnPtr<IDBObjectStoreBackendImpl::IndexWriter> > indexWriters; 716 String errorMessage; 717 bool obeysConstraints = false; 718 ASSERT(metadata().objectStores.contains(objectStoreId)); 719 const IDBObjectStoreMetadata& objectStoreMetadata = metadata().objectStores.get(objectStoreId); 720 bool backingStoreSuccess = IDBObjectStoreBackendImpl::makeIndexWriters(transaction, store.get(), id(), objectStoreMetadata, primaryKey, false, indexIds, indexKeys, &indexWriters, &errorMessage, obeysConstraints); 721 if (!backingStoreSuccess) { 722 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys.")); 723 return; 724 } 725 if (!obeysConstraints) { 726 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage)); 727 return; 728 } 729 730 for (size_t i = 0; i < indexWriters.size(); ++i) { 731 IDBObjectStoreBackendImpl::IndexWriter* indexWriter = indexWriters[i].get(); 732 indexWriter->writeIndexKeys(recordIdentifier, *store.get(), transaction->backingStoreTransaction(), id(), objectStoreId); 733 } 332 734 } 333 735 334 736 void IDBDatabaseBackendImpl::setIndexesReady(int64_t transactionId, int64_t objectStoreId, const Vector<int64_t>& indexIds) 335 737 { 336 ASSERT_NOT_REACHED(); 738 IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReady"); 739 740 if (!m_transactions.contains(transactionId)) 741 return; 742 743 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 744 if (transaction->isFinished()) 745 return; 746 747 if (!transaction->scheduleTask(IDBTransactionBackendInterface::PreemptiveTask, SetIndexesReadyOperation::create(indexIds.size()))) 748 ASSERT_NOT_REACHED(); 749 } 750 751 void SetIndexesReadyOperation::perform(IDBTransactionBackendImpl* transaction) 752 { 753 IDB_TRACE("SetIndexesReadyOperation"); 754 for (size_t i = 0; i < m_indexCount; ++i) 755 transaction->didCompletePreemptiveEvent(); 337 756 } 338 757 339 758 void IDBDatabaseBackendImpl::openCursor(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, bool keyOnly, TaskType taskType, PassRefPtr<IDBCallbacks> callbacks) 340 759 { 341 ASSERT_NOT_REACHED(); 342 } 343 344 void IDBDatabaseBackendImpl::count(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>) 345 { 346 ASSERT_NOT_REACHED(); 347 } 348 349 void IDBDatabaseBackendImpl::deleteRange(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>) 350 { 351 ASSERT_NOT_REACHED(); 352 } 353 354 void IDBDatabaseBackendImpl::clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks>) 355 { 356 ASSERT_NOT_REACHED(); 760 IDB_TRACE("IDBDatabaseBackendImpl::openCursor"); 761 ASSERT(m_transactions.contains(transactionId)); 762 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 763 764 transaction->scheduleTask(OpenCursorOperation::create(m_backingStore, id(), objectStoreId, indexId, keyRange, direction, keyOnly ? IDBCursorBackendInterface::KeyOnly : IDBCursorBackendInterface::KeyAndValue, taskType, callbacks)); 765 } 766 767 void OpenCursorOperation::perform(IDBTransactionBackendImpl* transaction) 768 { 769 IDB_TRACE("OpenCursorOperation"); 770 771 // The frontend has begun indexing, so this pauses the transaction 772 // until the indexing is complete. This can't happen any earlier 773 // because we don't want to switch to early mode in case multiple 774 // indexes are being created in a row, with put()'s in between. 775 if (m_taskType == IDBDatabaseBackendInterface::PreemptiveTask) 776 transaction->addPreemptiveEvent(); 777 778 IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(m_direction); 779 RefPtr<IDBBackingStore::Cursor> backingStoreCursor; 780 if (m_indexId == IDBIndexMetadata::InvalidId) { 781 ASSERT(m_cursorType != IDBCursorBackendInterface::KeyOnly); 782 backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), direction); 783 } else { 784 ASSERT(m_taskType == IDBDatabaseBackendInterface::NormalTask); 785 if (m_cursorType == IDBCursorBackendInterface::KeyOnly) 786 backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), direction); 787 else 788 backingStoreCursor = m_backingStore->openIndexCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), direction); 789 } 790 791 if (!backingStoreCursor) { 792 m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0)); 793 return; 794 } 795 796 IDBTransactionBackendInterface::TaskType taskType(static_cast<IDBTransactionBackendInterface::TaskType>(m_taskType)); 797 RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), m_cursorType, taskType, transaction, m_objectStoreId); 798 m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value()); 799 } 800 801 void IDBDatabaseBackendImpl::count(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 802 { 803 IDB_TRACE("IDBDatabaseBackendImpl::count"); 804 ASSERT(m_transactions.contains(transactionId)); 805 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 806 ASSERT(metadata().objectStores.contains(objectStoreId)); 807 transaction->scheduleTask(CountOperation::create(m_backingStore, id(), objectStoreId, indexId, keyRange, callbacks)); 808 } 809 810 void CountOperation::perform(IDBTransactionBackendImpl* transaction) 811 { 812 IDB_TRACE("CountOperation"); 813 uint32_t count = 0; 814 RefPtr<IDBBackingStore::Cursor> backingStoreCursor; 815 816 if (m_indexId == IDBIndexMetadata::InvalidId) 817 backingStoreCursor = m_backingStore->openObjectStoreKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT); 818 else 819 backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT); 820 if (!backingStoreCursor) { 821 m_callbacks->onSuccess(count); 822 return; 823 } 824 825 do { 826 ++count; 827 } while (backingStoreCursor->continueFunction(0)); 828 829 m_callbacks->onSuccess(count); 830 } 831 832 void IDBDatabaseBackendImpl::deleteRange(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 833 { 834 IDB_TRACE("IDBDatabaseBackendImpl::deleteRange"); 835 836 ASSERT(m_transactions.contains(transactionId)); 837 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 838 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY); 839 840 transaction->scheduleTask(DeleteRangeOperation::create(m_backingStore, id(), objectStoreId, keyRange, callbacks)); 841 } 842 843 void DeleteRangeOperation::perform(IDBTransactionBackendImpl* transaction) 844 { 845 IDB_TRACE("DeleteRangeOperation"); 846 847 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT); 848 if (backingStoreCursor) { 849 do { 850 m_backingStore->deleteRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, backingStoreCursor->recordIdentifier()); 851 } while (backingStoreCursor->continueFunction(0)); 852 } 853 854 m_callbacks->onSuccess(); 855 } 856 857 void IDBDatabaseBackendImpl::clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks) 858 { 859 IDB_TRACE("IDBDatabaseBackendImpl::clear"); 860 861 ASSERT(m_transactions.contains(transactionId)); 862 IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId); 863 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY); 864 865 transaction->scheduleTask(ClearOperation::create(m_backingStore, id(), objectStoreId, callbacks)); 866 } 867 868 void ClearOperation::perform(IDBTransactionBackendImpl* transaction) 869 { 870 IDB_TRACE("ObjectStoreClearOperation"); 871 m_backingStore->clearObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId); 872 m_callbacks->onSuccess(); 357 873 } 358 874 -
trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp
r138290 r138900 44 44 static const unsigned short defaultDirection = IDBCursor::NEXT; 45 45 46 IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend,IDBObjectStore* objectStore, IDBTransaction* transaction)46 IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction) 47 47 : m_metadata(metadata) 48 , m_backend(backend)49 48 , m_objectStore(objectStore) 50 49 , m_transaction(transaction) 51 50 , m_deleted(false) 52 51 { 53 ASSERT(m_backend);54 52 ASSERT(m_objectStore); 55 53 ASSERT(m_transaction); 54 ASSERT(m_metadata.id != IDBIndexMetadata::InvalidId); 56 55 } 57 56 … … 77 76 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 78 77 request->setCursorDetails(IDBCursorBackendInterface::KeyAndValue, direction); 79 m_backend->openCursor(keyRange, direction, request, m_transaction->backend(), ec); 80 ASSERT(!ec); 78 backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, false, IDBDatabaseBackendInterface::NormalTask, request); 81 79 return request; 82 80 } … … 103 101 } 104 102 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 105 m_backend->count(keyRange, request, m_transaction->backend(), ec);106 ASSERT(!ec);103 IDBDatabaseMetadata metadata(m_transaction->db()->metadata()); 104 backendDB()->count(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, request); 107 105 return request; 108 106 } … … 134 132 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 135 133 request->setCursorDetails(IDBCursorBackendInterface::KeyOnly, direction); 136 m_backend->openKeyCursor(keyRange, direction, request, m_transaction->backend(), ec); 137 ASSERT(!ec); 134 backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, true, IDBDatabaseBackendInterface::NormalTask, request); 138 135 return request; 139 136 } … … 174 171 175 172 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 176 m_backend->get(keyRange, request, m_transaction->backend(), ec); 177 ASSERT(!ec); 173 backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, false, request); 178 174 return request; 179 175 } … … 206 202 207 203 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 208 m_backend->getKey(keyRange, request, m_transaction->backend(), ec); 209 ASSERT(!ec); 210 return request; 204 backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, true, request); 205 return request; 206 } 207 208 IDBDatabaseBackendInterface* IDBIndex::backendDB() const 209 { 210 return m_transaction->backendDB(); 211 211 } 212 212 -
trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h
r134040 r138900 28 28 29 29 #include "IDBCursor.h" 30 #include "IDB IndexBackendInterface.h"30 #include "IDBDatabase.h" 31 31 #include "IDBKeyPath.h" 32 32 #include "IDBKeyRange.h" … … 46 46 class IDBIndex : public ScriptWrappable, public RefCounted<IDBIndex> { 47 47 public: 48 static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend,IDBObjectStore* objectStore, IDBTransaction* transaction)48 static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction) 49 49 { 50 return adoptRef(new IDBIndex(metadata, backend,objectStore, transaction));50 return adoptRef(new IDBIndex(metadata, objectStore, transaction)); 51 51 } 52 52 ~IDBIndex(); … … 84 84 void markDeleted() { m_deleted = true; } 85 85 86 IDBDatabaseBackendInterface* backendDB() const; 87 86 88 private: 87 IDBIndex(const IDBIndexMetadata&, PassRefPtr<IDBIndexBackendInterface>,IDBObjectStore*, IDBTransaction*);89 IDBIndex(const IDBIndexMetadata&, IDBObjectStore*, IDBTransaction*); 88 90 89 91 IDBIndexMetadata m_metadata; 90 RefPtr<IDBIndexBackendInterface> m_backend;91 92 RefPtr<IDBObjectStore> m_objectStore; 92 93 RefPtr<IDBTransaction> m_transaction; -
trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp
r138716 r138900 43 43 namespace WebCore { 44 44 45 class IDBIndexBackendImpl::OpenIndexCursorOperation : public IDBTransactionBackendImpl::Operation { 46 public: 47 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks) 48 { 49 return adoptPtr(new OpenIndexCursorOperation(index, keyRange, direction, cursorType, callbacks)); 50 } 51 virtual void perform(IDBTransactionBackendImpl*); 52 private: 53 OpenIndexCursorOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks) 54 : m_index(index) 55 , m_keyRange(keyRange) 56 , m_direction(direction) 57 , m_cursorType(cursorType) 58 , m_callbacks(callbacks) 59 { 60 } 61 62 RefPtr<IDBIndexBackendImpl> m_index; 63 RefPtr<IDBKeyRange> m_keyRange; 64 unsigned short m_direction; 65 IDBCursorBackendInterface::CursorType m_cursorType; 66 RefPtr<IDBCallbacks> m_callbacks; 67 }; 68 69 class IDBIndexBackendImpl::IndexCountOperation : public IDBTransactionBackendImpl::Operation { 70 public: 71 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 72 { 73 return adoptPtr(new IndexCountOperation(index, keyRange, callbacks)); 74 } 75 virtual void perform(IDBTransactionBackendImpl*); 76 private: 77 IndexCountOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 78 : m_index(index) 79 , m_keyRange(keyRange) 80 , m_callbacks(callbacks) 81 { 82 } 83 84 RefPtr<IDBIndexBackendImpl> m_index; 85 RefPtr<IDBKeyRange> m_keyRange; 86 RefPtr<IDBCallbacks> m_callbacks; 87 }; 88 89 class IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation : public IDBTransactionBackendImpl::Operation { 90 public: 91 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 92 { 93 return adoptPtr(new IndexReferencedValueRetrievalOperation(index, keyRange, callbacks)); 94 } 95 virtual void perform(IDBTransactionBackendImpl*); 96 private: 97 IndexReferencedValueRetrievalOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 98 : m_index(index) 99 , m_keyRange(keyRange) 100 , m_callbacks(callbacks) 101 { 102 } 103 104 RefPtr<IDBIndexBackendImpl> m_index; 105 RefPtr<IDBKeyRange> m_keyRange; 106 RefPtr<IDBCallbacks> m_callbacks; 107 }; 108 109 class IDBIndexBackendImpl::IndexValueRetrievalOperation : public IDBTransactionBackendImpl::Operation { 110 public: 111 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 112 { 113 return adoptPtr(new IndexValueRetrievalOperation(index, keyRange, callbacks)); 114 } 115 virtual void perform(IDBTransactionBackendImpl*); 116 private: 117 IndexValueRetrievalOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks) 118 : m_index(index) 119 , m_keyRange(keyRange) 120 , m_callbacks(callbacks) 121 { 122 } 123 124 RefPtr<IDBIndexBackendImpl> m_index; 125 RefPtr<IDBKeyRange> m_keyRange; 126 RefPtr<IDBCallbacks> m_callbacks; 127 }; 128 129 130 IDBIndexBackendImpl::IDBIndexBackendImpl(const IDBDatabaseBackendImpl* database, IDBObjectStoreBackendImpl* objectStoreBackend, const IDBIndexMetadata& metadata) 45 IDBIndexBackendImpl::IDBIndexBackendImpl(const IDBDatabaseBackendImpl* database, const IDBIndexMetadata& metadata) 131 46 : m_database(database) 132 , m_objectStoreBackend(objectStoreBackend)133 47 , m_metadata(metadata) 134 48 { … … 139 53 } 140 54 141 void IDBIndexBackendImpl::OpenIndexCursorOperation::perform(IDBTransactionBackendImpl* transaction)142 {143 IDB_TRACE("OpenIndexCursorOperation");144 IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(m_direction);145 146 RefPtr<IDBBackingStore::Cursor> backingStoreCursor;147 148 switch (m_cursorType) {149 case IDBCursorBackendInterface::KeyOnly:150 backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), direction);151 break;152 case IDBCursorBackendInterface::KeyAndValue:153 backingStoreCursor = m_index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), direction);154 break;155 default:156 ASSERT_NOT_REACHED();157 }158 159 if (!backingStoreCursor) {160 m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0));161 return;162 }163 164 RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), m_cursorType, transaction, m_index->m_objectStoreBackend);165 m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());166 }167 168 void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)169 {170 IDB_TRACE("IDBIndexBackendImpl::openCursor");171 RefPtr<IDBCallbacks> callbacks = prpCallbacks;172 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);173 transaction->scheduleTask(OpenIndexCursorOperation::create(this, keyRange, direction, IDBCursorBackendInterface::KeyAndValue, callbacks));174 }175 176 void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)177 {178 IDB_TRACE("IDBIndexBackendImpl::openKeyCursor");179 RefPtr<IDBCallbacks> callbacks = prpCallbacks;180 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);181 transaction->scheduleTask(OpenIndexCursorOperation::create(this, keyRange, direction, IDBCursorBackendInterface::KeyOnly, callbacks));182 }183 184 void IDBIndexBackendImpl::IndexCountOperation::perform(IDBTransactionBackendImpl* transaction)185 {186 IDB_TRACE("IndexCountOperation");187 uint32_t count = 0;188 189 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);190 if (!backingStoreCursor) {191 m_callbacks->onSuccess(count);192 return;193 }194 195 do {196 ++count;197 } while (backingStoreCursor->continueFunction(0));198 199 m_callbacks->onSuccess(count);200 }201 202 void IDBIndexBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)203 {204 IDB_TRACE("IDBIndexBackendImpl::count");205 RefPtr<IDBCallbacks> callbacks = prpCallbacks;206 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);207 transaction->scheduleTask(IndexCountOperation::create(this, range, callbacks));208 }209 210 void IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)211 {212 IDB_TRACE("IndexReferencedValueRetrievalOperation");213 214 RefPtr<IDBKey> key;215 216 if (m_keyRange->isOnlyKey())217 key = m_keyRange->lower();218 else {219 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);220 221 if (!backingStoreCursor) {222 m_callbacks->onSuccess();223 return;224 }225 key = backingStoreCursor->key();226 }227 228 RefPtr<IDBKey> primaryKey;229 bool ok = m_index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), *key, primaryKey);230 if (!ok) {231 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));232 return;233 }234 235 Vector<uint8_t> value;236 ok = m_index->backingStore()->getRecord(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), *primaryKey, value);237 if (!ok) {238 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));239 return;240 }241 242 if (value.isEmpty()) {243 m_callbacks->onSuccess();244 return;245 }246 if (m_index->m_objectStoreBackend->autoIncrement() && !m_index->m_objectStoreBackend->keyPath().isNull()) {247 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), primaryKey, m_index->m_objectStoreBackend->keyPath());248 return;249 }250 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value));251 }252 253 254 void IDBIndexBackendImpl::IndexValueRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)255 {256 IDB_TRACE("IndexValueRetrievalOperation");257 258 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);259 260 if (!backingStoreCursor) {261 m_callbacks->onSuccess(static_cast<IDBKey*>(0));262 return;263 }264 265 RefPtr<IDBKey> keyResult;266 bool ok = m_index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), *backingStoreCursor->key(), keyResult);267 if (!ok) {268 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));269 return;270 }271 if (!keyResult) {272 m_callbacks->onSuccess(static_cast<IDBKey*>(0));273 return;274 }275 m_callbacks->onSuccess(keyResult.get());276 }277 278 void IDBIndexBackendImpl::get(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)279 {280 IDB_TRACE("IDBIndexBackendImpl::get");281 RefPtr<IDBCallbacks> callbacks = prpCallbacks;282 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);283 transaction->scheduleTask(IndexReferencedValueRetrievalOperation::create(this, keyRange, callbacks));284 }285 286 void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)287 {288 IDB_TRACE("IDBIndexBackendImpl::getKey");289 RefPtr<IDBCallbacks> callbacks = prpCallbacks;290 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);291 transaction->scheduleTask(IndexValueRetrievalOperation::create(this, keyRange, callbacks));292 }293 294 55 } // namespace WebCore 295 56 -
trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h
r136696 r138900 43 43 class IDBIndexBackendImpl : public IDBIndexBackendInterface { 44 44 public: 45 static PassRefPtr<IDBIndexBackendImpl> create(const IDBDatabaseBackendImpl* database, IDBObjectStoreBackendImpl* objectStoreBackend,const IDBIndexMetadata& metadata)45 static PassRefPtr<IDBIndexBackendImpl> create(const IDBDatabaseBackendImpl* database, const IDBIndexMetadata& metadata) 46 46 { 47 return adoptRef(new IDBIndexBackendImpl(database, objectStoreBackend,metadata));47 return adoptRef(new IDBIndexBackendImpl(database, metadata)); 48 48 } 49 49 virtual ~IDBIndexBackendImpl(); … … 56 56 57 57 // IDBIndexBackendInterface 58 virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;59 virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;60 virtual void openKeyCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;61 virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;62 virtual void getKey(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;58 virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 59 virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 60 virtual void openKeyCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 61 virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 62 virtual void getKey(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 63 63 64 64 IDBIndexMetadata metadata() const { return m_metadata; } … … 69 69 70 70 private: 71 IDBIndexBackendImpl(const IDBDatabaseBackendImpl*, IDBObjectStoreBackendImpl*, const IDBIndexMetadata&); 72 73 class OpenIndexCursorOperation; 74 class IndexCountOperation; 75 class IndexReferencedValueRetrievalOperation; 76 class IndexValueRetrievalOperation; 71 IDBIndexBackendImpl(const IDBDatabaseBackendImpl*, const IDBIndexMetadata&); 77 72 78 73 static const int64_t InvalidId = 0; … … 82 77 83 78 const IDBDatabaseBackendImpl* m_database; 84 85 IDBObjectStoreBackendImpl* m_objectStoreBackend;86 79 87 80 IDBIndexMetadata m_metadata; -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
r138290 r138900 88 88 } 89 89 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 90 m_backend->get(keyRange, request, m_transaction->backend(), ec); 91 ASSERT(!ec); 90 backendDB()->get(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, keyRange, false, request); 92 91 return request.release(); 93 92 } … … 95 94 PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) 96 95 { 97 IDB_TRACE("IDBObjectStore::get");98 96 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec); 99 97 if (ec) … … 215 213 216 214 RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get()); 217 m_backend->put(serializedValue.release(), key.release(), putMode, request, m_transaction->backend(), indexIds, indexKeys);218 ASSERT(!ec);215 Vector<uint8_t> valueBytes = serializedValue->toWireBytes(); 216 backendDB()->put(m_transaction->id(), id(), &valueBytes, key.release(), static_cast<IDBDatabaseBackendInterface::PutMode>(putMode), request, indexIds, indexKeys); 219 217 return request.release(); 220 218 } … … 241 239 242 240 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 243 m_backend->deleteFunction(keyRange, request, m_transaction->backend(), ec); 244 ASSERT(!ec); 241 backendDB()->deleteRange(m_transaction->id(), id(), keyRange, request); 245 242 return request.release(); 246 243 } … … 248 245 PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) 249 246 { 250 IDB_TRACE("IDBObjectStore::delete");251 247 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec); 252 248 if (ec) … … 272 268 273 269 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 274 m_backend->clear(request, m_transaction->backend(), ec); 275 ASSERT(!ec); 270 backendDB()->clear(m_transaction->id(), id(), request); 276 271 return request.release(); 277 272 } … … 285 280 class IndexPopulator : public EventListener { 286 281 public: 287 static PassRefPtr<IndexPopulator> create(PassRefPtr<IDB ObjectStoreBackendInterface> backend, PassRefPtr<IDBTransactionBackendInterface> transaction, PassRefPtr<IDBRequest> request, const IDBIndexMetadata& indexMetadata)282 static PassRefPtr<IndexPopulator> create(PassRefPtr<IDBDatabaseBackendInterface> backend, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) 288 283 { 289 return adoptRef(new IndexPopulator(backend, transaction , indexMetadata));284 return adoptRef(new IndexPopulator(backend, transactionId, objectStoreId, indexMetadata)); 290 285 } 291 286 … … 296 291 297 292 private: 298 IndexPopulator(PassRefPtr<IDBObjectStoreBackendInterface> backend, 299 PassRefPtr<IDBTransactionBackendInterface> transaction, 300 const IDBIndexMetadata& indexMetadata) 293 IndexPopulator(PassRefPtr<IDBDatabaseBackendInterface> backend, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) 301 294 : EventListener(CPPEventListenerType) 302 , m_objectStoreBackend(backend) 303 , m_transaction(transaction) 295 , m_databaseBackend(backend) 296 , m_transactionId(transactionId) 297 , m_objectStoreId(objectStoreId) 304 298 , m_indexMetadata(indexMetadata) 305 299 { … … 334 328 indexKeysList.append(indexKeys); 335 329 336 m_objectStoreBackend->setIndexKeys(primaryKey, indexIds, indexKeysList, m_transaction.get()); 337 330 m_databaseBackend->setIndexKeys(m_transactionId, m_objectStoreId, primaryKey, indexIds, indexKeysList); 338 331 } else { 339 332 // Now that we are done indexing, tell the backend to go 340 333 // back to processing tasks of type NormalTask. 341 m_ objectStoreBackend->setIndexesReady(indexIds, m_transaction.get());342 m_ objectStoreBackend.clear();343 m_transaction.clear();344 } 345 346 } 347 348 RefPtr<IDBObjectStoreBackendInterface> m_objectStoreBackend;349 RefPtr<IDBTransactionBackendInterface> m_transaction;350 IDBIndexMetadata m_indexMetadata;334 m_databaseBackend->setIndexesReady(m_transactionId, m_objectStoreId, indexIds); 335 m_databaseBackend.clear(); 336 } 337 338 } 339 340 RefPtr<IDBDatabaseBackendInterface> m_databaseBackend; 341 const int64_t m_transactionId; 342 const int64_t m_objectStoreId; 343 const IDBIndexMetadata m_indexMetadata; 351 344 }; 352 345 } … … 393 386 394 387 int64_t indexId = m_metadata.maxIndexId + 1; 395 RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->createIndex(indexId, name, keyPath, unique, multiEntry, m_transaction->backend(), ec); 396 ASSERT(!indexBackend != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa. 388 m_backend->createIndex(indexId, name, keyPath, unique, multiEntry, m_transaction->backend(), ec); 397 389 if (ec) 398 390 return 0; … … 401 393 402 394 IDBIndexMetadata metadata(name, indexId, keyPath, unique, multiEntry); 403 RefPtr<IDBIndex> index = IDBIndex::create(metadata, indexBackend.release(),this, m_transaction.get());395 RefPtr<IDBIndex> index = IDBIndex::create(metadata, this, m_transaction.get()); 404 396 m_indexMap.set(name, index); 405 397 m_metadata.indexes.set(indexId, metadata); … … 416 408 417 409 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. 418 RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create( m_backend, m_transaction->backend(), indexRequest, metadata);410 RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(backendDB(), m_transaction->id(), id(), metadata); 419 411 indexRequest->setOnsuccess(indexPopulator); 420 412 … … 443 435 return 0; 444 436 } 445 446 RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->index(indexId);447 ASSERT(!ec && indexBackend);448 437 449 438 const IDBIndexMetadata* indexMetadata(0); … … 455 444 } 456 445 ASSERT(indexMetadata); 457 458 RefPtr<IDBIndex> index = IDBIndex::create(*indexMetadata, indexBackend.release(), this, m_transaction.get()); 446 ASSERT(indexMetadata->id != IDBIndexMetadata::InvalidId); 447 448 RefPtr<IDBIndex> index = IDBIndex::create(*indexMetadata, this, m_transaction.get()); 459 449 m_indexMap.set(name, index); 460 450 return index.release(); … … 505 495 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 506 496 request->setCursorDetails(IDBCursorBackendInterface::KeyAndValue, direction); 507 m_backend->openCursor(range, direction, request, taskType, m_transaction->backend(), ec); 508 ASSERT(!ec);497 498 backendDB()->openCursor(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, direction, false, static_cast<IDBDatabaseBackendInterface::TaskType>(taskType), request); 509 499 return request.release(); 510 500 } … … 512 502 PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, const String& direction, ExceptionCode& ec) 513 503 { 514 IDB_TRACE("IDBObjectStore::openCursor");515 504 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec); 516 505 if (ec) … … 531 520 } 532 521 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 533 m_backend->count(range, request, m_transaction->backend(), ec); 534 ASSERT(!ec); 522 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, request); 535 523 return request.release(); 536 524 } … … 538 526 PassRefPtr<IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) 539 527 { 540 IDB_TRACE("IDBObjectStore::count");541 528 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec); 542 529 if (ec) … … 564 551 } 565 552 553 IDBDatabaseBackendInterface* IDBObjectStore::backendDB() const 554 { 555 return m_transaction->backendDB(); 556 } 557 566 558 } // namespace WebCore 567 559 -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h
r138081 r138900 30 30 #include "IDBCursor.h" 31 31 #include "IDBIndex.h" 32 #include "IDBIndexBackendInterface.h" 32 33 #include "IDBKey.h" 33 34 #include "IDBKeyRange.h" … … 59 60 60 61 // Implement the IDBObjectStore IDL 62 int64_t id() const { return m_metadata.id; } 61 63 const String name() const { return m_metadata.name; } 62 64 PassRefPtr<IDBAny> keyPathAny() const { return IDBAny::create(m_metadata.keyPath); } … … 105 107 typedef HashMap<String, IndexKeys> IndexKeyMap; 106 108 109 IDBDatabaseBackendInterface* backendDB() const; 110 107 111 private: 108 112 IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*); -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp
r138716 r138900 45 45 namespace WebCore { 46 46 47 class IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation : public IDBTransactionBackendImpl::Operation {48 public:49 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)50 {51 return adoptPtr(new ObjectStoreRetrievalOperation(objectStore, keyRange, callbacks));52 }53 virtual void perform(IDBTransactionBackendImpl*);54 private:55 ObjectStoreRetrievalOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)56 : m_objectStore(objectStore)57 , m_keyRange(keyRange)58 , m_callbacks(callbacks)59 {60 }61 62 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;63 RefPtr<IDBKeyRange> m_keyRange;64 RefPtr<IDBCallbacks> m_callbacks;65 };66 67 class IDBObjectStoreBackendImpl::ObjectStoreStorageOperation : public IDBTransactionBackendImpl::Operation {68 public:69 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassOwnPtr<Vector<int64_t> > popIndexIds, PassOwnPtr<Vector<IndexKeys> > popIndexKeys)70 {71 return adoptPtr(new ObjectStoreStorageOperation(objectStore, value, key, putMode, callbacks, popIndexIds, popIndexKeys));72 }73 virtual void perform(IDBTransactionBackendImpl*);74 private:75 ObjectStoreStorageOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassOwnPtr<Vector<int64_t> > popIndexIds, PassOwnPtr<Vector<IndexKeys> > popIndexKeys)76 : m_objectStore(objectStore)77 , m_value(value)78 , m_key(key)79 , m_putMode(putMode)80 , m_callbacks(callbacks)81 , m_popIndexIds(popIndexIds)82 , m_popIndexKeys(popIndexKeys)83 {84 }85 86 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;87 RefPtr<SerializedScriptValue> m_value;88 RefPtr<IDBKey> m_key;89 PutMode m_putMode;90 RefPtr<IDBCallbacks> m_callbacks;91 OwnPtr<Vector<int64_t> > m_popIndexIds;92 OwnPtr<Vector<IndexKeys> > m_popIndexKeys;93 };94 95 class IDBObjectStoreBackendImpl::ObjectStoreIndexesReadyOperation : public IDBTransactionBackendImpl::Operation {96 public:97 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassOwnPtr<Vector<int64_t> > popIndexIds)98 {99 return adoptPtr(new ObjectStoreIndexesReadyOperation(objectStore, popIndexIds));100 }101 virtual void perform(IDBTransactionBackendImpl*);102 private:103 ObjectStoreIndexesReadyOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassOwnPtr<Vector<int64_t> > popIndexIds)104 : m_objectStore(objectStore)105 , m_popIndexIds(popIndexIds)106 {107 }108 109 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;110 OwnPtr<Vector<int64_t> > m_popIndexIds;111 };112 113 class IDBObjectStoreBackendImpl::ObjectStoreDeletionOperation : public IDBTransactionBackendImpl::Operation {114 public:115 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)116 {117 return adoptPtr(new ObjectStoreDeletionOperation(objectStore, keyRange, callbacks));118 }119 virtual void perform(IDBTransactionBackendImpl*);120 private:121 ObjectStoreDeletionOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)122 : m_objectStore(objectStore)123 , m_keyRange(keyRange)124 , m_callbacks(callbacks)125 {126 }127 128 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;129 RefPtr<IDBKeyRange> m_keyRange;130 RefPtr<IDBCallbacks> m_callbacks;131 };132 133 class IDBObjectStoreBackendImpl::ObjectStoreClearOperation : public IDBTransactionBackendImpl::Operation {134 public:135 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)136 {137 return adoptPtr(new ObjectStoreClearOperation(objectStore, callbacks));138 }139 virtual void perform(IDBTransactionBackendImpl*);140 private:141 ObjectStoreClearOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)142 : m_objectStore(objectStore)143 , m_callbacks(callbacks)144 {145 }146 147 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;148 RefPtr<IDBCallbacks> m_callbacks;149 };150 151 47 class IDBObjectStoreBackendImpl::CreateIndexOperation : public IDBTransactionBackendImpl::Operation { 152 48 public: … … 185 81 }; 186 82 187 class IDBObjectStoreBackendImpl::OpenObjectStoreCursorOperation : public IDBTransactionBackendImpl::Operation {188 public:189 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType)190 {191 return adoptPtr(new OpenObjectStoreCursorOperation(objectStore, range, direction, callbacks, taskType));192 }193 virtual void perform(IDBTransactionBackendImpl*);194 private:195 OpenObjectStoreCursorOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType)196 : m_objectStore(objectStore)197 , m_range(range)198 , m_direction(direction)199 , m_callbacks(callbacks)200 , m_taskType(taskType)201 {202 }203 204 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;205 RefPtr<IDBKeyRange> m_range;206 IDBCursor::Direction m_direction;207 RefPtr<IDBCallbacks> m_callbacks;208 IDBTransactionBackendInterface::TaskType m_taskType;209 };210 211 class IDBObjectStoreBackendImpl::ObjectStoreCountOperation : public IDBTransactionBackendImpl::Operation {212 public:213 static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks)214 {215 return adoptPtr(new ObjectStoreCountOperation(objectStore, range, callbacks));216 }217 virtual void perform(IDBTransactionBackendImpl*);218 private:219 ObjectStoreCountOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks)220 : m_objectStore(objectStore)221 , m_range(range)222 , m_callbacks(callbacks)223 {224 }225 226 RefPtr<IDBObjectStoreBackendImpl> m_objectStore;227 RefPtr<IDBKeyRange> m_range;228 RefPtr<IDBCallbacks> m_callbacks;229 };230 231 83 class IDBObjectStoreBackendImpl::CreateIndexAbortOperation : public IDBTransactionBackendImpl::Operation { 232 84 public: … … 283 135 metadata.indexes.set(it->key, it->value->metadata()); 284 136 return metadata; 285 }286 287 void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)288 {289 IDB_TRACE("IDBObjectStoreBackendImpl::get");290 RefPtr<IDBCallbacks> callbacks = prpCallbacks;291 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);292 transaction->scheduleTask(ObjectStoreRetrievalOperation::create(this, keyRange, callbacks));293 }294 295 void IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)296 {297 IDB_TRACE("ObjectStoreRetrievalOperation");298 RefPtr<IDBKey> key;299 if (m_keyRange->isOnlyKey())300 key = m_keyRange->lower();301 else {302 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_keyRange.get(), IDBCursor::NEXT);303 if (!backingStoreCursor) {304 m_callbacks->onSuccess();305 return;306 }307 key = backingStoreCursor->key();308 }309 310 Vector<uint8_t> wireData;311 bool ok = m_objectStore->backingStore()->getRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *key, wireData);312 if (!ok) {313 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));314 return;315 }316 if (wireData.isEmpty()) {317 m_callbacks->onSuccess();318 return;319 }320 321 if (m_objectStore->autoIncrement() && !m_objectStore->keyPath().isNull()) {322 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData), key, m_objectStore->keyPath());323 return;324 }325 m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData));326 }327 328 void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)329 {330 IDB_TRACE("IDBObjectStoreBackendImpl::put");331 332 RefPtr<IDBCallbacks> callbacks = prpCallbacks;333 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);334 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);335 336 OwnPtr<Vector<int64_t> > newIndexIds = adoptPtr(new Vector<int64_t>(indexIds));337 OwnPtr<Vector<IndexKeys> > newIndexKeys = adoptPtr(new Vector<IndexKeys>(indexKeys));338 339 ASSERT(autoIncrement() || key.get());340 341 transaction->scheduleTask(ObjectStoreStorageOperation::create(this, value, key, putMode, callbacks, newIndexIds.release(), newIndexKeys.release()));342 137 } 343 138 … … 418 213 } 419 214 420 void IDBObjectStoreBackendImpl::setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys, IDBTransactionBackendInterface* transactionPtr)421 {422 IDB_TRACE("IDBObjectStoreBackendImpl::setIndexKeys");423 RefPtr<IDBKey> primaryKey = prpPrimaryKey;424 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);425 if (transaction->isFinished())426 return;427 428 // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity.429 IDBBackingStore::RecordIdentifier recordIdentifier;430 bool found = false;431 bool ok = backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), databaseId(), id(), *primaryKey, &recordIdentifier, found);432 if (!ok) {433 LOG_ERROR("keyExistsInObjectStore reported an error");434 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error setting index keys."));435 return;436 }437 if (!found) {438 RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error setting index keys for object store '%s'.", name().utf8().data()));439 transaction->abort(error.release());440 return;441 }442 443 Vector<OwnPtr<IndexWriter> > indexWriters;444 String errorMessage;445 bool obeysConstraints = false;446 RefPtr<IDBBackingStore> store = backingStore();447 bool backingStoreSuccess = makeIndexWriters(transaction, store.get(), databaseId(), metadata(), primaryKey, false, indexIds, indexKeys, &indexWriters, &errorMessage, obeysConstraints);448 if (!backingStoreSuccess) {449 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));450 return;451 }452 if (!obeysConstraints) {453 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));454 return;455 }456 457 for (size_t i = 0; i < indexWriters.size(); ++i) {458 IndexWriter* indexWriter = indexWriters[i].get();459 indexWriter->writeIndexKeys(recordIdentifier, *backingStore(), transaction->backingStoreTransaction(), databaseId(), m_metadata.id);460 }461 }462 463 void IDBObjectStoreBackendImpl::setIndexesReady(const Vector<int64_t>& indexIds, IDBTransactionBackendInterface* transactionInterface)464 {465 IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReady");466 467 OwnPtr<Vector<int64_t> > newIndexIds = adoptPtr(new Vector<int64_t>(indexIds));468 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionInterface);469 if (transaction->isFinished())470 return;471 472 if (!transaction->scheduleTask(IDBTransactionBackendInterface::PreemptiveTask, ObjectStoreIndexesReadyOperation::create(this, newIndexIds.release())))473 ASSERT_NOT_REACHED();474 }475 476 void IDBObjectStoreBackendImpl::ObjectStoreIndexesReadyOperation::perform(IDBTransactionBackendImpl* transaction)477 {478 IDB_TRACE("ObjectStoreIndexesReadyOperation");479 for (size_t i = 0; i < m_popIndexIds->size(); ++i)480 transaction->didCompletePreemptiveEvent();481 }482 483 void IDBObjectStoreBackendImpl::ObjectStoreStorageOperation::perform(IDBTransactionBackendImpl* transaction)484 {485 IDB_TRACE("ObjectStoreStorageOperation");486 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);487 ASSERT(m_popIndexIds && m_popIndexKeys && m_popIndexIds->size() == m_popIndexKeys->size());488 const bool autoIncrement = m_objectStore->autoIncrement();489 bool keyWasGenerated = false;490 491 if (m_putMode != CursorUpdate && autoIncrement && !m_key) {492 RefPtr<IDBKey> autoIncKey = m_objectStore->generateKey(transaction);493 keyWasGenerated = true;494 if (!autoIncKey->isValid()) {495 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));496 return;497 }498 m_key = autoIncKey;499 }500 501 ASSERT(m_key && m_key->isValid());502 503 IDBObjectStoreMetadata objectStoreMetadata = m_objectStore->metadata();504 IDBBackingStore::RecordIdentifier recordIdentifier;505 RefPtr<IDBBackingStore> backingStore = m_objectStore->backingStore();506 if (m_putMode == AddOnly) {507 bool found = false;508 bool ok = backingStore->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, &recordIdentifier, found);509 if (!ok) {510 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));511 return;512 }513 if (found) {514 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));515 return;516 }517 }518 519 Vector<OwnPtr<IndexWriter> > indexWriters;520 String errorMessage;521 bool obeysConstraints = false;522 bool backingStoreSuccess = makeIndexWriters(transaction, backingStore.get(), m_objectStore->databaseId(), objectStoreMetadata, m_key, keyWasGenerated, *m_popIndexIds, *m_popIndexKeys, &indexWriters, &errorMessage, obeysConstraints);523 if (!backingStoreSuccess) {524 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));525 return;526 }527 if (!obeysConstraints) {528 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));529 return;530 }531 532 // Before this point, don't do any mutation. After this point, rollback the transaction in case of error.533 534 backingStoreSuccess = m_objectStore->backingStore()->putRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, m_value->toWireBytes(), &recordIdentifier);535 if (!backingStoreSuccess) {536 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));537 return;538 }539 540 for (size_t i = 0; i < indexWriters.size(); ++i) {541 IndexWriter* indexWriter = indexWriters[i].get();542 indexWriter->writeIndexKeys(recordIdentifier, *m_objectStore->backingStore(), transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->m_metadata.id);543 }544 545 if (autoIncrement && m_putMode != CursorUpdate && m_key->type() == IDBKey::NumberType) {546 bool ok = m_objectStore->updateKeyGenerator(transaction, m_key.get(), !keyWasGenerated);547 if (!ok) {548 m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));549 return;550 }551 }552 553 m_callbacks->onSuccess(m_key.release());554 }555 556 void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)557 {558 IDB_TRACE("IDBObjectStoreBackendImpl::delete");559 560 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);561 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);562 transaction->scheduleTask(ObjectStoreDeletionOperation::create(this, keyRange, callbacks));563 }564 565 void IDBObjectStoreBackendImpl::ObjectStoreDeletionOperation::perform(IDBTransactionBackendImpl* transaction)566 {567 IDB_TRACE("ObjectStoreDeletionOperation");568 569 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_keyRange.get(), IDBCursor::NEXT);570 if (backingStoreCursor) {571 572 do {573 m_objectStore->backingStore()->deleteRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), backingStoreCursor->recordIdentifier());574 575 } while (backingStoreCursor->continueFunction(0));576 }577 578 m_callbacks->onSuccess();579 }580 581 void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)582 {583 IDB_TRACE("IDBObjectStoreBackendImpl::clear");584 585 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);586 ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);587 transaction->scheduleTask(ObjectStoreClearOperation::create(this, callbacks));588 }589 590 void IDBObjectStoreBackendImpl::ObjectStoreClearOperation::perform(IDBTransactionBackendImpl* transaction)591 {592 IDB_TRACE("ObjectStoreClearOperation");593 m_objectStore->backingStore()->clearObjectStore(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id());594 m_callbacks->onSuccess();595 }596 597 215 PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(int64_t id, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) 598 216 { 599 217 ASSERT_WITH_MESSAGE(!m_indexes.contains(id), "Indexes already contain '%s'", name.utf8().data()); 600 218 601 RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database, this,IDBIndexMetadata(name, id, keyPath, unique, multiEntry));219 RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database, IDBIndexMetadata(name, id, keyPath, unique, multiEntry)); 602 220 ASSERT(index->name() == name); 603 221 … … 653 271 } 654 272 655 void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)656 {657 IDB_TRACE("IDBObjectStoreBackendImpl::openCursor");658 RefPtr<IDBCallbacks> callbacks = prpCallbacks;659 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);660 transaction->scheduleTask(OpenObjectStoreCursorOperation::create(this, range, direction, callbacks, taskType));661 }662 663 void IDBObjectStoreBackendImpl::OpenObjectStoreCursorOperation::perform(IDBTransactionBackendImpl* transaction)664 {665 IDB_TRACE("OpenObjectStoreCursor");666 667 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_range.get(), m_direction);668 // The frontend has begun indexing, so this pauses the transaction669 // until the indexing is complete. This can't happen any earlier670 // because we don't want to switch to early mode in case multiple671 // indexes are being created in a row, with put()'s in between.672 if (m_taskType == IDBTransactionBackendInterface::PreemptiveTask)673 transaction->addPreemptiveEvent();674 if (!backingStoreCursor) {675 m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0));676 return;677 }678 679 RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), IDBCursorBackendInterface::KeyAndValue, m_taskType, transaction, m_objectStore.get());680 m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());681 }682 683 void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)684 {685 IDB_TRACE("IDBObjectStoreBackendImpl::count");686 RefPtr<IDBCallbacks> callbacks = prpCallbacks;687 RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);688 transaction->scheduleTask(ObjectStoreCountOperation::create(this, range, callbacks));689 }690 691 void IDBObjectStoreBackendImpl::ObjectStoreCountOperation::perform(IDBTransactionBackendImpl* transaction)692 {693 IDB_TRACE("ObjectStoreCountOperation");694 uint32_t count = 0;695 RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreKeyCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_range.get(), IDBCursor::NEXT);696 if (!backingStoreCursor) {697 m_callbacks->onSuccess(count);698 return;699 }700 701 do {702 ++count;703 } while (backingStoreCursor->continueFunction(0));704 705 m_callbacks->onSuccess(count);706 }707 708 273 void IDBObjectStoreBackendImpl::loadIndexes() 709 274 { … … 711 276 712 277 for (size_t i = 0; i < indexes.size(); ++i) 713 m_indexes.set(indexes[i].id, IDBIndexBackendImpl::create(m_database, this,indexes[i]));278 m_indexes.set(indexes[i].id, IDBIndexBackendImpl::create(m_database, indexes[i])); 714 279 } 715 280 … … 728 293 } 729 294 730 PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::generateKey(PassRefPtr<IDB TransactionBackendImpl> transaction)295 PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::generateKey(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendImpl> transaction, int64_t databaseId, int64_t objectStoreId) 731 296 { 732 297 const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number. 733 298 int64_t currentNumber; 734 bool ok = backingStore ()->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), currentNumber);299 bool ok = backingStore->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, currentNumber); 735 300 if (!ok) { 736 301 LOG_ERROR("Failed to getKeyGeneratorCurrentNumber"); … … 743 308 } 744 309 745 bool IDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDB TransactionBackendImpl> transaction, const IDBKey* key, bool checkCurrent)310 bool IDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendImpl> transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey* key, bool checkCurrent) 746 311 { 747 312 ASSERT(key && key->type() == IDBKey::NumberType); 748 return backingStore ()->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), static_cast<int64_t>(floor(key->number())) + 1, checkCurrent);313 return backingStore->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, static_cast<int64_t>(floor(key->number())) + 1, checkCurrent); 749 314 } 750 315 -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h
r138290 r138900 63 63 64 64 // IDBObjectStoreBackendInterface 65 virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;66 virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<int64_t>&, const Vector<IndexKeys>&) ;65 virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 66 virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<int64_t>&, const Vector<IndexKeys>&) { ASSERT_NOT_REACHED(); } 67 67 68 virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;69 virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;68 virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 69 virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 70 70 71 71 virtual PassRefPtr<IDBIndexBackendInterface> createIndex(int64_t, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&); 72 virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>&, const Vector<IndexKeys>&, IDBTransactionBackendInterface*) ;73 virtual void setIndexesReady(const Vector<int64_t>&, IDBTransactionBackendInterface*) ;72 virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>&, const Vector<IndexKeys>&, IDBTransactionBackendInterface*) { ASSERT_NOT_REACHED(); } 73 virtual void setIndexesReady(const Vector<int64_t>&, IDBTransactionBackendInterface*) { ASSERT_NOT_REACHED(); } 74 74 virtual PassRefPtr<IDBIndexBackendInterface> index(int64_t); 75 75 virtual void deleteIndex(int64_t, IDBTransactionBackendInterface*, ExceptionCode&); 76 76 77 virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&) ;78 virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) ;77 virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 78 virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); } 79 79 80 80 static bool populateIndex(IDBBackingStore&, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl>); 81 82 const IndexMap::iterator iterIndexesBegin() { return m_indexes.begin(); };83 const IndexMap::iterator iterIndexesEnd() { return m_indexes.end(); };84 81 85 82 IDBObjectStoreMetadata metadata() const; … … 115 112 static bool makeIndexWriters(PassRefPtr<IDBTransactionBackendImpl>, IDBBackingStore*, int64_t databaseId, const IDBObjectStoreMetadata&, PassRefPtr<IDBKey> primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIds, const Vector<IDBObjectStoreBackendInterface::IndexKeys>&, Vector<OwnPtr<IndexWriter> >* indexWriters, String* errorMessage, bool& completed) WARN_UNUSED_RETURN; 116 113 114 static PassRefPtr<IDBKey> generateKey(PassRefPtr<IDBBackingStore>, PassRefPtr<IDBTransactionBackendImpl>, int64_t databaseId, int64_t objectStoreId); 115 static bool updateKeyGenerator(PassRefPtr<IDBBackingStore>, PassRefPtr<IDBTransactionBackendImpl>, int64_t databaseId, int64_t objectStoreId, const IDBKey*, bool checkCurrent); 116 117 117 private: 118 118 IDBObjectStoreBackendImpl(const IDBDatabaseBackendImpl*, const IDBObjectStoreMetadata&); 119 119 120 120 void loadIndexes(); 121 PassRefPtr<IDBKey> generateKey(PassRefPtr<IDBTransactionBackendImpl>);122 bool updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl>, const IDBKey*, bool checkCurrent);123 121 124 class ObjectStoreRetrievalOperation;125 class ObjectStoreStorageOperation;126 class ObjectStoreIndexesReadyOperation;127 class ObjectStoreDeletionOperation;128 class ObjectStoreClearOperation;129 122 class CreateIndexOperation; 130 123 class DeleteIndexOperation; 131 class OpenObjectStoreCursorOperation;132 class ObjectStoreCountOperation;133 124 134 125 // When a "versionchange" transaction aborts, these restore the back-end object hierarchy. -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
r136894 r138900 464 464 } 465 465 466 IDBDatabaseBackendInterface* IDBTransaction::backendDB() const 467 { 468 return db()->backend(); 469 } 470 466 471 } 467 472 -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h
r138674 r138900 48 48 class IDBOpenDBRequest; 49 49 class IDBTransactionBackendInterface; 50 class IDBDatabaseBackendInterface; 50 51 struct IDBObjectStoreMetadata; 51 52 … … 72 73 73 74 IDBTransactionBackendInterface* backend() const; 75 IDBDatabaseBackendInterface* backendDB() const; 76 74 77 int64_t id() const { return m_id; } 75 78 bool isActive() const { return m_state == Active; } -
trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.h
r136992 r138900 78 78 int64_t id() const { return m_id; } 79 79 80 IDBDatabaseBackendImpl* database() const { return m_database.get(); } 81 80 82 private: 81 83 IDBTransactionBackendImpl(int64_t id, const HashSet<int64_t>& objectStoreIds, IDBTransaction::Mode, IDBDatabaseBackendImpl*); -
trunk/Source/WebKit/chromium/ChangeLog
r138898 r138900 1 2013-01-05 Alec Flett <alecflett@chromium.org> 2 3 IndexedDB: Migrate backend ObjectStore calls to use transaction id 4 https://bugs.webkit.org/show_bug.cgi?id=102741 5 6 Reviewed by Tony Chang. 7 8 Fix a bug where an array was initialized with a large empty buffer, 9 clean up whitespace, and update to match signatures that changed 10 in WebCore. 11 12 * public/WebIDBDatabase.h: 13 (WebKit::WebIDBDatabase::clear): 14 * src/WebIDBDatabaseImpl.cpp: 15 (WebKit::WebIDBDatabaseImpl::put): 16 * src/WebIDBIndexImpl.cpp: 17 * tests/IDBDatabaseBackendTest.cpp: 18 1 19 2013-01-05 Alec Flett <alecflett@chromium.org> 2 20 -
trunk/Source/WebKit/chromium/public/WebIDBDatabase.h
r138898 r138900 93 93 virtual void count(long long transactionId, long long objectStoreId, long long indexId, const WebIDBKeyRange&, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } 94 94 virtual void deleteRange(long long transactionId, long long objectStoreId, const WebIDBKeyRange&, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } 95 virtual void clear(long long transactionId, long long objectStoreId, WebIDBCallbacks*) 95 virtual void clear(long long transactionId, long long objectStoreId, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } 96 96 97 97 protected: -
trunk/Source/WebKit/chromium/src/WebIDBDatabaseImpl.cpp
r138898 r138900 165 165 } 166 166 167 Vector<uint8_t> valueBuffer (value->size());167 Vector<uint8_t> valueBuffer; 168 168 valueBuffer.append(value->data(), value->size()); 169 169 m_databaseBackend->put(transactionId, objectStoreId, &valueBuffer, key, static_cast<IDBDatabaseBackendInterface::PutMode>(putMode), IDBCallbacksProxy::create(adoptPtr(callbacks)), indexIds, indexKeys); -
trunk/Source/WebKit/chromium/src/WebIDBIndexImpl.cpp
r121183 r138900 31 31 #include "IDBCallbacksProxy.h" 32 32 #include "IDBIndex.h" 33 #include "IDBIndexBackendInterface.h" 33 34 #include "IDBKeyRange.h" 34 35 #include "WebIDBCallbacks.h" -
trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp
r138898 r138900 63 63 const bool unique = false; 64 64 const bool multiEntry = false; 65 RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(db.get(), store.get(),IDBIndexMetadata("index", -1, IDBKeyPath("keyPath"), unique, multiEntry));65 RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(db.get(), IDBIndexMetadata("index", -1, IDBKeyPath("keyPath"), unique, multiEntry)); 66 66 EXPECT_GT(backingStore->refCount(), 1); 67 67
Note: See TracChangeset
for help on using the changeset viewer.