Skip to content

Instantly share code, notes, and snippets.

@Woody88
Created February 17, 2020 05:32
Show Gist options
  • Select an option

  • Save Woody88/e99b3fddeb1efb34bd2cc5ead33d3377 to your computer and use it in GitHub Desktop.

Select an option

Save Woody88/e99b3fddeb1efb34bd2cc5ead33d3377 to your computer and use it in GitHub Desktop.
module Infra.Resources.Config where
import Prelude
import Data.Either (Either(..), note)
import Dotenv as Dotenv
import Effect.Aff (Aff, error, makeAff, throwError)
import Foreign.Object (Object)
import Foreign.Object as Object
import Infra.Resources.Database.DBAdapter (MYSQL, REDIS, kind DBAdapter)
import Node.Process as Node
type Config (adapter :: DBAdapter) =
{ dbName :: String
}
readConfigRedis :: Object String -> Either String (Config REDIS)
readConfigRedis _ = pure { dbName: ""}
readConfigSQL :: Object String -> Either String (Config MYSQL)
readConfigSQL _ = pure { dbName: ""}
lookupEnv :: String -> Object String -> Either String String
lookupEnv name env = note ("Missing Environment variable " <> name) $ Object.lookup name env
readAdapter :: forall adapter. Object String -> String -> Either String (Config adapter)
readAdapter env "REDIS" = readConfigRedis env
readAdapter env "MYSQL" = readConfigSQL env
readAdapter _ _ = Left "Not a valid adapter"
loadConfig :: forall adapter. Aff (Config adapter)
loadConfig = do
_ <- Dotenv.loadFile
makeAff \done -> do
env <- Node.getEnv
let eConfig = lookupEnv "DB_ADAPTER" env >>= readAdapter env
done $ case eConfig of
Left e -> throwError $ error e
Right cfg -> pure cfg
pure mempty
module Infra.Resources.Database where
import Prelude
import Data.Newtype (class Newtype)
import Database.Redis as Redis
import Effect.Aff (Aff, error, makeAff, throwError)
import Infra.Resources.Config (Config) as Resources
import Infra.Resources.Database.DBAdapter (MYSQL, REDIS, kind DBAdapter)
import MySQL.Connection as MySQL
newtype Connection (adpter :: DBAdapter) conn = Connection conn
derive instance newtypeConnection :: Newtype (Connection adpter conn) _
class ConnectionAdapter (adapter :: DBAdapter) conn | adapter -> conn where
acquireConnection :: Resources.Config adapter -> Aff (Connection adapter conn)
instance connectionAdapterRedis :: ConnectionAdapter REDIS Redis.Connection where
acquireConnection _ = Connection <$> Redis.connect Redis.defaultConfig
else instance connectionAdapterMySQL :: ConnectionAdapter MYSQL MySQL.Connection where
acquireConnection cfg = makeAff \done -> do
mysqlConn <- MySQL.createConnection $ MySQL.defaultConnectionInfo { database = cfg.dbName }
done $ pure $ Connection mysqlConn
pure mempty
else instance connectionAdapterErr :: ConnectionAdapter a b where
acquireConnection _ = throwError $ error "DB Adapter could not be solved."
No type class instance was found for
Infra.Resources.Database.ConnectionAdapter t4
t5
The instance head contains unknown type variables. Consider adding a type annotation.
while applying a function acquireConnection
of type ConnectionAdapter t2 t3 => { dbName :: String
}
-> Aff (Connection t2 t3)
to argument config
while checking that expression acquireConnection config
has type t0 t1
in value declaration main
where t0 is an unknown type
t1 is an unknown type
t2 is an unknown type
t3 is an unknown type
t5 is an unknown type
t4 is an unknown type
module Main where
import Prelude
import Application.API (runServer)
import Effect (Effect)
import Effect.Aff as Aff
import Effect.Class (liftEffect)
import Effect.Class.Console (log)
import Infra.Resources.Config as Resources
import Infra.Resources.Database (Connection(..))
import Infra.Resources.Database as Database
main :: Effect Unit
main = Aff.launchAff_ do
liftEffect $ log "Hello, World!"
config <- Resources.loadConfig
conn <- Database.acquireConnection config -- this line is causing the error
liftEffect $ runServer conn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment