Awesome
dsync
<a href="https://crates.io/crates/dsync"><img src="https://img.shields.io/crates/v/dsync.svg?style=for-the-badge" height="20" alt="License: MIT OR Apache-2.0" /></a>
A utility to generate database structs and querying code from diesel schema files. Primarily built for create-rust-app.
Currently, it's more advantageous to generate code over deriving code with macros because intellisense and autocompletion isn't quite there when it comes to macro expansion.
Demo
Given the following schema:
// schema.rs
diesel::table! {
todos (id) {
id -> Int4,
text -> Text,
completed -> Bool,
}
}
We run:
dsync -i schema.rs -o models
Now we have everything we need!
use models::todos;
async fn demo(db: Connection) {
let created_todo = todos::create(&mut db, todos::CreateTodo {
text: "Create a demo",
completed: false,
})?;
let updated_todo = todos::update(&mut db, created_todo.id, UpdateTodo {
text: created_todo.text,
completed: true,
})?;
}
For a complete example, see test/simple_table_sqlite/schema.rs
which generates all the code in test/simple_schema_sqlite/models
.
Usage as a library
-
Add this crate:
cargo add dsync
-
Create a new binary in your project which uses the crate (for example,
bin/dsync.rs
)use std::{collections::HashMap, path::PathBuf}; use dsync::{GenerationConfig, TableOptions}; pub fn main() { let dir = env!("CARGO_MANIFEST_DIR"); dsync::generate_files( PathBuf::from_iter([dir, "src/schema.rs"]), PathBuf::from_iter([dir, "src/models"]), GenerationConfig { connection_type: "diesel::sqlite::SqliteConnection", options: Default::default(), } ); }
-
Create a
Cargo.toml
binary entry:[[bin]] name = "dsync" path = "bin/dsync.rs"
-
Execute!
cargo run --bin dsync
Protip: to use cargo dsync
, create an alias in .cargo/config
:
[alias]
dsync="run --bin dsync"
Pre-built binary
Setting up a custom binary allows you to completely customize the generation; however, if complete customization isn't necessary, you can install the CLI directly (you'll have to make sure you keep it up-to-date by running this periodically):
cargo install dsync
CLI Usage
Generate rust structs & query functions from diesel schema files.
Usage: dsync [OPTIONS] --input <INPUT> --output <OUTPUT> --connection-type <CONNECTION_TYPE>
dsync [OPTIONS] <COMMAND>
Commands:
completions Generate shell completions
Options:
-i, --input <INPUT>
Input diesel schema file
-o, --output <OUTPUT>
Output file, stdout if not present
--tsync
adds the #[tsync] attribute to all structs; see
https://github.com/Wulf/tsync
-g, --autogenerated-columns <AUTOGENERATED_COLUMNS>
List of columns which are automatically generated but are not primary
keys (for example: "created_at", "updated_at", etc.)
-c, --connection-type <CONNECTION_TYPE>
rust type which describes a connection
For example:
- `diesel::pg::PgConnection`
- `diesel::sqlite::SqliteConnection`
- `diesel::mysql::MysqlConnection`
-
`diesel::r2d2::PooledConnection<diesel::r2d2::ConnectionManager<diesel::pg::PgConnection>>`
- or, your custom diesel connection type (struct which implements
`diesel::connection::Connection`)
--no-serde
Disable generating serde implementations
--schema-path <SCHEMA_PATH>
Set custom schema use path
[default: crate::schema::]
--model-path <MODEL_PATH>
Set custom model use path
[default: crate::models::]
--no-crud
Do not generate the CRUD (impl) functions for generated models
--create-str <CREATE_STR>
Set which string type to use for Create* structs
[default: string]
Possible values:
- string: Use "String"
- str: Use "&str"
- cow: Use "Cow<str>"
--update-str <UPDATE_STR>
Set which string type to use for Update* structs
[default: string]
Possible values:
- string: Use "String"
- str: Use "&str"
- cow: Use "Cow<str>"
--create-bytes <CREATE_BYTES>
Set which bytes type to use for Create* structs
[default: vec]
Possible values:
- vec: Use "Vec<u8>"
- slice: Use "&[u8]"
- cow: Use "Cow<[u8]>"
--update-bytes <UPDATE_BYTES>
Set which bytes type to use for Update* structs
[default: vec]
Possible values:
- vec: Use "Vec<u8>"
- slice: Use "&[u8]"
- cow: Use "Cow<[u8]>"
--single-model-file
Only Generate a single model file instead of a directory with "mod.rs"
and "generated.rs"
--once-common-structs
Generate common structs only once in a "common.rs" file
--once-connection-type
Generate the "ConnectionType" type only once in a "common.rs" file
--readonly-prefix <READONLY_PREFIXES>
A Prefix to treat a table matching this as readonly (only generate the
Read struct)
--readonly-suffix <READONLY_SUFFIXES>
A Suffix to treat a table matching this as readonly (only generate the
Read struct)
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
Example
dsync -i src/schema.rs -o src/models
Notes
- the CLI has fail-safes to prevent accidental file overwriting
- *2: "readonly" tables don't have
Update*
(UpdateTodos
) &Create*
(CreateTodos
) structs, only*
(Todos
, no suffix / prefix) structs. For example this is useful for Sqlite views, which are read-only (cannot be written to, but can be read)
Experimental API
We're currently experimenting with advanced query generation. This includes pagination, filtering/searching, and the like. Enable the advanced-queries
feature flag to see some of it in action.
Alternatively, you can see what gets generated in the advanced queries test here: test/advanced_queries/models
Feel free to open an issue to discuss these API and provide your feedback.
Docs
See dsync --help
for all CLI arguments and documentation.
See docs.rs for library documentation.
Feel free to open tickets for support or feature requests.
Development/Testing
Use ./test/test_all.sh
to run tests.
After running the test, there should be no unexpected changes to files in ./test
(use git status
and git diff
to see if there were any changes).
License
This tool is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.