Shaka Player Embedded
request_impls.cc
Go to the documentation of this file.
1 // Copyright 2019 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 
16 
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 #include "src/js/idb/cursor.h"
22 #include "src/js/idb/database.h"
23 #include "src/js/idb/idb_utils.h"
25 #include "src/js/idb/transaction.h"
27 
28 namespace shaka {
29 namespace js {
30 namespace idb {
31 
32 namespace {
33 
34 ExceptionOr<Any> ReadAndLoad(SqliteTransaction* transaction,
35  const std::string& db_name,
36  const std::string& store_name, IdbKeyType key,
37  bool allow_not_found) {
38  std::vector<uint8_t> data;
39  const DatabaseStatus status =
40  transaction->GetData(db_name, store_name, key, &data);
41  if (status == DatabaseStatus::NotFound) {
42  if (allow_not_found)
43  return Any(); // Undefined
45  }
46  if (status != DatabaseStatus::Success)
47  return JsError::DOMException(UnknownError);
48 
49  proto::Value proto;
50  if (!proto.ParseFromArray(data.data(), data.size())) {
51  return JsError::DOMException(UnknownError,
52  "Invalid data stored in database");
53  }
54 
55  return LoadFromProto(proto);
56 }
57 
58 } // namespace
59 
62  RefPtr<IDBTransaction> transaction, IdbKeyType key)
63  : IDBRequest(source, transaction), key_(key) {}
65 
67  RefPtr<IDBObjectStore> store = get<Member<IDBObjectStore>>(source.value());
68  RefPtr<IDBDatabase> db = store->transaction->db;
69 
70  ExceptionOr<Any> data =
71  ReadAndLoad(transaction, db->db_name, store->store_name, key_,
72  /* allow_not_found */ true);
73  if (holds_alternative<JsError>(data))
74  return CompleteError(get<JsError>(std::move(data)));
75  return CompleteSuccess(get<Any>(data));
76 }
77 
78 
81  RefPtr<IDBTransaction> transaction, proto::Value value,
82  optional<IdbKeyType> key, bool no_override)
83  : IDBRequest(source, transaction),
84  value_(std::move(value)),
85  key_(key),
86  no_override_(no_override) {}
88 
90  RefPtr<IDBObjectStore> store = get<Member<IDBObjectStore>>(source.value());
91  RefPtr<IDBDatabase> db = store->transaction->db;
92 
93  DatabaseStatus status;
94  if (key_.has_value()) {
95  std::vector<uint8_t> ignored;
96  status = transaction->GetData(db->db_name, store->store_name, key_.value(),
97  &ignored);
98  if (status == DatabaseStatus::Success) {
99  if (no_override_) {
101  ConstraintError, "An object with the given key already exists"));
102  }
103  } else if (status != DatabaseStatus::NotFound) {
104  return CompleteError(status);
105  }
106  }
107 
108  std::string data;
109  if (!value_.SerializeToString(&data))
111  std::vector<uint8_t> data_vec(data.begin(), data.end());
112  IdbKeyType key{};
113  if (key_.has_value()) {
114  status = transaction->UpdateData(db->db_name, store->store_name,
115  key_.value(), data_vec);
116  } else {
117  status =
118  transaction->AddData(db->db_name, store->store_name, data_vec, &key);
119  }
120  if (status != DatabaseStatus::Success)
121  return CompleteError(status);
122  return CompleteSuccess(Any(key_.value_or(key)));
123 }
124 
125 
128  RefPtr<IDBTransaction> transaction, IdbKeyType key)
129  : IDBRequest(source, transaction), key_(key) {}
131 
133  RefPtr<IDBObjectStore> store = get<Member<IDBObjectStore>>(source.value());
134  RefPtr<IDBDatabase> db = store->transaction->db;
135 
136  const DatabaseStatus status =
137  transaction->DeleteData(db->db_name, store->store_name, key_);
138  if (status != DatabaseStatus::Success)
139  return CompleteError(status);
140  return CompleteSuccess(Any()); // undefined
141 }
142 
143 
146  RefPtr<IDBTransaction> transaction, RefPtr<IDBCursor> cursor,
147  uint32_t count)
148  : IDBRequest(source, transaction), count(count), cursor_(cursor) {}
150 
152  IDBRequest::Trace(tracer);
153  tracer->Trace(&cursor_);
154 }
155 
157  RefPtr<IDBObjectStore> store = get<Member<IDBObjectStore>>(source.value());
158  RefPtr<IDBDatabase> db = store->transaction->db;
159 
160  optional<int64_t> position = cursor_->key;
161  const bool ascending = cursor_->direction == IDBCursorDirection::NEXT ||
162  cursor_->direction == IDBCursorDirection::NEXT_UNIQUE;
163  for (uint32_t i = 0; i < count; i++) {
164  int64_t new_key;
165  const DatabaseStatus status = transaction->FindData(
166  db->db_name, store->store_name, position, ascending, &new_key);
167  if (status == DatabaseStatus::NotFound) {
168  cursor_->key = nullopt;
169  cursor_->value = Any();
170  return CompleteSuccess(Any(nullptr));
171  }
172  if (status != DatabaseStatus::Success) {
173  return CompleteError(status);
174  }
175  position = new_key;
176  }
177 
178  ExceptionOr<Any> data =
179  ReadAndLoad(transaction, db->db_name, store->store_name, position.value(),
180  /* allow_not_found */ false);
181  if (holds_alternative<JsError>(data))
182  return CompleteError(get<JsError>(std::move(data)));
183 
184  cursor_->key = position;
185  cursor_->value = get<Any>(data);
186  cursor_->got_value = true;
187  return CompleteSuccess(Any(cursor_));
188 }
189 
190 } // namespace idb
191 } // namespace js
192 } // namespace shaka
DatabaseStatus DeleteData(const std::string &db_name, const std::string &store_name, int64_t key)
Definition: sqlite.cc:367
Any LoadFromProto(const proto::Value &value)
Definition: idb_utils.cc:238
IDBStoreRequest(optional< variant< Member< IDBObjectStore >, Member< IDBCursor >>> source, RefPtr< IDBTransaction > transaction, proto::Value value, optional< IdbKeyType > key, bool no_override)
Definition: any.h:31
IDBIterateCursorRequest(optional< variant< Member< IDBObjectStore >, Member< IDBCursor >>> source, RefPtr< IDBTransaction > transaction, RefPtr< IDBCursor > cursor, uint32_t count)
void Trace(memory::HeapTracer *tracer) const override
Definition: request.cc:40
IDBDeleteRequest(optional< variant< Member< IDBObjectStore >, Member< IDBCursor >>> source, RefPtr< IDBTransaction > transaction, IdbKeyType key)
void PerformOperation(SqliteTransaction *transaction) override
DatabaseStatus GetData(const std::string &db_name, const std::string &store_name, int64_t key, std::vector< uint8_t > *data)
Definition: sqlite.cc:342
DatabaseStatus AddData(const std::string &db_name, const std::string &store_name, const std::vector< uint8_t > &data, int64_t *key)
Definition: sqlite.cc:324
DatabaseStatus UpdateData(const std::string &db_name, const std::string &store_name, int64_t key, const std::vector< uint8_t > &data)
Definition: sqlite.cc:354
optional< variant< Member< IDBObjectStore >, Member< IDBCursor > > > source
Definition: request.h:72
const nullopt_t nullopt
Definition: optional.cc:22
const char * source
Definition: media_utils.cc:30
const T & value() const &
Definition: optional.h:147
void CompleteError(JsError error)
Definition: request.cc:75
int64_t IdbKeyType
Definition: idb_utils.h:29
void Trace(memory::HeapTracer *tracer) const override
void PerformOperation(SqliteTransaction *transaction) override
void Trace(const Traceable *ptr)
Definition: heap_tracer.cc:43
void CompleteSuccess(Any result)
Definition: request.cc:64
T value_or(U &&default_value) const &
Definition: optional.h:165
DatabaseStatus FindData(const std::string &db_name, const std::string &store_name, optional< int64_t > key, bool ascending, int64_t *found_key)
Definition: sqlite.cc:378
void PerformOperation(SqliteTransaction *transaction) override
static JsError DOMException(ExceptionCode code)
Definition: js_error.cc:115
void PerformOperation(SqliteTransaction *transaction) override
bool has_value() const
Definition: optional.h:143
IDBGetRequest(optional< variant< Member< IDBObjectStore >, Member< IDBCursor >>> source, RefPtr< IDBTransaction > transaction, IdbKeyType key)