-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
add to guideUse case worth including in the guideUse case worth including in the guide
Description
I have coded a findByCredentials query with selda. Email, password goes in, User record comes out. The User record has restricted newtypes inside of it (LongString, ShortString).
The same information User(bio,...) is now represented 4 times in the code (see below) + database table definition in sql. Can you help me getting the number down?
Thanks.
findByCredentials :: PG.Pool -> Credentials -> Aff (Either InputError User)
findByCredentials pool { email, password } =
PG.withConnection pool case _ of
Left pgError -> throwError $ error $ ("PostgreSQL connection error: " <> show pgError)
Right conn -> do
runSelda conn (app email password) >>= validate
validate :: forall a. Either PGError (Array a) -> Aff (Either InputError a)
validate result = do
case result of
Left e -> case e of
IntegrityError detail -> case detail.constraint of
"email_unique" -> pure $ Left EMAIL_EXISTS
"username_unique" -> pure $ Left USERNAME_EXISTS
otherwise -> throwError $ error $ show e
otherwise -> throwError $ error $ show e
Right rows -> case head rows of
Nothing -> pure $ Left NOT_FOUND
Just row -> pure $ Right row
user ∷
Table
( bio :: Maybe String -- 1. representation
, email :: String
, id :: Auto Int
, image :: Maybe String
, password :: String
, username :: String
)
user =
Source "user"
$ case _ of
Nothing → "\"user\""
Just alias → "\"user\"" <> " " <> alias
type InterUser
= { bio :: Maybe String -- 2. representation
, email :: String
, id :: Int
, image :: Maybe String
, password :: String
, username :: String
}
mkUser :: InterUser -> User
mkUser i =
unsafePartial
{ bio: LongString.unsafeFromString <$> i.bio -- 3. representation
, email: ShortString.unsafeFromString (i.email)
, id: i.id
, image: LongString.unsafeFromString <$> i.image
, password: ShortString.unsafeFromString i.password
, username: ShortString.unsafeFromString i.username
}
selectUser ∷
∀ s.
Email ->
Password ->
FullQuery s
{ bio :: Col s (Maybe String) -- 4. representation
, email ∷ Col s String
, id ∷ Col s Int
, image :: Col s (Maybe String)
, password :: Col s String
, username :: Col s String
}
selectUser email password =
selectFrom user \r → do
restrict $ r.email .== lit (ShortString.toString email) && r.password .== lit (ShortString.toString password)
pure r
queryUser ∷
∀ m.
MonadSeldaPG m =>
Email -> Password -> m (Array InterUser)
queryUser email password = query (selectUser email password)
app ∷ ∀ m. MonadSeldaPG m => Email -> Password -> m (Array User)
app email password = do
logQuery $ selectUser email password
rows <- queryUser email password
pure $ mkUser <$> rows
logQuery ∷ ∀ s i m. GetCols i ⇒ MonadEffect m ⇒ FullQuery s { | i } → m Unit
logQuery q = do
let
{ strQuery, params } = showPG $ showQuery q
log strQuery
log $ unsafeStringify params
log ""Metadata
Metadata
Assignees
Labels
add to guideUse case worth including in the guideUse case worth including in the guide