use std::path::PathBuf;
use cratestack::include_embedded_schema;
use cratestack::{Decimal, RusqliteRuntime, rusqlite_backend::ddl::create_table_sql};
use cratestack_rusqlite::ModelDelegate;
include_embedded_schema!("examples/sqlite_offline_first.cstack");
use cratestack_schema::models::{Account, Transfer};
use cratestack_schema::{
ACCOUNT_MODEL, CreateAccountInput, CreateTransferInput, TRANSFER_MODEL, UpdateAccountInput,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let db_path: PathBuf = std::env::temp_dir().join("cratestack_offline_first.sqlite");
let _ = std::fs::remove_file(&db_path);
let runtime = RusqliteRuntime::open(&db_path)?;
println!("opened {}", db_path.display());
runtime.with_connection(|conn| {
conn.execute_batch(&format!(
"{};\n{};",
create_table_sql(&ACCOUNT_MODEL),
create_table_sql(&TRANSFER_MODEL),
))
.expect("create tables");
Ok(())
})?;
let accounts = ModelDelegate::<Account, uuid::Uuid>::new(&runtime, &ACCOUNT_MODEL);
let transfers = ModelDelegate::<Transfer, uuid::Uuid>::new(&runtime, &TRANSFER_MODEL);
let alice_id = uuid::Uuid::new_v4();
let bob_id = uuid::Uuid::new_v4();
accounts
.create(CreateAccountInput {
id: alice_id,
ownerName: "Alice".to_string(),
balance: "1234.5600".parse::<Decimal>()?,
active: true,
openedAt: chrono::Utc::now(),
})
.run()?;
accounts
.create(CreateAccountInput {
id: bob_id,
ownerName: "Bob".to_string(),
balance: "42.00".parse::<Decimal>()?,
active: true,
openedAt: chrono::Utc::now(),
})
.run()?;
for (amount, memo) in [
("-10.00", "coffee"),
("-150.99", "groceries"),
("2500.00", "salary"),
] {
transfers
.create(CreateTransferInput {
id: uuid::Uuid::new_v4(),
accountId: alice_id,
amount: amount.parse::<Decimal>()?,
memo: memo.to_string(),
createdAt: chrono::Utc::now(),
})
.run()?;
}
let recent = transfers
.find_many()
.where_(cratestack_schema::transfer::accountId().eq(alice_id))
.order_by(cratestack_schema::transfer::createdAt().desc())
.limit(2)
.run()?;
println!("\nAlice's two most recent transfers:");
for transfer in &recent {
println!(" {:>10} {}", transfer.amount, transfer.memo);
}
let updated = accounts
.update(bob_id)
.set(UpdateAccountInput {
active: Some(false),
..Default::default()
})
.run()?;
println!(
"\nBob's account is now active={} (balance stayed {})",
updated.active, updated.balance
);
let active = accounts
.find_many()
.where_(cratestack_schema::account::active().is_true())
.order_by(cratestack_schema::account::ownerName().asc())
.run()?;
println!("\nactive accounts:");
for account in &active {
println!(" {:<10} {}", account.ownerName, account.balance);
}
Ok(())
}