ejdb2-binding 0.2.0.0 → 0.3.0.0
raw patch · 13 files changed
+169/−177 lines, 13 filesdep +mtlPVP ok
version bump matches the API change (PVP)
Dependencies added: mtl
API changes (from Hackage documentation)
- Database.EJDB2.Query: data Query
- Database.EJDB2.Query: fromString :: String -> IO Query
- Database.EJDB2.Query: setBool :: Bool -> String -> Query -> IO ()
- Database.EJDB2.Query: setBoolAtIndex :: Bool -> Int -> Query -> IO ()
- Database.EJDB2.Query: setF64 :: Double -> String -> Query -> IO ()
- Database.EJDB2.Query: setF64AtIndex :: Double -> Int -> Query -> IO ()
- Database.EJDB2.Query: setI64 :: Int64 -> String -> Query -> IO ()
- Database.EJDB2.Query: setI64AtIndex :: Int64 -> Int -> Query -> IO ()
- Database.EJDB2.Query: setNull :: String -> Query -> IO ()
- Database.EJDB2.Query: setNullAtIndex :: Int -> Query -> IO ()
- Database.EJDB2.Query: setRegex :: String -> String -> Query -> IO ()
- Database.EJDB2.Query: setRegexAtIndex :: String -> Int -> Query -> IO ()
- Database.EJDB2.Query: setString :: String -> String -> Query -> IO ()
- Database.EJDB2.Query: setStringAtIndex :: String -> Int -> Query -> IO ()
+ Database.EJDB2: Query :: String -> BindM a -> Query a
+ Database.EJDB2: data Query a
+ Database.EJDB2: noBind :: BindM ()
+ Database.EJDB2: setBool :: Bool -> String -> BindM ()
+ Database.EJDB2: setBoolAtIndex :: Bool -> Int -> BindM ()
+ Database.EJDB2: setF64 :: Double -> String -> BindM ()
+ Database.EJDB2: setF64AtIndex :: Double -> Int -> BindM ()
+ Database.EJDB2: setI64 :: Int64 -> String -> BindM ()
+ Database.EJDB2: setI64AtIndex :: Int64 -> Int -> BindM ()
+ Database.EJDB2: setNull :: String -> BindM ()
+ Database.EJDB2: setNullAtIndex :: Int -> BindM ()
+ Database.EJDB2: setRegex :: String -> String -> BindM ()
+ Database.EJDB2: setRegexAtIndex :: String -> Int -> BindM ()
+ Database.EJDB2: setString :: String -> String -> BindM ()
+ Database.EJDB2: setStringAtIndex :: String -> Int -> BindM ()
- Database.EJDB2: fold :: FromJSON b => Database -> (a -> (Int64, Maybe b) -> a) -> a -> Query -> IO a
+ Database.EJDB2: fold :: FromJSON b => Database -> (a -> (Int64, Maybe b) -> a) -> a -> Query q -> IO a
- Database.EJDB2: getCount :: Database -> Query -> IO Int64
+ Database.EJDB2: getCount :: Database -> Query q -> IO Int64
- Database.EJDB2: getList :: FromJSON a => Database -> Query -> IO [(Int64, Maybe a)]
+ Database.EJDB2: getList :: FromJSON a => Database -> Query q -> IO [(Int64, Maybe a)]
- Database.EJDB2: getList' :: FromJSON a => Database -> Query -> IO [Maybe a]
+ Database.EJDB2: getList' :: FromJSON a => Database -> Query q -> IO [Maybe a]
Files
- CHANGELOG.md +5/−0
- cbits/finalizer.c +0/−8
- cbits/finalizer.h +0/−3
- ejdb2-binding.cabal +4/−9
- src/Database/EJDB2.hs +25/−11
- src/Database/EJDB2/Bindings/JQL.hs +0/−3
- src/Database/EJDB2/HTTP.hsc +1/−1
- src/Database/EJDB2/Query.hs +85/−66
- src/Database/EJDB2/QueryConstructor.hs +0/−14
- test/CollectionTests.hs +2/−3
- test/FoldTests.hs +1/−2
- test/GetTests.hs +8/−11
- test/QueryTests.hs +38/−46
CHANGELOG.md view
@@ -3,6 +3,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +## [0.3.0.0] - 2020-05-01+### Changed+- Query is now a data type with binding as Monad+- Query is available via Database.EJDB2 module+ ## [0.2.0.0] - 2020-04-19 ### Added - fold function to reduce a query result
− cbits/finalizer.c
@@ -1,8 +0,0 @@-#include "finalizer.h"-#include <stdlib.h>--void finalizerJQL(JQL* jql) {- JQL* jqlCopy = jql;- jql_destroy(jql);- free(jqlCopy);-}
− cbits/finalizer.h
@@ -1,3 +0,0 @@-#include <ejdb2/ejdb2.h>--void finalizerJQL(JQL* jql);
ejdb2-binding.cabal view
@@ -3,7 +3,7 @@ category: Database description: Binding to EJDB2 C library, an embedded JSON noSQL database. Package requires libejdb2 to build. Please see the README on GitHub at <https://github.com/cescobaz/ejdb2haskell#readme> synopsis: Binding to EJDB2 C library, an embedded JSON noSQL database-version: 0.2.0.0+version: 0.3.0.0 license: MIT license-file: LICENSE homepage: https://github.com/cescobaz/ejdb2haskell#readme@@ -12,8 +12,6 @@ author: Francesco Burelli maintainer: francesco.burelli@protonmail.com extra-source-files: CHANGELOG.md- cbits/finalizer.h- cbits/finalizer.c test/read-only-db source-repository head@@ -22,7 +20,6 @@ library exposed-modules: Database.EJDB2- , Database.EJDB2.Query , Database.EJDB2.Meta , Database.EJDB2.CollectionMeta , Database.EJDB2.IndexMeta@@ -31,10 +28,10 @@ , Database.EJDB2.WAL , Database.EJDB2.KV other-modules:- Database.EJDB2.JBL+ Database.EJDB2.Query+ , Database.EJDB2.JBL , Database.EJDB2.Result , Database.EJDB2.IndexMode- , Database.EJDB2.QueryConstructor , Database.EJDB2.Bindings.EJDB2 , Database.EJDB2.Bindings.JQL , Database.EJDB2.Bindings.JBL@@ -45,12 +42,10 @@ , bytestring ^>=0.10.10.0 , aeson ^>=1.4.6.0 , unordered-containers ^>=0.2.10.0+ , mtl ^>=2.2.2 build-tool-depends: hsc2hs:hsc2hs extra-libraries: ejdb2 pkgconfig-depends: libejdb2- c-sources: cbits/finalizer.c- install-includes: finalizer.h- include-dirs: cbits hs-source-dirs: src default-language: Haskell2010
src/Database/EJDB2.hs view
@@ -31,6 +31,20 @@ , removeIndex , onlineBackup , fold+ , Query(..)+ , noBind+ , setBool+ , setBoolAtIndex+ , setI64+ , setI64AtIndex+ , setF64+ , setF64AtIndex+ , setString+ , setStringAtIndex+ , setRegex+ , setRegexAtIndex+ , setNull+ , setNullAtIndex ) where import Control.Exception@@ -53,7 +67,6 @@ import qualified Database.EJDB2.KV as KV import Database.EJDB2.Options as Options import Database.EJDB2.Query-import Database.EJDB2.QueryConstructor import Database.EJDB2.Result import Foreign@@ -128,16 +141,17 @@ (c_jbl_destroy jblPtr) -- | Executes a given query and returns the number of documents.-getCount :: Database -> Query -> IO Int64-getCount (Database _ ejdb) (Query jql _ _) = alloca $+getCount :: Database -> Query q -> IO Int64+getCount (Database _ ejdb) query = withQuery query $ \jql -> alloca $ \countPtr -> c_ejdb_count ejdb jql countPtr 0 >>= checkRC >> peek countPtr >>= \(CIntMax int) -> return int -exec :: EJDBExecVisitor -> Database -> Query -> IO ()-exec visitor (Database _ ejdb) (Query jql _ _) = do- visitor <- mkEJDBExecVisitor visitor- let exec = EJDBExec.zero { db = ejdb, q = jql, EJDBExec.visitor = visitor }- finally (with exec c_ejdb_exec >>= checkRC) (freeHaskellFunPtr visitor)+exec :: EJDBExecVisitor -> Database -> Query q -> IO ()+exec visitor (Database _ ejdb) query = withQuery query $ \jql -> do+ cVisitor <- mkEJDBExecVisitor visitor+ let exec =+ EJDBExec.zero { db = ejdb, q = jql, EJDBExec.visitor = cVisitor }+ finally (with exec c_ejdb_exec >>= checkRC) (freeHaskellFunPtr cVisitor) -- | Iterate over query result building the result fold :: Aeson.FromJSON b@@ -146,7 +160,7 @@ -> (Int64, Maybe b) -> a) -- ^ The second argument is a tuple with the object id and the object -> a -- ^ Initial result- -> Query+ -> Query q -> IO a fold database f i query = newIORef (f, i) >>= \ref -> exec (foldVisitor ref) database query >> snd <$> readIORef ref@@ -164,7 +178,7 @@ {-| Executes a given query and builds a query result as list of tuple with id and document. -}-getList :: Aeson.FromJSON a => Database -> Query -> IO [(Int64, Maybe a)]+getList :: Aeson.FromJSON a => Database -> Query q -> IO [(Int64, Maybe a)] getList database query = reverse <$> fold database foldList [] query foldList :: Aeson.FromJSON a@@ -176,7 +190,7 @@ {-| Executes a given query and builds a query result as list of documents with id injected as attribute. -}-getList' :: Aeson.FromJSON a => Database -> Query -> IO [Maybe a]+getList' :: Aeson.FromJSON a => Database -> Query q -> IO [Maybe a] getList' database query = reverse <$> fold database foldList' [] query foldList'
src/Database/EJDB2/Bindings/JQL.hs view
@@ -33,6 +33,3 @@ foreign import ccall unsafe "ejdb2/jql.h jql_destroy" c_jql_destroy :: Ptr JQL -> IO ()--foreign import ccall "finalizer.h &finalizerJQL" p_finalizerJQL- :: FunPtr (Ptr JQL -> IO ())
src/Database/EJDB2/HTTP.hsc view
@@ -21,7 +21,7 @@ , port :: !Int32 -- ^ Listen port number, required , bind :: Maybe String -- ^ Listen IP\/host. Default: /localhost/ , accessToken :: Maybe String -- ^ Server access token passed in /X-Access-Token/ header. Default: zero- , blocking :: !Bool -- ^ Block 'open' thread until http service finished.+ , blocking :: !Bool -- ^ Block open thread until http service finished. -- Otherwise HTTP servee started in background. , readAnon :: !Bool -- ^ Allow anonymous read-only database access
src/Database/EJDB2/Query.hs view
@@ -1,6 +1,8 @@ module Database.EJDB2.Query- ( Query- , fromString+ ( Query(..)+ , BindM+ , withQuery+ , noBind , setBool , setBoolAtIndex , setI64@@ -15,12 +17,14 @@ , setNullAtIndex ) where -import qualified Data.Bool as Bool+import Control.Monad.IO.Class+import Control.Monad.State.Lazy++import qualified Data.Bool as Bool import Data.IORef import Data.Int import Database.EJDB2.Bindings.JQL-import Database.EJDB2.QueryConstructor import Database.EJDB2.Result import Foreign@@ -28,33 +32,62 @@ import Foreign.C.Types import Foreign.Marshal.Alloc --- | Create query object from specified text query. Collection must be specified in query.-fromString :: String -- ^ Query text- -> IO Query-fromString string = do+-- | Query data with binding. Collection must be specified in query.+data Query a = Query String -- ^ Query text with collection+ (BindM a)++data BindState = BindState JQL [CString]++-- | Monad to apply binding to 'Query'+type BindM a = StateT BindState IO a++bind :: BindM a -> BindState -> IO BindState+bind bindM state = execStateT bindM state++getJQL :: BindM JQL+getJQL = get >>= \(BindState jql _) -> return jql++noBind :: BindM ()+noBind = return ()++freeBindState :: BindState -> IO BindState+freeBindState (BindState jql cStrings) = mapM_ free cStrings+ >> return (BindState jql [])++withQuery :: Query a -> (JQL -> IO b) -> IO b+withQuery (Query query bindM) f = do+ (jqlPtr, jql) <- createQuery query+ bindState <- bind bindM (BindState jql [])+ result <- f jql+ destroyQuery jqlPtr+ freeBindState bindState+ return result++createQuery :: String -- ^ Query text+ -> IO (Ptr JQL, JQL)+createQuery string = do jqlPtr <- malloc withCString string $ \cString -> do c_jql_create jqlPtr nullPtr cString >>= checkRC jql <- peek jqlPtr- jqlFPtr <- newForeignPtr p_finalizerJQL jqlPtr- ioRef <- newIORef []- return $ Query jql jqlFPtr ioRef+ return (jqlPtr, jql) +destroyQuery :: Ptr JQL -> IO ()+destroyQuery jqlPtr = c_jql_destroy jqlPtr >> free jqlPtr+ -- | Bind bool to query placeholder setBool :: Bool -> String -- ^ Placeholder- -> Query- -> IO ()-setBool bool placeholder (Query jql _ _) =- withCString placeholder $ \cPlaceholder ->+ -> BindM ()+setBool bool placeholder =+ getJQL >>= \jql -> liftIO $ withCString placeholder $ \cPlaceholder -> c_jql_set_bool jql cPlaceholder 0 (CBool (Bool.bool 0 1 bool)) >>= checkRC -- | Bind bool to query at specified index setBoolAtIndex :: Bool -> Int -- ^ Index- -> Query- -> IO ()-setBoolAtIndex bool index (Query jql _ _) =+ -> BindM ()+setBoolAtIndex bool index = getJQL >>= \jql -> liftIO $ c_jql_set_bool jql nullPtr (CInt $ fromIntegral index)@@ -63,94 +96,80 @@ -- | Bind number to query placeholder setI64 :: Int64 -> String -- ^ Placeholder- -> Query- -> IO ()-setI64 number placeholder (Query jql _ _) = withCString placeholder $- \cPlaceholder -> c_jql_set_i64 jql cPlaceholder 0 (CIntMax number)- >>= checkRC+ -> BindM ()+setI64 number placeholder =+ getJQL >>= \jql -> liftIO $ withCString placeholder $ \cPlaceholder ->+ c_jql_set_i64 jql cPlaceholder 0 (CIntMax number) >>= checkRC -- | Bind number to query at specified index setI64AtIndex :: Int64 -> Int -- ^ Index- -> Query- -> IO ()-setI64AtIndex number index (Query jql _ _) =+ -> BindM ()+setI64AtIndex number index = getJQL >>= \jql -> liftIO $ c_jql_set_i64 jql nullPtr (CInt $ fromIntegral index) (CIntMax number) >>= checkRC -- | Bind 'Double' to query placeholder setF64 :: Double -> String -- ^ Placeholder- -> Query- -> IO ()-setF64 number placeholder (Query jql _ _) = withCString placeholder $- \cPlaceholder -> c_jql_set_f64 jql cPlaceholder 0 (CDouble number)- >>= checkRC+ -> BindM ()+setF64 number placeholder =+ getJQL >>= \jql -> liftIO $ withCString placeholder $ \cPlaceholder ->+ c_jql_set_f64 jql cPlaceholder 0 (CDouble number) >>= checkRC -- | Bind 'Double' to query at specified index setF64AtIndex :: Double -> Int -- ^ Index- -> Query- -> IO ()-setF64AtIndex number index (Query jql _ _) =+ -> BindM ()+setF64AtIndex number index = getJQL >>= \jql -> liftIO $ c_jql_set_f64 jql nullPtr (CInt $ fromIntegral index) (CDouble number) >>= checkRC -newCStringInIORef :: String -> IORef [ForeignPtr CChar] -> IO CString-newCStringInIORef string ioRef = do- cString <- newCString string- cStringPtr <- newForeignPtr finalizerFree cString- modifyIORef' ioRef ((:) cStringPtr)- return cString+newCStringInBindState :: String -> BindM CString+newCStringInBindState string = get >>= \(BindState jql strings) ->+ liftIO (newCString string) >>= \cString ->+ put (BindState jql (cString : strings)) >> return cString -- | Bind string to query placeholder setString :: String -> String -- ^ Placeholder- -> Query- -> IO ()-setString string placeholder (Query jql _ ioRef) = do- cString <- newCStringInIORef string ioRef- withCString placeholder $- \cPlaceholder -> c_jql_set_str jql cPlaceholder 0 cString >>= checkRC+ -> BindM ()+setString string placeholder = newCStringInBindState string+ >>= \cString -> getJQL >>= \jql -> liftIO $ withCString placeholder $+ \cPlaceholder -> c_jql_set_str jql cPlaceholder 0 cString >>= checkRC -- | Bind string to query at specified index setStringAtIndex :: String -> Int -- ^ Index- -> Query- -> IO ()-setStringAtIndex string index (Query jql _ ioRef) = do- cString <- newCStringInIORef string ioRef+ -> BindM ()+setStringAtIndex string index =+ newCStringInBindState string >>= \cString -> getJQL >>= \jql -> liftIO $ c_jql_set_str jql nullPtr (CInt $ fromIntegral index) cString >>= checkRC -- | Bind regex to query placeholder setRegex :: String -- ^ Regex -> String -- ^ Placeholder- -> Query- -> IO ()-setRegex string placeholder (Query jql _ ioRef) = do- cString <- newCStringInIORef string ioRef- withCString placeholder $- \cPlaceholder -> c_jql_set_regexp jql cPlaceholder 0 cString >>= checkRC+ -> BindM ()+setRegex string placeholder = newCStringInBindState string+ >>= \cString -> getJQL >>= \jql -> liftIO $ withCString placeholder $+ \cPlaceholder -> c_jql_set_regexp jql cPlaceholder 0 cString >>= checkRC -- | Bind regex to query at specified index setRegexAtIndex :: String -- ^ Regex -> Int -- ^ Index- -> Query- -> IO ()-setRegexAtIndex string index (Query jql _ ioRef) = do- cString <- newCStringInIORef string ioRef+ -> BindM ()+setRegexAtIndex string index =+ newCStringInBindState string >>= \cString -> getJQL >>= \jql -> liftIO $ c_jql_set_regexp jql nullPtr (CInt $ fromIntegral index) cString >>= checkRC -- | Bind /null/ value to query placeholder setNull :: String -- ^ Placeholder- -> Query- -> IO ()-setNull placeholder (Query jql _ _) = withCString placeholder $+ -> BindM ()+setNull placeholder = getJQL >>= \jql -> liftIO $ withCString placeholder $ \cPlaceholder -> c_jql_set_null jql cPlaceholder 0 >>= checkRC -- | Bind /null/ value to query at specified index setNullAtIndex :: Int -- ^ Index- -> Query- -> IO ()-setNullAtIndex index (Query jql _ _) =+ -> BindM ()+setNullAtIndex index = getJQL >>= \jql -> liftIO $ c_jql_set_null jql nullPtr (CInt $ fromIntegral index) >>= checkRC
− src/Database/EJDB2/QueryConstructor.hs
@@ -1,14 +0,0 @@-module Database.EJDB2.QueryConstructor ( Query(..) ) where--import Data.IORef--import Database.EJDB2.Bindings.JQL--import Foreign-import Foreign.C.Types---- | Query handle-data Query = Query { jql :: JQL- , jqlPtr :: ForeignPtr JQL- , strings :: IORef [ForeignPtr CChar]- }
test/CollectionTests.hs view
@@ -4,7 +4,6 @@ import Database.EJDB2 import Database.EJDB2.Options-import qualified Database.EJDB2.Query as Query import Plant @@ -29,7 +28,7 @@ database <- databaseIO id <- putNew database "plants" plant removeCollection database "plants"- count <- Query.fromString "@plants/*" >>= getCount database+ count <- getCount database $ Query "@plants/*" noBind count @?= 0 where plant = nothingPlant { id = Nothing@@ -44,7 +43,7 @@ database <- databaseIO id <- putNew database "plants" plant renameCollection database "plants" "vegetables"- count <- Query.fromString "@plants/*" >>= getCount database+ count <- getCount database $ Query "@plants/*" noBind count @?= 0 storedPlant <- getById database "vegetables" id storedPlant @?= Just plant
test/FoldTests.hs view
@@ -4,7 +4,6 @@ import qualified Database.EJDB2 as DB import Database.EJDB2.Options-import qualified Database.EJDB2.Query as Query import Plant @@ -24,7 +23,7 @@ foldOnIsTreeTest :: IO DB.Database -> TestTree foldOnIsTreeTest databaseIO = testCase "foldOnIsTree" $ do database <- databaseIO- query <- Query.fromString "@plants/*"+ let query = DB.Query "@plants/*" DB.noBind result <- DB.fold database foldOnIsTree (0, 0) query result @?= (1, 3)
test/GetTests.hs view
@@ -10,7 +10,6 @@ import Database.EJDB2 import Database.EJDB2.Options-import qualified Database.EJDB2.Query as Query import Plant @@ -55,19 +54,17 @@ getCountTest :: IO Database -> TestTree getCountTest databaseIO = testCase "getCount" $ do database <- databaseIO- count <- Query.fromString "@plants/*" >>= getCount database+ count <- getCount database $ Query "@plants/*" noBind count @?= 4 -getListTestQuery :: IO Query.Query-getListTestQuery = do- query <- Query.fromString "@plants/[isTree=:tree] | asc /name"- Query.setBool False "tree" query- return query+getListTestQuery :: Query ()+getListTestQuery =+ Query "@plants/[isTree=:tree] | asc /name" $ setBool False "tree" getListTest :: IO Database -> TestTree getListTest databaseIO = testCase "getList" $ do database <- databaseIO- plants <- getListTestQuery >>= getList database+ plants <- getList database getListTestQuery plants @?= [ ( 2 , Just nothingPlant { id = Nothing@@ -101,7 +98,7 @@ getListTest' :: IO Database -> TestTree getListTest' databaseIO = testCase "getList'" $ do database <- databaseIO- plants <- getListTestQuery >>= getList' database+ plants <- getList' database getListTestQuery plants @?= [ Just nothingPlant { id = Just 2 , name = Just "gentiana brentae" , isTree = Just False@@ -137,7 +134,7 @@ getListFromNotExistingCollectionTest databaseIO = testCase "getListFromNotExistingCollectionTest" $ do database <- databaseIO- query <- Query.fromString "@noexisting/[isTree=:tree] | asc /name"- Query.setBool False "tree" query+ let query = Query "@noexisting/[isTree=:tree] | asc /name" $+ setBool False "tree" list <- getList database query :: IO [(Int64, Maybe Value)] list @?= []
test/QueryTests.hs view
@@ -7,7 +7,6 @@ import Database.EJDB2 import Database.EJDB2.Options-import qualified Database.EJDB2.Query as Query import Plant @@ -41,8 +40,8 @@ getListWithBoolQueryTest :: IO Database -> TestTree getListWithBoolQueryTest databaseIO = testCase "getListWithBoolQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[isTree=:?] | asc /name"- Query.setBoolAtIndex False 0 query+ let query = Query "@plants/[isTree=:?] | asc /name"+ (setBoolAtIndex False 0) plants <- getList database query plants @?= [ ( 2@@ -77,8 +76,7 @@ getListWithI64QueryTest :: IO Database -> TestTree getListWithI64QueryTest databaseIO = testCase "getListWithI64Query" $ do database <- databaseIO- query <- Query.fromString "@plants/[year>:year] | asc /name"- Query.setI64 1800 "year" query+ let query = Query "@plants/[year>:year] | asc /name" (setI64 1800 "year") plants <- getList database query plants @?= [ ( 2@@ -103,8 +101,7 @@ getListWithI64AtIndexQueryTest :: IO Database -> TestTree getListWithI64AtIndexQueryTest databaseIO = testCase "getListWithI64AtIndexQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[year>:?] | asc /name"- Query.setI64AtIndex 1800 0 query+ let query = Query "@plants/[year>:?] | asc /name" (setI64AtIndex 1800 0) plants <- getList database query plants @?= [ ( 2@@ -129,8 +126,8 @@ getListWithF64QueryTest :: IO Database -> TestTree getListWithF64QueryTest databaseIO = testCase "getListWithF64Query" $ do database <- databaseIO- query <- Query.fromString "@plants/[ratio > :ratio] | asc /name"- Query.setF64 1.6 "ratio" query+ let query = Query "@plants/[ratio > :ratio] | asc /name"+ (setF64 1.6 "ratio") plants <- getList database query plants @?= [ ( 4 , Just nothingPlant { id = Nothing@@ -145,29 +142,27 @@ ] getListWithF64AtIndexQueryTest :: IO Database -> TestTree-getListWithF64AtIndexQueryTest databaseIO =- testCase "getListWithF64AtIndexQuery" $ do- database <- databaseIO- query <- Query.fromString "@plants/[ratio > :?] | asc /name"- Query.setF64AtIndex 1.6 0 query- plants <- getList database query- plants @?= [ ( 4- , Just nothingPlant { id = Nothing- , name =- Just "leucanthemum vulgare"- , isTree = Just False- , year = Just 1778- , description = Just "very common flower in Italy 🍕"- , ratio = Just 1.618- }- )- ]+getListWithF64AtIndexQueryTest databaseIO = testCase "getListWithF64AtIndexQuery" $ do+ database <- databaseIO+ let query = Query "@plants/[ratio > :?] | asc /name" (setF64AtIndex 1.6 0)+ plants <- getList database query+ plants @?= [ ( 4+ , Just nothingPlant { id = Nothing+ , name =+ Just "leucanthemum vulgare"+ , isTree = Just False+ , year = Just 1778+ , description = Just "very common flower in Italy 🍕"+ , ratio = Just 1.618+ }+ )+ ] getListWithStringQueryTest :: IO Database -> TestTree getListWithStringQueryTest databaseIO = testCase "getListWithStringQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[name=:name] | asc /name"- Query.setString "pinus" "name" query+ let query = Query "@plants/[name=:name] | asc /name"+ (setString "pinus" "name") plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing@@ -183,8 +178,8 @@ getListWithStringAtIndexQueryTest databaseIO = testCase "getListWithStringAtIndexQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[name=:?] | asc /name"- Query.setStringAtIndex "pinus" 0 query+ let query = Query "@plants/[name=:?] | asc /name"+ (setStringAtIndex "pinus" 0) plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing@@ -199,9 +194,8 @@ getListWithRegexQueryTest :: IO Database -> TestTree getListWithRegexQueryTest databaseIO = testCase "getListWithRegexQuery" $ do database <- databaseIO- query- <- Query.fromString "@plants/[description re :description ] | asc /name"- Query.setRegex ".*Italy.*" "description" query+ let query = Query "@plants/[description re :description ] | asc /name"+ (setRegex ".*Italy.*" "description") plants <- getList database query plants @?= [ ( 4 , Just nothingPlant { id = Nothing@@ -219,8 +213,8 @@ getListWithRegexAtIndexQueryTest databaseIO = testCase "getListWithRegexAtIndexQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[description re :?] | asc /name"- Query.setRegexAtIndex "very.*Italy" 0 query+ let query = Query "@plants/[description re :?] | asc /name"+ (setRegexAtIndex "very.*Italy" 0) plants <- getList database query plants @?= [ ( 4 , Just nothingPlant { id = Nothing@@ -237,8 +231,7 @@ getListWithNullQueryTest :: IO Database -> TestTree getListWithNullQueryTest databaseIO = testCase "getListWithNullQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[ratio=:ratio] | asc /name"- Query.setNull "ratio" query+ let query = Query "@plants/[ratio=:ratio] | asc /name" (setNull "ratio") plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing@@ -255,8 +248,7 @@ getListWithNullAtIndexQueryTest databaseIO = testCase "getListWithNullAtIndexQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[ratio=:?] | asc /name"- Query.setNullAtIndex 0 query+ let query = Query "@plants/[ratio=:?] | asc /name" (setNullAtIndex 0) plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing@@ -272,10 +264,10 @@ getListWithMixedQueryTest :: IO Database -> TestTree getListWithMixedQueryTest databaseIO = testCase "getListWithMixedQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[year>:year] and /[isTree=:?] and /[name=:?] | asc /name"- Query.setI64 1700 "year" query- Query.setBoolAtIndex True 0 query- Query.setStringAtIndex "pinus" 1 query+ let query = Query "@plants/[year>:year] and /[isTree=:?] and /[name=:?] | asc /name" $ do+ setI64 1700 "year"+ setBoolAtIndex True 0+ setStringAtIndex "pinus" 1 plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing@@ -291,9 +283,9 @@ getListWithTwoStringsQueryTest databaseIO = testCase "getListWithTwoStringsQuery" $ do database <- databaseIO- query <- Query.fromString "@plants/[description re :descr] and /[name=:name] | asc /name"- Query.setRegex ".*wow.*" "descr" query- Query.setString "pinus" "name" query+ let query = Query "@plants/[description re :descr] and /[name=:name] | asc /name" $ do+ setRegex ".*wow.*" "descr"+ setString "pinus" "name" plants <- getList database query plants @?= [ ( 1 , Just nothingPlant { id = Nothing