-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Add ACID guarantees to any serializable Haskell data structure.
--   
--   Use regular Haskell data structures as your database and get stronger
--   ACID guarantees than most RDBMS offer.
@package acid-state
@version 0.8.1


-- | AcidState container without a transaction log. Mostly used for
--   testing.
module Data.Acid.Memory

-- | Create an AcidState given an initial value.
openMemoryState :: IsAcidic st => st -> IO (AcidState st)
instance Typeable1 MemoryState


-- | AcidState container without a transaction log. Mostly used for
--   testing.
module Data.Acid.Memory.Pure
class SafeCopy st => IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   <ul>
--   <li><i><tt>Atomicity</tt></i> State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.</li>
--   <li><i><tt>Consistency</tt></i> No event or set of events will break
--   your data invariants.</li>
--   <li><i><tt>Isolation</tt></i> Transactions cannot interfere with each
--   other even when issued in parallel.</li>
--   <li><i><tt>Durability</tt></i> Successful transaction are guaranteed
--   to survive system failure (both hardware and software).</li>
--   </ul>
data AcidState st

-- | We distinguish between events that modify the state and those that do
--   not.
--   
--   UpdateEvents are executed in a MonadState context and have to be
--   serialized to disk before they are considered durable.
--   
--   QueryEvents are executed in a MonadReader context and obviously do not
--   have to be serialized to disk.
data Event st
UpdateEvent :: (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
QueryEvent :: (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)

-- | Events return the same thing as Methods. The exact type of
--   <a>EventResult</a> depends on the event.
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev

-- | All UpdateEvents are also Methods.
class Method ev => UpdateEvent ev

-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev

-- | Context monad for Update events.
data Update st a

-- | Context monad for Query events.
data Query st a

-- | Create an AcidState given an initial value.
openAcidState :: IsAcidic st => st -> AcidState st

-- | Issue an Update event and wait for its result. Once this call returns,
--   you are guaranteed that the changes to the state are durable. Events
--   may be issued in parallel.
--   
--   It's a run-time error to issue events that aren't supported by the
--   AcidState.
update :: UpdateEvent event => AcidState (EventState event) -> event -> (AcidState (EventState event), EventResult event)

-- | Same as <a>update</a> but ignoring the event result.
update_ :: UpdateEvent event => AcidState (EventState event) -> event -> AcidState (EventState event)

-- | Issue a Query event and wait for its result.
query :: QueryEvent event => AcidState (EventState event) -> event -> EventResult event

-- | Run a query in the Update Monad.
runQuery :: Query st a -> Update st a


-- | Network backend.
module Data.Acid.Remote

-- | Accept connections on <tt>port</tt> and serve requests using the given
--   <a>AcidState</a>. This call doesn't return.
acidServer :: SafeCopy st => AcidState st -> PortID -> IO ()

-- | Connect to a remotely running <a>AcidState</a>.
openRemoteState :: IsAcidic st => HostName -> PortID -> IO (AcidState st)
instance Typeable1 RemoteState
instance Serialize Response
instance Serialize Command


-- | Home of the more specialized functions.
module Data.Acid.Advanced

-- | Issue an Update event and return immediately. The event is not durable
--   before the MVar has been filled but the order of events is honored.
--   The behavior in case of exceptions is exactly the same as for
--   <a>update</a>.
--   
--   If EventA is scheduled before EventB, EventA <i>will</i> be executed
--   before EventB:
--   
--   <pre>
--   do scheduleUpdate acid EventA
--      scheduleUpdate acid EventB
--   </pre>
scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))

-- | Schedule multiple Update events and wait for them to be durable, but
--   throw away their results. This is useful for importing existing
--   datasets into an AcidState.
groupUpdates :: UpdateEvent event => AcidState (EventState event) -> [event] -> IO ()

