A safe, extensible ORM and Query Builder for Rust
Go to file
Georg Semmler 381be19568
Merge pull request #4284 from JMLX42/feature/sqlite-json
Add SQLite support for serde_json::Value using the Json/Jsonb
2024-10-02 06:57:31 +00:00
.cargo Rewrite the test script as cargo xtask run-tests 2024-08-02 09:50:36 +02:00
.config Rewrite the test script as cargo xtask run-tests 2024-08-02 09:50:36 +02:00
.github Fix a flaky test 2024-09-27 10:37:08 +02:00
bin Rewrite the test script as cargo xtask run-tests 2024-08-02 09:50:36 +02:00
diesel Merge pull request #4284 from JMLX42/feature/sqlite-json 2024-10-02 06:57:31 +00:00
diesel_bench Update benchmark dependencies 2024-08-23 12:31:10 +00:00
diesel_cli Bump similar_asserts to 1.6 2024-09-19 12:21:51 +02:00
diesel_compile_tests Add Order attribute & generic to combination clause 2024-09-11 09:26:21 +02:00
diesel_derives Add test and support for update(...) to auto_type 2024-09-27 10:15:49 +00:00
diesel_dynamic_schema Rewrite the test script as cargo xtask run-tests 2024-08-02 09:50:36 +02:00
diesel_migrations Rewrite the test script as cargo xtask run-tests 2024-08-02 09:50:36 +02:00
diesel_table_macro_syntax Fix the includes in all Cargo.toml files 2024-05-31 09:32:57 +02:00
diesel_tests add test 2024-09-25 14:45:23 +02:00
docker fix syntax errors in the docker-compose mysql initialization 2019-02-19 20:31:48 +01:00
dsl_auto_type Add support of binary operators to auto_type 2024-09-27 10:15:49 +00:00
examples Cleanup the parallel testsetup 2024-08-30 14:05:03 +02:00
guide_drafts Rename the sql_function_v2! macro to define_sql_function 2024-03-08 11:35:09 +01:00
migrations Add support for the postgres multirange type 2024-08-12 00:08:27 -03:00
xtask Fix the tidy command 2024-08-24 15:39:37 +02:00
.editorconfig Set YAML indent to 2 2020-04-11 09:18:40 +09:00
.env.sample add password for postgres docker image; 2020-03-31 22:04:08 +02:00
.gitignore Update .gitignore 2024-08-23 14:42:30 +02:00
.typos.toml Allow raw identifiers for SqlIdentifier (column-name) 2024-05-24 10:40:26 +02:00
Cargo.toml Merge pull request #4169 from marvin-hansen/master 2024-08-30 12:52:31 +00:00
CHANGELOG.md update CHANGELOG with SQLite+Json/Jsonb support 2024-09-27 23:42:14 +02:00
clippy.toml Fix new clippy warnings 2022-01-24 15:46:36 +01:00
code_of_conduct.md Convert other misc links to https 2017-11-04 01:18:59 +00:00
CONTRIBUTING.md selecting caching strategy 2024-08-27 11:02:51 +03:00
docker-compose.yml add password for postgres docker image; 2020-03-31 22:04:08 +02:00
LICENSE-APACHE add Diesel Core Team to lisences 2021-03-10 13:42:11 +05:30
LICENSE-MIT add Diesel Core Team to lisences 2021-03-10 13:42:11 +05:30
README.md Merge pull request #3704 from hasezoey/fixREADME2 2023-07-20 16:10:41 +00:00
rust-toolchain Bump rust version to 1.81.0 2024-09-05 19:51:59 +02:00

diesel logo

A safe, extensible ORM and Query Builder for Rust

Build Status Gitter Crates.io

API Documentation: latest release master branch

Homepage

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:

  1. PostgreSQL
  2. MySQL
  3. SQLite

You can configure the database backend in Cargo.toml:

[dependencies]
diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }

Getting Started

Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.

Getting help

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.

Usage

Simple queries

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;

Complex queries

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

Less boilerplate

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"),
        }
    }
}

Inserting data

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 *

Updating data

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)

Raw SQL

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)?;

Code of conduct

Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.

License

Licensed under either of these:

Contributing

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.