sqlite_wasm_example/
lib.rs1pub mod models;
2pub mod schema;
3
4use std::sync::Mutex;
5use std::sync::Once;
6
7use crate::models::{NewPost, Post};
8use diesel::prelude::*;
9use diesel_migrations::embed_migrations;
10use diesel_migrations::EmbeddedMigrations;
11use diesel_migrations::MigrationHarness;
12use wasm_bindgen::prelude::*;
13
14const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
15
16#[wasm_bindgen]
17extern "C" {
18 #[wasm_bindgen(js_namespace = console)]
21 fn log(s: &str);
22}
23
24macro_rules! console_log {
29 ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
32}
33
34static VFS: Mutex<(i32, Once)> = Mutex::new((0, Once::new()));
35
36pub fn establish_connection() -> SqliteConnection {
37 let (vfs, once) = &*VFS.lock().unwrap();
38 let url = match vfs {
39 0 => "post.db",
40 1 => "file:post.db?vfs=opfs-sahpool",
41 2 => "file:post.db?vfs=relaxed-idb",
42 _ => unreachable!(),
43 };
44 let mut conn =
45 SqliteConnection::establish(url).unwrap_or_else(|_| panic!("Error connecting to post.db"));
46 once.call_once(|| {
47 conn.run_pending_migrations(MIGRATIONS).unwrap();
48 });
49 conn
50}
51
52#[cfg(all(target_family = "wasm", target_os = "unknown"))]
53#[wasm_bindgen(js_name = installOpfsSahpool)]
54pub async fn install_opfs_sahpool() {
55 use sqlite_wasm_rs::sahpool_vfs::{install, OpfsSAHPoolCfg};
56 install(&OpfsSAHPoolCfg::default(), false).await.unwrap();
57}
58
59#[cfg(all(target_family = "wasm", target_os = "unknown"))]
60#[wasm_bindgen(js_name = installRelaxedIdb)]
61pub async fn install_relaxed_idb() {
62 use sqlite_wasm_rs::relaxed_idb_vfs::{install, RelaxedIdbCfg};
63 install(&RelaxedIdbCfg::default(), false).await.unwrap();
64}
65
66#[wasm_bindgen(js_name = switchVfs)]
67pub fn switch_vfs(id: i32) {
68 *VFS.lock().unwrap() = (id, Once::new());
69}
70
71#[wasm_bindgen(js_name = createPost)]
72pub fn create_post(title: &str, body: &str) -> JsValue {
73 use crate::schema::posts;
74
75 let new_post = NewPost { title, body };
76
77 let post = diesel::insert_into(posts::table)
78 .values(&new_post)
79 .returning(Post::as_returning())
80 .get_result(&mut establish_connection())
81 .expect("Error saving new post");
82
83 serde_wasm_bindgen::to_value(&post).unwrap()
84}
85
86#[wasm_bindgen(js_name = deletePost)]
87pub fn delete_post(pattern: &str) {
88 let connection = &mut establish_connection();
89 let num_deleted = diesel::delete(
90 schema::posts::dsl::posts.filter(schema::posts::title.like(pattern.to_string())),
91 )
92 .execute(connection)
93 .expect("Error deleting posts");
94
95 console_log!("Deleted {num_deleted} posts");
96}
97
98#[wasm_bindgen(js_name = getPost)]
99pub fn get_post(post_id: i32) -> JsValue {
100 use schema::posts::dsl::posts;
101
102 let connection = &mut establish_connection();
103
104 let post = posts
105 .find(post_id)
106 .select(Post::as_select())
107 .first(connection)
108 .optional(); match &post {
111 Ok(Some(post)) => console_log!("Post with id: {} has a title: {}", post.id, post.title),
112 Ok(None) => console_log!("Unable to find post {}", post_id),
113 Err(_) => console_log!("An error occurred while fetching post {}", post_id),
114 }
115 serde_wasm_bindgen::to_value(&post.ok().flatten()).unwrap()
116}
117
118#[wasm_bindgen(js_name = publishPost)]
119pub fn publish_post(id: i32) {
120 let connection = &mut establish_connection();
121
122 let post = diesel::update(schema::posts::dsl::posts.find(id))
123 .set(schema::posts::dsl::published.eq(true))
124 .returning(Post::as_returning())
125 .get_result(connection)
126 .unwrap();
127
128 console_log!("Published post {}", post.title);
129}
130
131#[wasm_bindgen(js_name = showPosts)]
132pub fn show_posts() -> Vec<JsValue> {
133 let connection = &mut establish_connection();
134 let results = schema::posts::dsl::posts
135 .filter(schema::posts::dsl::published.eq(true))
136 .limit(5)
137 .select(Post::as_select())
138 .load(connection)
139 .expect("Error loading posts");
140
141 console_log!("Displaying {} posts", results.len());
142 for post in &results {
143 console_log!("{}", post.title);
144 console_log!("----------\n");
145 console_log!("{}", post.body);
146 }
147
148 results
149 .into_iter()
150 .map(|x| serde_wasm_bindgen::to_value(&x).unwrap())
151 .collect()
152}