rustでのdbfluteの活用

32 views
Skip to first unread message

Masanobu Shimura

unread,
Feb 3, 2025, 4:40:24 AMFeb 3
to dbf...@googlegroups.com
久保様

趣味でrustをいじり始めたのですがdbfluteの無い世界は住み難いので、
dbfluteを活用したので報告します。

テーブルや テーブルをJOINしたentityはまずJAVAでdbfluteのBsEntityをもとにAccessでrustのstructを自動作成しました。
またInsertやUpdateもそのstructを活用して自動作成しました。
Updateは通常 entityを読み込んで一部更新が必要なものを変更してコミットするのでうまく行きそうです。
またSelectはまず全項目をentityから自動作成して、それをもとにTwo Way Sqlファイルを作成し、dbfぅてdbfluteでpmberanを作りそれをもとにrustのstructのpmbeanを自動作成しています。
rustは初めての言語ですのでMicrosoft Copilotの世話になりっぱなしです。
疑問点やエラーを送ると即座に修正したプログラムを書いてくれます。

今回Two Way SQL とPmbeanから動的にSQLを作成するプログラムをCopulotに要件提示し、何度かテストしながら修正して動く様になりました。
Copilotさまさまです。またGithub Copilotもすごく良い提案をしてくれます。
Two Way SQLまで補完してくれたのには驚きました。

参考までCopiltが作った 動的SQL作成プログラムをつけます。

ub async fn process_sql<P>(params: &P, filename: &str) -> io::Result<String>
where
    P: Serialize,
{
    let mut file = File::open(filename)?;
    let mut sql = String::new();
    file.read_to_string(&mut sql)?;

    // JSONにシリアライズ
    let params_json = serde_json::to_value(params).unwrap();

    // フィールド名と値を動的に取得
    let mut replacements = HashMap::new();
    if let serde_json::Value::Object(map) = params_json {
        for (key, value) in map.iter() {
            if value.is_null() {
                replacements.insert(key.clone(), None);
            } else if let serde_json::Value::String(val) = value {
                replacements.insert(key.clone(), Some(format!("'{}'", val)));
            } else if let serde_json::Value::Number(val) = value {
                replacements.insert(key.clone(), Some(val.to_string()));
            } else if key == "RegisterDatetime" {
                let datetime = value.as_str().unwrap();
                replacements.insert(key.clone(), Some(format!("'{}'", datetime)));
            } else {
                replacements.insert(key.clone(), Some(value.to_string()));
            }
        }
    }

    // プレースホルダーの置換と行の削除
    for (key, value) in replacements.iter() {
        let placeholder_pattern = format!(r"/\*pmb\.{}\*/[^ ,)\n]*", key);
        let re = Regex::new(&placeholder_pattern).unwrap();
        if let Some(val) = value {
            sql = re.replace_all(&sql, val).to_string();
        } else {
            // プレースホルダーを含む行全体を削除し、前後のカンマを適切に処理
            let line_pattern = format!(r"(?m)^\s*([^,]*,)?\s*.*{}\*/[^\n]*,?", key);
            let line_re = Regex::new(&line_pattern).unwrap();
            sql = line_re.replace_all(&sql, "").to_string();
        }
    }

    // 不要なANDやWHEREを削除
    sql = Regex::new(r"(?i)\s*AND\s*$").unwrap().replace_all(&sql, "").to_string();
    sql = Regex::new(r"(?i)\s*WHERE\s*$").unwrap().replace_all(&sql, "").to_string();

    println!("{:?}", sql);
    Ok(sql)
}
pub async fn get_login(pool: &sqlx::PgPool, params: &get_login_pmb) -> Result<Vec<login>> {
    let sql = process_sql(params, "resources/Getlogin.sql").await?;
    let rows = sqlx::query_as::<_, login>(
        sql.as_str()
    )
        .fetch_all(pool)
        .await?;
    Ok(rows)
}
pub async fn test_sql() -> String {
    // 構造体を mut で宣言
    let mut params = get_login_pmb {
        Id: None,
        LoginId: None,
    };

    // 構造体の値を変更
    params.Id = Some(3);
    params.LoginId = None;
    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");

    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&database_url) // ここを修正
        .await
        .expect("Failed to create pool");

    let logins = get_login(&pool, &params).await.unwrap();
    let mut login = logins[0].clone();
    println!("{:?}", login);
    "ok".to_string()
}

これが自動作成で1時間も掛からずに出来るのは凄いですね。

志村

kubo

unread,
Feb 5, 2025, 9:53:08 PMFeb 5
to dbf...@googlegroups.com
jfluteです。

志村さん、こんにちは。

めちゃくちゃ興奮するメールありがとうございます!!!

全く rust の知識ないので、こういうきっかけありがたいです。
そして、Copilot すごいですね。まさかDBFluteのことをフォローしてもらえるなんて(^^。


> dbfluteの無い世界は住み難いので、

そこまで言って頂けるの本当に感謝の極みです。

あと、Google Groupを活用してくださってありがたいです。
これから気軽にぜひ投稿してください(^^。


Masanobu Shimura

unread,
Feb 5, 2025, 10:08:44 PMFeb 5
to dbf...@googlegroups.com
dbfluteさま

下記私のFscebookの投稿です。

志村

昔コンピューターのあつまりで、seasarというのがあり、そこでdbfluteという便利なJAVAのデータベースのアクセスツールがあり、いまだに愛用していて、Go言語版も随分前に自分で、ほぼ必要な機能を作り、仕事はすべてそれでやっている。
今新たにrustの勉強を始め、そのうち省力化に結びつく、読み込んだときの入れ物や、挿入、更新処理、検索時の特別なTwo way sqlを使用した、動的な検索条件やSort条件の変更までは対応した。
Two way sqlは5分位考えて要件をまとめ、Microsoft Copilotに書かせた。
かなり複雑なのだけど、数時間で完成した。
自分の作る方法と違い、正規表現を多用した方法で、全く分からないけど、ちゃんと動いている。
これからはロジック部分は人間が要件を提示して、プログラムはAIにやらせる方向に進みそうなのが、実感できた。
RUSTの学習も疑問点があると、copilotにきくと、一瞬で、詳細な説明とサンプルプログラムを提示してくれる。
便利な世の中になったものだ。
私の時代はコンピューターの黎明期から発展を見れたと思っていたが、さらにAIまで見れそうです。

2025年2月6日(木) 11:53 kubo <dbf...@gmail.com>:
--
このメールは Google グループのグループ「DBFluteユーザの集い」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには dbflute+u...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/dbflute/CAALfU-D%2BvjmpysFWEmWUjPCj4Cy1T0RpkeMK89wxkfFsimq3EA%40mail.gmail.com にアクセスしてください。

kubo

unread,
Feb 7, 2025, 4:25:27 AMFeb 7
to dbf...@googlegroups.com
jfluteです

素敵なFacebook投稿ですね!

> ロジック部分は人間が要件を提示して

要件をちゃんと提示する能力が求められてくると思っています(^^


Reply all
Reply to author
Forward
0 new messages