Spock 0.8.0.0 → 0.8.1.0
raw patch · 6 files changed
+151/−3 lines, 6 filesdep +focusPVP ok
version bump matches the API change (PVP)
Dependencies added: focus
API changes (from Hackage documentation)
+ Web.Spock.Internal.SessionVault: mapSessions :: IsSession s => (s -> STM s) -> SessionVault s -> STM ()
+ Web.Spock.Shared: mapAllSessions :: (sess -> STM sess) -> SpockAction conn sess st ()
Files
- README.md +116/−0
- Spock.cabal +6/−2
- src/Web/Spock/Internal/SessionManager.hs +10/−0
- src/Web/Spock/Internal/SessionVault.hs +8/−0
- src/Web/Spock/Internal/Types.hs +2/−0
- src/Web/Spock/Shared.hs +9/−1
+ README.md view
@@ -0,0 +1,116 @@+Spock+=====++[](https://travis-ci.org/agrafix/Spock)++[](http://packdeps.haskellers.com/reverse/Spock)++For more information and tutorials, visit [spock.li](http://www.spock.li)++## Intro++Hackage: [Spock](http://hackage.haskell.org/package/Spock)+Tutorial: [Spock Tutorial](https://www.spock.li/tutorial/)++Another Haskell web framework for rapid development: This toolbox provides+everything you need to get a quick start into web hacking with haskell:++* fast routing (both typesafe and "untyped")+* middleware+* json+* sessions+* cookies+* database helper+* csrf-protection++Benchmarks:++* https://github.com/philopon/apiary-benchmark+* https://github.com/agrafix/Spock-scotty-benchmark++## Usage (Typesafe, recommended)++```haskell+{-# LANGUAGE OverloadedStrings #-}+import Web.Spock++import qualified Data.Text as T++main =+ runSpock 3000 $ spockT id $+ do get ("echo" <//> var) $ \something ->+ text $ T.concat ["Echo: ", something]+```++(read more at [Type-safe routing in Spock](https://www.spock.li/2015/04/19/type-safe_routing.html))++## Usage (Simple)++```haskell+{-# LANGUAGE OverloadedStrings #-}+import Web.Spock.Simple++import qualified Data.Text as T++main =+ runSpock 3000 $ spockT id $+ do get ("echo" <//> ":something") $+ do Just something <- param "something"+ text $ T.concat ["Echo: ", something]+ get ("regex" <//> "{number:^[0-9]+$}") $+ do Just number <- param "number"+ text $ T.concat ["Just a number: ", number]+```++## Install++* Using cabal: `cabal install Spock`+* From Source: `git clone https://github.com/agrafix/Spock.git && cd Spock && cabal install`++## Candy++### Extensions++The following Spock extensions exist:++* Background workers for Spock: [Spock-worker](http://hackage.haskell.org/package/Spock-worker)+* Digestive functors for Spock: [Spock-digestive](http://hackage.haskell.org/package/Spock-digestive)++### Works well with Spock++* User management [users](http://hackage.haskell.org/package/users)+* Data validation [validate-input](http://hackage.haskell.org/package/validate-input)+* Blaze bootstrap helpers [blaze-bootstrap](http://hackage.haskell.org/package/blaze-bootstrap)+* digestive-forms bootstrap helpers [digestive-bootstrap](http://hackage.haskell.org/package/digestive-bootstrap)++## Example Projects++* [funblog](https://github.com/agrafix/funblog)+* [makeci](https://github.com/openbrainsrc/makeci)+* [curry-recipes](https://github.com/timjb/reroute-talk/tree/06574561918b50c1809f1e24ec7faeff731fddcf/curry-recipes)++## Talks++* German: [Moderne typsichere Web-Entwicklung mit Haskell](https://dl.dropboxusercontent.com/u/15078797/talks/typesafe-webdev-2015.pdf) (by Alexander Thiemann)+* German: [reroute-talk](https://github.com/timjb/reroute-talk) (by Tim Baumann)++## Companies / Projects using Spock++* http://cp-med.com/+* http://openbrain.co.uk/+* http://findmelike.com/+* https://www.tramcloud.net+* http://thitp.de++## Notes++Since version 0.7.0.0 Spock supports typesafe routing. If you wish to continue using the untyped version of Spock you can Use `Web.Spock.Simple`. The implementation of the routing is implemented in a separate haskell package called `reroute`.++Since version 0.5.0.0 Spock is no longer built on top of scotty. The+design and interface is still influenced by scotty, but the internal+implementation differs from scotty's.++## Thanks to++* Tim Baumann [Github](https://github.com/timjb) (lot's of help with typesafe routing)+* Tom Nielsen [Github](https://github.com/glutamate) (much feedback and small improvements)
Spock.cabal view
@@ -1,5 +1,5 @@ name: Spock-version: 0.8.0.0+version: 0.8.1.0 synopsis: Another Haskell web framework for rapid development description: This toolbox provides everything you need to get a quick start into web hacking with haskell: .@@ -28,8 +28,11 @@ category: Web build-type: Simple cabal-version: >=1.8-tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.1+tested-with: GHC==7.6.3, GHC==7.8.4, GHC==7.10.2 +extra-source-files:+ README.md+ library hs-source-dirs: src exposed-modules:@@ -54,6 +57,7 @@ case-insensitive >=1.1, containers >=0.5, directory >=1.2,+ focus >=0.1, hashable >=1.2, http-types >=0.8, hvect >= 0.2,
src/Web/Spock/Internal/SessionManager.hs view
@@ -55,6 +55,7 @@ , sm_writeSession = writeSessionImpl vaultKey cacheHM , sm_modifySession = modifySessionImpl vaultKey cacheHM , sm_clearAllSessions = clearAllSessionsImpl cacheHM+ , sm_mapSessions = mapAllSessionsImpl cacheHM , sm_middleware = sessionMiddleware cfg vaultKey cacheHM , sm_addSafeAction = addSafeActionImpl vaultKey cacheHM , sm_lookupSafeAction = lookupSafeActionImpl vaultKey cacheHM@@ -288,6 +289,15 @@ -> SpockAction conn sess st () clearAllSessionsImpl sessionRef = liftIO $ atomically $ SV.filterSessions (const False) sessionRef++mapAllSessionsImpl ::+ SV.SessionVault (Session conn sess st)+ -> (sess -> STM sess)+ -> SpockAction conn sess st ()+mapAllSessionsImpl sessionRef f =+ liftIO $ atomically $ flip SV.mapSessions sessionRef $ \sess ->+ do newData <- f (sess_data sess)+ return $ sess { sess_data = newData } housekeepSessions :: SessionCfg sess -> SV.SessionVault (Session conn sess st)
src/Web/Spock/Internal/SessionVault.hs view
@@ -12,6 +12,7 @@ import Control.Concurrent.STM (STM) import Control.Monad import Data.Hashable+import Focus as F import qualified ListT as L import qualified STMContainers.Map as STMMap import qualified Data.Text as T@@ -55,3 +56,10 @@ map getSessionKey $ filter (not . cond) allVals forM_ deleteKeys $ flip deleteSession sv++-- | Perform action on all sessions+mapSessions :: IsSession s => (s -> STM s) -> SessionVault s -> STM ()+mapSessions f sv@(SessionVault smap) =+ do allVals <- toList sv+ forM_ allVals $ \sess ->+ STMMap.focus (F.adjustM f) (getSessionKey sess) smap
src/Web/Spock/Internal/Types.hs view
@@ -16,6 +16,7 @@ #else import Control.Applicative #endif+import Control.Concurrent.STM import Control.Monad.Base import Control.Monad.Reader import Control.Monad.Trans.Control@@ -200,6 +201,7 @@ , sm_readSession :: SpockAction conn sess st sess , sm_writeSession :: sess -> SpockAction conn sess st () , sm_modifySession :: forall a. (sess -> (sess, a)) -> SpockAction conn sess st a+ , sm_mapSessions :: (sess -> STM sess) -> SpockAction conn sess st () , sm_clearAllSessions :: SpockAction conn sess st () , sm_middleware :: Middleware , sm_addSafeAction :: PackedSafeAction conn sess st -> SpockAction conn sess st SafeActionHash
@@ -34,7 +34,7 @@ , SessionPersistCfg(..), readShowSessionPersist , SessionId , getSessionId, readSession, writeSession- , modifySession, modifySession', modifyReadSession, clearAllSessions+ , modifySession, modifySession', modifyReadSession, mapAllSessions, clearAllSessions -- * Internals for extending Spock , getSpockHeart, runSpockIO, WebStateM, WebState )@@ -45,6 +45,7 @@ import Web.Spock.Internal.Types import Web.Spock.Internal.CoreAction import Control.Monad+import Control.Concurrent.STM (STM) import System.Directory import qualified Web.Spock.Internal.Wire as W import qualified Network.Wai as Wai@@ -105,6 +106,13 @@ clearAllSessions = do mgr <- getSessMgr sm_clearAllSessions mgr++-- | Apply a transformation to all sessions. Be careful with this, as this+-- may cause many STM transaction retries.+mapAllSessions :: (sess -> STM sess) -> SpockAction conn sess st ()+mapAllSessions f =+ do mgr <- getSessMgr+ sm_mapSessions mgr f -- | Simple session persisting configuration. DO NOT USE IN PRODUCTION readShowSessionPersist :: (Read a, Show a) => FilePath -> SessionPersistCfg a