Skip to content

Commit 6233184

Browse files
committed
Add storage crate
1 parent e9a3fa3 commit 6233184

File tree

7 files changed

+516
-1
lines changed

7 files changed

+516
-1
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ readme = "README.md"
88
version = "0.1.0"
99

1010
[dependencies]
11-
gloo-timers = { version = "0.1.0", path = "crates/timers" }
1211
gloo-console-timer = { version = "0.1.0", path = "crates/console-timer" }
12+
gloo-storage = { version = "0.1.0", path = "crates/storage" }
13+
gloo-timers = { version = "0.1.0", path = "crates/timers" }
1314

1415
[features]
1516
default = []

crates/storage/Cargo.toml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[package]
2+
name = "gloo-storage"
3+
version = "0.1.0"
4+
authors = ["Rust and WebAssembly Working Group"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
futures = "0.1.25"
9+
js-sys = "0.3.17"
10+
serde_json = { optional = true, version = "1.0" }
11+
wasm-bindgen = "0.2.40"
12+
wasm-bindgen-futures = "0.3.17"
13+
web-sys = "0.3.17"
14+
15+
[dev-dependencies]
16+
wasm-bindgen-test = "0.2.37"
17+
18+
[features]
19+
default = ["indexed-db"]
20+
indexed-db = [
21+
"web-sys/IdbDatabase",
22+
"web-sys/IdbFactory",
23+
"web-sys/IdbIndex",
24+
"web-sys/IdbIndexParameters",
25+
"web-sys/IdbObjectStore",
26+
"web-sys/IdbObjectStoreParameters",
27+
"web-sys/IdbOpenDbOptions",
28+
"web-sys/IdbOpenDbRequest",
29+
"web-sys/IdbRequest",
30+
"web-sys/IdbTransaction",
31+
"web-sys/Window",
32+
33+
"web-sys/console"
34+
]
35+
json-storage = ["serde_json", "web-sys/Storage", "web-sys/Window"]

crates/storage/src/indexed_db.rs

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
use crate::{Index, Storage, TableDefinition, TableManager, Version};
2+
use wasm_bindgen::{prelude::*, JsCast};
3+
use web_sys::{IdbDatabase, IdbFactory, IdbIndexParameters, IdbObjectStore, IdbOpenDbOptions};
4+
5+
/// IndexedDB
6+
#[derive(Debug)]
7+
pub struct IndexedDb {
8+
database_name: String,
9+
factory: IdbFactory,
10+
}
11+
12+
impl IndexedDb {
13+
/// Creates a new instance for database `name`.
14+
pub fn new<I>(name: I) -> Self
15+
where
16+
I: Into<String>,
17+
{
18+
Self {
19+
database_name: name.into(),
20+
factory: web_sys::window()
21+
.unwrap_throw()
22+
.indexed_db()
23+
.unwrap_throw()
24+
.unwrap_throw(),
25+
}
26+
}
27+
}
28+
29+
impl Storage for IndexedDb {
30+
type TableManager = IndexedDbTableManager;
31+
type Version = IndexedDbVersion;
32+
33+
fn add_version<F, I>(&mut self, version: I, cb: F)
34+
where
35+
F: FnOnce(Self::Version) -> Self::Version + 'static,
36+
I: Into<f64>,
37+
{
38+
let request = self
39+
.factory
40+
.open_with_idb_open_db_options(
41+
&self.database_name,
42+
IdbOpenDbOptions::new().version(version.into()),
43+
)
44+
.unwrap_throw();
45+
let result = request.result();
46+
let closure = Closure::once(move || {
47+
let database = result.unwrap_throw().unchecked_into::<IdbDatabase>();
48+
cb(IndexedDbVersion { database })
49+
});
50+
let func = closure.as_ref().unchecked_ref::<js_sys::Function>();
51+
request.set_onupgradeneeded(Some(func));
52+
}
53+
54+
fn delete(&mut self) {
55+
self.factory
56+
.delete_database(&self.database_name)
57+
.unwrap_throw();
58+
}
59+
60+
fn name(&self) -> &str {
61+
&self.database_name
62+
}
63+
64+
fn table_manager(&mut self, _: &str) -> Self::TableManager {
65+
unimplemented!();
66+
}
67+
68+
fn transaction(&mut self) {
69+
unimplemented!();
70+
}
71+
}
72+
73+
/// IndexedDB table definition
74+
#[derive(Debug)]
75+
pub struct IndexedDbTableDefinition {
76+
object_store: IdbObjectStore,
77+
}
78+
79+
impl TableDefinition for IndexedDbTableDefinition {
80+
fn add_row_with_index(self, name: &str, index: Index) -> Self {
81+
let mut params = IdbIndexParameters::new();
82+
match index {
83+
Index::MultiEntry => {
84+
params.multi_entry(true);
85+
}
86+
Index::Unique => {
87+
params.unique(true);
88+
}
89+
_ => {}
90+
};
91+
self.object_store
92+
.create_index_with_str_and_optional_parameters(name, name, &params)
93+
.unwrap_throw();
94+
self
95+
}
96+
97+
fn remove_old_row(self, name: &str) -> Self {
98+
self.object_store.delete(&name.into()).unwrap_throw();;
99+
self
100+
}
101+
}
102+
103+
/// IndexedDB table manager
104+
#[derive(Debug)]
105+
pub struct IndexedDbTableManager();
106+
107+
impl TableManager for IndexedDbTableManager {
108+
fn get_all() {
109+
unimplemented!();
110+
}
111+
112+
fn push() {
113+
unimplemented!();
114+
}
115+
}
116+
117+
/// IndexedDB version
118+
#[wasm_bindgen]
119+
#[derive(Debug)]
120+
pub struct IndexedDbVersion {
121+
database: web_sys::IdbDatabase,
122+
}
123+
124+
impl Version for IndexedDbVersion {
125+
type TableDefinition = IndexedDbTableDefinition;
126+
127+
fn add_table(self, name: &str) -> Self {
128+
self.database.create_object_store(name).unwrap_throw();
129+
self
130+
}
131+
132+
fn add_and_update_table<F>(self, name: &str, cb: F) -> Self
133+
where
134+
F: FnMut(Self::TableDefinition) -> Self::TableDefinition,
135+
{
136+
self.add_table(name).update_table(name, cb)
137+
}
138+
139+
fn remove_table(self, name: &str) -> Self {
140+
self.database.delete_object_store(name).unwrap_throw();
141+
self
142+
}
143+
144+
fn update_table<F>(self, name: &str, mut cb: F) -> Self
145+
where
146+
F: FnMut(Self::TableDefinition) -> Self::TableDefinition,
147+
{
148+
cb(IndexedDbTableDefinition {
149+
object_store: self
150+
.database
151+
.transaction_with_str(name)
152+
.unwrap_throw()
153+
.object_store(name)
154+
.unwrap(),
155+
});
156+
self
157+
}
158+
159+
fn update_version(self) -> Self {
160+
unimplemented!();
161+
}
162+
}

0 commit comments

Comments
 (0)