1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "ActiveDOMObject.h"
31#include "ExceptionOr.h"
32#include "IDBCursorDirection.h"
33#include "IDBKeyPath.h"
34#include "IDBObjectStoreInfo.h"
35
36namespace JSC {
37class ExecState;
38class JSValue;
39class SlotVisitor;
40}
41
42namespace WebCore {
43
44class DOMStringList;
45class IDBIndex;
46class IDBKey;
47class IDBKeyRange;
48class IDBRequest;
49class IDBTransaction;
50
51struct IDBKeyRangeData;
52
53namespace IndexedDB {
54enum class ObjectStoreOverwriteMode;
55}
56
57class IDBObjectStore final : public ActiveDOMObject {
58 WTF_MAKE_NONCOPYABLE(IDBObjectStore);
59 WTF_MAKE_FAST_ALLOCATED;
60public:
61 IDBObjectStore(ScriptExecutionContext&, const IDBObjectStoreInfo&, IDBTransaction&);
62 ~IDBObjectStore();
63
64 const String& name() const;
65 ExceptionOr<void> setName(const String&);
66 const Optional<IDBKeyPath>& keyPath() const;
67 Ref<DOMStringList> indexNames() const;
68 IDBTransaction& transaction();
69 bool autoIncrement() const;
70
71 struct IndexParameters {
72 bool unique;
73 bool multiEntry;
74 };
75
76 ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, RefPtr<IDBKeyRange>&&, IDBCursorDirection);
77 ExceptionOr<Ref<IDBRequest>> openCursor(JSC::ExecState&, JSC::JSValue key, IDBCursorDirection);
78 ExceptionOr<Ref<IDBRequest>> openKeyCursor(JSC::ExecState&, RefPtr<IDBKeyRange>&&, IDBCursorDirection);
79 ExceptionOr<Ref<IDBRequest>> openKeyCursor(JSC::ExecState&, JSC::JSValue key, IDBCursorDirection);
80 ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, JSC::JSValue key);
81 ExceptionOr<Ref<IDBRequest>> get(JSC::ExecState&, IDBKeyRange*);
82 ExceptionOr<Ref<IDBRequest>> getKey(JSC::ExecState&, JSC::JSValue key);
83 ExceptionOr<Ref<IDBRequest>> getKey(JSC::ExecState&, IDBKeyRange*);
84 ExceptionOr<Ref<IDBRequest>> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
85 ExceptionOr<Ref<IDBRequest>> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key);
86 ExceptionOr<Ref<IDBRequest>> deleteFunction(JSC::ExecState&, IDBKeyRange*);
87 ExceptionOr<Ref<IDBRequest>> deleteFunction(JSC::ExecState&, JSC::JSValue key);
88 ExceptionOr<Ref<IDBRequest>> clear(JSC::ExecState&);
89 ExceptionOr<Ref<IDBIndex>> createIndex(JSC::ExecState&, const String& name, IDBKeyPath&&, const IndexParameters&);
90 ExceptionOr<Ref<IDBIndex>> index(const String& name);
91 ExceptionOr<void> deleteIndex(const String& name);
92 ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, IDBKeyRange*);
93 ExceptionOr<Ref<IDBRequest>> count(JSC::ExecState&, JSC::JSValue key);
94 ExceptionOr<Ref<IDBRequest>> getAll(JSC::ExecState&, RefPtr<IDBKeyRange>&&, Optional<uint32_t> count);
95 ExceptionOr<Ref<IDBRequest>> getAll(JSC::ExecState&, JSC::JSValue key, Optional<uint32_t> count);
96 ExceptionOr<Ref<IDBRequest>> getAllKeys(JSC::ExecState&, RefPtr<IDBKeyRange>&&, Optional<uint32_t> count);
97 ExceptionOr<Ref<IDBRequest>> getAllKeys(JSC::ExecState&, JSC::JSValue key, Optional<uint32_t> count);
98
99 ExceptionOr<Ref<IDBRequest>> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>);
100
101 void markAsDeleted();
102 bool isDeleted() const { return m_deleted; }
103
104 const IDBObjectStoreInfo& info() const { return m_info; }
105
106 void rollbackForVersionChangeAbort();
107
108 void ref();
109 void deref();
110
111 void visitReferencedIndexes(JSC::SlotVisitor&) const;
112 void renameReferencedIndex(IDBIndex&, const String& newName);
113
114private:
115 enum class InlineKeyCheck { Perform, DoNotPerform };
116 ExceptionOr<Ref<IDBRequest>> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck);
117 ExceptionOr<Ref<IDBRequest>> doCount(JSC::ExecState&, const IDBKeyRangeData&);
118 ExceptionOr<Ref<IDBRequest>> doDelete(JSC::ExecState&, WTF::Function<ExceptionOr<RefPtr<IDBKeyRange>>()> &&);
119 ExceptionOr<Ref<IDBRequest>> doOpenCursor(JSC::ExecState&, IDBCursorDirection, WTF::Function<ExceptionOr<RefPtr<IDBKeyRange>>()>&&);
120 ExceptionOr<Ref<IDBRequest>> doOpenKeyCursor(JSC::ExecState&, IDBCursorDirection, WTF::Function<ExceptionOr<RefPtr<IDBKeyRange>>()>&&);
121 ExceptionOr<Ref<IDBRequest>> doGetAll(JSC::ExecState&, Optional<uint32_t> count, WTF::Function<ExceptionOr<RefPtr<IDBKeyRange>>()> &&);
122 ExceptionOr<Ref<IDBRequest>> doGetAllKeys(JSC::ExecState&, Optional<uint32_t> count, WTF::Function<ExceptionOr<RefPtr<IDBKeyRange>>()> &&);
123
124 const char* activeDOMObjectName() const final;
125 bool canSuspendForDocumentSuspension() const final;
126 bool hasPendingActivity() const final;
127
128 IDBObjectStoreInfo m_info;
129 IDBObjectStoreInfo m_originalInfo;
130
131 // IDBObjectStore objects are always owned by their referencing IDBTransaction.
132 // ObjectStores will never outlive transactions so its okay to keep a raw C++ reference here.
133 IDBTransaction& m_transaction;
134
135 bool m_deleted { false };
136
137 mutable Lock m_referencedIndexLock;
138 HashMap<String, std::unique_ptr<IDBIndex>> m_referencedIndexes;
139 HashMap<uint64_t, std::unique_ptr<IDBIndex>> m_deletedIndexes;
140};
141
142} // namespace WebCore
143
144#endif // ENABLE(INDEXED_DATABASE)
145