Haskell Persistent insertion strings, if not already in the database

I am trying to use Yesod and persistently building a website. I am a bit confused about how to use a persistent API.

Here are two of my tables

Feed url Text UniqueFeed url Subscription feed FeedId title Text UniqueSubscription feed 

I am trying to create a feed if the feed with this URL does not exist, then add a subscription to this channel if the subscription does not already exist.

 postFeedR :: Handler RepHtml postFeedR = do url <- runInputPost $ ireq urlField "url" title <- runInputPost $ ireq textField "title" runDB $ do feedId <- insertFeed $ UniqueFeed url subscriptionId <- insertSubscription feedId title return defaultLayout [whamlet| <p>done|] insertFeed url = do f <- insertBy $ UniqueFeed url case f of Left (Entity uid _) -> uid Right (Key uid) -> do (Key uid) <- insert $ Feed url return uid insertSubscription feedId title = do s <- insertBy $ UniqueSubscription feedId case s of Left (Entity uid _) -> uid Right (Key uid) -> do (Key uid) <- insert $ Subscription feedId title return uid 

I get errors below. I don't understand why ghc thinks that the return value of insertFeed and insertSubscription should be UniqueFeed and UniqueSubscription. I would like these functions to return the keys of newly created records.

In addition, it seems that I am discarding the key that I am returning at each of the points of the case. Why a constant return of these keys. If UniqueSubscription is not in the database, the permanent does not have enough information to create a new subscription record, because it does not have a header that is not in UniqueSubscription.

If someone can give me some guidance on how to use a persistent API, I would really appreciate it.

 Handler/Home.hs:62:9: Kind incompatibility when matching types: a0 :: * GHandler App App :: * -> * Expected type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0) Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0 In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url In the second argument of `($)', namely `do { feedId <- insertFeed $ UniqueFeed url; subscriptionId <- insertSubscription feedId title; return }' Handler/Home.hs:62:9: Couldn't match type `YesodPersistBackend App' with `(->)' Expected type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0) Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0 In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url In the second argument of `($)', namely `do { feedId <- insertFeed $ UniqueFeed url; subscriptionId <- insertSubscription feedId title; return }' Handler/Home.hs:74:20: Couldn't match expected type `Unique Feed' with actual type `Database.Persist.Store.PersistValue' In the first argument of `return', namely `uid' In a stmt of a 'do' block: return uid In the expression: do { (Key uid) <- insert $ Feed url; return uid } Handler/Home.hs:83:20: Couldn't match expected type `Unique Subscription' with actual type `Database.Persist.Store.PersistValue' In the first argument of `return', namely `uid' In a stmt of a 'do' block: return uid In the expression: do { (Key uid) <- insert $ Subscription feedId title; return uid } 
+6
source share
1 answer

insertBy does not accept a unique constraint as a parameter; getBy is more appropriate.

But insertUnique is a short opportunity with a Maybe result.

 postFeedR :: Handler RepHtml postFeedR = do url <- runInputPost $ ireq urlField "url" title <- runInputPost $ ireq textField "title" runDB $ do feedId <- insertFeed url _mbSubscriptionId <- insertUnique $ Subscription feedId title return () defaultLayout ... insertFeed url = do f <- insertBy $ Feed url case f of Left (Entity uid _) -> return uid Right uid -> return uid 
+7
source

Source: https://habr.com/ru/post/943939/


All Articles