15af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke/* 25af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * Copyright (C) 2010 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 "IDBObjectStore.h" 285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#if ENABLE(INDEXED_DATABASE) 304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "DOMStringList.h" 325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "IDBAny.h" 334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "IDBDatabaseException.h" 34db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "IDBIndex.h" 35e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "IDBKey.h" 36dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBKeyRange.h" 372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "IDBTransaction.h" 385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "SerializedScriptValue.h" 395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include <wtf/UnusedParam.h> 405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkenamespace WebCore { 425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangstatic const unsigned short defaultDirection = IDBCursor::NEXT; 444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 452fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockIDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction) 465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke : m_objectStore(idbObjectStore) 47bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_transaction(transaction) 485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(m_objectStore); 50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(m_transaction); 51e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // We pass a reference to this object before it can be adopted. 52e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke relaxAdoptionRequirement(); 535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 55dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochString IDBObjectStore::name() const 565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return m_objectStore->name(); 585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 60dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochString IDBObjectStore::keyPath() const 615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return m_objectStore->keyPath(); 635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 65dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochPassRefPtr<DOMStringList> IDBObjectStore::indexNames() const 665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return m_objectStore->indexNames(); 685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 70a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) 715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 72bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->get(key, request, m_transaction->backend(), ec); 7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 78bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return request.release(); 795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 81a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec) 825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 83a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->put(value, key, IDBObjectStoreBackendInterface::AddOnly, request, m_transaction->backend(), ec); 8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 8681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return request.release(); 905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 92a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec) 935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->put(value, key, IDBObjectStoreBackendInterface::AddOrUpdate, request, m_transaction->backend(), ec); 9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return request.release(); 1015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 1025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 1034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangPassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) 1045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->deleteFunction(key, request, m_transaction->backend(), ec); 10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return request.release(); 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockPassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCode& ec) 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->clear(request, m_transaction->backend(), ec); 11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return request.release(); 1235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 1245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 1254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangPassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const OptionsObject& options, ExceptionCode& ec) 1265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 1274576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool unique = false; 1284576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang options.getKeyBool("unique", unique); 1294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<IDBIndexBackendInterface> index = m_objectStore->createIndex(name, keyPath, unique, m_transaction->backend(), ec); 131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!index != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa. 132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!index) 133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 13481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return IDBIndex::create(index.release(), this, m_transaction.get()); 1355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 1365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 137a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBIndex> IDBObjectStore::index(const String& name, ExceptionCode& ec) 1385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBIndexBackendInterface> index = m_objectStore->index(name, ec); 140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!index != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa. 141bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!index) 142bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return 0; 14381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return IDBIndex::create(index.release(), this, m_transaction.get()); 1445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 1455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 1464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec) 1475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->deleteIndex(name, m_transaction->backend(), ec); 1495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 1505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 1512fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockPassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, unsigned short direction, ExceptionCode& ec) 152dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{ 1534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (direction != IDBCursor::NEXT && direction != IDBCursor::NEXT_NO_DUPLICATE && direction != IDBCursor::PREV && direction != IDBCursor::PREV_NO_DUPLICATE) { 1544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // FIXME: May need to change when specced: http://www.w3.org/Bugs/Public/show_bug.cgi?id=11406 1554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ec = IDBDatabaseException::CONSTRAINT_ERR; 1564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return 0; 1574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 1584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->setCursorType(IDBCursorBackendInterface::ObjectStoreCursor); 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_objectStore->openCursor(range, direction, request, m_transaction->backend(), ec); 16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (ec) { 16381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch request->markEarlyDeath(); 164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 0; 16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 166dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return request.release(); 167dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch} 168dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 1695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} // namespace WebCore 1705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 1715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#endif // ENABLE(INDEXED_DATABASE) 172