diesel クレート
バージョン:2.2.5
事前準備
Rustのバージョンは以下の通り、MySQL8.0 を利用
# cargo -V
cargo 1.82.0 (8f40fc59f 2024-08-21)
# rustc -V
rustc 1.82.0 (f6e511eec 2024-10-15)
下記のテーブルが存在している前提(diesel のマイグレーションは使わない)
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
操作
-
.env
にDATABASE_URL
を設定- dieselコマンドの使用時に
--database_url
を指定するか、DATABASE_URL
環境変数をセットしておく必要がある
- dieselコマンドの使用時に
- diesel cli のインストール・テーブル情報から
schema.rs
を生成
cargo install diesel_cli --no-default-features --features mysql
diesel print-schema > src/schema.rs
Cargo.toml
[package]
name = "app"
version = "0.1.0"
edition = "2021"
[dependencies]
chrono = "0.4.38"
diesel = { version = "2.2.5", features = ["mysql", "chrono"] }
dotenvy = "0.15.7"
schema.rs
// @generated automatically by Diesel CLI.
diesel::table! {
articles (id) {
id -> Integer,
#[max_length = 255]
title -> Varchar,
content -> Text,
created_at -> Nullable<Datetime>,
updated_at -> Nullable<Datetime>,
}
}
- select, insert, update, delete の例を記載
- (エラーハンドリングが弱い)
main.rs
mod schema;
use chrono::NaiveDateTime;
use diesel::{prelude::*, Connection, MysqlConnection, RunQueryDsl};
use dotenvy::dotenv;
use schema::articles::dsl::*;
use std::{env, error::Error};
fn main() -> Result<(), Box<dyn Error>> {
let conn = &mut establish_connection();
let results = select_articles(conn);
println!("{:?}", results);
let result = select_article_by_id(conn, 3);
print!("{:?}", result);
let new_article = Article {
id: 0,
title: String::from("diesel title"),
content: String::from("diesel content"),
created_at: None,
updated_at: None,
};
let _ = insert_article(conn, &new_article);
let mut article_to_update = select_article_by_id(conn, 5)?;
article_to_update.title = String::from("UPDATE TITLE");
let _ = update_article(conn, &article_to_update);
let article_to_delete = select_article_by_id(conn, 4)?;
let _ = delete_article(conn, &article_to_delete)?;
Ok(())
}
fn select_articles(conn: &mut MysqlConnection) -> QueryResult<Vec<Article>> {
articles.load::<Article>(conn)
}
fn select_article_by_id(conn: &mut MysqlConnection, article_id: i32) -> QueryResult<Article> {
articles.filter(id.eq(article_id)).first::<Article>(conn)
}
fn insert_article(conn: &mut MysqlConnection, new_article: &Article) -> QueryResult<usize> {
diesel::insert_into(articles)
.values(new_article)
.execute(conn)
}
fn update_article(conn: &mut MysqlConnection, article: &Article) -> QueryResult<usize> {
diesel::update(articles.find(article.id)).set(
(
title.eq(article.title.to_string()),
content.eq(article.content.to_string()),
)
).execute(conn)
}
fn delete_article(conn: &mut MysqlConnection, article: &Article) -> QueryResult<usize> {
diesel::delete(articles.find(article.id)).execute(conn)
}
fn establish_connection() -> MysqlConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
MysqlConnection::establish(&database_url).unwrap()
}
#[derive(Queryable, Insertable, Debug, PartialEq, Eq)]
#[diesel(table_name = crate::schema::articles)]
struct Article {
id: i32,
title: String,
content: String,
created_at: Option<NaiveDateTime>,
updated_at: Option<NaiveDateTime>,
}