mightybyte / snaplet-postgresql-simple

BSD 3-Clause "New" or "Revised" License
40 stars 38 forks source link

Missing definition of the HasPostgres instance in the example and the docu #23

Closed bulldog98 closed 9 years ago

bulldog98 commented 10 years ago

Hi,

right now I'm trying to port my old snap project to the new snaplet-postgres-simple release, but I get No instance nor default method for class operation Snap.Snaplet.PostgresqlSimple.Internal.setLocalPostgresState for my Type as soon as I try to load a page with an database query.

mightybyte commented 10 years ago

You need to modify your HasPostgres instance to include a definition for setLocalPostgresState. You can see some examples of built-in instances here:

https://github.com/mightybyte/snaplet-postgresql-simple/blob/master/src/Snap/Snaplet/PostgresqlSimple.hs#L158

bulldog98 commented 10 years ago

I knew that my main problem is that I do not know what function I should use for this

mightybyte commented 10 years ago

I can't help without more detailed information about your monad.

sopvop commented 10 years ago

I have this in my code, can't say if this is right though.

data AuthData a = AuthData
  {  -- snip
    database              :: Lens' a (Snaplet Postgres)
  }

instance HasPostgres (Handler a (AuthData a)) where
  getPostgresState = (gets database >>= \d -> withTop d getPostgresState)
  setLocalPostgresState pg act = do
    d <- gets database
    orig <- withTop d $ do
       orig <- getsSnapletState (view snapletValue)
       modifySnapletState (set snapletValue pg)
       return orig
    act `finally` withTop d (modifySnapletState (set snapletValue orig))
bulldog98 commented 9 years ago

What I have right now is the following:

data App = App
    { _heist :: Snaplet (Heist App) -- ^ the heist subsnaplet
     , _sess :: Snaplet SessionManager -- ^ the sessionmanager subsnaplet
     , _db :: Snaplet Postgres -- ^ the postgres subsnaplet
     , _auth :: Snaplet (AuthManager App) -- ^ the authmanager subsnaplet
     }

 makeLenses ''App

 instance HasPostgres (Handler b App) where
         getPostgresState = with db get
mightybyte commented 9 years ago

Try this:

setLocalPostgresState s = local (set (db . snapletValue) s)
dzhus commented 9 years ago

@mightybyte, What do I write if I have a lens defined directly (to be able to use provide it from upper-level snaplet in initializer)?

data MySnaplet b = MS{db :: SnapletLens b Postgres}

instance HasPostgres (Handler b (MySnaplet b)) where
  setLocalPostgresState s = ???