Rust の ORM「Diesel」とたわむれてみた。

## 諸注意

- Rust超初心者です。お手柔らかにお願いします。
- いつもはpythonとC++を使うことが多いですが、Rust書いてみたかったので触ってみました。
- RustのORMについて何があるんだろうと調べて、どうやら「Diesel」とういうものがあると知り、使い勝手はどんなものか簡単に調べてみました。


## やったこと

- gitにある[Dieselのexampleコード](https://github.com/SergioBenitez/Rocket/tree/master/examples/todo)を追いかけてみました。
    - sqliteにdieselのマイグレーションでテーブルを作る。
    - 手でサンプルデータをインサートする。
    - diselからコネクションを作って、データの一覧を受け取る。

また、こちら[dieselのサンプル(sqlite)を動かしてみた](https://qiita.com/techno-tanoC/items/4ca564bd1ea8db409496)を参考にさせていただきました。素晴らしい記事をありがとうございます！！

##rustの環境
```bash
$ rustc --version
rustc 1.40.0-nightly (1423bec54 2019-11-05)
```

## 感想
- Dieselはそれに比べて少しドキュメントが少ないし、本家のgitのexampleもけっこうバグが出て悲しみが多い。([Dieselのexampleコード](https://github.com/SergioBenitez/Rocket/tree/master/examples/todo))


チュートリアルでバグが出るのはきついですよね、下のコードは下の環境下で動くことを確認済みなので、ぜひご活用ください！！
これからRust勉強していきます。
「いいね」や「コメント」お待ちしております！！

## Diesel
いつものごとくプロジェクトを作ります。

```bash
cargo new web_diesel
```

Cargo.toml

```
[dependencies]
rocket="0.4"
rocket_contrib={version="0.4", features=["json"]}
serde = {version="1.0", features=["derive"]}
serde_json="1.0.0"
diesel = { version = "1.4.0", features = ["sqlite"] }
dotenv = "0.10"
```

データベースを作ります。
これでsample.dbというsqliteのファイルができます。

```
$ echo DATABASE_URL=./sample.db > .env
$ diesel setup
```

マイグレーションをします。

```
$ diesel migration generate create_posts
```

できたマイグレーションフォルダのup.sqlに

```up.sql
CREATE TABLE posts (
  id INTEGER NOT NULL PRIMARY KEY,
  title VARCHAR NOT NULL,
  body TEXT NOT NULL,
  published BOOLEAN NOT NULL DEFAULT 0
)
```
down.sqlに

```down.sql
DROP TABLE posts
```

と書く。


ここで、フォルダの中は

```bash
$ls
Cargo.lock   Cargo.toml   diesel.toml  migrations/  sample.db    src/         target/
```

```bash
tree src
src
├── main.rs
├── models.rs
├── sample.db
├── schema.rs
```

となっている。

main.rs

```rust
#[macro_use]
extern crate diesel;

use web_diesel::models::*;
use diesel::prelude::*;

#[macro_use]
extern crate dotenv;

// models.rsとschema.rsのインポート
pub mod models;
pub mod schema;

use diesel::prelude::*;
use dotenv::dotenv;
use std::env;

//Sqliteコネクションを作る。
pub fn establish_connection() -> SqliteConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    SqliteConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

//レコードをすべて受け取る。
fn main() {
    use web_diesel::schema::posts::dsl::*;

    let connection = establish_connection();
    let results = posts
        // .filter(published.eq(true))
        .limit(5)
        .load::<Post>(&connection)
        .expect("Error loading posts");

    println!("Displaying {} posts", results.len());
    for post in results {
        println!("{}", post.title);
        println!("----------\n");
        println!("{}", post.body);
    }
}
```

models.rs

```rust
#[derive(Queryable)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub body: String,
    pub published: bool,
}
```

schema.rs

```rust
table! {
    posts (id) {
        id -> Integer,
        title -> Text,
        body -> Text,
        published -> Bool,
    }
}
```

とりあえず、手でデータをインサートして、ORMで全件取得ということをしてみます。

```bash
$sqlite3 sample.db
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .table
__diesel_schema_migrations  posts                     
sqlite> insert into posts values(1,"title1", "body1",0);
```

という感じで五件くらい入れてみます。

```
$sqlite3 sample.db
sqlite> select * from posts;
1|title1|body1|0
2|title2|body2|0
3|title3|body3|0
4|title4|body4|0
5|title5|body5|0
sqlite> 
```

が確認できたら、
プロジェクトリポジトリ直下(sample.dbがある場所)で、

```bash
cargo run
```

```bash

    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/web_diesel`
Displaying 5 posts
title1
----------

body1
title2
----------

body2
title3
----------

body3
title4
----------

body4
title5
----------

body5

```

とレコードが取得できるのを確認できました。


後日もっといろいろやってみたいと思います！！