0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rust】dieselを使ったMySQLのデータ操作

Posted at

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

操作

  • .envDATABASE_URL を設定
    • dieselコマンドの使用時に--database_url を指定するか、DATABASE_URL 環境変数をセットしておく必要がある
  • 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>,
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?