-- | Same as <a>update</a> but lifted into any monad capable of doing IO.
update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | Same as <a>query</a> but lifted into any monad capable of doing IO.
query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | The basic Method class. Each Method has an indexed result type and a
--   unique tag.
class (Typeable ev, SafeCopy ev, Typeable (MethodResult ev), SafeCopy (MethodResult ev)) => Method ev where type family MethodResult ev type family MethodState ev methodTag ev = pack (showQualifiedTypeRep (typeOf ev))
methodTag :: Method ev => ev -> Tag
class SafeCopy st => IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | We distinguish between events that modify the state and those that do
--   not.
--   
--   UpdateEvents are executed in a MonadState context and have to be
--   serialized to disk before they are considered durable.
--   
--   QueryEvents are executed in a MonadReader context and obviously do not
--   have to be serialized to disk.
data Event st
UpdateEvent :: (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
QueryEvent :: (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)


-- | AcidState container using a transaction log on disk. The term 'Event'
--   is loosely used for transactions with ACID guarantees. 'Method' is
--   loosely used for state operations without ACID guarantees (see
--   <a>Data.Acid.Core</a>).
module Data.Acid.Local

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory.
openLocalState :: (Typeable st, IsAcidic st) => st -> IO (AcidState st)

-- | Create an AcidState given a log directory and an initial value.
--   
--   This will create or resume a log found in <tt>directory</tt>. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: IsAcidic st => FilePath -> st -> IO (AcidState st)

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory. The most recent checkpoint will be loaded immediately but
--   the AcidState will not be opened until the returned function is
--   executed.
prepareLocalState :: (Typeable st, IsAcidic st) => st -> IO (IO (AcidState st))

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in <tt>directory</tt>. The most
--   recent checkpoint will be loaded immediately but the AcidState will
--   not be opened until the returned function is executed.
prepareLocalStateFrom :: IsAcidic st => FilePath -> st -> IO (IO (AcidState st))

-- | Move all log files that are no longer necessary for state restoration
--   into the <tt>Archive</tt> folder in the state directory. This folder
--   can then be backed up or thrown out as you see fit. Reverting to a
--   state before the last checkpoint will not be possible if the
--   <tt>Archive</tt> folder has been thrown out.
--   
--   This method is idempotent and does not block the normal operation of
--   the AcidState.
createArchive :: AcidState st -> IO ()

-- | Save a snapshot to disk and close the AcidState as a single atomic
--   action. This is useful when you want to make sure that no events are
--   saved to disk after a checkpoint.
createCheckpointAndClose :: SafeCopy st => AcidState st -> IO ()
instance Typeable1 LocalState
instance SafeCopy Checkpoint


-- | AcidState container using a transaction log on disk.
--   
--   To see how it all fits together, have a look at these example
--   <a>http://mirror.seize.it/acid-state/examples/</a>.
module Data.Acid

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   <ul>
--   <li><i><tt>Atomicity</tt></i> State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.</li>
--   <li><i><tt>Consistency</tt></i> No event or set of events will break
--   your data invariants.</li>
--   <li><i><tt>Isolation</tt></i> Transactions cannot interfere with each
--   other even when issued in parallel.</li>
--   <li><i><tt>Durability</tt></i> Successful transaction are guaranteed
--   to survive unexpected system shutdowns (both those caused by hardware
--   and software).</li>
--   </ul>
data AcidState st

-- | Create an AcidState given an initial value.
--   
--   This will create or resume a log found in the "state/[typeOf state]/"
--   directory.
openLocalState :: (Typeable st, IsAcidic st) => st -> IO (AcidState st)

-- | Create an AcidState given a log directory and an initial value.
--   
--   This will create or resume a log found in <tt>directory</tt>. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: IsAcidic st => FilePath -> st -> IO (AcidState st)

-- | Close an AcidState and associated resources. Any subsequent usage of
--   the AcidState will throw an exception.
closeAcidState :: AcidState st -> IO ()

-- | Take a snapshot of the state and save it to disk. Creating checkpoints
--   makes it faster to resume AcidStates and you're free to create them as
--   often or seldom as fits your needs. Transactions can run concurrently
--   with this call.
--   
--   This call will not return until the operation has succeeded.
createCheckpoint :: AcidState st -> IO ()

-- | Issue an Update event and wait for its result. Once this call returns,
--   you are guaranteed that the changes to the state are durable. Events
--   may be issued in parallel.
--   
--   It's a run-time error to issue events that aren't supported by the
--   AcidState.
update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Issue a Query event and wait for its result. Events may be issued in
--   parallel.
query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)

-- | Events return the same thing as Methods. The exact type of
--   <a>EventResult</a> depends on the event.
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev

-- | All UpdateEvents are also Methods.
class Method ev => UpdateEvent ev

-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev

-- | Context monad for Update events.
data Update st a

-- | Context monad for Query events.
data Query st a
class SafeCopy st => IsAcidic st

-- | Create the control structures required for acid states using Template
--   Haskell.
--   
--   This code:
--   
--   <pre>
--   myUpdate :: Argument -&gt; Update State Result
--   myUpdate arg = ...
--   
--   myQuery :: Argument -&gt; Query State Result
--   myQuery arg = ...
--   
--   $(makeAcidic ''State ['myUpdate, 'myQuery])
--   </pre>
--   
--   will make <tt>State</tt> an instance of <a>IsAcidic</a> and provide
--   the following events:
--   
--   <pre>
--   data MyUpdate = MyUpdate Argument
--   data MyQuery  = MyQuery Argument
--   </pre>
makeAcidic :: Name -> [Name] -> Q [Dec]

-- | Run a query in the Update Monad.
runQuery :: Query st a -> Update st a
