Overview of [rust_query] and where to find relevant docs.
# Setup
`cargo add rust-query`
Then start definition your schema using the [migration::schema] macro.
```
use rust_query::{Database, migration::{schema, Config}};
#[schema(MyDb)]
pub mod vN {
pub struct SomeDataType {
pub field1: String,
pub field2: i64,
pub some_ref: rust_query::TableRow<OtherTable>,
}
pub struct OtherTable {
pub field: f64,
}
}
use v0::*; // import the first version of the schema.
pub fn main() {
let _db = Database::<MyDb>::new(Config::open_in_memory());
}
```
Refer to the documentation of [migration::schema] for more information on available options.
# Inserting, updating and deleting
All mutation requires a mutable [Transaction], which can be obtained using [Database::transaction_mut] or [Database::transaction_mut_ok].
All mutation are done using [Transaction::insert], [Transaction::mutable] and [TransactionWeak::delete] methods. In some cases it is possible to use the more ergonomic [Transaction::insert_ok] and [TransactionWeak::delete_ok].
Deleting is special as it requires the [Transaction] to be downgraded using [Transaction::downgrade]. This signals that all [TableRow] have lost their proof of existence, since rows can now be deleted.
# Queries
Assuming that there is already some data in the database, we can use a mutable or immutable [Transaction] to read the data.
There are generally two ways to read data:
- [Transaction::query_one] and [Transaction::query] are the original query methods, they give fine grained control over what is queried and can be used together with the [derive@FromExpr] and [derive@Select] macros.
- [Transaction::lazy] and [Transaction::lazy_iter] are easier to use in common situations, but they don't give full control over the data that is retrieved from the database.
All query methods can use [aggregate] and [optional] combinators to build more complicated queries.
The [aggregate] combinator in particular is really powerful and can be used to combine multiple rows into one.
# Migrations
Migrations are currently defined using types generated by the [migration::schema] macro, in a similar way to how the rest of [rust_query] works.
Everything that can be queried in normal transactions can also be queried in migrations.
However it is not possible to mutate the database freely.
Only rows that already existed in the database can be migrated to the new version.
To make migrations more flexible it is possible to make any other kind of change in a separate [migration::Migrator::fixup] phase that runs after the main migration.