tag | 07a8b54e1226190083284aa5496bbf8de3b09404 | |
---|---|---|
tagger | Georg Semmler <github@weiznich.de> | Fri May 31 09:38:56 2024 +0200 |
object | 197f06d8d1c0f66774b1ab24c5db93d28962e07a |
Diesel 2.2.0 Added: * Support `[print_schema] exclude_custom_type_definitions = ["Vector"]`. If a `custom type` matches one element on the list it's skipped. * Added automatic usage of all sqlite `rowid` aliases when no explicit primary key is defined for `print-schema` * Added a `#[dsl::auto_type]` attribute macro, allowing to infer type of query fragment functions * Added the same type inference on `Selectable` derives, which allows skipping specifying `select_expression_type` most of the time, in turn enabling most queries to be written using just a `Selectable` derive. * Added an optional `#[diesel(skip_insertion)]` field attribute to the `Insertable` derive macro, allowing fields which map to generated columns to be skipped during insertion. * Support for connection instrumentation. This allows to inspect any query run by your application * Logging in diesel-cli * Support for libsqlite3-sys 0.28 * Add `sqlite-integer-primary-key-is-bigint` configuration option, usable with SQLite 3.37 or above, allowing to use `BigInt` for `INTEGER PRIMARY KEY` columns in SQLite for tables without the `WITHOUT ROWID` attribute ([SQLite doc](https://www.sqlite.org/lang_createtable.html#rowid)). * Support for multiple `print_schema` entry in `diesel.toml` (e.g. `[print_schema.user1]`), which allows generating multiple schema.rs files * Add support for `COPY TO` and `COPY FROM` statements * Add support for mapping `chrono::Duration` to postgresql's `INTERVAL` sql type * Added `serialize_database_to_buffer` and `deserialize_readonly_database_from_buffer` methods in `SqliteConnection` to support serialization/deserialization of SQLite databases to and from byte buffers. * Added `SerializedDatabase` wrapper type for a serialized database that is dynamically allocated by calling `serialize_database_to_buffer`. This RAII wrapper deallocates the memory when it goes out of scope with `sqlite3_free`. Changed: * The minimal officially supported rustc version is now 1.78.0 * Deprecated `sql_function!` in favour of `define_sql_function!` which provides compatibility with `#[dsl::auto_type]` * Deserialization error messages now contain information about the field that failed to deserialize
commit | 197f06d8d1c0f66774b1ab24c5db93d28962e07a | [log] [tgz] |
---|---|---|
author | Georg Semmler <github@weiznich.de> | Fri May 31 09:32:57 2024 +0200 |
committer | Georg Semmler <github@weiznich.de> | Fri May 31 09:32:57 2024 +0200 |
tree | f12eb41200538f3b759fa78f6b79cd4388024be4 | |
parent | 874b8dcade31fd7309c804b17a217fdd3c45fa0d [diff] |
Fix the includes in all `Cargo.toml` files
API Documentation: latest release – master branch
Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance. It takes full advantage of Rust's type system to create a low overhead query builder that “feels like Rust.”
Supported databases:
You can configure the database backend in Cargo.toml
:
[dependencies] diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }
Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.
If you run into problems, Diesel has a very active Gitter room. You can come ask for help at gitter.im/diesel-rs/diesel. For help with longer questions and discussion about the future of Diesel, open a discussion on GitHub Discussions.
Simple queries are a complete breeze. Loading all users from a database:
users::table.load(&mut connection)
Executed SQL:
SELECT * FROM users;
Loading all the posts for a user:
Post::belonging_to(user).load(&mut connection)
Executed SQL:
SELECT * FROM posts WHERE user_id = 1;
Diesel's powerful query builder helps you construct queries as simple or complex as you need, at zero cost.
let versions = Version::belonging_to(krate) .select(id) .order(num.desc()) .limit(5); let downloads = version_downloads .filter(date.gt(now - 90.days())) .filter(version_id.eq_any(versions)) .order(date) .load::<Download>(&mut conn)?;
Executed SQL:
SELECT version_downloads.* WHERE date > (NOW() - '90 days') AND version_id = ANY( SELECT id FROM versions WHERE crate_id = 1 ORDER BY num DESC LIMIT 5 ) ORDER BY date
Diesel codegen generates boilerplate for you. It lets you focus on your business logic, not mapping to and from SQL rows.
That means you can write this:
#[derive(Queryable, Selectable)] #[diesel(table_name = downloads)] pub struct Download { id: i32, version_id: i32, downloads: i32, counted: i32, date: SystemTime, }
Instead of this without Diesel:
pub struct Download { id: i32, version_id: i32, downloads: i32, counted: i32, date: SystemTime, } impl Download { fn from_row(row: &Row) -> Download { Download { id: row.get("id"), version_id: row.get("version_id"), downloads: row.get("downloads"), counted: row.get("counted"), date: row.get("date"), } } }
It's not just about reading data. Diesel makes it easy to use structs for new records.
#[derive(Insertable)] #[diesel(table_name = users)] struct NewUser<'a> { name: &'a str, hair_color: Option<&'a str>, } let new_users = vec![ NewUser { name: "Sean", hair_color: Some("Black") }, NewUser { name: "Gordon", hair_color: None }, ]; insert_into(users) .values(&new_users) .execute(&mut connection);
Executed SQL:
INSERT INTO users (name, hair_color) VALUES ('Sean', 'Black'), ('Gordon', DEFAULT)
If you need data from the rows you inserted, just change execute
to get_result
or get_results
. Diesel will take care of the rest.
let new_users = vec![ NewUser { name: "Sean", hair_color: Some("Black") }, NewUser { name: "Gordon", hair_color: None }, ]; let inserted_users = insert_into(users) .values(&new_users) .get_results::<User>(&mut connection);
Executed SQL:
INSERT INTO users (name, hair_color) VALUES ('Sean', 'Black'), ('Gordon', DEFAULT) RETURNING *
Diesel's codegen can generate several ways to update a row, letting you encapsulate your logic in the way that makes sense for your app.
Modifying a struct:
post.published = true; post.save_changes(&mut connection);
One-off batch changes:
update(users.filter(email.like("%@spammer.com"))) .set(banned.eq(true)) .execute(&mut connection)
Using a struct for encapsulation:
update(Settings::belonging_to(current_user)) .set(&settings_form) .execute(&mut connection)
There will always be certain queries that are just easier to write as raw SQL, or can't be expressed with the query builder. Even in these cases, Diesel provides an easy to use API for writing raw SQL.
#[derive(QueryableByName)] #[diesel(table_name = users)] struct User { id: i32, name: String, organization_id: i32, } // Using `include_str!` allows us to keep the SQL in a // separate file, where our editor can give us SQL specific // syntax highlighting. sql_query(include_str!("complex_users_by_organization.sql")) .bind::<Integer, _>(organization_id) .bind::<BigInt, _>(offset) .bind::<BigInt, _>(limit) .load::<User>(&mut conn)?;
Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.
Licensed under either of these:
Before contributing, please read the contributors guide for useful information about setting up Diesel locally, coding style and common abbreviations.
Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.