Crates.io | rust-query |
lib.rs | rust-query |
version | |
source | src |
created_at | 2024-05-06 12:51:23.979415 |
updated_at | 2024-11-24 14:35:28.896595 |
description | A query builder using rust concepts. |
homepage | |
repository | https://github.com/LHolten/rust-query/ |
max_upload_size | |
id | 1231122 |
Cargo.toml error: | TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
The goal of this library is to allow writing relational database queries using familiar Rust syntax. The library should guarantee that a query can not fail if it compiles. This already includes preventing use after free for row ids passed between queries and even database migrations!
Writing queries using this library involves:
filter
and join
.Notably it does not involve any new syntax or macro, while still being completely type safe.
This project is under development and there are many things missing.
Query types:
Basic operations:
Advanced operations:
Backend support:
Despite these limitations, I am dogfooding this query builder and using it in my own project: advent-of-wasm.
Define a schema using enum
syntax:
use rust_query::migration::schema;
#[schema]
enum MySchema {
// Enum variants are database tables
User {
// This table has one column with String type.
name: String,
},
Image {
description: String,
// This column has a foreign key constraint to the User table
uploaded_by: User,
},
}
Get proof that we are running on a unique thread:
let mut client = LocalClient::try_new().unwrap();
Initialize a database:
let database = client
.migrator(Config::open("my_database.sqlite"))
.expect("database version is before supported versions")
// migrations go here
.finish()
.expect("database version is after supported versions");
Perform a transaction!
let mut transaction = client.transaction_mut(&database);
do_stuff_with_database(&mut transaction);
// After we are done we commit the changes!
transaction.commit();
Insert in the database:
// Lets make a new user 'mike',
let mike = User { name: "mike" };
let mike_id = db.insert(mike);
// and also insert a dog picture for 'mike'.
let dog_picture = Image {
description: "dog",
uploaded_by: mike_id,
};
let _picture_id = db.insert(dog_picture);
Query from the database:
// Now we want to get all pictures for 'mike'.
let mike_pictures = db.query(|rows| {
// Initially there is one empty row.
// Lets join the pictures table.
let picture = Image::join(rows);
// Now lets filter for pictures from mike,
rows.filter(picture.uploaded_by().eq(mike_id));
// and finally turn the rows into a vec.
rows.into_vec(picture.description())
});
println!("{mike_pictures:?}"); // This should print `["dog"]`.
The full example code can be found in insert_and_select.rs
Some features not shown in this example are:
Migrations and unique constraints
Lookups by unique constraint
Aggregations
For more example queries you can look at the chinook example.
First download the Chinook_Sqlite.sqlite
from here and put it in the root of this repository (the working dir).
Then you can run with cargo test
.