diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/app/Main.hs b/app/Main.hs index 60d904e..1408ed1 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,8 +1,61 @@ +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE DeriveGeneric #-} module Main where +import Data.Text (Text(..)) +import Data.Aeson import qualified MyLib (someFunc) +import Database.SQLite.Simple +import Database.SQLite.Simple.FromRow (FromRow) +import Database.SQLite.Simple.FromField (fromField) +import Database.SQLite.Simple.QQ +import Network.Wai +import Network.Wai.Handler.Warp +import Deriving.Aeson +import Data.Proxy +import Servant + +import Control.Monad.IO.Class + +data Quote = Quote { qQuote :: Text + , qAuthor :: Text + , qBook :: Text + } deriving (Show, Eq, Ord, Generic) + deriving (FromJSON,ToJSON) + via CustomJSON '[OmitNothingFields, FieldLabelModifier '[StripPrefix "q", CamelToSnake]] Quote + +instance FromRow Quote where + fromRow = Quote <$> field <*> field <*> field + main :: IO () main = do putStrLn "Hello, Haskell!" - MyLib.someFunc + let dbfile = "quotes.db" + initDb dbfile + runApp dbfile + + +type API = Get '[JSON] [Quote] + +api :: Proxy API +api = Proxy + +initDb :: FilePath -> IO () +initDb dbFile = withConnection dbFile $ \conn -> + execute_ conn + [sql|CREATE TABLE IF NOT EXISTS quotes (quote text non null, author text, book text)|] + +server :: FilePath -> Server API +server dbf = listQuotes dbf + + +listQuotes :: FilePath -> Handler [Quote] +listQuotes db = liftIO $ withConnection db $ \conn -> query_ conn [sql|SELECT * FROM quotes;|] + +runApp :: FilePath -> IO () +runApp dbfile = run 8081 (serve api $ server dbfile) diff --git a/quotes-api.cabal b/quotes-api.cabal index 2612d11..688a03b 100644 --- a/quotes-api.cabal +++ b/quotes-api.cabal @@ -69,7 +69,6 @@ library -- Other library packages from which modules are imported. build-depends: base ^>=4.16.3.0 - -- Directories containing source files. hs-source-dirs: lib @@ -92,6 +91,13 @@ executable quotes-api -- Other library packages from which modules are imported. build-depends: base ^>=4.16.3.0, + sqlite-simple ^>=0.4.18.0, + text ^>=1.2.5.0, + servant-server ^>=0.19.1, + wai, + warp, + aeson, + deriving-aeson, quotes-api -- Directories containing source files. diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..6eac1bc --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ +let + pkgs = import { }; # pin the channel to ensure reproducibility! +in +pkgs.haskellPackages.developPackage { + root = ./.; + modifier = drv: + pkgs.haskell.lib.addBuildTools drv (with pkgs.haskellPackages; + [ cabal-install + ghcid + ghc + haskell-language-server + zlib + ]); +} +