15af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke/* 22daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved. 35af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * 45af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * Redistribution and use in source and binary forms, with or without 55af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * modification, are permitted provided that the following conditions 65af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * are met: 75af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * 85af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * 1. Redistributions of source code must retain the above copyright 95af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * notice, this list of conditions and the following disclaimer. 105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * 2. Redistributions in binary form must reproduce the above copyright 115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * notice, this list of conditions and the following disclaimer in the 125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * documentation and/or other materials provided with the distribution. 135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * 145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke */ 255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "config.h" 27dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBObjectStoreBackendImpl.h" 285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if ENABLE(INDEXED_DATABASE) 30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CrossThreadTask.h" 325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "DOMStringList.h" 3381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "IDBBackingStore.h" 34e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "IDBBindingUtilities.h" 355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "IDBCallbacks.h" 36dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBCursorBackendImpl.h" 37e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBDatabaseBackendImpl.h" 385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "IDBDatabaseException.h" 39db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "IDBIndexBackendImpl.h" 40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "IDBKey.h" 41e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBKeyPath.h" 42e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBKeyPathBackendImpl.h" 43dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBKeyRange.h" 44bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "IDBTransactionBackendInterface.h" 45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "ScriptExecutionContext.h" 465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkenamespace WebCore { 485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 49dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochIDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl() 505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochIDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, int64_t id, const String& name, const String& keyPath, bool autoIncrement) 5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_backingStore(backingStore) 552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_databaseId(databaseId) 56e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_id(id) 57e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_name(name) 58545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch , m_keyPath(keyPath) 59545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch , m_autoIncrement(autoIncrement) 60ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch , m_autoIncrementNumber(-1) 615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 62e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block loadIndexes(); 635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochIDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement) 6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_backingStore(backingStore) 672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_databaseId(databaseId) 68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_id(InvalidId) 69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_name(name) 70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_keyPath(keyPath) 71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_autoIncrement(autoIncrement) 72ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch , m_autoIncrementNumber(-1) 73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 76dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochPassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const 775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<DOMStringList> indexNames = DOMStringList::create(); 795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke for (IndexMap::const_iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) 805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke indexNames->append(it->first); 815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return indexNames.release(); 825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) 85bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBKey> key = prpKey; 88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBCallbacks> callbacks = prpCallbacks; 89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::getInternal, objectStore, key, callbacks))) 90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) 94e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String wireData = objectStore->m_backingStore->getObjectStoreRecord(objectStore->m_databaseId, objectStore->id(), *key); 9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (wireData.isNull()) { 97ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch callbacks->onSuccess(SerializedScriptValue::undefinedValue()); 98e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return; 99e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 100e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData)); 102e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 103e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickstatic PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const String& keyPath) 1055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 1065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick Vector<RefPtr<SerializedScriptValue> > values; 1075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick values.append(value); 1085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick Vector<RefPtr<IDBKey> > keys; 1095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys); 1105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (keys.isEmpty()) 1115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return 0; 1125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick ASSERT(keys.size() == 1); 1135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return keys[0].release(); 1145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath) 1175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(key, value, keyPath); 119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) 122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (transactionPtr->mode() == IDBTransaction::READ_ONLY) { 12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ec = IDBDatabaseException::READ_ONLY_ERR; 12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<SerializedScriptValue> value = prpValue; 130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBKey> key = prpKey; 131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBCallbacks> callbacks = prpCallbacks; 132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; 133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: This should throw a SERIAL_ERR on structured clone problems. 134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: This should throw a DATA_ERR when the wrong key/keyPath data is supplied. 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction))) 136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 1375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 13981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochPassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks, RefPtr<SerializedScriptValue>& value) 140e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (putMode == CursorUpdate) 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(key); 143e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const bool autoIncrement = objectStore->autoIncrement(); 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const bool hasKeyPath = !objectStore->m_keyPath.isNull(); 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (hasKeyPath && key && putMode != CursorUpdate) { 148ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "A key was supplied for an objectStore that has a keyPath.")); 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 150ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 151ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (autoIncrement && key) { 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block objectStore->resetAutoIncrementKeyCache(); 1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return key; 155ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 156ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (autoIncrement) { 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!key); 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!hasKeyPath) 1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return objectStore->genAutoIncrementKey(); 161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath); 1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (keyPathKey) { 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block objectStore->resetAutoIncrementKeyCache(); 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return keyPathKey; 166e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 167ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBKey> autoIncKey = objectStore->genAutoIncrementKey(); 16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(autoIncKey, value, objectStore->m_keyPath); 17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!valueAfterInjection) { 17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The generated key could not be inserted into the object using the keyPath.")); 17281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return 0; 17381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch value = valueAfterInjection; 17581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return autoIncKey.release(); 1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (hasKeyPath) { 17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath); 1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!keyPathKey) { 182ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key could not be fetched from the keyPath.")); 1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 184e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (putMode == CursorUpdate && !keyPathKey->isEqual(key)) { 1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key fetched from the keyPath does not match the key of the cursor.")); 1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return keyPathKey.release(); 1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!key) { 1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "No key supplied")); 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 197e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 198ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return key; 2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) 2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<SerializedScriptValue> value = prpValue; 20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), prpKey.get(), putMode, callbacks.get(), value); 2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!key) 2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (key->type() == IDBKey::NullType) { 2104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "NULL key is not allowed.")); 2114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return; 2124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 213e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 2145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick Vector<RefPtr<IDBKey> > indexKeys; 215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) { 2165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick RefPtr<IDBKey> key = fetchKeyFromKeyPath(value.get(), it->second->keyPath()); 2175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!key) { 2185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from an index's keyPath.")); 2195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 2214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (key->type() == IDBKey::NullType) { 2224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "One of the derived (from a keyPath) keys for an index is NULL.")); 2234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return; 2244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 2255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!it->second->addingKeyAllowed(key.get())) { 2265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements.")); 2275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 2295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick indexKeys.append(key.release()); 2305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 2315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> recordIdentifier = objectStore->m_backingStore->createInvalidRecordIdentifier(); 2332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool isExistingValue = objectStore->m_backingStore->keyExistsInObjectStore(objectStore->m_databaseId, objectStore->id(), *key, recordIdentifier.get()); 234e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (putMode == AddOnly && isExistingValue) { 236e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); 237e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return; 238e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 239e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Before this point, don't do any mutation. After this point, rollback the transaction in case of error. 241e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 2422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->putObjectStoreRecord(objectStore->m_databaseId, objectStore->id(), *key, value->toWireString(), recordIdentifier.get())) { 243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors. 244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage.")); 245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->abort(); 246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick int i = 0; 250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it, ++i) { 25181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!it->second->hasValidId()) 25281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch continue; // The index object has been created, but does not exist in the database yet. 2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->deleteIndexDataForRecord(objectStore->m_databaseId, objectStore->id(), it->second->id(), recordIdentifier.get())) { 2552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors. 2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage.")); 2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch transaction->abort(); 2582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 2592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 2602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->putIndexDataForRecord(objectStore->m_databaseId, objectStore->id(), it->second->id(), *indexKeys[i], recordIdentifier.get())) { 262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors. 263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage.")); 264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->abort(); 265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 268e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 269e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke callbacks->onSuccess(key.get()); 270e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 271e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 2724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) 273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (transaction->mode() == IDBTransaction::READ_ONLY) { 27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ec = IDBDatabaseException::READ_ONLY_ERR; 27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBKey> key = prpKey; 281a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBCallbacks> callbacks = prpCallbacks; 28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::deleteInternal, objectStore, key, callbacks))) 284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBObjectStoreBackendImpl::deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) 288e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> recordIdentifier = objectStore->m_backingStore->createInvalidRecordIdentifier(); 2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->keyExistsInObjectStore(objectStore->m_databaseId, objectStore->id(), *key, recordIdentifier.get())) { 291e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store.")); 292e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 293e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 294e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) { 2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!it->second->hasValidId()) 2972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch continue; // The index object has been created, but does not exist in the database yet. 2982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 2992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->deleteIndexDataForRecord(objectStore->m_databaseId, objectStore->id(), it->second->id(), recordIdentifier.get())) 3002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT_NOT_REACHED(); 3012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 3022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch objectStore->m_backingStore->deleteObjectStoreRecord(objectStore->m_databaseId, objectStore->id(), recordIdentifier.get()); 3042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callbacks->onSuccess(SerializedScriptValue::nullValue()); 3052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) 3082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 3092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (transaction->mode() == IDBTransaction::READ_ONLY) { 3102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ec = IDBDatabaseException::READ_ONLY_ERR; 3112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 3122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 3132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 3152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<IDBCallbacks> callbacks = prpCallbacks; 3162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::clearInternal, objectStore, callbacks))) 3182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ec = IDBDatabaseException::NOT_ALLOWED_ERR; 3192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 3202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 32181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks) 3222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch objectStore->m_backingStore->clearObjectStore(objectStore->m_databaseId, objectStore->id()); 32481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch callbacks->onSuccess(SerializedScriptValue::undefinedValue()); 3252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 3262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 32781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochnamespace { 32881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass PopulateIndexCallback : public IDBBackingStore::ObjectStoreRecordCallback { 32981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochpublic: 3302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch PopulateIndexCallback(IDBBackingStore& backingStore, const String& indexKeyPath, int64_t databaseId, int64_t objectStoreId, int64_t indexId) 33181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_backingStore(backingStore) 33281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_indexKeyPath(indexKeyPath) 3332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_databaseId(databaseId) 3342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_objectStoreId(objectStoreId) 33581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_indexId(indexId) 33681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 33781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 3382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual bool callback(const IDBBackingStore::ObjectStoreRecordIdentifier* recordIdentifier, const String& value) 34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch { 34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<SerializedScriptValue> objectValue = SerializedScriptValue::createFromWire(value); 34281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(objectValue.get(), m_indexKeyPath); 34381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 34454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block if (!indexKey) 34554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block return true; 3462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_backingStore.putIndexDataForRecord(m_databaseId, m_objectStoreId, m_indexId, *indexKey, recordIdentifier)) 34781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 34881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 34981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return true; 35081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 35181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 35281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochprivate: 35381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch IDBBackingStore& m_backingStore; 35481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch const String& m_indexKeyPath; 3552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_databaseId; 3562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch int64_t m_objectStoreId; 35781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int64_t m_indexId; 35881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}; 35981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 36081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 3612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool populateIndex(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& indexKeyPath) 36281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 3632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch PopulateIndexCallback callback(backingStore, indexKeyPath, databaseId, objectStoreId, indexId); 3642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!backingStore.forEachObjectStoreRecord(databaseId, objectStoreId, callback)) 36581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 36681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return true; 367e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 368e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 369a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const String& keyPath, bool unique, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) 3705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 3715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (m_indexes.contains(name)) { 372a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::CONSTRAINT_ERR; 373a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 374a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 375a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (transaction->mode() != IDBTransaction::VERSION_CHANGE) { 376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 3795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 3802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_backingStore.get(), m_databaseId, this, name, m_name, keyPath, unique); 3815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(index->name() == name); 382a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 383a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 384a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBTransactionBackendInterface> transactionPtr = transaction; 385a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::createIndexInternal, objectStore, index, transaction), 386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch createCallbackTask(&IDBObjectStoreBackendImpl::removeIndexFromMap, objectStore, index))) { 387a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 388a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 389a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 390a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_indexes.set(name, index); 392a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return index.release(); 3935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 3945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 395a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBTransactionBackendInterface> transaction) 3965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 39781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int64_t id; 3982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!objectStore->m_backingStore->createIndex(objectStore->m_databaseId, objectStore->id(), index->name(), index->keyPath(), index->unique(), id)) { 399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->abort(); 400a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 40281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 40381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch index->setId(id); 40481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!populateIndex(*objectStore->m_backingStore, objectStore->m_databaseId, objectStore->m_id, id, index->keyPath())) { 406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->abort(); 407a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 408a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 40981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 410a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->didCompleteTaskEvents(); 411a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 412a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 413a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::index(const String& name, ExceptionCode& ec) 414a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 415a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBIndexBackendInterface> index = m_indexes.get(name); 416a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!index) { 417a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_FOUND_ERR; 418a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 419a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 420a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return index.release(); 4215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 4225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBObjectStoreBackendImpl::deleteIndex(const String& name, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) 4245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 42565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (transaction->mode() != IDBTransaction::VERSION_CHANGE) { 42665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 42765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 42865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 42965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name); 4315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!index) { 432a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_FOUND_ERR; 4335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 4345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 435e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 436a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 437a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBTransactionBackendInterface> transactionPtr = transaction; 4384576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::deleteIndexInternal, objectStore, index, transactionPtr), 439a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch createCallbackTask(&IDBObjectStoreBackendImpl::addIndexToMap, objectStore, index))) { 440a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 441a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 442a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_indexes.remove(name); 4445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 4455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBObjectStoreBackendImpl::deleteIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBTransactionBackendInterface> transaction) 447a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 4482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch objectStore->m_backingStore->deleteIndex(objectStore->m_databaseId, objectStore->id(), index->id()); 449a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch transaction->didCompleteTaskEvents(); 450a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 451a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 452a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) 453a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 454a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBObjectStoreBackendImpl> objectStore = this; 455a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBKeyRange> range = prpRange; 456a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBCallbacks> callbacks = prpCallbacks; 457a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; 458a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal, objectStore, range, direction, callbacks, transaction))) 459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ec = IDBDatabaseException::NOT_ALLOWED_ERR; 460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) 4635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 4645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(tmpDirection); 46581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch RefPtr<IDBBackingStore::Cursor> backingStoreCursor = objectStore->m_backingStore->openObjectStoreCursor(objectStore->m_databaseId, objectStore->id(), range.get(), direction); 46781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!backingStoreCursor) { 4682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callbacks->onSuccess(SerializedScriptValue::nullValue()); 469e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 470e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 471e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 47281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), direction, IDBCursorBackendInterface::ObjectStoreCursor, transaction.get(), objectStore.get()); 473e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block callbacks->onSuccess(cursor.release()); 474e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 475e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 476e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid IDBObjectStoreBackendImpl::loadIndexes() 477e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 47881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Vector<int64_t> ids; 47981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Vector<String> names; 48081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Vector<String> keyPaths; 48181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch Vector<bool> uniqueFlags; 4822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_backingStore->getIndexes(m_databaseId, m_id, ids, names, keyPaths, uniqueFlags); 483e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 48481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(names.size() == ids.size()); 48581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(keyPaths.size() == ids.size()); 48681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(uniqueFlags.size() == ids.size()); 487e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 48881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (size_t i = 0; i < ids.size(); i++) 4892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_indexes.set(names[i], IDBIndexBackendImpl::create(m_backingStore.get(), m_databaseId, this, ids[i], names[i], m_name, keyPaths[i], uniqueFlags[i])); 490dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch} 4915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 492a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index) 493a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 494a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(objectStore->m_indexes.contains(index->name())); 495a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch objectStore->m_indexes.remove(index->name()); 496a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 497a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 498a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBObjectStoreBackendImpl::addIndexToMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index) 499a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBIndexBackendImpl> indexPtr = index; 501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!objectStore->m_indexes.contains(indexPtr->name())); 502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch objectStore->m_indexes.set(indexPtr->name(), indexPtr); 503a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 504a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 505ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochPassRefPtr<IDBKey> IDBObjectStoreBackendImpl::genAutoIncrementKey() 506ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 507ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (m_autoIncrementNumber > 0) 508ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return IDBKey::createNumber(m_autoIncrementNumber++); 509ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 5102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_autoIncrementNumber = static_cast<int>(m_backingStore->nextAutoIncrementNumber(m_databaseId, id())); 511ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return IDBKey::createNumber(m_autoIncrementNumber++); 512ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 513ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 514a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 515545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} // namespace WebCore 5165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 517545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#endif 518