1 /* 2 * Copyright (C) 2010 Google 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBJECT_STORE_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBJECT_STORE_H_ 28 29 #include "base/memory/scoped_refptr.h" 30 #include "third_party/blink/public/common/indexeddb/web_idb_types.h" 31 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" 32 #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_index_parameters.h" 33 #include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h" 34 #include "third_party/blink/renderer/modules/indexeddb/idb_index.h" 35 #include "third_party/blink/renderer/modules/indexeddb/idb_key.h" 36 #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" 37 #include "third_party/blink/renderer/modules/indexeddb/idb_metadata.h" 38 #include "third_party/blink/renderer/modules/indexeddb/idb_request.h" 39 #include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h" 40 #include "third_party/blink/renderer/modules/indexeddb/web_idb_cursor.h" 41 #include "third_party/blink/renderer/modules/indexeddb/web_idb_database.h" 42 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" 43 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" 44 45 namespace blink { 46 47 class DOMStringList; 48 class ExceptionState; 49 50 class MODULES_EXPORT IDBObjectStore final : public ScriptWrappable { 51 DEFINE_WRAPPERTYPEINFO(); 52 53 public: 54 IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata>, IDBTransaction*); 55 ~IDBObjectStore() override = default; 56 57 void Trace(Visitor*) override; 58 Metadata()59 const IDBObjectStoreMetadata& Metadata() const { return *metadata_; } IdbKeyPath()60 const IDBKeyPath& IdbKeyPath() const { return Metadata().key_path; } 61 62 // Per spec prose, keyPath attribute should return the same object each time 63 // (if it is not just a primitive type). The IDL cannot use [SameObject] 64 // because the key path may not be an 'object'. So use [CachedAttribute], 65 // but never dirty the cache. IsKeyPathDirty()66 bool IsKeyPathDirty() const { return false; } 67 68 // Implement the IDBObjectStore IDL Id()69 int64_t Id() const { return Metadata().id; } name()70 const String& name() const { return Metadata().name; } 71 void setName(const String& name, ExceptionState&); 72 ScriptValue keyPath(ScriptState*) const; 73 DOMStringList* indexNames() const; transaction()74 IDBTransaction* transaction() const { return transaction_.Get(); } autoIncrement()75 bool autoIncrement() const { return Metadata().auto_increment; } 76 77 IDBRequest* openCursor(ScriptState*, 78 const ScriptValue& range, 79 const String& direction, 80 ExceptionState&); 81 IDBRequest* openKeyCursor(ScriptState*, 82 const ScriptValue& range, 83 const String& direction, 84 ExceptionState&); 85 IDBRequest* get(ScriptState*, const ScriptValue& key, ExceptionState&); 86 IDBRequest* getKey(ScriptState*, const ScriptValue& key, ExceptionState&); 87 IDBRequest* getAll(ScriptState*, 88 const ScriptValue& range, 89 uint32_t max_count, 90 ExceptionState&); 91 IDBRequest* getAll(ScriptState*, const ScriptValue& range, ExceptionState&); 92 IDBRequest* getAllKeys(ScriptState*, 93 const ScriptValue& range, 94 uint32_t max_count, 95 ExceptionState&); 96 IDBRequest* getAllKeys(ScriptState*, 97 const ScriptValue& range, 98 ExceptionState&); 99 IDBRequest* add(ScriptState*, const ScriptValue& value, ExceptionState&); 100 IDBRequest* add(ScriptState*, 101 const ScriptValue& value, 102 const ScriptValue& key, 103 ExceptionState&); 104 IDBRequest* put(ScriptState*, const ScriptValue& value, ExceptionState&); 105 IDBRequest* put(ScriptState*, 106 const ScriptValue& value, 107 const ScriptValue& key, 108 ExceptionState&); 109 IDBRequest* Delete(ScriptState*, const ScriptValue& key, ExceptionState&); 110 IDBRequest* clear(ScriptState*, ExceptionState&); 111 createIndex(ScriptState * script_state,const String & name,const StringOrStringSequence & key_path,const IDBIndexParameters * options,ExceptionState & exception_state)112 IDBIndex* createIndex(ScriptState* script_state, 113 const String& name, 114 const StringOrStringSequence& key_path, 115 const IDBIndexParameters* options, 116 ExceptionState& exception_state) { 117 return createIndex(script_state, name, IDBKeyPath(key_path), options, 118 exception_state); 119 } 120 IDBIndex* index(const String& name, ExceptionState&); 121 void deleteIndex(const String& name, ExceptionState&); 122 123 IDBRequest* count(ScriptState*, const ScriptValue& range, ExceptionState&); 124 125 // Exposed for the use of IDBCursor::update(). 126 IDBRequest* DoPut(ScriptState*, 127 mojom::IDBPutMode, 128 const IDBRequest::Source&, 129 const ScriptValue&, 130 const IDBKey*, 131 ExceptionState&); 132 133 // Used internally and by InspectorIndexedDBAgent: 134 IDBRequest* openCursor( 135 ScriptState*, 136 IDBKeyRange*, 137 mojom::IDBCursorDirection, 138 mojom::IDBTaskType = mojom::IDBTaskType::Normal, 139 IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState()); 140 IDBRequest* deleteFunction( 141 ScriptState*, 142 IDBKeyRange*, 143 IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState()); 144 IDBRequest* getKeyGeneratorCurrentNumber( 145 ScriptState*, 146 IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState()); 147 148 void MarkDeleted(); IsDeleted()149 bool IsDeleted() const { return deleted_; } 150 151 // True if this object store was created in its associated transaction. 152 // Only valid if the store's associated transaction is a versionchange. IsNewlyCreated()153 bool IsNewlyCreated() const { 154 DCHECK(transaction_->IsVersionChange()); 155 // Object store IDs are allocated sequentially, so we can tell if an object 156 // store was created in this transaction by comparing its ID against the 157 // database's maximum object store ID at the time when the transaction was 158 // started. 159 return Id() > transaction_->OldMaxObjectStoreId(); 160 } 161 162 // Clears the cache used to implement the index() method. 163 // 164 // This should be called when the store's transaction clears its reference 165 // to this IDBObjectStore instance, so the store can clear its references to 166 // IDBIndex instances. This way, Oilpan can garbage-collect the instances 167 // that are not referenced in JavaScript. 168 // 169 // For most stores, the condition above is met when the transaction 170 // finishes. The exception is stores that are created and deleted in the 171 // same transaction. Those stores will remain marked for deletion even if 172 // the transaction aborts, so the transaction can forget about them (and 173 // clear their index caches) right when they are deleted. 174 void ClearIndexCache(); 175 176 // Sets the object store's metadata to a previous version. 177 // 178 // The reverting process includes reverting the metadata for the IDBIndex 179 // instances that are still tracked by the store. It does not revert the 180 // IDBIndex metadata for indexes that were deleted in this transaction. 181 // 182 // Used when a versionchange transaction is aborted. 183 void RevertMetadata(scoped_refptr<IDBObjectStoreMetadata> previous_metadata); 184 // This relies on the changes made by RevertMetadata(). 185 void RevertDeletedIndexMetadata(IDBIndex& deleted_index); 186 187 // Used by IDBIndex::setName: ContainsIndex(const String & name)188 bool ContainsIndex(const String& name) const { 189 return FindIndexId(name) != IDBIndexMetadata::kInvalidId; 190 } 191 void RenameIndex(int64_t index_id, const String& new_name); 192 193 WebIDBDatabase* BackendDB() const; 194 195 private: 196 using IDBIndexMap = HeapHashMap<String, Member<IDBIndex>>; 197 198 IDBIndex* createIndex(ScriptState*, 199 const String& name, 200 const IDBKeyPath&, 201 const IDBIndexParameters*, 202 ExceptionState&); 203 IDBRequest* DoPut(ScriptState*, 204 mojom::IDBPutMode, 205 const ScriptValue&, 206 const ScriptValue& key_value, 207 ExceptionState&); 208 209 int64_t FindIndexId(const String& name) const; 210 211 // The IDBObjectStoreMetadata is shared with the object store map in the 212 // database's metadata. 213 scoped_refptr<IDBObjectStoreMetadata> metadata_; 214 Member<IDBTransaction> transaction_; 215 bool deleted_ = false; 216 217 // Caches the IDBIndex instances returned by the index() method. 218 // 219 // The spec requires that an object store's index() returns the same 220 // IDBIndex instance for a specific index, so this cache is necessary 221 // for correctness. 222 // 223 // index() throws for completed/aborted transactions, so this is not used 224 // after a transaction is finished, and can be cleared. 225 IDBIndexMap index_map_; 226 227 #if DCHECK_IS_ON() 228 bool clear_index_cache_called_ = false; 229 #endif // DCHECK_IS_ON() 230 }; 231 232 } // namespace blink 233 234 #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBJECT_STORE_H_ 235