gdritter repos tansu-sqlite3 / 52e6709
Working sqlite3 backend for tansu Getty Ritter 8 years ago
5 changed file(s) with 152 addition(s) and 0 deletion(s). Collapse all Expand all
1 {-# LANGUAGE OverloadedStrings #-}
2
3 module Database.Tansu.Backend.SQLite3 where
4
5 import Control.Monad (when, void)
6 import Data.ByteString (ByteString)
7 import Data.Text (Text)
8 import qualified Data.Text as T
9 import Database.SQLite3
10 import Database.Tansu.Internal
11 import System.Directory (doesFileExist)
12
13 schema :: Text
14 schema = "CREATE TABLE tansu ( k blob primary key not null \
15 \ , v blob not null );"
16
17 sqlset :: Database -> ByteString -> ByteString -> IO (Either TansuError ())
18 sqlset db k v = do
19 stmt <- prepare db "INSERT INTO tansu (k, v) VALUES (:k, :v);"
20 bindNamed stmt [ (":k", SQLBlob k)
21 , (":v", SQLBlob v)
22 ]
23 void (step stmt)
24 finalize stmt
25 return (return ())
26
27 sqlget :: Database -> ByteString -> IO (Either TansuError ByteString)
28 sqlget db k = do
29 stmt <- prepare db "SELECT v FROM tansu WHERE k = :k;"
30 bindNamed stmt [ (":k", SQLBlob k) ]
31 void (step stmt)
32 cs <- columns stmt
33 finalize stmt
34 case cs of
35 [SQLBlob v] -> return (Right v)
36 [SQLNull] -> return (Left (KeyNotFound k))
37 rs -> return (Left (OtherError (show rs)))
38
39 sqldel :: Database -> ByteString -> IO (Either TansuError ())
40 sqldel db k = do
41 stmt <- prepare db "DELETE FROM tansu WHERE k = :k;"
42 bindNamed stmt [ (":k", SQLBlob k) ]
43 void (step stmt)
44 finalize stmt
45 return (Right ())
46
47 sqltransact :: Database -> IO a -> IO a
48 sqltransact db mote = do
49 exec db "BEGIN TRANSACTION;"
50 result <- mote
51 exec db "END TRANSACTION;"
52 return result
53
54 withSQLiteDb :: FilePath -> (TansuDb k v -> IO a) -> IO a
55 withSQLiteDb path mote = do
56 exists <- doesFileExist path
57 conn <- open (T.pack path)
58 when (not exists) $ do
59 exec conn schema
60 result <- mote $ TansuDb { dbGet = sqlget conn
61 , dbSet = sqlset conn
62 , dbDel = sqldel conn
63 , dbRunTransaction = id
64 }
65 close conn
66 return result
1 Copyright (c) 2016, Getty Ritter
2
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15
16 * Neither the name of Getty Ritter nor the names of other
17 contributors may be used to endorse or promote products derived
18 from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 import Distribution.Simple
2 main = defaultMain
1 module Main where
2
3 import Control.Monad (void)
4 import Database.Tansu
5 import Database.Tansu.Backend.SQLite3
6
7 main :: IO ()
8 main = void $ withSQLiteDb "sample.db" $ \ db -> do
9 putStrLn "Populating test database"
10 run db $ do
11 "one" =: "un"
12 "two" =: "du"
13 "three" =: "tri"
14 "four" =: "kvar"
15
16 putStr "looking up key 'three': "
17 rs <- run db $ get "three"
18 case rs of
19 Right val -> putStrLn val
20 Left _ -> putStrLn "...not in the database."
21
22 putStr "looking up key 'five': "
23 rs <- run db $ get "five"
24 case rs of
25 Right val -> putStrLn val
26 Left _ -> putStrLn "...not in the database."
1 name: tansu-sqlite3
2 version: 0.1.0.0
3 -- synopsis:
4 -- description:
5 license: BSD3
6 license-file: LICENSE
7 author: Getty Ritter
8 maintainer: gdritter@galois.com
9 copyright: 2015 Getty Ritter
10 category: Database
11 build-type: Simple
12 cabal-version: >=1.10
13
14 library
15 exposed-modules: Database.Tansu.Backend.SQLite3
16 build-depends: base >=4.8 && <4.9,
17 tansu,
18 bytestring,
19 text,
20 directory,
21 direct-sqlite
22 default-language: Haskell2010
23
24 executable sample
25 main-is: Main.hs
26 build-depends: base, tansu, tansu-sqlite3
27 hs-source-dirs: sample
28 default-language: Haskell2010