ささいなことですが。

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

最近のLambdicSql - PCL(Xamarin)でも使えます

github.com

この世の全てのSQLC#で表現してやる!
ってことでマルチプラットフォーム対応もしました。
.NETCoreやPCLでも使えます。

SQLiteと連携

Xamarinって言ったらSQLiteです。
LambdicSqlはSQLiteとの連携機能も入れています。
まずは、LambdicSqlとsqlite-net-pclをインストールします。
f:id:ishikawa-tatsuya:20170127094450p:plain
そして、使うところで以下をusingします。
フィーチャーしてますw

using LambdicSql.feat.SQLiteNetPcl;

これで準備完了。
以下コードです。
テーブル作って、Insertして、Selectしてます。
まあ、テーブルの生成とかInsertはSQLite自体に便利なのがあるから使うことはあんまりないと思いますが、Selectは細かくやりたいときは便利に使えると思います。サブクエリとかね。もちろん入れ子のサブクエリとかもっと複雑なのも書けますよ。

using System;
using SQLite;
using LambdicSql;
using LambdicSql.feat.SQLiteNetPcl;
using static LambdicSql.Symbol;
using System.Collections.Generic;

namespace LambdicSqlTest
{
    public class Staff
    {
        public int id { get; set; }
        public string name { get; set; }
    }

    public class Remuneration
    {
        public int id { get; set; }
        public int staff_id { get; set; }
        public DateTime payment_date { get; set; }
        public decimal money { get; set; }
    }

    public class DB
    {
        public Staff tbl_staff { get; set; }
        public Remuneration tbl_remuneration { get; set; }
    }

    public class SelectedData
    {
        public string Name { get; set; }
        public DateTime PaymentDate { get; set; }
        public decimal Money { get; set; }
        public decimal Total { get; set; }
    }

    public static class SqlSample
    {
        public static List<SelectedData> Test(SQLiteConnection con)
        {
            DeleteTablesTest(con);
            CreateTablesTest(con);
            InsertTest(con);
            return SelectTest(con);
        }

        static void DeleteTablesTest(SQLiteConnection con)
        {
            var deleteRemuneration = Db<DB>.Sql(db => DropTable(db.tbl_remuneration));
            con.Execute(deleteRemuneration);

            var deleteStaff = Db<DB>.Sql(db => DropTable(db.tbl_staff));
            con.Execute(deleteStaff);
        }

        static void CreateTablesTest(SQLiteConnection con)
        {
            var createStaff = Db<DB>.Sql(db => CreateTable(
                db.tbl_staff,
                new Column(db.tbl_staff.id, DataType.Int(), NotNull(), PrimaryKey()),
                new Column(db.tbl_staff.name, DataType.VarChar(50), NotNull())
                ));
            con.Execute(createStaff);

            var createRemuneration = Db<DB>.Sql(db => CreateTable(
                db.tbl_remuneration,
                new Column(db.tbl_remuneration.id, DataType.Int(), NotNull(), PrimaryKey()),
                new Column(db.tbl_remuneration.staff_id, DataType.Int(), NotNull()),
                new Column(db.tbl_remuneration.payment_date, DataType.VarChar(50), NotNull()),
                new Column(db.tbl_remuneration.money, DataType.Decimal(), NotNull())
                ));
            con.Execute(createRemuneration);
        }

        static void InsertTest(SQLiteConnection con)
        {
            var insertStaff = Db<DB>.Sql(db =>
                InsertInto(db.tbl_staff, db.tbl_staff.id, db.tbl_staff.name).
                Values(1, "taro-yamada"));
            con.Execute(insertStaff);

            var insertRemuneration = Db<DB>.Sql(db =>
                InsertInto(db.tbl_remuneration,
                    db.tbl_remuneration.id,
                    db.tbl_remuneration.staff_id,
                    db.tbl_remuneration.payment_date,
                    db.tbl_remuneration.money).
                Values(1, 1, DateTime.Today, 300000));
            con.Execute(insertRemuneration);
        }

        static List<SelectedData> SelectTest(SQLiteConnection con)
        {
            var min = 3000;

            var sql = Db<DB>.Sql(db =>
                Select(new SelectedData
                {
                    Name = db.tbl_staff.name,
                    PaymentDate = db.tbl_remuneration.payment_date,
                    Money = db.tbl_remuneration.money,
                    //サブクエリとかね
                    Total = Select(Sum(db.tbl_remuneration.money)).From(db.tbl_remuneration)
                }).
                From(db.tbl_remuneration).
                    Join(db.tbl_staff, db.tbl_staff.id == db.tbl_remuneration.staff_id).
                Where(min < db.tbl_remuneration.money && db.tbl_remuneration.money < 1000000)
                );

            return con.Query(sql);
        }
    }
}

呼び出し元です。

public override void ViewDidLoad()
{
    base.ViewDidLoad();

    // Perform any additional setup after loading the view, typically from a nib.
    Button.AccessibilityIdentifier = "myButton";
    Button.TouchUpInside += delegate
    {
        string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "test.db3");
        var con = new SQLiteConnection(dbPath);
        var datas = SqlSample.Test(con);
        var title = string.Format("data count = {0}", datas.Count);
        Button.SetTitle(title, UIControlState.Normal);
    };
}

しかし、VS for Mac でビルドが通らない・・・

で、動かそうと思ってMacの方に持っていくと・・・
ぐはっ、コンパイル通らんやんけ!
なんも曖昧ちゃうわ!
f:id:ishikawa-tatsuya:20170127102333p:plain
なんかわからんけど、拡張メソッドが解決できないみたいです。まあ、まだプレビューなので大目に見よう・・・。
LambdicSqlは分解して書けるので以下のように書き換えました。

static List<SelectedData> SelectTest(SQLiteConnection con)
{
    var min = 3000;

    //一つづつ作って
    var select = Db<DB>.Sql(db =>
        Select(new SelectedData
        {
            Name = db.tbl_staff.name,
            PaymentDate = db.tbl_remuneration.payment_date,
            Money = db.tbl_remuneration.money,
        }));
    var from = Db<DB>.Sql(db => From(db.tbl_remuneration));
    var join = Db<DB>.Sql(db => Join(db.tbl_staff, db.tbl_staff.id == db.tbl_remuneration.staff_id));
    var where = Db<DB>.Sql(db => Where(min < db.tbl_remuneration.money && db.tbl_remuneration.money < 1000000));

    //+で結合
    return con.Query(select + from + join + where);
}

でもこれは、メソッドチェーンでなくて、+演算に変えろっていうお告げなのか?

で実行結果です。
f:id:ishikawa-tatsuya:20170127104401p:plain:w250