F#からSQLiteをつかってみる ( OSX )


Summary

FSharp on OSXSQLiteをつかう

下記の3点が必要

System.Data.SQLitenugetする

libSQLite.Interop.dylibをコンパイルする

FSharpコード内でDLLImportする

すること

その1

System.Data.SQLitenugetする

その2

libSQLite.Interop.dylibをコンパイルする

下記からソースコードをダウンロード

System.Data.SQLite Downloads

List of Release Packages
-> Source Code
-> sqlite-netFx-full-source-1.0.104.0.zip

zipを解凍して

$ cd Setup

$ chmod +x compile-interop-assembly-release.sh

$ bash compile-interop-assembly-release.sh

これでlibSQLite.Interop.dylibができるので

$ chmod -x bin/2013/Release/bin/libSQLite.Interop.dylib

その3

FSharpコード内でDLLImportする

さっきのlibSQLite.Interop.dylibfsxと同じ場所にコピーしてくる

で、コード

#r @"./packages/System.Data.SQLite.Core/lib/net46/System.Data.SQLite.dll"
open System.Data.SQLite
open System.Runtime.InteropServices

module Database =

    [<DllImport(@"/Users/kohei/Documents/jikkenSqlite3/libSQLite.Interop.dylib" , CallingConvention = CallingConvention.Cdecl)>] 
    let sqlite_connection : System.Data.SQLite.SQLiteConnection  =
        ( new SQLiteConnection( @"Data Source=:memory:;Version=3;foreign keys=true" ))

    type ABC ( connection : System.Data.SQLite.SQLiteConnection ) =

        let cn = connection

        member theis.sqlite_open : unit =
            cn.Open()

        member this.sqlite_createTable sql  =
            ( new SQLiteCommand(sql, cn)).ExecuteNonQuery() |> ignore

        member this.sqlite_insert  sql =
            ( new SQLiteCommand(sql, cn)).ExecuteNonQuery() |> ignore

        member this.sqlite_select  sql f =
            let reader = ( new SQLiteCommand(sql, cn )).ExecuteReader()
            while ( reader.Read() ) do
               f reader 

module Jikken =
    open Database

    let s0 = @"CREATE TABLE IF NOT EXISTS foo ( name VARCHAR(20), price INT )"
    let s1 = @"INSERT INTO foo ( name, price ) VALUES ('apple', 3000 )"
    let s2 = @"SELECT name FROM foo"
    let f = fun (r:SQLiteDataReader) -> 
        [0]
        |> List.fold ( fun acc n -> acc + " " + r.GetString(n) |> fun s -> s.TrimStart() ) ""
        |> stdout.WriteLine

    let db = ABC( sqlite_connection )
    db.sqlite_open
    db.sqlite_createTable s0
    db.sqlite_insert s1
    db.sqlite_select s2 f

なんとなくスクリプト

wget https://system.data.sqlite.org/blobs/1.0.108.0/sqlite-netFx-full-source-1.0.108.0.zip
mkdir foo
unzip sqlite-netFx-full-source-1.0.108.0.zip -d ./foo/
bash foo/Setup/compile-interop-assembly-release.sh
cp foo/bin/2013/Release/bin/libSQLite.Interop.dylib ./
rm -rf foo
rm ./sqlite-netFx-full-source-1.0.108.0.zip