Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Example for Yesod / Persistent

Haskell and Yesod newbie here. I've been trying to follow the Integration with Yesod example from the Persistent chapter in the Yesod book (http://www.yesodweb.com/book/persistent). The Sqlite compiles and runs fine it seems. However, I'm trying to use MongDB and am having a hard time getting things to work. Specifically:

  1. In the example for sqlite:

    share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|

    The Yesod book says "Mongo code will use mongoSettings instead." But I can't find it in any of the modules, and the code doesn't compile. So instead, I had to use this instead of mongoSettings:

    MkPersistSettings { mpsBackend = ConT ''Action }

    I had to import Language.Haskell.TH.Syntax to get it to compile, which I'm assuming should be hidden from the user so I'm certainly not doing it right.

    Also, I found that in the Persistent tests for Mongo do without the "share" and "migrate" part. I'm actually not sure why, I'm guessing it's because MongoDB is Schema-less and doesn't need migration?

  2. SqlPersist

    I thought MongoPersist would be the counterpart to SqlPersist, and I guess it almost is--I found one instance of MongoPersist in the init.hs in the test directory of Persistent. But it's commented out, so I have a feeling it's obsolete? Otherwise it's not defined anyway as far as I can tell. So I don't know how to convert the following line (P.115 of the Yesod book, or near the end of http://www.yesodweb.com/book/persistent) to work for MongoDB:

    instance YesodPersist PersistTest where
        type YesodPersistBackend PersistTest = SqlPersist
        runDB action = do
            PersistTest pool <- getYesod
            runSqlPool action pool
    
  3. Using withMongoDBConn

    So for sqlite, the code is (1st example from the webpage above):

    main :: IO ()
    main = withSqliteConn ":memory:" $ runSqlConn $ do
        runMigration migrateAll
        johnId <- insert $ Person "John Doe" $ Just 35
        ... and so on
    

    But

    main :: IO()
    main = withMongoDBConn ":memory:" $ runMongoDBConn $ do
        runMigration migrateAll 
        johnId <- insert $ Person "John Doe" $ Just 35
        ... and so on          
    

doesn't work. First off, runMigration for some reason isn't in scope. Okay, maybe I don't need migration for MongoDB, so I remove that line. Then, the compiler complains: Couldn't match expected typeAccessMode' with actual type m0 b0' Expected type: m0 t0 -> (t0 -> m0 b0) -> AccessMode Actual type: m0 t0 -> (t0 -> m0 b0) -> m0 b0 and so on. And by this stage my very cursory knowledge of monads just isn't enough to figure this one out.

All in all, I am having a really tough time converting the Integration with Yesod example from the book from Sqlite to MongoDB. Could someone please provide me with a concrete example of Yesod/Persistent with MongoDB? Much thanks in advance.

like image 495
Victor Avatar asked Jul 31 '12 01:07

Victor


2 Answers

I added a page in the Github Yesod Cookbook today that uses MongoDB in conjunction with Persistent. It does not, however, use withMongoDBConn, neither does it avoid TH. Also, I explain there why I use a separate YAML config file. The link: http://bit.ly/VLvmoK

like image 139
fcar Avatar answered Oct 28 '22 12:10

fcar


I know this is an answer to an old question, but here is a Yesod independent way to get Persistent working with MongoDB. This might be of use to others new to Persistent.

{-# LANGUAGE TemplateHaskell #-}

import Database.Persist 
import Database.Persist.TH
import Database.Persist.MongoDB
import Network (PortID (PortNumber))

let mongoSettings = (mkPersistSettings (ConT ''MongoBackend)) {mpsGeneric = False}
    in share [mkPersist mongoSettings] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
BlogPost
    title String
    authorId PersonId
    deriving Show
|]
runDBActions actions = 
    withMongoDBConn "myDatabaseName" "localhost" (PortNumber 27017) Nothing 2000 $ \pool ->    
        runMongoDBPool master actions pool

actions = do
    mkey <- insert $ Person "John Doe" $ Just 35
    ...

main :: IO ()
main = do
    runDBactions actions
like image 41
iamnat Avatar answered Oct 28 '22 14:10

iamnat