feat(card_db): Switch to fully-fledged diesel-based sqlite db
This commit is contained in:
parent
7e9f0ff128
commit
2bb09cbe54
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
|||
edition = "2024"
|
266
Cargo.lock
generated
266
Cargo.lock
generated
|
@ -242,6 +242,41 @@ version = "0.8.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "6.1.0"
|
||||
|
@ -267,6 +302,15 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-where"
|
||||
version = "1.2.7"
|
||||
|
@ -278,6 +322,60 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "2.2.4"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361"
|
||||
dependencies = [
|
||||
"diesel_derives",
|
||||
"downcast-rs",
|
||||
"libsqlite3-sys",
|
||||
"sqlite-wasm-rs",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel-derive-enum"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81c5131a2895ef64741dad1d483f358c2a229a3a2d1b256778cdc5e146db64d4"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_derives"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361"
|
||||
dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"dsl_auto_type",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_migrations"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
"migrations_internals",
|
||||
"migrations_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_table_macro_syntax"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361"
|
||||
dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
|
@ -289,20 +387,31 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
|
||||
[[package]]
|
||||
name = "draft-manager"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"dedent",
|
||||
"diesel",
|
||||
"diesel-derive-enum",
|
||||
"diesel_migrations",
|
||||
"futures",
|
||||
"idb",
|
||||
"leptos",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"serde_json",
|
||||
"sqlite-wasm-rs",
|
||||
"thiserror 2.0.12",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -311,6 +420,19 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408"
|
||||
|
||||
[[package]]
|
||||
name = "dsl_auto_type"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"either",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.19"
|
||||
|
@ -375,6 +497,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fragile"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
|
@ -548,6 +676,18 @@ version = "0.15.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
|
@ -707,18 +847,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "idb"
|
||||
version = "0.6.4"
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3afe8830d5802f769dc0be20a87f9f116798c896650cb6266eb5c19a3c109eed"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
|
@ -912,6 +1044,16 @@ version = "0.2.170"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linear-map"
|
||||
version = "1.2.0"
|
||||
|
@ -969,6 +1111,25 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "migrations_internals"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_macros"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -1001,13 +1162,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
|
@ -1129,6 +1287,18 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.30"
|
||||
|
@ -1516,12 +1686,35 @@ version = "1.14.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||
|
||||
[[package]]
|
||||
name = "sqlite-wasm-rs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84473e8335ed2f167c6f8040970d976990fb66aa62292ae58735de6d61ecfb73"
|
||||
dependencies = [
|
||||
"fragile",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.99"
|
||||
|
@ -1639,6 +1832,37 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.7.6"
|
||||
|
@ -1769,6 +1993,12 @@ dependencies = [
|
|||
"getrandom 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
|
|
@ -7,10 +7,17 @@ edition = "2021"
|
|||
console_error_panic_hook = "0.1.7"
|
||||
dedent = "0.1.1"
|
||||
futures = "0.3.31"
|
||||
idb = "0.6.4"
|
||||
leptos = { version = "0.7.7", features = ["csr"] }
|
||||
diesel = { git = "https://github.com/diesel-rs/diesel.git", features = ["sqlite"] }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde-wasm-bindgen = "0.6.5"
|
||||
serde_json = "1.0.140"
|
||||
thiserror = "2.0.12"
|
||||
url = "2.5.4"
|
||||
wasm-bindgen = "0.2.100"
|
||||
wasm-bindgen-futures = "0.4.50"
|
||||
diesel-derive-enum = { version = "2.1.0", features = ["sqlite"] }
|
||||
diesel_migrations = { git = "https://github.com/diesel-rs/diesel.git", features = ["sqlite"] }
|
||||
|
||||
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies]
|
||||
sqlite-wasm-rs = { version = ">=0.3.0, <0.4.0" , default-features = false, features = ["precompiled"]}
|
||||
|
|
9
diesel.toml
Normal file
9
diesel.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
# For documentation on how to configure this file,
|
||||
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
||||
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||
|
||||
[migrations_directory]
|
||||
dir = "/home/tlater/Documents/Projects/draft-manager/migrations"
|
|
@ -26,6 +26,8 @@
|
|||
packages = with pkgs; [
|
||||
cargo
|
||||
clippy
|
||||
diesel-cli
|
||||
emscripten
|
||||
rustc
|
||||
rustfmt
|
||||
leptosfmt
|
||||
|
|
1
migrations/2025-03-13-161839_create_cards/down.sql
Normal file
1
migrations/2025-03-13-161839_create_cards/down.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- This file should undo anything in `up.sql`
|
7
migrations/2025-03-13-161839_create_cards/up.sql
Normal file
7
migrations/2025-03-13-161839_create_cards/up.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE cards (
|
||||
password PRIMARY KEY,
|
||||
name VARCHAR NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
frame TEXT CHECK(frame IN ('normal', 'effect', 'ritual', 'fusion', 'synchro', 'xyz', 'link', 'normal_pendulum', 'effect_pendulum', 'ritual_pendulum', 'fusion_pendulum', 'synchro_pendulum', 'xyz_pendulum', 'spell', 'trap', 'token')) NOT NULL,
|
||||
image TEXT
|
||||
)
|
|
@ -1,6 +1,6 @@
|
|||
use leptos::prelude::*;
|
||||
|
||||
use crate::utils::card_database::CardDetails;
|
||||
use crate::database::models::CardDetails;
|
||||
|
||||
#[component]
|
||||
pub fn Card(details: Option<CardDetails>) -> impl IntoView {
|
||||
|
|
2
src/database.rs
Normal file
2
src/database.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod models;
|
||||
pub mod schema;
|
38
src/database/models.rs
Normal file
38
src/database/models.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use diesel::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::database::schema::cards;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Insertable, Selectable, Queryable)]
|
||||
#[diesel(table_name = cards)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct CardDetails {
|
||||
pub password: i32,
|
||||
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
|
||||
pub frame: FrameType,
|
||||
pub image: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, diesel_derive_enum::DbEnum)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FrameType {
|
||||
Normal,
|
||||
Effect,
|
||||
Ritual,
|
||||
Fusion,
|
||||
Synchro,
|
||||
Xyz,
|
||||
Link,
|
||||
NormalPendulum,
|
||||
EffectPendulum,
|
||||
RitualPendulum,
|
||||
FusionPendulum,
|
||||
SynchroPendulum,
|
||||
XyzPendulum,
|
||||
Spell,
|
||||
Trap,
|
||||
Token,
|
||||
}
|
9
src/database/schema.rs
Normal file
9
src/database/schema.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
diesel::table! {
|
||||
cards (password) {
|
||||
password -> Integer,
|
||||
name -> VarChar,
|
||||
description -> Text,
|
||||
frame -> crate::database::models::FrameTypeMapping,
|
||||
image -> Text,
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod components;
|
||||
pub mod draft_list;
|
||||
pub mod utils;
|
||||
pub mod database;
|
||||
|
|
|
@ -10,8 +10,8 @@ fn main() {
|
|||
#[component]
|
||||
fn App() -> impl IntoView {
|
||||
let card = LocalResource::new(|| async move {
|
||||
let database = CardDatabase::open().await?;
|
||||
database.load_data().await?;
|
||||
let mut database = CardDatabase::open()?;
|
||||
database.load_data()?;
|
||||
|
||||
database.get_card(1861629).await
|
||||
});
|
||||
|
|
|
@ -1,145 +1,51 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use idb::{
|
||||
event::VersionChangeEvent, Database, DatabaseEvent, Factory, KeyPath, ObjectStoreParams, Query,
|
||||
TransactionMode,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_wasm_bindgen::Serializer;
|
||||
use crate::database::{self, models::FrameType, schema::cards};
|
||||
use database::models::CardDetails;
|
||||
use diesel::prelude::*;
|
||||
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FrameType {
|
||||
Normal,
|
||||
Effect,
|
||||
Ritual,
|
||||
Fusion,
|
||||
Synchro,
|
||||
Xyz,
|
||||
Link,
|
||||
NormalPendulum,
|
||||
EffectPendulum,
|
||||
RitualPendulum,
|
||||
FusionPendulum,
|
||||
SynchroPendulum,
|
||||
XyzPendulum,
|
||||
Spell,
|
||||
Trap,
|
||||
Token,
|
||||
}
|
||||
const DB_URL: &str = "cards.db";
|
||||
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct CardDetails {
|
||||
pub password: u32,
|
||||
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
|
||||
pub frame: FrameType,
|
||||
pub image: String,
|
||||
}
|
||||
|
||||
pub struct CardDatabase(Database);
|
||||
|
||||
const DB_VERSION: u32 = 1;
|
||||
pub struct CardDatabase(SqliteConnection);
|
||||
|
||||
impl CardDatabase {
|
||||
pub async fn open() -> Result<Self> {
|
||||
let factory = Factory::new()?;
|
||||
let mut open_request = factory.open("cards", Some(DB_VERSION))?;
|
||||
|
||||
let err = Rc::new(RefCell::new(Ok(())));
|
||||
let moved_err = err.clone(); // Will be moved inside closure
|
||||
open_request.on_upgrade_needed(move |event| {
|
||||
let res = Self::upgrade_database(event);
|
||||
|
||||
if let Err(e) = res {
|
||||
*std::cell::RefCell::<_>::borrow_mut(&moved_err) = Err(e);
|
||||
drop(moved_err);
|
||||
}
|
||||
});
|
||||
|
||||
let database = open_request.await?;
|
||||
// Get the error if there is one - note that if the Rc has a
|
||||
// strong count > 1 and therefore Symbol’s value as variable is void: into_inner returns Symbol’s value as variable is void: None,
|
||||
// this means that the callback was not called, and as such
|
||||
// there cannot have been an error.
|
||||
let res = Rc::into_inner(err).unwrap_or(Ok(()).into()).into_inner();
|
||||
|
||||
res.map(|_| Self(database))
|
||||
pub fn open() -> Result<Self> {
|
||||
let mut connection = SqliteConnection::establish(DB_URL)?;
|
||||
connection.run_pending_migrations(MIGRATIONS).unwrap();
|
||||
Ok(Self(connection))
|
||||
}
|
||||
|
||||
pub async fn get_card(&self, key: u32) -> Result<Option<CardDetails>> {
|
||||
let transaction = self.0.transaction(&["cards"], TransactionMode::ReadOnly)?;
|
||||
let store = transaction.object_store("cards")?;
|
||||
let card = store.get(Query::Key(key.into()))?.await?;
|
||||
Ok(card.map(serde_wasm_bindgen::from_value).transpose()?)
|
||||
pub async fn get_card(&mut self, password: i32) -> Result<Option<CardDetails>> {
|
||||
match cards::dsl::cards.find(password).first(&mut self.0) {
|
||||
Ok(details) => Ok(Some(details)),
|
||||
Err(diesel::result::Error::NotFound) => Ok(None),
|
||||
Err(other) => Err(other.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn load_data(&self) -> Result<()> {
|
||||
let transaction = self.0.transaction(&["cards"], TransactionMode::ReadWrite)?;
|
||||
let store = transaction.object_store("cards")?;
|
||||
|
||||
// Add some test data for now
|
||||
let decode_talker = serde_json::json!({
|
||||
"password": 1861629,
|
||||
"name": "Decode Talker",
|
||||
"description": "2+ Effect Monsters\r\nGains 500 ATK for each monster it points to. When your opponent activates a card or effect that targets a card(s) you control (Quick Effect): You can Tribute 1 monster this card points to; negate the activation, and if you do, destroy that card.",
|
||||
"frame": "link",
|
||||
"image": "https://images.ygoprodeck.com/images/cards/1861629.jpg"
|
||||
});
|
||||
|
||||
store
|
||||
.put(
|
||||
&decode_talker.serialize(&Serializer::json_compatible())?,
|
||||
None,
|
||||
)?
|
||||
.await?;
|
||||
|
||||
transaction.commit()?.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Upgrade the database; this is called by the browser whenever
|
||||
/// we try to open a newer database version.
|
||||
fn upgrade_database(event: VersionChangeEvent) -> Result<()> {
|
||||
let database = event.database()?;
|
||||
|
||||
let upgrade_from = event.old_version()?;
|
||||
match upgrade_from {
|
||||
// This version number signals that the database
|
||||
// hasn't been created before.
|
||||
0 => {
|
||||
let mut store_params = ObjectStoreParams::new();
|
||||
store_params.key_path(Some(KeyPath::new_single("password")));
|
||||
|
||||
let store = database.create_object_store("cards", store_params)?;
|
||||
|
||||
store.create_index(
|
||||
"fulltext",
|
||||
KeyPath::new_array(vec!["password", "name", "description"]),
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
other => return Err(CardDatabaseError::UnknownDatabaseVersion(other)),
|
||||
pub fn load_data(&mut self) -> Result<()> {
|
||||
let decode_talker = CardDetails {
|
||||
password: 1861629,
|
||||
name: "Decode Talker".to_owned(),
|
||||
description: "2+ Effect Monsters\r\nGains 500 ATK for each monster it points to. When your opponent activates a card or effect that targets a card(s) you control (Quick Effect): You can Tribute 1 monster this card points to; negate the activation, and if you do, destroy that card.".to_owned(),
|
||||
frame: FrameType::Link,
|
||||
image: "https://images.ygoprodeck.com/images/cards/1861629.jpg".to_owned()
|
||||
};
|
||||
|
||||
diesel::insert_into(cards::table)
|
||||
.values(decode_talker)
|
||||
.execute(&mut self.0)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CardDatabaseError {
|
||||
#[error(
|
||||
"unknown card database version `{0}`, please close the tab and re-open the application"
|
||||
)]
|
||||
UnknownDatabaseVersion(u32),
|
||||
#[error("card database operation failed; does the browser support IndexedDB?")]
|
||||
BrowserError(#[from] idb::Error),
|
||||
#[error("invalid test data")]
|
||||
SerdeError(#[from] serde_wasm_bindgen::Error),
|
||||
#[error("failed to connect to database")]
|
||||
DieselConnectionError(#[from] diesel::ConnectionError),
|
||||
#[error("failed to query database")]
|
||||
DieselQueryError(#[from] diesel::result::Error),
|
||||
}
|
||||
type Result<T> = std::result::Result<T, CardDatabaseError>;
|
||||
|
|
Loading…
Reference in a new issue