Shaka Player Embedded
database.cc
Go to the documentation of this file.
1 // Copyright 2016 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/js/idb/database.h"
16 
19 #include "src/js/idb/transaction.h"
20 #include "src/js/js_error.h"
21 #include "src/memory/heap_tracer.h"
22 
23 namespace shaka {
24 namespace js {
25 namespace idb {
26 
27 DEFINE_STRUCT_SPECIAL_METHODS_COPYABLE(IDBObjectStoreParameters);
28 
29 IDBDatabase::IDBDatabase(std::shared_ptr<SqliteConnection> connection,
30  const std::string& name, int64_t version,
31  const std::vector<std::string>& store_names)
32  : db_name(name),
33  object_store_names(new dom::DOMStringList(store_names)),
34  version(version),
35  connection_(connection) {
36  AddListenerField(EventType::Abort, &on_abort);
37  AddListenerField(EventType::Error, &on_error);
38  AddListenerField(EventType::VersionChange, &on_version_change);
39 }
40 
41 // \cond Doxygen_Skip
42 IDBDatabase::~IDBDatabase() {}
43 // \endcond Doxygen_Skip
44 
47  tracer->Trace(&object_store_names);
48  tracer->Trace(&version_change_trans_);
49 }
50 
52  const std::string& name, optional<IDBObjectStoreParameters> parameters) {
53  // 1. Let database be the database associated with this connection.
54  // 2. Let transaction be database’s upgrade transaction if it is not null, or
55  // throw an "InvalidStateError" DOMException otherwise.
56  if (!version_change_trans_)
58  // 3. If transaction’s state is not active, then throw a
59  // "TransactionInactiveError" DOMException.
60  if (!version_change_trans_->active ||
61  !version_change_trans_->sqlite_transaction) {
63  }
64  // 4. Let keyPath be options’s keyPath member if it is not undefined or null,
65  // or null otherwise.
66  // 5. If keyPath is not null and is not a valid key path, throw a
67  // "SyntaxError" DOMException.
68  if (!parameters || !parameters->keyPath.empty() || !parameters->autoIncrement)
70 
71  // 6. If an object store named name already exists in database throw a
72  // "ConstraintError" DOMException.
73  if (object_store_names->contains(name))
75 
76  // 7. Let autoIncrement be options’s autoIncrement member.
77  // 8. If autoIncrement is true and keyPath is an empty string or any sequence
78  // (empty or otherwise), throw an "InvalidAccessError" DOMException.
79 
80  // 9. Let store be a new object store in database. Set the created object
81  // store's name to name. If autoIncrement is true, then the created object
82  // store uses a key generator. If keyPath is not null, set the created
83  // object store's key path to keyPath.
84  const auto status =
85  version_change_trans_->sqlite_transaction->CreateObjectStore(db_name,
86  name);
87  if (status != DatabaseStatus::Success)
89  object_store_names->emplace_back(name);
90  version_change_trans_->AddObjectStore(name);
91 
92  // 10. Return a new object store handle associated with store and transaction.
93  return new IDBObjectStore(version_change_trans_, name);
94 }
95 
97  // 1. Let database be the database associated with this connection.
98  // 2. Let transaction be database’s upgrade transaction if it is not null, or
99  // throw an "InvalidStateError" DOMException otherwise.
100  if (!version_change_trans_)
102  // 3. If transaction’s state is not active, then throw a
103  // "TransactionInactiveError" DOMException.
104  if (!version_change_trans_->active ||
105  !version_change_trans_->sqlite_transaction) {
107  }
108  // 4. Let store be the object store named name in database, or throw a
109  // "NotFoundError" DOMException if none.
110  if (!object_store_names->contains(name))
112 
113  // 5. Remove store from this connection's object store set.
114  // 6. If there is an object store handle associated with store and
115  // transaction, remove all entries from its index set.
116  // TODO: We don't do step 6, we usually throw a NotFoundError.
117  // 7. Destroy store.
118  const auto status =
119  version_change_trans_->sqlite_transaction->DeleteObjectStore(db_name,
120  name);
121  if (status != DatabaseStatus::Success)
124  version_change_trans_->DeleteObjectStore(name);
125 
126  return {};
127 }
128 
130  variant<std::string, std::vector<std::string>> store_names,
132  // 1. If a running upgrade transaction is associated with the connection,
133  // throw an "InvalidStateError" DOMException.
134  // 2. If the connection's close pending flag is true, throw an
135  // "InvalidStateError" DOMException.
136  if (version_change_trans_ || close_pending_)
138 
139  // 3. Let scope be the set of unique strings in storeNames if it is a
140  // sequence, or a set containing one string equal to storeNames otherwise.
141  std::vector<std::string> scope;
142  if (holds_alternative<std::string>(store_names))
143  scope.emplace_back(get<std::string>(store_names));
144  else
145  scope = get<std::vector<std::string>>(store_names);
146 
147  // 4. If any string in scope is not the name of an object store in the
148  // connected database, throw a "NotFoundError" DOMException.
149  for (const std::string& name : scope) {
150  if (!object_store_names->contains(name))
152  }
153  // 5. If scope is empty, throw an "InvalidAccessError" DOMException.
154  if (scope.empty())
156 
157  // 6. If mode is not "readonly" or "readwrite", throw a TypeError.
158  const IDBTransactionMode real_mode =
160  if (real_mode != IDBTransactionMode::READ_ONLY &&
161  real_mode != IDBTransactionMode::READ_WRITE) {
162  return JsError::TypeError(
163  "Transaction mode must be 'readonly' or 'readwrite'");
164  }
165 
166  // 7. Let transaction be a newly created transaction with connection, mode and
167  // the set of object stores named in scope.
168  // 8. Set transaction’s cleanup event loop to the current event loop.
169  RefPtr<IDBTransaction> ret = new IDBTransaction(this, real_mode, scope);
170 
171  std::shared_ptr<SqliteConnection> connection = connection_;
173  TaskPriority::Internal, "IndexedDb Commit Transaction",
174  [ret, connection]() { ret->DoCommit(connection.get()); });
175  // 9. Return an IDBTransaction object representing transaction.
176  return ret;
177 }
178 
180  if (!close_pending_) {
181  close_pending_ = true;
182  }
183 }
184 
185 
187  AddReadOnlyProperty("name", &IDBDatabase::db_name);
188  AddReadOnlyProperty("objectStoreNames", &IDBDatabase::object_store_names);
189  AddReadOnlyProperty("version", &IDBDatabase::version);
190 
191  AddListenerField(EventType::Abort, &IDBDatabase::on_abort);
192  AddListenerField(EventType::Error, &IDBDatabase::on_error);
193  AddListenerField(EventType::VersionChange, &IDBDatabase::on_version_change);
194 
195  AddMemberFunction("createObjectStore", &IDBDatabase::CreateObjectStore);
196  AddMemberFunction("deleteObjectStore", &IDBDatabase::DeleteObjectStore);
197  AddMemberFunction("transaction", &IDBDatabase::Transaction);
198  AddMemberFunction("close", &IDBDatabase::Close);
199 }
200 
201 } // namespace idb
202 } // namespace js
203 } // namespace shaka
ExceptionOr< RefPtr< IDBObjectStore > > CreateObjectStore(const std::string &name, optional< IDBObjectStoreParameters > parameters)
Definition: database.cc:51
T * get() const
Definition: member.h:122
const char * name
ExceptionOr< void > DeleteObjectStore(const std::string &name)
Definition: database.cc:96
DEFINE_STRUCT_SPECIAL_METHODS_COPYABLE(IDBObjectStoreParameters)
void Trace(const Traceable *ptr)
Definition: heap_tracer.cc:43
const int64_t version
Definition: database.h:67
Member< dom::DOMStringList > object_store_names
Definition: database.h:66
IDBDatabase(std::shared_ptr< SqliteConnection > connection, const std::string &name, int64_t version, const std::vector< std::string > &store_names)
Definition: database.cc:29
void Trace(memory::HeapTracer *tracer) const override
Definition: event_target.cc:31
void RemoveElement(List *list, Elem &&elem)
Definition: utils.h:95
ExceptionOr< RefPtr< IDBTransaction > > Transaction(variant< std::string, std::vector< std::string >> store_names, optional< IDBTransactionMode > mode)
Definition: database.cc:129
T value_or(U &&default_value) const &
Definition: optional.h:165
const std::string db_name
Definition: database.h:65
std::shared_ptr< ThreadEvent< impl::RetOf< Func > > > AddInternalTask(TaskPriority priority, const std::string &name, Func &&callback)
Definition: task_runner.h:219
static JsError TypeError(const std::string &message)
Definition: js_error.cc:81
static JsError DOMException(ExceptionCode code)
Definition: js_error.cc:115
void Trace(memory::HeapTracer *tracer) const override
Definition: database.cc:45
void AddListenerField(EventType type, Listener *on_field)
Definition: event_target.h:138
std::string name() const
TaskRunner * MainThread()