diff --git a/components/script/dom/idbobjectstore.rs b/components/script/dom/idbobjectstore.rs index 6739a521937..ad445880d80 100644 --- a/components/script/dom/idbobjectstore.rs +++ b/components/script/dom/idbobjectstore.rs @@ -13,6 +13,7 @@ use js::jsapi::{ }; use js::jsval::UndefinedValue; use js::rust::{HandleValue, MutableHandleValue}; +use log::error; use net_traits::IpcSend; use net_traits::indexeddb_thread::{ AsyncOperation, IndexedDBKeyType, IndexedDBThreadMsg, SyncOperation, @@ -25,6 +26,7 @@ use crate::dom::bindings::codegen::Bindings::IDBObjectStoreBinding::IDBObjectSto use crate::dom::bindings::codegen::Bindings::IDBTransactionBinding::IDBTransactionMode; // We need to alias this name, otherwise test-tidy complains at &String reference. use crate::dom::bindings::codegen::UnionTypes::StringOrStringSequence as StrOrStringSequence; +use crate::dom::bindings::conversions::jsstring_to_str; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; @@ -150,22 +152,22 @@ impl IDBObjectStore { let _seen = seen.unwrap_or_default(); // Step 2: If seen contains input, then return invalid. - // FIXME:(rasviitanen) + // FIXME:(arihant2math) implement this // Check if we have seen this key // Does not currently work with HandleValue, // as it does not implement PartialEq // Step 3 - // FIXME:(rasviitanen) Accept buffer, array and date as well + // FIXME:(arihant2math) Accept buffer, array and date as well if input.is_number() { - // FIXME:(rasviitanen) check for NaN - let key = structuredclone::write(cx, input, None).expect("Could not serialize key"); - return Ok(IndexedDBKeyType::Number(key.serialized)); + // FIXME:(arihant2math) check for NaN + return Ok(IndexedDBKeyType::Number(input.to_number())); } if input.is_string() { - let key = structuredclone::write(cx, input, None).expect("Could not serialize key"); - return Ok(IndexedDBKeyType::String(key.serialized)); + let string_ptr = std::ptr::NonNull::new(input.to_string()).unwrap(); + let key = unsafe { jsstring_to_str(*cx, string_ptr).str().to_string() }; + return Ok(IndexedDBKeyType::String(key)); } if input.is_object() { @@ -185,11 +187,9 @@ impl IDBObjectStore { } if IsArrayBufferObject(*object) || JS_IsArrayBufferViewObject(*object) { - let key = - structuredclone::write(cx, input, None).expect("Could not serialize key"); - // FIXME:(arihant2math) Return the correct type here - // it doesn't really matter at the moment... - return Ok(IndexedDBKeyType::Number(key.serialized.clone())); + // FIXME:(arihant2math) + error!("Array buffers as keys is currently unsupported"); + return Err(Error::NotSupported); } if let ESClass::Array = built_in_class { diff --git a/components/shared/net/indexeddb_thread.rs b/components/shared/net/indexeddb_thread.rs index 8d946651eff..d3d8e9fb97c 100644 --- a/components/shared/net/indexeddb_thread.rs +++ b/components/shared/net/indexeddb_thread.rs @@ -15,19 +15,57 @@ pub enum IndexedDBTxnMode { } // https://www.w3.org/TR/IndexedDB-2/#key-type -#[derive(Clone, Debug, Deserialize, Serialize)] +// FIXME:(arihant2math) Ordering needs to completely be reimplemented as per https://www.w3.org/TR/IndexedDB-2/#compare-two-keys +#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)] pub enum IndexedDBKeyType { - Number(Vec), - String(Vec), + Number(f64), + String(String), Binary(Vec), + // FIXME:(arihant2math) Date should not be stored as a Vec Date(Vec), - // FIXME:(arihant2math) implment Array(), + Array(Vec), + // FIXME:(arihant2math) implment ArrayBuffer } -// https://www.w3.org/TR/IndexedDB-2/#key-range -#[derive(Clone, Debug, Deserialize, Serialize)] +// +#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[allow(unused)] -pub enum IndexedDBKeyRange {} +pub struct IndexedDBKeyRange { + pub lower: Option, + pub upper: Option, + pub lower_open: bool, + pub upper_open: bool, +} + +impl From for IndexedDBKeyRange { + fn from(key: IndexedDBKeyType) -> Self { + IndexedDBKeyRange { + lower: Some(key.clone()), + upper: Some(key), + ..Default::default() + } + } +} + +impl IndexedDBKeyRange { + // + pub fn contains(&self, key: &IndexedDBKeyType) -> bool { + // A key is in a key range if both of the following conditions are fulfilled: + // The lower bound is null, or it is less than key, + // or it is both equal to key and the lower open flag is unset. + // The upper bound is null, or it is greater than key, + // or it is both equal to key and the upper open flag is unset + let lower_bound_condition = self + .lower + .as_ref() + .is_none_or(|lower| lower < key || (!self.lower_open && lower == key)); + let upper_bound_condition = self + .upper + .as_ref() + .is_none_or(|upper| key < upper || (!self.upper_open && key == upper)); + lower_bound_condition && upper_bound_condition + } +} // Operations that are not executed instantly, but rather added to a // queue that is eventually run.