packages feed

cqrs-example (empty) → 0.4.0

raw patch · 6 files changed

+233/−0 lines, 6 filesdep +basedep +cerealdep +cqrssetup-changed

Dependencies added: base, cereal, cqrs, data-default, text, transformers

Files

+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (c) 2011 Bardur Arantsson++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cqrs-example.cabal view
@@ -0,0 +1,28 @@+Name:                cqrs-example+Version:             0.4.0+Synopsis:            Example for cqrs package+License:             MIT+License-file:        LICENSE+Author:              Bardur Arantsson+Maintainer:          spam@scientician.net+Category:            Web+Build-type:          Simple+Cabal-version:       >=1.6.0.1++Executable cqrs-example+  Main-is:           Main.hs+  Build-depends:     base == 4.*+                   , cereal >= 0.3 && < 0.4+                   , cqrs >= 0.4 && < 0.5+                   , data-default >= 0.3 && < 0.4+                   , text >= 0.11 && < 0.12+                   , transformers >= 0.2.2 && < 0.3+  Ghc-options:       -Wall+  Extensions:        DeriveDataTypeable+                     MultiParamTypeClasses+                     OverloadedStrings+                     ScopedTypeVariables+  Hs-source-dirs:    src+  Other-modules:     Aggregates+                     Events+                     
+ src/Aggregates.hs view
@@ -0,0 +1,105 @@+module Aggregates+       ( Project(..)+       , ProjectId+       , ProjectState(..)+       , Task(..)+       , TaskId+       , TaskState(..)+       ) where++import Control.Monad (liftM)+import Data.CQRS (Aggregate(..), GUID)+import Data.Default (Default(..))+import Data.Serialize (Serialize(..), decode, encode)+import Data.Text (Text)+import qualified Data.Text as T+import Data.Text.Encoding (decodeUtf8, encodeUtf8)+import Data.Typeable (Typeable)+import Data.Word (Word8)++-- Projects.++type ProjectId = GUID Project++data ProjectState = New+                  | Active+                  deriving (Eq, Typeable)++instance Serialize ProjectState where+  put New = put (0 :: Word8)+  put Active = put (1 :: Word8)+  get = do+    i :: Word8 <- get+    case i of+      0 -> return New+      1 -> return Active+      _ -> fail $ "Cannot decode project state: " ++ show i++data Project = Project { projectName :: Text+                       , projectState :: ProjectState+                       }+               deriving (Typeable)++instance Serialize Project where+  put (Project pn ps) = do+    put $ encodeUtf8 pn+    put ps+  get = do+    pn <- liftM decodeUtf8 get+    ps <- get+    return $ Project pn ps++instance Aggregate Project where+  encodeAggregate = encode+  decodeAggregate s =+    case decode s of+      Left e -> error e+      Right a -> a++instance Default Project where+  def = Project T.empty New++-- Tasks.++type TaskId = GUID Task++data TaskState = TaskNew+               | TaskActive+                 deriving (Eq, Typeable)++instance Serialize TaskState where+  put TaskNew = put (0 :: Word8)+  put TaskActive = put (1 :: Word8)+  get = do+    i :: Word8 <- get+    case i of+      0 -> return TaskNew+      1 -> return TaskActive+      _ -> fail $ "Cannot decode task state: " ++ show i++data Task = Task { taskProjectId :: ProjectId+                 , taskState :: TaskState+                 , taskShortDescription :: Text+                 }+            deriving (Typeable)++instance Serialize Task where+  put (Task tpid ts tsd) = do+    put tpid+    put ts+    put $ encodeUtf8 tsd+  get = do+    tpid <- get+    ts <- get+    tsd <- liftM decodeUtf8 get+    return $ Task tpid ts tsd++instance Aggregate Task where+  encodeAggregate = encode+  decodeAggregate s =+    case decode s of+      Left e -> error e+      Right a -> a++instance Default Task where+  def = Task def TaskNew T.empty
+ src/Events.hs view
@@ -0,0 +1,44 @@+module Events+       ( ExampleEvent(..)+       ) where++import Aggregates+import Control.Monad (liftM)+import Data.Serialize (Serialize(..))+import Data.Text (Text)+import Data.Text.Encoding (decodeUtf8, encodeUtf8)+import Data.Typeable (Typeable)+import Data.Word (Word8)++data ExampleEvent = CreateProject Text+                  | RenameProject Text+                  | AddTask ProjectId Text+                    deriving (Typeable)++instance Serialize ExampleEvent where+  put (CreateProject name) = do+    put (0 :: Word8)+    put $ encodeUtf8 name+  put (RenameProject name) = do+    put (1 :: Word8)+    put $ encodeUtf8 name+  put (AddTask pid tsd) = do+    put (2 :: Word8)+    put $ pid+    put $ encodeUtf8 tsd+  get = do+    i :: Word8 <- get+    case i of+      0 -> do+        n <- liftM decodeUtf8 get+        return $ CreateProject n+      1 -> do+        n <- liftM decodeUtf8 get+        return $ RenameProject n+      2 -> do+        pid <- get+        tsd <- liftM decodeUtf8 get+        return $ AddTask pid tsd+      _ -> do+        fail $ "Unrecognized event type " ++ show i+
+ src/Main.hs view
@@ -0,0 +1,35 @@+import Control.Monad.Trans.Class (lift)+import Data.CQRS+import Data.CQRS.EventStore (withEventStore)+import Data.CQRS.EventStore.Sqlite3+import Aggregates+import Events+import Instances ()++sqliteFile :: String+sqliteFile = "example.db"++test1 :: IO ()+test1 =+    withEventStore (openSqliteEventStore sqliteFile) $ \eventStore -> do+      runTransactionT eventStore $ do+        -- Create new project.+        projectId :: GUID Project <- lift $ newGUID+        (projectRef, _) <- getAggregateRoot projectId+        publishEvent projectRef $ CreateProject "my project"++        -- Add a couple of tasks+        taskId1 :: GUID Task <- lift $ newGUID+        (taskRef1, _) <- getAggregateRoot taskId1+        publishEvent taskRef1 $ AddTask projectId "tweak knob"++        taskId2 :: GUID Task <- lift $ newGUID+        (taskRef2, _) <- getAggregateRoot taskId2+        publishEvent taskRef2 $ AddTask projectId "pull lever"++main :: IO ()+main = do+  putStrLn "Running test1..."+  test1+  putStrLn "Done."+