mirror of
https://github.com/servo/servo.git
synced 2025-09-17 10:28:22 +01:00
script: Ensure autoincrement and keypath are passed in correctly from IDBTransaction (#38738)
Previously, the correct autoincremented and keypath parameters were only being passed if the object store is being created. This PR queries this info from the backend and passes it onto the constructor in IDBTransaction. Furthermore it exposes keypath and index_names from IDBObjectStore, mainly for WPT. Testing: WPT Fixes: None --------- Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This commit is contained in:
parent
722b0de8d8
commit
97690b1cba
12 changed files with 84 additions and 170 deletions
|
@ -3,6 +3,8 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::gc::MutableHandleValue;
|
||||
use js::jsval::NullValue;
|
||||
use js::rust::HandleValue;
|
||||
use net_traits::IpcSend;
|
||||
use net_traits::indexeddb_thread::{
|
||||
|
@ -10,6 +12,7 @@ use net_traits::indexeddb_thread::{
|
|||
IndexedDBThreadMsg, SyncOperation,
|
||||
};
|
||||
use profile_traits::ipc;
|
||||
use script_bindings::conversions::SafeToJSValConvertible;
|
||||
use script_bindings::error::ErrorResult;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
|
@ -34,7 +37,7 @@ use crate::indexed_db::{
|
|||
};
|
||||
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
#[derive(Clone, JSTraceable, MallocSizeOf)]
|
||||
pub enum KeyPath {
|
||||
String(DOMString),
|
||||
StringSequence(Vec<DOMString>),
|
||||
|
@ -133,38 +136,6 @@ impl IDBObjectStore {
|
|||
receiver.recv().unwrap().unwrap()
|
||||
}
|
||||
|
||||
// fn get_stored_key_path(&mut self) -> Option<KeyPath> {
|
||||
// let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||
//
|
||||
// let operation = SyncOperation::KeyPath(
|
||||
// sender,
|
||||
// self.global().origin().immutable().clone(),
|
||||
// self.db_name.to_string(),
|
||||
// self.name.borrow().to_string(),
|
||||
// );
|
||||
//
|
||||
// self.global()
|
||||
// .resource_threads()
|
||||
// .sender()
|
||||
// .send(IndexedDBThreadMsg::Sync(operation))
|
||||
// .unwrap();
|
||||
//
|
||||
// // First unwrap for ipc
|
||||
// // Second unwrap will never happen unless this db gets manually deleted somehow
|
||||
// let key_path = receiver.recv().unwrap().unwrap();
|
||||
// key_path.map(|p| {
|
||||
// // TODO: have separate storage for string sequence of len 1 and signle string
|
||||
// if p.len() == 1 {
|
||||
// KeyPath::String(DOMString::from_string(p[0].clone()))
|
||||
// } else {
|
||||
// let strings: Vec<_> = p.into_iter().map(|s| {
|
||||
// DOMString::from_string(s)
|
||||
// }).collect();
|
||||
// KeyPath::StringSequence(strings)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// https://www.w3.org/TR/IndexedDB-2/#object-store-in-line-keys
|
||||
fn uses_inline_keys(&self) -> bool {
|
||||
self.key_path.is_some()
|
||||
|
@ -546,14 +517,18 @@ impl IDBObjectStoreMethods<crate::DomTypeHolder> for IDBObjectStore {
|
|||
}
|
||||
|
||||
// https://www.w3.org/TR/IndexedDB-2/#dom-idbobjectstore-keypath
|
||||
// fn KeyPath(&self, _cx: SafeJSContext, _val: MutableHandleValue) {
|
||||
// unimplemented!();
|
||||
// }
|
||||
fn KeyPath(&self, cx: SafeJSContext, mut ret_val: MutableHandleValue) {
|
||||
match &self.key_path {
|
||||
Some(KeyPath::String(path)) => path.safe_to_jsval(cx, ret_val),
|
||||
Some(KeyPath::StringSequence(paths)) => paths.safe_to_jsval(cx, ret_val),
|
||||
None => ret_val.set(NullValue()),
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/IndexedDB-2/#dom-idbobjectstore-indexnames
|
||||
// fn IndexNames(&self) -> DomRoot<DOMStringList> {
|
||||
// unimplemented!();
|
||||
// }
|
||||
fn IndexNames(&self) -> DomRoot<DOMStringList> {
|
||||
self.index_names.clone()
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/IndexedDB-2/#dom-idbobjectstore-transaction>
|
||||
fn Transaction(&self) -> DomRoot<IDBTransaction> {
|
||||
|
|
|
@ -8,12 +8,14 @@ use std::collections::HashMap;
|
|||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use net_traits::IpcSend;
|
||||
use net_traits::indexeddb_thread::{IndexedDBThreadMsg, SyncOperation};
|
||||
use net_traits::indexeddb_thread::{IndexedDBThreadMsg, KeyPath, SyncOperation};
|
||||
use profile_traits::ipc;
|
||||
use script_bindings::codegen::GenericUnionTypes::StringOrStringSequence;
|
||||
use stylo_atoms::Atom;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::DOMStringListBinding::DOMStringListMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::IDBDatabaseBinding::IDBObjectStoreParameters;
|
||||
use crate::dom::bindings::codegen::Bindings::IDBTransactionBinding::{
|
||||
IDBTransactionMethods, IDBTransactionMode,
|
||||
};
|
||||
|
@ -203,6 +205,52 @@ impl IDBTransaction {
|
|||
fn get_idb_thread(&self) -> IpcSender<IndexedDBThreadMsg> {
|
||||
self.global().resource_threads().sender()
|
||||
}
|
||||
|
||||
fn object_store_parameters(
|
||||
&self,
|
||||
object_store_name: &DOMString,
|
||||
) -> Option<IDBObjectStoreParameters> {
|
||||
let global = self.global();
|
||||
let idb_sender = global.resource_threads().sender();
|
||||
let (sender, receiver) =
|
||||
ipc::channel(global.time_profiler_chan().clone()).expect("failed to create channel");
|
||||
|
||||
let origin = global.origin().immutable().clone();
|
||||
let db_name = self.db.get_name().to_string();
|
||||
let object_store_name = object_store_name.to_string();
|
||||
|
||||
let operation = SyncOperation::HasKeyGenerator(
|
||||
sender,
|
||||
origin.clone(),
|
||||
db_name.clone(),
|
||||
object_store_name.clone(),
|
||||
);
|
||||
|
||||
let _ = idb_sender.send(IndexedDBThreadMsg::Sync(operation));
|
||||
|
||||
// First unwrap for ipc
|
||||
// Second unwrap will never happen unless this db gets manually deleted somehow
|
||||
let auto_increment = receiver.recv().ok()?.ok()?;
|
||||
|
||||
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).ok()?;
|
||||
let operation = SyncOperation::KeyPath(sender, origin, db_name, object_store_name);
|
||||
|
||||
let _ = idb_sender.send(IndexedDBThreadMsg::Sync(operation));
|
||||
|
||||
// First unwrap for ipc
|
||||
// Second unwrap will never happen unless this db gets manually deleted somehow
|
||||
let key_path = receiver.recv().unwrap().ok()?;
|
||||
let key_path = key_path.map(|key_path| match key_path {
|
||||
KeyPath::String(s) => StringOrStringSequence::String(DOMString::from_string(s)),
|
||||
KeyPath::Sequence(seq) => StringOrStringSequence::StringSequence(
|
||||
seq.into_iter().map(DOMString::from_string).collect(),
|
||||
),
|
||||
});
|
||||
Some(IDBObjectStoreParameters {
|
||||
autoIncrement: auto_increment,
|
||||
keyPath: key_path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl IDBTransactionMethods<crate::DomTypeHolder> for IDBTransaction {
|
||||
|
@ -213,7 +261,7 @@ impl IDBTransactionMethods<crate::DomTypeHolder> for IDBTransaction {
|
|||
|
||||
// https://www.w3.org/TR/IndexedDB-2/#dom-idbtransaction-objectstore
|
||||
fn ObjectStore(&self, name: DOMString) -> Fallible<DomRoot<IDBObjectStore>> {
|
||||
// Step 1: Handle the case where transaction has finised
|
||||
// Step 1: If transaction has finished, throw an "InvalidStateError" DOMException.
|
||||
if self.finished.get() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
@ -228,12 +276,12 @@ impl IDBTransactionMethods<crate::DomTypeHolder> for IDBTransaction {
|
|||
// returns the same IDBObjectStore instance.
|
||||
let mut store_handles = self.store_handles.borrow_mut();
|
||||
let store = store_handles.entry(name.to_string()).or_insert_with(|| {
|
||||
// TODO: get key path from backend
|
||||
let parameters = self.object_store_parameters(&name);
|
||||
let store = IDBObjectStore::new(
|
||||
&self.global(),
|
||||
self.db.get_name(),
|
||||
name,
|
||||
None,
|
||||
parameters.as_ref(),
|
||||
CanGc::note(),
|
||||
self,
|
||||
);
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
[Pref="dom_indexeddb_enabled", Exposed=(Window,Worker)]
|
||||
interface IDBObjectStore {
|
||||
[SetterThrows] attribute DOMString name;
|
||||
// readonly attribute any keyPath;
|
||||
// readonly attribute DOMStringList indexNames;
|
||||
readonly attribute any keyPath;
|
||||
readonly attribute DOMStringList indexNames;
|
||||
[SameObject] readonly attribute IDBTransaction transaction;
|
||||
readonly attribute boolean autoIncrement;
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
[Index key path evaluations operate on a clone]
|
||||
expected: FAIL
|
||||
|
||||
[Key generator and key path validity check operates on a clone]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[clone-before-keypath-eval.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
@ -28,6 +31,9 @@
|
|||
[Index key path evaluations operate on a clone]
|
||||
expected: FAIL
|
||||
|
||||
[Key generator and key path validity check operates on a clone]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[clone-before-keypath-eval.any.sharedworker.html]
|
||||
expected: ERROR
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
[Both with empty name]
|
||||
expected: FAIL
|
||||
|
||||
[Object store 'name' and 'keyPath' properties are correctly set ]
|
||||
expected: FAIL
|
||||
|
||||
[Attempt to create an object store outside of a version change transaction ]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -22,9 +19,6 @@
|
|||
[Both with empty name]
|
||||
expected: FAIL
|
||||
|
||||
[Object store 'name' and 'keyPath' properties are correctly set ]
|
||||
expected: FAIL
|
||||
|
||||
[Attempt to create an object store outside of a version change transaction ]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -39,6 +39,3 @@
|
|||
|
||||
[Calling open() with version argument 9007199254740991 should not throw.]
|
||||
expected: FAIL
|
||||
|
||||
[Calling open() with version argument 1.5 should not throw.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -68,9 +68,6 @@
|
|||
[Get all values with both options and count]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAll-options.tentative.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
@ -147,6 +144,3 @@
|
|||
|
||||
[Get all values with both options and count]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with invalid query keys]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[idbobjectstore_getAll.any.html]
|
||||
[Single item get]
|
||||
expected: FAIL
|
||||
|
||||
[Single item get (generated key)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -17,12 +14,6 @@
|
|||
[Test maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get upper excluded]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -32,21 +23,12 @@
|
|||
[Get bound range (generated) with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Non existent key]
|
||||
expected: FAIL
|
||||
|
||||
[zero maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Max value count]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where first key < upperBound]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where lowerBound < last key]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with transaction.commit()]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -58,9 +40,6 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbobjectstore_getAll.any.worker.html]
|
||||
[Single item get]
|
||||
expected: FAIL
|
||||
|
||||
[Single item get (generated key)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -76,12 +55,6 @@
|
|||
[Test maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get upper excluded]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -91,21 +64,12 @@
|
|||
[Get bound range (generated) with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Non existent key]
|
||||
expected: FAIL
|
||||
|
||||
[zero maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Max value count]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where first key < upperBound]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where lowerBound < last key]
|
||||
expected: FAIL
|
||||
|
||||
[Get all values with transaction.commit()]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@
|
|||
[Get all keys with both options and count]
|
||||
expected: FAIL
|
||||
|
||||
[Get all keys with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAllKeys-options.tentative.any.serviceworker.html]
|
||||
expected: ERROR
|
||||
|
@ -139,9 +136,6 @@
|
|||
[Get all keys with both options and count]
|
||||
expected: FAIL
|
||||
|
||||
[Get all keys with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAllKeys-options.tentative.any.sharedworker.html]
|
||||
expected: ERROR
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
expected: ERROR
|
||||
|
||||
[idbobjectstore_getAllKeys.any.worker.html]
|
||||
[Single item get]
|
||||
expected: FAIL
|
||||
|
||||
[Single item get (generated key)]
|
||||
expected: FAIL
|
||||
|
||||
[getAllKeys on empty object store]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -20,47 +14,23 @@
|
|||
[Test maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get upper excluded]
|
||||
expected: FAIL
|
||||
|
||||
[Get lower excluded]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range (generated) with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Non existent key]
|
||||
expected: FAIL
|
||||
|
||||
[zero maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Max value count]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where first key < upperBound]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where lowerBound < last key]
|
||||
expected: FAIL
|
||||
|
||||
[Get all keys with invalid query keys]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idbobjectstore_getAllKeys.any.html]
|
||||
[Single item get]
|
||||
expected: FAIL
|
||||
|
||||
[Single item get (generated key)]
|
||||
expected: FAIL
|
||||
|
||||
[getAllKeys on empty object store]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -70,35 +40,17 @@
|
|||
[Test maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Get upper excluded]
|
||||
expected: FAIL
|
||||
|
||||
[Get lower excluded]
|
||||
expected: FAIL
|
||||
|
||||
[Get bound range (generated) with maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Non existent key]
|
||||
expected: FAIL
|
||||
|
||||
[zero maxCount]
|
||||
expected: FAIL
|
||||
|
||||
[Max value count]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where first key < upperBound]
|
||||
expected: FAIL
|
||||
|
||||
[Query with empty range where lowerBound < last key]
|
||||
expected: FAIL
|
||||
|
||||
[Get all keys with invalid query keys]
|
||||
expected: FAIL
|
||||
|
|
12
tests/wpt/meta/IndexedDB/idlharness.any.js.ini
vendored
12
tests/wpt/meta/IndexedDB/idlharness.any.js.ini
vendored
|
@ -5,12 +5,6 @@
|
|||
[IDBFactory interface: operation databases()]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: attribute keyPath]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: attribute indexNames]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: operation openCursor(optional any, optional IDBCursorDirection)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -115,12 +109,6 @@
|
|||
[IDBFactory interface: operation databases()]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: attribute keyPath]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: attribute indexNames]
|
||||
expected: FAIL
|
||||
|
||||
[IDBObjectStore interface: operation openCursor(optional any, optional IDBCursorDirection)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
[keypath-special-identifiers.any.html]
|
||||
expected: TIMEOUT
|
||||
[Type: String, identifier: length]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Array, identifier: length]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Blob, identifier: size]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Blob, identifier: type]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: File, identifier: name]
|
||||
expected: FAIL
|
||||
|
@ -25,17 +26,18 @@
|
|||
expected: ERROR
|
||||
|
||||
[keypath-special-identifiers.any.worker.html]
|
||||
expected: TIMEOUT
|
||||
[Type: String, identifier: length]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Array, identifier: length]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Blob, identifier: size]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: Blob, identifier: type]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Type: File, identifier: name]
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue