mirror of
https://github.com/servo/servo.git
synced 2025-09-23 13:20:11 +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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue