content: {-# LANGUAGE DeriveFunctor #-}
  {-# LANGUAGE TypeFamilies #-}
  
  module Eventful.Store.Queries
    ( QueryRange (..)
    , QueryStart (..)
    , QueryLimit (..)
    , allEvents
    , eventsUntil
    , eventsStartingAt
    , eventsStartingAtUntil
    , eventsStartingAtTakeLimit
    ) where
  
  -- | This type defines how to query an event stream. It defines the stream key
  -- and the start/stop points for the query.
  data QueryRange key position
    = QueryRange
    { queryRangeKey :: key
    , queryRangeStart :: QueryStart position
    , queryRangeLimit :: QueryLimit position
    } deriving (Show, Eq)
  
  -- | This type defines where an event store query starts.
  data QueryStart position
    = StartFromBeginning
    | StartQueryAt position
    deriving (Show, Eq, Functor)
  
  -- | This type is used to limit the results of a query from an event store.
  data QueryLimit position
    = NoQueryLimit
    | MaxNumberOfEvents Int
    | StopQueryAt position
    deriving (Show, Eq, Functor)
  
  allEvents :: key -> QueryRange key position
  allEvents key = QueryRange key StartFromBeginning NoQueryLimit
  
  eventsUntil :: key -> position -> QueryRange key position
  eventsUntil key end = QueryRange key StartFromBeginning (StopQueryAt end)
  
  eventsStartingAt :: key -> position -> QueryRange key position
  eventsStartingAt key start = QueryRange key (StartQueryAt start) NoQueryLimit
  
  eventsStartingAtUntil :: key -> position -> position -> QueryRange key position
  eventsStartingAtUntil key start end = QueryRange key (StartQueryAt start) (StopQueryAt end)
  
  eventsStartingAtTakeLimit :: key -> position -> Int -> QueryRange key position
  eventsStartingAtTakeLimit key start maxNum = QueryRange key (StartQueryAt start) (MaxNumberOfEvents maxNum)
  