poppy-1.0.0: test/Schema/Article.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE TypeApplications #-}
module Schema.Article
( ArticleTable (..),
ArticleRow (..),
ArticleSelect (..),
ArticlePicked (..),
articleSelect,
articleSelectColumns,
parseArticlePicked,
toArticlePicked,
ArticleCreate (..),
ArticleUpdate (..),
articleId,
articleAuthorId,
articleTitle
)
where
import Data.Text (Text)
import Data.UUID (UUID)
import Poppy.Internal.Generated
( FromRow (..),
RowParser,
field,
Entity (..),
Field (..),
PrimaryKeyType,
ModelTable,
Picked (..),
picked,
Insertable (..),
emptyInsert,
set,
setMaybe,
Updatable (..),
emptyUpdate,
setFieldMaybe
)
data ArticleTable = ArticleTable
type instance PrimaryKeyType ArticleTable = UUID
type instance ModelTable "Article" = ArticleTable
instance Entity ArticleTable where
tableName = "test_article"
primaryKey = articleId
tableColumns = ["id", "author_id", "title"]
instance Insertable ArticleTable where
type CreateInput ArticleTable = ArticleCreate
toInsertBuilder input =
setMaybe articleId input.id $
set articleAuthorId input.authorId $
set articleTitle input.title $
emptyInsert @ArticleTable
instance Updatable ArticleTable where
type UpdateInput ArticleTable = ArticleUpdate
updatedAtField = Nothing
toUpdateBuilder input =
setFieldMaybe articleAuthorId input.authorId $
setFieldMaybe articleTitle input.title $
emptyUpdate @ArticleTable
data ArticleRow = ArticleRow
{ id :: UUID,
authorId :: UUID,
title :: Text
}
deriving (Show, Eq)
data ArticleCreate = ArticleCreate
{ id :: Maybe UUID,
authorId :: UUID,
title :: Text
}
deriving (Show, Eq)
data ArticleUpdate = ArticleUpdate
{ authorId :: Maybe UUID,
title :: Maybe Text
}
deriving (Show, Eq)
instance FromRow ArticleRow where
fromRow = ArticleRow <$> field <*> field <*> field
data ArticleSelect = ArticleSelect
{ id :: Bool,
authorId :: Bool,
title :: Bool
}
deriving (Show, Eq)
data ArticlePicked = ArticlePicked
{ id :: UUID,
authorId :: Picked UUID,
title :: Picked Text
}
deriving (Show, Eq)
articleSelect :: ArticleSelect
articleSelect =
ArticleSelect
{ id = False,
authorId = False,
title = False
}
articleSelectColumns :: ArticleSelect -> [Text]
articleSelectColumns select_ =
fieldColumn articleId
: concat
[ [fieldColumn articleAuthorId | select_.authorId]
, [fieldColumn articleTitle | select_.title]
]
parseArticlePicked :: ArticleSelect -> RowParser ArticlePicked
parseArticlePicked select_ = do
idVal <- field
authorIdVal <- if select_.authorId then Picked <$> field else pure Skipped
titleVal <- if select_.title then Picked <$> field else pure Skipped
pure ArticlePicked { id = idVal, authorId = authorIdVal, title = titleVal }
toArticlePicked :: ArticleSelect -> ArticleRow -> ArticlePicked
toArticlePicked select_ row =
ArticlePicked
{ id = row.id,
authorId = picked select_.authorId row.authorId,
title = picked select_.title row.title
}
articleId :: Field ArticleTable UUID
articleId = Field "id" "id"
articleAuthorId :: Field ArticleTable UUID
articleAuthorId = Field "authorId" "author_id"
articleTitle :: Field ArticleTable Text
articleTitle = Field "title" "title"