commit
6c54873ca2
34 changed files with 5502 additions and 0 deletions
81
examples/basic.rs
Normal file
81
examples/basic.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use owl::prelude::*;
|
||||
|
||||
#[model]
|
||||
#[derive(Debug)]
|
||||
pub struct Item {
|
||||
pub id: Id,
|
||||
pub cost: f64,
|
||||
pub strength: f64,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Init
|
||||
let db = Database::in_memory();
|
||||
|
||||
// Save
|
||||
let item = Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 1.80,
|
||||
strength: 0.4,
|
||||
};
|
||||
|
||||
let first_id = item.id.clone();
|
||||
|
||||
dbg!(&item);
|
||||
let item = db.save(item);
|
||||
|
||||
// Get
|
||||
let i: Model<Item> = db.get(item.read().id.clone()).unwrap();
|
||||
|
||||
dbg!(&i.read());
|
||||
|
||||
db.save(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 0.3,
|
||||
strength: 2.4,
|
||||
});
|
||||
|
||||
db.save(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 3.4,
|
||||
strength: 0.4,
|
||||
});
|
||||
|
||||
db.save(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 20.0,
|
||||
strength: 200.5,
|
||||
});
|
||||
|
||||
db.save(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 4.2,
|
||||
strength: 4.2,
|
||||
});
|
||||
|
||||
// Query
|
||||
let res = db.query(|x: &Item| x.cost > 1.5);
|
||||
dbg!(&res
|
||||
.into_iter()
|
||||
.map(|x| format!("{:?}", x.read()))
|
||||
.collect::<Vec<_>>());
|
||||
|
||||
// Update
|
||||
db.update(&mut db.query(|x: &Item| x.cost > 1.5), |x: &mut Item| {
|
||||
x.cost += 1.0;
|
||||
});
|
||||
|
||||
let item: Model<Item> = db.get(first_id.to_string().as_str()).unwrap();
|
||||
dbg!(&item.read());
|
||||
assert_eq!(item.read().cost, 2.80);
|
||||
|
||||
// Aggregates
|
||||
let count = db.query(|x: &Item| x.cost > 1.5).len();
|
||||
let sum: f64 = db
|
||||
.query(|x: &Item| x.cost > 1.5)
|
||||
.iter()
|
||||
.map(|x| x.read().cost)
|
||||
.sum();
|
||||
dbg!(count);
|
||||
dbg!(sum);
|
||||
}
|
81
examples/basic_global.rs
Normal file
81
examples/basic_global.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use owl::{get, prelude::*, query, save, set_global_db, update};
|
||||
|
||||
#[model]
|
||||
#[derive(Debug)]
|
||||
pub struct Item {
|
||||
pub id: Id,
|
||||
pub cost: f64,
|
||||
pub strength: f64,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Init
|
||||
let db = Database::in_memory();
|
||||
set_global_db!(db);
|
||||
|
||||
// Save
|
||||
let item = Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 1.80,
|
||||
strength: 0.4,
|
||||
};
|
||||
|
||||
let first_id = item.id.clone();
|
||||
|
||||
dbg!(&item);
|
||||
let item = save!(item);
|
||||
|
||||
// Get
|
||||
let i: Model<Item> = get!(item.read().id.clone()).unwrap();
|
||||
|
||||
dbg!(&i.read());
|
||||
|
||||
save!(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 0.3,
|
||||
strength: 2.4,
|
||||
});
|
||||
|
||||
save!(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 3.4,
|
||||
strength: 0.4,
|
||||
});
|
||||
|
||||
save!(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 20.0,
|
||||
strength: 200.5,
|
||||
});
|
||||
|
||||
save!(Item {
|
||||
id: Id::new_ulid(),
|
||||
cost: 4.2,
|
||||
strength: 4.2,
|
||||
});
|
||||
|
||||
// Query
|
||||
let res = query!(|x: &Item| x.cost > 1.5);
|
||||
dbg!(&res
|
||||
.into_iter()
|
||||
.map(|x| format!("{:?}", x.read()))
|
||||
.collect::<Vec<_>>());
|
||||
|
||||
// Update
|
||||
update!(&mut query!(|x: &Item| x.cost > 1.5), |x: &mut Item| {
|
||||
x.cost += 1.0;
|
||||
});
|
||||
|
||||
let item: Model<Item> = get!(first_id.to_string().as_str()).unwrap();
|
||||
dbg!(&item.read());
|
||||
assert_eq!(item.read().cost, 2.80);
|
||||
|
||||
// Aggregates
|
||||
let count = query!(|x: &Item| x.cost > 1.5).len();
|
||||
let sum: f64 = query!(|x: &Item| x.cost > 1.5)
|
||||
.iter()
|
||||
.map(|x| x.read().cost)
|
||||
.sum();
|
||||
dbg!(count);
|
||||
dbg!(sum);
|
||||
}
|
17
examples/blob.rs
Normal file
17
examples/blob.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use owl::{db::model::file::File, prelude::*, Identifiable};
|
||||
|
||||
pub fn main() {
|
||||
// Init
|
||||
let db = Database::in_memory();
|
||||
|
||||
let f = File::new(
|
||||
include_bytes!("../Cargo.toml").to_vec(),
|
||||
Some("Cargo.toml".to_string()),
|
||||
&db,
|
||||
);
|
||||
dbg!(&f);
|
||||
|
||||
let f: Model<File> = db.get(f.id()).unwrap();
|
||||
let data = String::from_utf8(f.read_file(&db)).unwrap();
|
||||
println!("Content: {data}");
|
||||
}
|
80
examples/friends.rs
Normal file
80
examples/friends.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use owl::{
|
||||
db::{
|
||||
model::person::Person,
|
||||
relation::{clean_graph_traversal, find_path, get_other},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#[relation("friend", Person, "friendy", Person, RelationKind::Unidirectional)]
|
||||
pub struct Friendship;
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let db = Database::filesystem("./db");
|
||||
let alice = Person::new_id("alice", "", "");
|
||||
let alice = db.save(alice);
|
||||
let bob = Person::new_id("bob", "", "");
|
||||
let bob = db.save(bob);
|
||||
|
||||
Friendship {}.add(&alice, &bob, None, &db);
|
||||
|
||||
let charizard = Person::new_id("charizard", "", "");
|
||||
let charizard = db.save(charizard);
|
||||
|
||||
Friendship.add(&alice, &charizard, None, &db);
|
||||
Friendship.add(&charizard, &bob, None, &db);
|
||||
|
||||
let pika = db.save(Person::new_id("pika", "", ""));
|
||||
|
||||
Friendship.add(&pika, &charizard, None, &db);
|
||||
|
||||
let malice = db.save(Person::new_id("malice", "", ""));
|
||||
|
||||
Friendship.add(&pika, &malice, None, &db);
|
||||
|
||||
let drache = db.save(Person::new_id("drache", "", ""));
|
||||
Friendship.add(&drache, &bob, None, &db);
|
||||
Friendship.add(&drache, &malice, None, &db);
|
||||
|
||||
let enid = db.save(Person::new_id("enid", "", ""));
|
||||
|
||||
Friendship.add(&enid, &alice, None, &db);
|
||||
|
||||
print_friends("person::alice", &db);
|
||||
print_friends("person::bob", &db);
|
||||
print_friends("person::charizard", &db);
|
||||
print_friends("person::drache", &db);
|
||||
print_friends("person::enid", &db);
|
||||
print_friends("person::malice", &db);
|
||||
|
||||
println!(
|
||||
"alice to malice? - {:?}",
|
||||
clean_graph_traversal(
|
||||
"person::alice",
|
||||
&find_path(
|
||||
"person::alice".into(),
|
||||
"person::malice".into(),
|
||||
6,
|
||||
|id, db| get_friends_of(id, &db),
|
||||
&db
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
pub fn print_friends(id: &str, db: &Database) {
|
||||
let other: Vec<_> = get_friends_of(id, db);
|
||||
println!("friends of {id} -- {other:?}");
|
||||
}
|
||||
|
||||
pub fn get_friends_of<T: Into<IdRef<Person>>>(id: T, db: &Database) -> Vec<IdRef<Person>> {
|
||||
let id: IdRef<Person> = id.into();
|
||||
let refs = Friendship::get_friend_of(id.to_string(), db);
|
||||
dbg!(&refs);
|
||||
get_other::<Person, _, _>(id, refs, db)
|
||||
.into_iter()
|
||||
.map(|x| IdRef::<Person>::from(&x))
|
||||
.collect()
|
||||
}
|
55
examples/loan.rs
Normal file
55
examples/loan.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use owl::{db::model::person::Person, prelude::*};
|
||||
#[relation("receiver", Person, "payer", Person, RelationKind::Bidirectional)]
|
||||
pub struct LoanRelation {
|
||||
debt: f64,
|
||||
}
|
||||
|
||||
pub fn lend_money(who: &Model<Person>, from: &Model<Person>, amount: f64, db: &Database) {
|
||||
LoanRelation { debt: amount }.add(who, from, None, db)
|
||||
}
|
||||
|
||||
pub fn pay_off(who: &Model<Person>, to: &Model<Person>, amount: f64, db: &Database) {
|
||||
let mut loan = LoanRelation::get(who, to, db).unwrap();
|
||||
loan.write(db, |loan| {
|
||||
loan.alter_meta(|x: &mut _| {
|
||||
x.debt -= amount;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let db = Database::filesystem("./db");
|
||||
let p = db.save(Person::new_id("myperson", "first", "last"));
|
||||
let p2 = db.save(Person::new_id("secperson", "second", "last"));
|
||||
let banker = db.save(Person::new_id("banker", "boss", "bank"));
|
||||
|
||||
lend_money(&p, &banker, 250.0, &db);
|
||||
|
||||
lend_money(&p2, &p, 100.0, &db);
|
||||
|
||||
lend_money(&p2, &banker, 150.0, &db);
|
||||
|
||||
let financer: Vec<_> = LoanRelation::get_payer_of(&p2, &db)
|
||||
.into_iter()
|
||||
.map(|x| LoanRelation::payer(&x.dereference(&db), &db))
|
||||
.map(|x| x.read().first_name.current().cloned().unwrap())
|
||||
.collect();
|
||||
println!(
|
||||
"{} is financed by {:?}",
|
||||
p2.read().first_name.current().unwrap(),
|
||||
financer
|
||||
);
|
||||
|
||||
let brokers = LoanRelation::get_receiver_of(&p, &db);
|
||||
dbg!(&brokers);
|
||||
let brokers = dereference(&brokers, &db);
|
||||
|
||||
brokers.iter().for_each(|x| println!("{:?}", x.read()));
|
||||
|
||||
pay_off(&p2, &p, 100.0, &db);
|
||||
|
||||
let brokers = dereference(&LoanRelation::get_receiver_of(&p, &db), &db);
|
||||
brokers.iter().for_each(|x| println!("{:?}", x.read()));
|
||||
}
|
29
examples/parent.rs
Normal file
29
examples/parent.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use owl::{db::model::person::Person, prelude::*};
|
||||
|
||||
#[relation("parent", Person, "child", Person, RelationKind::Unidirectional)]
|
||||
pub struct ParentRelation;
|
||||
|
||||
pub fn main() {
|
||||
let db = Database::in_memory();
|
||||
let p = Person::new_id("myperson", "first", "last");
|
||||
db.save(p);
|
||||
let p: Model<Person> = db.get("myperson").unwrap();
|
||||
|
||||
let p2 = Person::new_id("secperson", "second", "last");
|
||||
let p2 = db.save(p2);
|
||||
|
||||
ParentRelation.add(&p, &p2, None, &db);
|
||||
|
||||
let children_of = ParentRelation::get_child_of(&p, &db);
|
||||
dbg!(&children_of);
|
||||
|
||||
let children_of = dereference(&children_of, &db);
|
||||
children_of
|
||||
.iter()
|
||||
.for_each(|x| println!("child: {:?}", x.read()));
|
||||
|
||||
let my_parents = dereference(&ParentRelation::get_parent_of(&p2, &db), &db);
|
||||
my_parents
|
||||
.iter()
|
||||
.for_each(|x| println!("parent: {:?}", x.read()));
|
||||
}
|
61
examples/references.rs
Normal file
61
examples/references.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use owl::{db::model::person::Person, prelude::*};
|
||||
|
||||
#[model]
|
||||
#[derive(Debug)]
|
||||
pub struct Car {
|
||||
pub id: Id,
|
||||
pub price: u32,
|
||||
pub driver: IdRef<Person>,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
// Init
|
||||
let db = Database::in_memory();
|
||||
|
||||
let per = Person::new_id("perso", "P1", "");
|
||||
let per2: Person = Person::new_id("perso2", "P2", "");
|
||||
|
||||
// Save
|
||||
let car = Car {
|
||||
id: Id::new_ulid(),
|
||||
price: 1000,
|
||||
driver: per.reference(),
|
||||
};
|
||||
db.save(per);
|
||||
let per2 = db.save(per2);
|
||||
let mut car = db.save(car);
|
||||
|
||||
println!(
|
||||
"P1 has {} cars",
|
||||
db.query(|car: &Car| {
|
||||
car.driver
|
||||
.dereference(&db)
|
||||
.read()
|
||||
.first_name
|
||||
.current()
|
||||
.unwrap()
|
||||
.as_str()
|
||||
== "P1"
|
||||
})
|
||||
.iter()
|
||||
.count()
|
||||
);
|
||||
|
||||
car.write(&db, |car| {
|
||||
car.driver = per2.reference();
|
||||
});
|
||||
|
||||
println!(
|
||||
"P1 has {} cars",
|
||||
db.query(|car: &Car| {
|
||||
car.driver
|
||||
.try_dereference(&db)
|
||||
.map(|x| x.read().first_name.current().unwrap().as_str() == "P1")
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.iter()
|
||||
.count()
|
||||
);
|
||||
}
|
43
examples/stock.rs
Normal file
43
examples/stock.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use owl::prelude::*;
|
||||
|
||||
#[model]
|
||||
pub struct Stock {
|
||||
pub id: Id,
|
||||
}
|
||||
|
||||
#[model]
|
||||
pub struct Owner {
|
||||
pub id: Id,
|
||||
}
|
||||
|
||||
#[relation("owner", Owner, "stock", Stock, RelationKind::Unidirectional)]
|
||||
pub struct StockOrder {
|
||||
amount: f64,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let db = Database::filesystem("./db");
|
||||
|
||||
let o = Owner { id: Id::new_ulid() };
|
||||
let o = db.save(o);
|
||||
|
||||
let apl = Stock {
|
||||
id: Id::String("APL".to_string()),
|
||||
};
|
||||
let apl = db.save(apl);
|
||||
|
||||
StockOrder { amount: 1.0 }.add(&o, &apl, None, &db);
|
||||
|
||||
for order in StockOrder::get_stock_of(&o, &db) {
|
||||
let rel = db.get(order).unwrap();
|
||||
|
||||
println!(
|
||||
"{} has {} {}",
|
||||
StockOrder::owner(&rel, &db).read().id.to_string(),
|
||||
StockOrder::meta(&rel).unwrap().amount,
|
||||
StockOrder::stock(&rel, &db).read().id.to_string()
|
||||
);
|
||||
}
|
||||
}
|
61
examples/watch.rs
Normal file
61
examples/watch.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use owl::prelude::*;
|
||||
|
||||
#[model]
|
||||
#[derive(Debug)]
|
||||
pub struct Contact {
|
||||
pub id: Id,
|
||||
pub age: u16,
|
||||
}
|
||||
|
||||
pub fn age_one_year(p: &mut Model<Contact>, db: &Database) {
|
||||
p.write(db, |p| p.age += 1);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
// Init
|
||||
let db = Database::in_memory();
|
||||
|
||||
let mut c1 = db.save(Contact {
|
||||
id: Id::String("c1".to_string()),
|
||||
age: 15,
|
||||
});
|
||||
let mut c2 = db.save(Contact {
|
||||
id: Id::String("c2".to_string()),
|
||||
age: 17,
|
||||
});
|
||||
let mut c3 = db.save(Contact {
|
||||
id: Id::String("c3".to_string()),
|
||||
age: 16,
|
||||
});
|
||||
|
||||
let age_18_watcher = db.watch::<Contact, _, _>(
|
||||
|c| c.age == 18,
|
||||
|c| {
|
||||
println!("{} turned 18", c.id);
|
||||
},
|
||||
);
|
||||
|
||||
std::thread::spawn(move || loop {
|
||||
age_18_watcher.process();
|
||||
});
|
||||
|
||||
age_one_year(&mut c1, &db);
|
||||
age_one_year(&mut c2, &db);
|
||||
age_one_year(&mut c3, &db);
|
||||
|
||||
age_one_year(&mut c1, &db);
|
||||
age_one_year(&mut c2, &db);
|
||||
age_one_year(&mut c3, &db);
|
||||
|
||||
age_one_year(&mut c1, &db);
|
||||
age_one_year(&mut c2, &db);
|
||||
age_one_year(&mut c3, &db);
|
||||
|
||||
age_one_year(&mut c1, &db);
|
||||
age_one_year(&mut c2, &db);
|
||||
age_one_year(&mut c3, &db);
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue