native db is just a key value store with more boilerplate but handy generics
parent
20a3bc7864
commit
4c2ab4a592
|
|
@ -0,0 +1,3 @@
|
|||
[gd_scene format=3 uid="uid://dg85xsdqg6wj0"]
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
|
@ -305,6 +305,8 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"futures",
|
||||
"native_db",
|
||||
"native_model",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -6,3 +6,5 @@ edition = "2024"
|
|||
[dependencies]
|
||||
futures = "0.3.31"
|
||||
native_db = "0.8.1"
|
||||
native_model = "0.4.20"
|
||||
serde = "1.0.218"
|
||||
|
|
|
|||
|
|
@ -1,28 +1,101 @@
|
|||
mod main {
|
||||
use {
|
||||
};
|
||||
use {super::data};
|
||||
|
||||
pub fn run() {
|
||||
let mut db = DB::new(false);
|
||||
db.init().expect("db init failed");
|
||||
let db = data::DB::new().expect("could not make db");
|
||||
}
|
||||
|
||||
struct DB {
|
||||
db: bool,
|
||||
}
|
||||
|
||||
impl DB {
|
||||
fn new(db: bool) -> DB {
|
||||
DB{db: db}
|
||||
mod data {
|
||||
mod models {
|
||||
use {
|
||||
native_db::{
|
||||
native_db,
|
||||
ToKey,
|
||||
},
|
||||
native_model::{
|
||||
native_model,
|
||||
Model,
|
||||
},
|
||||
serde::{Deserialize, Serialize},
|
||||
};
|
||||
|
||||
pub mod v1 {
|
||||
use super::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||
#[native_model(id = 1, version = 1)]
|
||||
#[native_db]
|
||||
pub struct Person {
|
||||
#[primary_key]
|
||||
pub name: String,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init(self: &mut DB) -> Result<(), String> {
|
||||
//self.exec("DROP TABLE IF EXISTS t")?;
|
||||
//self.exec("DROP TABLE IF EXISTS t2")?;
|
||||
//self.exec("CREATE TABLE t (id INTEGER PRIMARY KEY, k TEXT, v TEXT)")?;
|
||||
//self.exec("CREATE TABLE t2 (id INTEGER PRIMARY KEY, t_id INTEGER, FOREIGN KEY (t_id) REFERENCES t (id))")?;
|
||||
use native_db::*;
|
||||
|
||||
pub type Person = models::v1::Person;
|
||||
|
||||
static MODELS: std::sync::LazyLock<Models> = std::sync::LazyLock::new(|| {
|
||||
let mut models = Models::new();
|
||||
models.define::<Person>().expect("failed to define person");
|
||||
models
|
||||
});
|
||||
|
||||
pub struct DB<'a> {
|
||||
db: Database<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DB<'a> {
|
||||
pub fn new() -> Result<DB<'a>, String> {
|
||||
let db = match Builder::new().create_in_memory(&MODELS) {
|
||||
Ok(db) => Ok(db),
|
||||
Err(msg) => Err(msg.to_string()),
|
||||
}?;
|
||||
Ok(DB{
|
||||
db: db,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert<T: ToInput>(self: &DB<'a>, v: T) -> Result<(), String> {
|
||||
let t = match self.db.rw_transaction() {
|
||||
Ok(t) => t,
|
||||
Err(msg) => return Err(msg.to_string()),
|
||||
};
|
||||
if let Err(msg) = t.insert(v) {
|
||||
return Err(msg.to_string());
|
||||
}
|
||||
if let Err(msg) = t.commit() {
|
||||
return Err(msg.to_string());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get<T: ToInput, S: ToKey>(self: &DB<'a>, primary: S) -> Result<Option<T>, String> {
|
||||
let t = match self.db.r_transaction() {
|
||||
Ok(t) => t,
|
||||
Err(msg) => return Err(msg.to_string()),
|
||||
};
|
||||
match t.get().primary(primary) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(msg) => Err(msg.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn mvp() {
|
||||
let db = DB::new().expect("could not make db");
|
||||
let person = Person{name: "me".to_string()};
|
||||
db.insert(person.clone()).expect("could not insert person");
|
||||
assert_eq!(person, db.get("me".to_string()).expect("could not get").expect("got none"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue