mirror of
https://github.com/servo/servo.git
synced 2025-07-15 11:23:39 +01:00
[IndexedDB] Key ranges implementation (#37684)
Improves the implementation of keys to a point where key ranges can be implemented as well. Due to me making branching mistakes I'll have to cherry-pick out the first commit (it's from #37682) --------- Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This commit is contained in:
parent
32d889f770
commit
6ad57a343e
2 changed files with 57 additions and 19 deletions
|
@ -13,6 +13,7 @@ use js::jsapi::{
|
||||||
};
|
};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::{HandleValue, MutableHandleValue};
|
use js::rust::{HandleValue, MutableHandleValue};
|
||||||
|
use log::error;
|
||||||
use net_traits::IpcSend;
|
use net_traits::IpcSend;
|
||||||
use net_traits::indexeddb_thread::{
|
use net_traits::indexeddb_thread::{
|
||||||
AsyncOperation, IndexedDBKeyType, IndexedDBThreadMsg, SyncOperation,
|
AsyncOperation, IndexedDBKeyType, IndexedDBThreadMsg, SyncOperation,
|
||||||
|
@ -25,6 +26,7 @@ use crate::dom::bindings::codegen::Bindings::IDBObjectStoreBinding::IDBObjectSto
|
||||||
use crate::dom::bindings::codegen::Bindings::IDBTransactionBinding::IDBTransactionMode;
|
use crate::dom::bindings::codegen::Bindings::IDBTransactionBinding::IDBTransactionMode;
|
||||||
// We need to alias this name, otherwise test-tidy complains at &String reference.
|
// 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::codegen::UnionTypes::StringOrStringSequence as StrOrStringSequence;
|
||||||
|
use crate::dom::bindings::conversions::jsstring_to_str;
|
||||||
use crate::dom::bindings::error::{Error, Fallible};
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
|
@ -150,22 +152,22 @@ impl IDBObjectStore {
|
||||||
let _seen = seen.unwrap_or_default();
|
let _seen = seen.unwrap_or_default();
|
||||||
|
|
||||||
// Step 2: If seen contains input, then return invalid.
|
// Step 2: If seen contains input, then return invalid.
|
||||||
// FIXME:(rasviitanen)
|
// FIXME:(arihant2math) implement this
|
||||||
// Check if we have seen this key
|
// Check if we have seen this key
|
||||||
// Does not currently work with HandleValue,
|
// Does not currently work with HandleValue,
|
||||||
// as it does not implement PartialEq
|
// as it does not implement PartialEq
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
// FIXME:(rasviitanen) Accept buffer, array and date as well
|
// FIXME:(arihant2math) Accept buffer, array and date as well
|
||||||
if input.is_number() {
|
if input.is_number() {
|
||||||
// FIXME:(rasviitanen) check for NaN
|
// FIXME:(arihant2math) check for NaN
|
||||||
let key = structuredclone::write(cx, input, None).expect("Could not serialize key");
|
return Ok(IndexedDBKeyType::Number(input.to_number()));
|
||||||
return Ok(IndexedDBKeyType::Number(key.serialized));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.is_string() {
|
if input.is_string() {
|
||||||
let key = structuredclone::write(cx, input, None).expect("Could not serialize key");
|
let string_ptr = std::ptr::NonNull::new(input.to_string()).unwrap();
|
||||||
return Ok(IndexedDBKeyType::String(key.serialized));
|
let key = unsafe { jsstring_to_str(*cx, string_ptr).str().to_string() };
|
||||||
|
return Ok(IndexedDBKeyType::String(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.is_object() {
|
if input.is_object() {
|
||||||
|
@ -185,11 +187,9 @@ impl IDBObjectStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsArrayBufferObject(*object) || JS_IsArrayBufferViewObject(*object) {
|
if IsArrayBufferObject(*object) || JS_IsArrayBufferViewObject(*object) {
|
||||||
let key =
|
// FIXME:(arihant2math)
|
||||||
structuredclone::write(cx, input, None).expect("Could not serialize key");
|
error!("Array buffers as keys is currently unsupported");
|
||||||
// FIXME:(arihant2math) Return the correct type here
|
return Err(Error::NotSupported);
|
||||||
// it doesn't really matter at the moment...
|
|
||||||
return Ok(IndexedDBKeyType::Number(key.serialized.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ESClass::Array = built_in_class {
|
if let ESClass::Array = built_in_class {
|
||||||
|
|
|
@ -15,19 +15,57 @@ pub enum IndexedDBTxnMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/IndexedDB-2/#key-type
|
// 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 {
|
pub enum IndexedDBKeyType {
|
||||||
Number(Vec<u8>),
|
Number(f64),
|
||||||
String(Vec<u8>),
|
String(String),
|
||||||
Binary(Vec<u8>),
|
Binary(Vec<u8>),
|
||||||
|
// FIXME:(arihant2math) Date should not be stored as a Vec<u8>
|
||||||
Date(Vec<u8>),
|
Date(Vec<u8>),
|
||||||
// FIXME:(arihant2math) implment Array(),
|
Array(Vec<IndexedDBKeyType>),
|
||||||
|
// FIXME:(arihant2math) implment ArrayBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/IndexedDB-2/#key-range
|
// <https://www.w3.org/TR/IndexedDB-2/#key-range>
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub enum IndexedDBKeyRange {}
|
pub struct IndexedDBKeyRange {
|
||||||
|
pub lower: Option<IndexedDBKeyType>,
|
||||||
|
pub upper: Option<IndexedDBKeyType>,
|
||||||
|
pub lower_open: bool,
|
||||||
|
pub upper_open: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IndexedDBKeyType> for IndexedDBKeyRange {
|
||||||
|
fn from(key: IndexedDBKeyType) -> Self {
|
||||||
|
IndexedDBKeyRange {
|
||||||
|
lower: Some(key.clone()),
|
||||||
|
upper: Some(key),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexedDBKeyRange {
|
||||||
|
// <https://www.w3.org/TR/IndexedDB-2/#in>
|
||||||
|
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
|
// Operations that are not executed instantly, but rather added to a
|
||||||
// queue that is eventually run.
|
// queue that is eventually run.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue