script/dom/indexeddb/
idbindex.rs1use dom_struct::dom_struct;
5use js::context::JSContext;
6use js::gc::MutableHandleValue;
7use script_bindings::cell::DomRefCell;
8use script_bindings::codegen::GenericBindings::IDBIndexBinding::IDBIndexMethods;
9use script_bindings::codegen::GenericBindings::IDBTransactionBinding::IDBTransactionMode;
10use script_bindings::conversions::SafeToJSValConvertible;
11use script_bindings::error::{Error, ErrorResult};
12use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
13use script_bindings::str::DOMString;
14
15use crate::dom::bindings::root::{Dom, DomRoot};
16use crate::dom::globalscope::GlobalScope;
17use crate::dom::idbobjectstore::KeyPath;
18use crate::dom::indexeddb::idbobjectstore::IDBObjectStore;
19
20#[dom_struct]
21pub(crate) struct IDBIndex {
22 reflector_: Reflector,
23 object_store: Dom<IDBObjectStore>,
24 name: DomRefCell<DOMString>,
25 multi_entry: bool,
26 unique: bool,
27 key_path: KeyPath,
28}
29
30impl IDBIndex {
31 pub fn new_inherited(
32 object_store: &IDBObjectStore,
33 name: DOMString,
34 multi_entry: bool,
35 unique: bool,
36 key_path: KeyPath,
37 ) -> IDBIndex {
38 IDBIndex {
39 reflector_: Reflector::new(),
40 object_store: Dom::from_ref(object_store),
41 name: DomRefCell::new(name),
42 multi_entry,
43 unique,
44 key_path,
45 }
46 }
47
48 pub fn new(
49 cx: &mut JSContext,
50 global: &GlobalScope,
51 object_store: &IDBObjectStore,
52 name: DOMString,
53 multi_entry: bool,
54 unique: bool,
55 key_path: KeyPath,
56 ) -> DomRoot<IDBIndex> {
57 reflect_dom_object_with_cx(
58 Box::new(IDBIndex::new_inherited(
59 object_store,
60 name,
61 multi_entry,
62 unique,
63 key_path,
64 )),
65 global,
66 cx,
67 )
68 }
69}
70
71impl IDBIndexMethods<crate::DomTypeHolder> for IDBIndex {
72 fn Name(&self) -> DOMString {
74 self.name.borrow().clone()
75 }
76
77 fn SetName(&self, name: DOMString) -> ErrorResult {
79 let transaction = self.object_store.transaction();
82
83 if transaction.get_mode() != IDBTransactionMode::Versionchange {
88 return Err(Error::InvalidState(Some(
89 "Transaction is not an upgrade transaction".to_owned(),
90 )));
91 }
92
93 if !transaction.is_active() {
95 return Err(Error::TransactionInactive(Some(
96 "Transaction is not active while updating index name".to_owned(),
97 )));
98 }
99
100 let mut stored_name = self.name.borrow_mut();
102 if !self.object_store.has_index(&stored_name) ||
103 !transaction
104 .get_db()
105 .object_store_exists(&self.object_store.get_name())
106 {
107 return Err(Error::InvalidState(Some(
108 "Index or its object store has been deleted".to_owned(),
109 )));
110 }
111
112 if *stored_name == name {
114 return Ok(());
115 }
116
117 if self.object_store.has_index(&name) {
119 return Err(Error::Constraint(Some(
120 "An index with the given name already exists".to_owned(),
121 )));
122 }
123
124 self.object_store.rename_index(&stored_name, &name);
126
127 *stored_name = name;
129 Ok(())
130 }
131
132 fn ObjectStore(&self) -> DomRoot<IDBObjectStore> {
134 self.object_store.as_rooted()
135 }
136
137 fn MultiEntry(&self) -> bool {
139 self.multi_entry
140 }
141
142 fn Unique(&self) -> bool {
144 self.unique
145 }
146
147 fn KeyPath(&self, cx: &mut JSContext, retval: MutableHandleValue) {
149 match &self.key_path {
150 KeyPath::String(string) => {
151 string.safe_to_jsval(cx, retval);
152 },
153 KeyPath::StringSequence(sequence) => {
154 sequence.safe_to_jsval(cx, retval);
155 },
156 }
157 }
158}