読者です 読者をやめる 読者になる 読者になる

ささいなことですが。

Windowsアプリテスト自動化ライブラリFriendly開発者の日記です。

LambdicSql - 文字列連携、そして2WaySQL -

LambdicSqlはLambdaでSQLを表現することを目的にしています。でも、やっぱり文字列も使えた方が安心感がありますよね。てわけで文字列を埋め込める機能を追加しました。

文字列を式に変換

こんな感じで文字列を途中に埋めれます。ただ文字列を入れるだけではなく、そこにラムダで表現した情報を入れれるのです。

public void TestFormatText()
{
    var query = Db<DB>.Sql(db =>
        Select(new SelectData()
        {
            name = db.tbl_staff.name,
            payment_date = db.tbl_remuneration.payment_date,
            //好きな文字列を入れることができる
            money = Text<decimal>("{0} + {1}", db.tbl_remuneration.money, 1000),
        }).
        From(db.tbl_remuneration).
            Join(db.tbl_staff, db.tbl_remuneration.staff_id == db.tbl_staff.id).
        Where(3000 < db.tbl_remuneration.money && db.tbl_remuneration.money < 4000));

    //to string and params.
    var info = query.Build(_connection.GetType());
    Debug.Print(info.SqlText);

    //dapper
    var datas = _connection.Query<SelectData1>(query).ToList();
}
SELECT
	tbl_staff.name AS "name",
	tbl_remuneration.payment_date AS "payment_date",
	/*↓こんな感じで合成される*/
	tbl_remuneration.money + @p_0 AS "money"
FROM tbl_remuneration
	JOIN tbl_staff ON (tbl_remuneration.staff_id) = (tbl_staff.id)
WHERE ((@p_1) < (tbl_remuneration.money)) AND ((tbl_remuneration.money) < (@p_2))

2WaySQL

これは総監督から強い要望があった機能です。2WaySQLという考え方があるようです。Javaの界隈ではDomaというライブラリが有名なようです。

  1. テキストでベースのSQLを書く
  2. 動的に変えたいところにコメントで印をつける
  3. プログラムで動的に置換

ポイントは2.の時点でコメントで印をつけただけなので、そのままDBMSで実行することができるという点です。基本のSQLだけでも確認取れてた方が安心感が増しますよね。LambdicSqlではシンプルに/*no*/~/**/の間を置き換えるというルールにしました。

public void TestFormat2WaySql(bool minCondition, bool maxCondition, decimal bonus)
{
    var sql = @"
SELECT
tbl_staff.name AS name,
tbl_remuneration.payment_date AS payment_date,
tbl_remuneration.money + /*0*/1000/**/ AS money
FROM tbl_remuneration 
JOIN tbl_staff ON tbl_staff.id = tbl_remuneration.staff_id
/*1*/WHERE tbl_remuneration.money = 100/**/";

    var query = Db<DB>.Sql(db => TwoWaySql(sql,
        bonus,
        Where(
            Condition(minCondition, 3000 < db.tbl_remuneration.money) &&
            Condition(maxCondition, db.tbl_remuneration.money < 4000))
        ));
    var info = query.Build(_connection.GetType());
    Debug.Print(info.SqlText);

    //Dapperを使っているなら以下で実行できます。
    //型はこの時点で指定してください
    var datas = _connection.Query<SelectedData>(query).ToList();
}
SELECT
    tbl_staff.name AS name,
    tbl_remuneration.payment_date AS payment_date,
    /*ここは置き換えられた*/
    tbl_remuneration.money + @bonus AS money
FROM tbl_remuneration 
    JOIN tbl_staff ON tbl_staff.id = tbl_remuneration.staff_id
/*ここも置き換えられた*/
/*最小の条件はfalseだったので消えた*/
/*条件がなくなった場合はWhereも消えます*/
WHERE (tbl_remuneration.money) < (@p_0)

Where句とかを動的に作って差し込めるのは便利ですね。まあ、好みで使い分けていただけたらと思います。それに、場合によってはラムダで書けないみたいなケースも出てきそうですし、そんな時にテキストも使えると心強いですよね!

履歴

2016/09/02 β版対応