{"id":16376606,"url":"https://github.com/killercup/presentation-diesel-adventure","last_synced_at":"2026-05-03T05:35:27.620Z","repository":{"id":66475146,"uuid":"83570004","full_name":"killercup/presentation-diesel-adventure","owner":"killercup","description":null,"archived":false,"fork":false,"pushed_at":"2017-03-01T17:07:52.000Z","size":1560,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-01T08:15:11.389Z","etag":null,"topics":["diesel","presentation","rust","slides","sql"],"latest_commit_sha":null,"homepage":"https://killercup.github.io/presentation-diesel-adventure/index.html","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/killercup.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-01T15:28:41.000Z","updated_at":"2017-03-06T13:57:05.000Z","dependencies_parsed_at":"2023-06-01T13:00:42.631Z","dependency_job_id":null,"html_url":"https://github.com/killercup/presentation-diesel-adventure","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/killercup%2Fpresentation-diesel-adventure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/killercup%2Fpresentation-diesel-adventure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/killercup%2Fpresentation-diesel-adventure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/killercup%2Fpresentation-diesel-adventure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/killercup","download_url":"https://codeload.github.com/killercup/presentation-diesel-adventure/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239970660,"owners_count":19727010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diesel","presentation","rust","slides","sql"],"created_at":"2024-10-11T03:25:17.929Z","updated_at":"2026-04-07T01:30:17.151Z","avatar_url":"https://github.com/killercup.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: Diesel – Type-safe SQL\nauthor: Pascal Hertleif\ndate: 2017-03-01\n---\n\n## Pascal Hertleif\n\n- Web stuff by day, Rust by night!\n- Coorganizer of [Rust Cologne]\n- {[twitter],[github]}.com/killercup\n\n[Rust Cologne]: http://rust.cologne/\n[twitter]: https://twitter.com/killercup\n[github]: https://github.com/killercup\n\n\n# First off\n\n## [diesel.rs](http://diesel.rs)\n\n![](assets/diesel.svg){ style=\"padding: 5px\" }\n\n## Requires Rust 1.15\n\n## Supported Backends\n\n- Postgres\n- SQLite\n- MySQL\n\n# Getting started\n\n---\n\n```sh\n$ cargo new --bin diesel-example\n$ cd diesel-example\n$ echo \"DATABASE_URL=test.db\" \u003e .env\n```\n\nAdd to `Cargo.toml`:\n\n```toml\n[dependencies]\ndiesel = { version = \"0.10.1\", features = [\"sqlite\"] }\ndiesel_codegen = { version = \"0.10.1\", features = [\"sqlite\"] }\ndotenv = \"0.8.0\"\n```\n\n---\n\nAnd you are good to go!\n\n\n# Query Builder\n\n---\n\nWrite queries in Rust\n\nInvalid queries are compile-time errors\n\n## Basic Usage\n\n```rust\nlet still_todo: Vec\u003cTodo\u003e =\n    todos\n    .filter(done.eq(false))\n    .limit(100)\n    .load(\u0026connection)\n    .unwrap();\n```\n\n---\n\nNot shown:\n\n```rust\n#[derive(Queryable)]\nstruct Todo { title: String, done: bool };\n\npub mod schema {\n    infer_schema!(\"dotenv:DATABASE_URL\");\n}\n\nuse schema::todos::dsl::{todos, done};\n```\n\n---\n\n- [Tell me more about this DSL](#dsl)\n- [What kind of sorcery is `infer_schema!`?!](#infer_schema)\n\n\n# DSL {#dsl}\n\n## Idea\n\n1. Create zero-sized structs for table and its columns\n2. Implement traits on these structs\n3. ???\n4. PROFIT!\n\n## Intuitive Methods\n\n- `todos.select((id, title))`\n- `.filter(done.eq(false))`\n- `.limit(100)`\n\n## Each method returns a new, nested type.\n\n`todos.filter(done.eq(false)).limit(100)`\n\n```rust\nSelectStatement\u003c\n    (Integer, Text, Bool),\n    (todos::id, todos::title, todos::done),\n    todos::table,\n    NoDistinctClause,\n    WhereClause\u003cEq\u003ctodos::done, Bound\u003cBool, bool\u003e\u003e\u003e,\n    NoOrderClause,\n    LimitClause\u003cBound\u003cBigInt, i64\u003e\u003e\n\u003e\n```\n\n---\n\n- [That sounds like a lot of boilerplate…](#table)\n- [Is this what makes it fast?](#perf)\n\n\n# Traits for Everything {#traits}\n\n---\n\nDiesel has `i32::MAX` traits in its codebase last time I counted\n\n---\n\nAdd methods to methods to query builder? Write a trait like [`FilterDsl`](http://docs.diesel.rs/diesel/prelude/trait.FilterDsl.html)!\n\nAnd implement generically:\n\n```rust\nimpl\u003cT, Predicate, ST\u003e FilterDsl\u003cPredicate\u003e for T\n```\n\n---\n\nWell, actually...\n\n```rust\nimpl\u003cT, Predicate, ST\u003e FilterDsl\u003cPredicate\u003e for T where\n  Predicate: Expression\u003cSqlType=Bool\u003e + NonAggregate,\n  FilteredQuerySource\u003cT, Predicate\u003e: AsQuery\u003cSqlType=ST\u003e,\n  T: AsQuery\u003cSqlType=ST\u003e + NotFiltered\n```\n\n(Those constraints are all traits as well!)\n\n## Using rustdoc to Create Mazes\n\n**[docs.diesel.rs](http://docs.diesel.rs)**\n\nPro tip: Just search for what you think it should be called\n\n---\n\n- [Do I need to implement these traits myself?](#derive)\n- [What's with the `SqlType`?](#mapping-types)\n\n\n# A Duality of Types {#mapping-types}\n\n---\n\nThere are\n\n- SQL types\n- Rust types\n\nand ways to convert between them\n\n---\n\n- Your schema contains SQL types\n- Your application's structs contain Rust types\n\n---\n\n- `FromSql`, `ToSql`\n- Can map 1:1 like [`Float`](http://docs.diesel.rs/diesel/types/struct.Float.html)\n- Or not, like [`Timestamp`](http://docs.diesel.rs/diesel/types/struct.Timestamp.html)\n\n---\n\n- [Do I need to implement these conversions myself?](#derive)\n\n\n# The `table!` Macro {#table}\n\n---\n\n```rust\ntable! {\n    todos (id) {\n        id -\u003e Integer,\n        title -\u003e Text,\n        done -\u003e Bool,\n    }\n}\n```\n\n---\n\n[Let's see what we end up with](file:///Users/pascal/Projekte/diesel-demo/target/doc/diesel_demo/schema/todos/index.html)\n\n---\n\n- [Those don't look like Rust types](#mapping-types)\n- [Do I have to type that?](#infer_schema)\n\n\n# The Amazing Schema Inference {#infer_schema}\n\n---\n\nNever let your code and database schema diverge!\n\n`infer_schema!(\"dotenv:DATABASE_URL\");`\n\n---\n\nIt basically generates the [`table!`](#table) macro calls for you.\n\n---\n\n- You need to have a database running on your dev machine\n- The schema needs to be the same as in production\n\n---\n\n`diesel print-schema`\n\nprints the `table!` macro calls `infer_schema!` generates\n\n(So you can e.g. put it in version control)\n\n---\n\n- [How do you manage migrations](#migrations)\n- [Oh, what's that `diesel` tool?](#cli)\n\n\n# Derive ALL the Traits {#derive}\n\n---\n\n[Did I tell you about our Lord and Savior, Macros 1.1?](https://blog.rust-lang.org/2017/02/02/Rust-1.15.html)\n\n---\n\n```rust\n#[macro_use] extern crate diesel;\n#[macro_use] extern crate diesel_codegen;\n\n#[derive(Debug, Queryable)]\nstruct Todo {\n    id: i32,\n    title: String,\n    done: bool,\n}\n```\n\nIt Just Works™\n\n---\n\n\u003e Diesel Codegen provides custom derive implementations for\n\u003e [`Queryable`][queryable], [`Identifiable`][identifiable],\n\u003e [`Insertable`][insertable], [`AsChangeset`][as-changeset], and [`Associations`][associations].\n\u003e\n\u003e It also provides the macros [`infer_schema!`][infer-schema],\n\u003e [`infer_table_from_schema!`][infer-table-from-schema], and\n\u003e [`embed_migrations!`][embed-migrations].\n\u003e\n\u003e – [diesel_codegen Readme](https://github.com/diesel-rs/diesel/tree/6a6f5835a40efd515dfc774d4b1d335cc87dd4da/diesel_codegen)\n\n[queryable]: http://docs.diesel.rs/diesel/query_source/trait.Queryable.html\n[identifiable]: http://docs.diesel.rs/diesel/associations/trait.Identifiable.html\n[insertable]: http://docs.diesel.rs/diesel/prelude/trait.Insertable.html\n[as-changeset]: http://docs.diesel.rs/diesel/query_builder/trait.AsChangeset.html\n[associations]: http://docs.diesel.rs/diesel/associations/index.html\n[infer-schema]: http://docs.diesel.rs/diesel/macro.infer_schema!.html\n[infer-table-from-schema]: http://docs.diesel.rs/diesel/macro.infer_table_from_schema!.html\n[embed-migrations]: http://docs.diesel.rs/diesel/macro.embed_migrations!.html\n\n---\n\n- [How do these traits work?](#traits)\n- [Associations, you say?](#associations)\n\n\n# Associations {#associations}\n\n---\n\n```rust\n#[derive(Identifiable, Queryable, Associations)]\n#[has_many(posts)]\npub struct User { id: i32, name: String, }\n\n#[derive(Identifiable, Queryable, Associations)]\n#[belongs_to(User)]\npub struct Post { id: i32, user_id: i32, title: String, }\n```\n\n---\n\n```rust\nlet user = try!(users::find(1).first(\u0026connection));\nlet posts = Post::belonging_to(\u0026user).load(\u0026connection);\n```\n\n---\n\nRead much more about this at [docs.diesel.rs/diesel/associations/](http://docs.diesel.rs/diesel/associations/index.html)\n\n\n# Diesel CLI Tool {#cli}\n\n---\n\nInstall it with\n\n```sh\n$ cargo install diesel\n```\n\n---\n\nThis makes it easy to\n\n- Setup your database\n- Manage your [migrations](#migrations)\n- Print your schema\n\n---\n\n- [Tell me more about migrations](#migrations)\n- [What was that about schema printing?](#infer_schema)\n\n\n# Migrations {#migrations}\n\n---\n\n`migrations/datetime-name/{up,down}.sql`\n\nSimple SQL files that change your database schema (e.g. `CREATE TABLE`, `DROP TABLE`)\n\n---\n\n- `diesel migration generate create_todos`\n- `diesel migration run`\n- `diesel migration revert`\n\n---\n\n- [Oh, what's that `diesel` tool?](#cli)\n\n\n# Performance {#perf}\n\n---\n\n- Almost all queries can be represented by unique types\n- Each of these types returns a query (that uses bind params)\n- Let's cache these queries as Prepared Statements!\n\n---\n\n- Is it faster than `c`? [Yes you can use Diesel in warp drives](https://hackernoon.com/comparing-diesel-and-rust-postgres-97fd8c656fdd#.kdof0mold)\n\n\n# Type System Shenanigans\n\n---\n\nMacros to implement traits for generic tuples of up to 52 elements\n\n---\n\nEnable query builder features depending on the used backend\n\n- Basically every type and trait is generic over the backend\n- E.g.: Only Postgres implements `RETURNING` clause\n\n\n# Testing Diesel\n\n## Unit tests\n\nFor helper/converter functions\n\n- `unix_epoch_decodes_correctly_with_timezone`\n- `queries_with_different_types_have_different_ids`\n\n## Integration tests\n\nUsing diesel like a library\n\n## Doc test\n\nExamples in the API documentation are tests!\n\n---\n\nSecret sauce: `include!(\"src/doctest_setup.rs\");`\n\n## Quickcheck\n\nTest roundtrips from Rust → DB → Rust\n\n(With lots of macros, of course)\n\n[Source](https://github.com/diesel-rs/diesel/blob/6a6f5835a40efd515dfc774d4b1d335cc87dd4da/diesel_tests/tests/types_roundtrip.rs)\n\n## Compile-fail Tests\n\nInvalid queries should not compile\n\nSo let's test that they return the expected errors!\n\n---\n\nThe [compiletest](https://github.com/laumann/compiletest-rs) tool is also used by the Rust compiler and Clippy\n\n# Thank you for listening!\n\n- Try diesel tonight!\n- Read the docs at [diesel.rs](http://diesel.rs/)\n- Get help at [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)\n\n# Questions?\n\n---\n\nSlides are available at [git.io/diesel-adventure](https://git.io/diesel-adventure)\n\nLicense: [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkillercup%2Fpresentation-diesel-adventure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkillercup%2Fpresentation-diesel-adventure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkillercup%2Fpresentation-diesel-adventure/lists"}