SomaとF#スクリプトを使ったお手軽DBアクセス

Somaは大きなプロジェクトでも使えますし、小さなツール作成の用途にも使えます。
今回は後者をターゲットとして、Somaを使って手軽にDBアクセスを行うサンプルを紹介します。

環境準備

まず環境を整えます。

  1. DBにはSQL Server 2008を使います。tempdbにアクセスします。
  2. Visual StudioでF#のプロジェクトを作ります。
  3. F#のスクリプト用ファイルであるfsxファイルを追加します。
  4. スクリプトと同じディレクトリにSoma 0.12.0.0のSoma.Core.dllを配置します。
    • ここではF#やF# PowerPackがインストールされていることを前提にしますが、インストールしていない場合はFSharp.Core.dllとFSharp.PowerPack.dllも同じディレクトリに配置してください。
    • Somaのエラーメッセージを日本語で表示したい場合は、Somaの配布パッケージに含まれるja/Soma.Core.resources.dllも配置してください。

プロジェクトの中はこうなります。

いたってシンプルですね。

F#スクリプト

次にスクリプトを書きましょう。ここでは、テーブルを作って、データを投入して、取り出す、ということをします。上で用意したScript1.fsxに次のコードを記述します。

#r @"Soma.Core.dll"

open Soma.Core

(* DBアクセスのための準備 *)let config =
{ new MsSqlConfig() with
member
this.ConnectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True" }
let query sql = Db.query<dynamic> config sql <@ () @>
let execute sql = Db.execute config sql <@ () @>

(* テーブル削除 : 存在しない場合に例外が発生しても無視 *)try
execute "
drop table Person
"
|> ignore
with| e -> printfn "%A" e

(* テーブル作成 *)execute "
create table Person (
Id int identity primary key,
Name nvarchar(10),
Age int
)
"

(* データ追加 : 複文使える *)execute "
insert into Person (Name, Age) values ('Smith', 20)
insert into Person (Name, Age) values ('King', 30)
insert into Person (Name, Age) values ('Jhone', 40)
"

(* 全件取得 *)query "
select * from Person
"
|> List.iter (fun p -> printfn "%A %A %A" p?Id p?Name p?Age)

ここでのポイントは、

  • テーブルに対応するクラスを作っておく必要がない
  • create table や insert など更新系SQLを実行するにはexecuteという関数を使う
  • selectのSQLを実行するにはquery関数を使う
    • Db.queryの型パラメータにdynamicを渡しておくことで動的オブジェクトを要素とするlistを取得できるようになる
    • listの要素である動的オブジェクトには ?カラム名でアクセスできる(大文字小文字の区別はなし)。
  • 数行準備のためのコードを書けば、後はSQLを書いて実行するだけ
実行結果

スクリプトができたら実行してみましょう。Visual Studioのエディタ上でスクリプトの全行を選択して右クリックし、Send To Interactive を実行します。すると次のような結果がF# Interactiveに表示されます。

LOG : drop table Person
LOG : create table Person (
    Id int identity primary key, 
    Name nvarchar(10),
    Age int 
  )
LOG : insert into Person (Name, Age) values ('Smith', 20)
  insert into Person (Name, Age) values ('King', 30)
  insert into Person (Name, Age) values ('Jhone', 40)
LOG : select * from Person
1 "Smith" 20
2 "King" 30
3 "Jhone" 40

val config : Soma.Core.MsSqlConfig
val query : string -> Soma.Core.dynamic list
val execute : string -> int

出力内容ですが簡単に説明すると

  • LOGで始まる文字列はSomaが自動で出力している実行されたSQLのログです。これを見れば意図通りSQLが発行されていることがわかります。もちろん、ログについては変更したり抑制したりできます。
  • スクリプトで明示的に出力したのは、「LOG : select * from Person」の直下の3行になります。投入したデータがちゃんと出力されていますね。
まとめ

Somaを使って手軽にDBアクセスを行うサンプルを紹介しました。
SQLを簡単に実行して結果をF#で扱えることがわかってもらえたでしょうか?
というわけで、Somaをぜひお試しください。

使ってくれる人、ドキュメント書いてくれる人、いっしょに開発してくれる人募集中です。

追記

F# Interactiveに流し込んだ後は、出力用の関数作ってF# Interactivからqueryしたりデータ操作すると便利かもしれない。

> let p seq = Seq.iter (printfn "%A") seq;;

val p : seq<'a> -> unit

> query "select * from Person" |> p;;
LOG : select * from Person
seq [[ID, 1]; [NAME, Smith]; [AGE, 20]]
seq [[ID, 2]; [NAME, King]; [AGE, 30]]
seq [[ID, 3]; [NAME, Jhone]; [AGE, 40]]
val it : unit = ()
>