callmekohei's blog

callmekoheiのひとりごと

F#からSQLiteをつかってみる

下記のページに書いてある分でやるとOSXでのFSharpでもSQLite使えました〜

fsprojects.github.io

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 Page

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

実行

fsi ではなく fsc で実行すること

結果

apple

*** time : 0.081165 s ***

追加

libSQLite.Interop.dylibコンパイルするのがめんどくさい人は

下記に置いてますのでgit cloneしてお使いくださいっ

github.com

Remove all ads