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