-- 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.14.3

module Data.Acid.CRC
crc16 :: ByteString -> Word16


-- | Low-level controls for transaction-based state changes. This module
--   defines structures and tools for running state modifiers indexed
--   either by an Method or a serialized Method. This module should rarely
--   be used directly although the <a>Method</a> class is needed when
--   defining events manually.
--   
--   The term 'Event' is loosely used for transactions with ACID
--   guarantees. 'Method' is loosely used for state operations without ACID
--   guarantees
module Data.Acid.Core

-- | The control structure at the very center of acid-state. This module
--   provides access to a mutable state through methods. No efforts towards
--   durability, checkpointing or sharding happens at this level. Important
--   things to keep in mind in this module: * We don't distinguish between
--   updates and queries. * We allow direct access to the core state as
--   well as through events.
data Core st

-- | 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 :: Method ev => ev -> Tag

-- | Method container structure that hides the exact type of the method.
data MethodContainer st
[Method] :: Method method => (method -> State (MethodState method) (MethodResult method)) -> MethodContainer (MethodState method)
type Tagged a = (Tag, a)

-- | Construct a new Core using an initial state and a list of Methods.
mkCore :: [MethodContainer st] -> st -> IO (Core st)

-- | Mark Core as closed. Any subsequent use will throw an exception.
closeCore :: Core st -> IO ()

-- | Access the state and then mark the Core as closed. Any subsequent use
--   will throw an exception.
closeCore' :: Core st -> (st -> IO ()) -> IO ()

-- | Modify the state component. The resulting state is ensured to be in
--   WHNF.
modifyCoreState :: Core st -> (st -> IO (st, a)) -> IO a

-- | Modify the state component. The resulting state is ensured to be in
--   WHNF.
modifyCoreState_ :: Core st -> (st -> IO st) -> IO ()

-- | Access the state component.
withCoreState :: Core st -> (st -> IO a) -> IO a

-- | Find the state action that corresponds to an in-memory method.
lookupHotMethod :: Method method => MethodMap (MethodState method) -> method -> State (MethodState method) (MethodResult method)

-- | Find the state action that corresponds to a tagged and serialized
--   method.
lookupColdMethod :: Core st -> Tagged ByteString -> State st ByteString

-- | Apply an in-memory method to the state.
runHotMethod :: Method method => Core (MethodState method) -> method -> IO (MethodResult method)

-- | Execute a method as given by a type identifier and an encoded string.
--   The exact format of the encoded string depends on the type identifier.
--   Results are encoded and type tagged before they're handed back out.
--   This function is used when running events from a log-file or from
--   another server. Events that originate locally are most likely executed
--   with the faster <a>runHotMethod</a>.
runColdMethod :: Core st -> Tagged ByteString -> IO ByteString

-- | Collection of Methods indexed by a Tag.
type MethodMap st = Map Tag (MethodContainer st)

-- | Construct a <a>MethodMap</a> from a list of Methods using their
--   associated tag.
mkMethodMap :: [MethodContainer st] -> MethodMap st

module Data.Acid.Abstract

-- | 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
AcidState :: (forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))) -> (Tagged ByteString -> IO (MVar ByteString)) -> (forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)) -> (Tagged ByteString -> IO ByteString) -> IO () -> IO () -> IO () -> AnyState st -> AcidState st
[_scheduleUpdate] :: AcidState st -> forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))
[scheduleColdUpdate] :: AcidState st -> Tagged ByteString -> IO (MVar ByteString)
[_query] :: AcidState st -> forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)
[queryCold] :: AcidState st -> Tagged ByteString -> IO ByteString

-- | 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 ()

-- | 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 ()

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

-- | 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 ()

-- | 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)

-- | 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)

-- | 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)

-- | 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)
mkAnyState :: Typeable sub_st => sub_st st -> AnyState st
downcast :: (Typeable sub, Typeable st) => AcidState st -> sub st


-- | 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 :: 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] :: UpdateEvent ev => (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
[QueryEvent] :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)


-- | 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)


-- | 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] :: UpdateEvent ev => (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
[QueryEvent] :: QueryEvent ev => (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.
liftQuery :: Query st a -> Update st a

-- | Execute the <a>Update</a> monad in a pure environment.
runUpdate :: Update s r -> s -> (r, s)

-- | Execute the <a>Query</a> monad in a pure environment.
runQuery :: Query s r -> s -> r


-- | This module provides the ability perform <a>update</a> and
--   <a>query</a> calls from a remote process.
--   
--   On the server-side you:
--   
--   <ol>
--   <li>open your <a>AcidState</a> normally</li>
--   <li>then use <a>acidServer</a> to share the state</li>
--   </ol>
--   
--   On the client-side you:
--   
--   <ol>
--   <li>use <a>openRemoteState</a> to connect to the remote state</li>
--   <li>use the returned <a>AcidState</a> like any other <a>AcidState</a>
--   handle</li>
--   </ol>
--   
--   <a>openRemoteState</a> and <a>acidServer</a> communicate over an
--   unencrypted socket. If you need an encrypted connection, see
--   <tt>acid-state-tls</tt>.
--   
--   On Unix®-like systems you can use <a>UnixSocket</a> to create a socket
--   file for local communication between the client and server. Access can
--   be controlled by setting the permissions of the parent directory
--   containing the socket file.
--   
--   It is also possible to perform some simple authentication using
--   <a>sharedSecretCheck</a> and <a>sharedSecretPerform</a>. Keep in mind
--   that secrets will be sent in plain-text if you do not use
--   <tt>acid-state-tls</tt>. If you are using a <a>UnixSocket</a>
--   additional authentication may not be required, so you can use
--   <a>skipAuthenticationCheck</a> and <a>skipAuthenticationPerform</a>.
--   
--   Working with a remote <a>AcidState</a> is nearly identical to working
--   with a local <a>AcidState</a> with a few important differences.
--   
--   The connection to the remote <a>AcidState</a> can be lost. The client
--   will automatically attempt to reconnect every second. Because
--   <a>query</a> events do not affect the state, an aborted <a>query</a>
--   will be retried automatically after the server is reconnected.
--   
--   If the connection was lost during an <a>update</a> event, the event
--   will not be retried. Instead <a>RemoteConnectionError</a> will be
--   raised. This is because it is impossible for the client to know if the
--   aborted update completed on the server-side or not.
--   
--   When using a local <a>AcidState</a>, an update event in one thread
--   does not block query events taking place in other threads. With a
--   remote connection, all queries and requests are channeled over a
--   single connection. As a result, updates and queries are performed in
--   the order they are executed and do block each other. In the rare case
--   where this is an issue, you could create one remote connection per
--   thread.
--   
--   When working with local state, a query or update which returns the
--   whole state is not usually a problem due to memory sharing. The
--   update/query event basically just needs to return a pointer to the
--   data already in memory. But, when working remotely, the entire result
--   will be serialized and sent to the remote client. Hence, it is good
--   practice to create queries and updates that will only return the
--   required data.
--   
--   This module is designed to be extenible. You can easily add your own
--   authentication methods by creating a suitable pair of functions and
--   passing them to <a>acidServer</a> and <a>openRemoteState</a>.
--   
--   It is also possible to create alternative communication layers using
--   <a>CommChannel</a>, <a>process</a>, and <a>processRemoteState</a>.
module Data.Acid.Remote

-- | Accept connections on <tt>port</tt> and handle requests using the
--   given <a>AcidState</a>. This call doesn't return.
--   
--   On Unix®-like systems you can use <a>UnixSocket</a> to communicate
--   using a socket file. To control access, you can set the permissions of
--   the parent directory which contains the socket file.
--   
--   see also: <a>openRemoteState</a> and <a>sharedSecretCheck</a>.
acidServer :: SafeCopy st => (CommChannel -> IO Bool) -> PortID -> AcidState st -> IO ()

-- | Works the same way as <a>acidServer</a>, but uses pre-binded socket
--   <tt>listenSocket</tt>.
--   
--   Can be useful when fine-tuning of socket binding parameters is needed
--   (for example, listening on a particular network interface, IPv4/IPv6
--   options).
acidServer' :: SafeCopy st => (CommChannel -> IO Bool) -> Socket -> AcidState st -> IO ()

-- | Connect to an acid-state server which is sharing an <a>AcidState</a>.
openRemoteState :: IsAcidic st => (CommChannel -> IO ()) -> HostName -> PortID -> IO (AcidState st)

-- | skip server-side authentication checking entirely.
skipAuthenticationCheck :: CommChannel -> IO Bool

-- | skip client-side authentication entirely.
skipAuthenticationPerform :: CommChannel -> IO ()

-- | check that the client knows a shared secret.
--   
--   The function takes a <a>Set</a> of shared secrets. If a client knows
--   any of them, it is considered to be trusted.
--   
--   The shared secret is any <tt>ByteString</tt> of your choice.
--   
--   If you give each client a different shared secret then you can revoke
--   access individually.
--   
--   see also: <a>sharedSecretPerform</a>
sharedSecretCheck :: Set ByteString -> CommChannel -> IO Bool

-- | attempt to authenticate with the server using a shared secret.
sharedSecretPerform :: ByteString -> CommChannel -> IO ()
data AcidRemoteException
RemoteConnectionError :: AcidRemoteException
AcidStateClosed :: AcidRemoteException
SerializeError :: String -> AcidRemoteException
AuthenticationError :: String -> AcidRemoteException

-- | <a>CommChannel</a> is a record containing the IO functions we need for
--   communication between the server and client.
--   
--   We abstract this out of the core processing function so that we can
--   easily add support for SSL/TLS and Unit testing.
data CommChannel
CommChannel :: (ByteString -> IO ()) -> (Int -> IO ByteString) -> IO () -> CommChannel
[ccPut] :: CommChannel -> ByteString -> IO ()
[ccGetSome] :: CommChannel -> Int -> IO ByteString
[ccClose] :: CommChannel -> IO ()

-- | Server inner-loop
--   
--   This function is generally only needed if you are adding a new
--   communication channel.
process :: SafeCopy st => CommChannel -> AcidState st -> IO ()

-- | Client inner-loop
--   
--   This function is generally only needed if you are adding a new
--   communication channel.
processRemoteState :: IsAcidic st => IO CommChannel -> IO (AcidState st)
instance GHC.Show.Show Data.Acid.Remote.AcidRemoteException
instance GHC.Classes.Eq Data.Acid.Remote.AcidRemoteException
instance Data.Serialize.Serialize Data.Acid.Remote.Response
instance Data.Serialize.Serialize Data.Acid.Remote.Command
instance GHC.Exception.Type.Exception Data.Acid.Remote.AcidRemoteException

module Data.Acid.Log
data FileLog object
FileLog :: LogKey object -> MVar FHandle -> TVar EntryId -> TVar ([ByteString], [IO ()]) -> [ThreadId] -> FileLog object
[logIdentifier] :: FileLog object -> LogKey object
[logCurrent] :: FileLog object -> MVar FHandle
[logNextEntryId] :: FileLog object -> TVar EntryId
[logQueue] :: FileLog object -> TVar ([ByteString], [IO ()])
[logThreads] :: FileLog object -> [ThreadId]
data LogKey object
LogKey :: FilePath -> String -> LogKey object
[logDirectory] :: LogKey object -> FilePath
[logPrefix] :: LogKey object -> String
type EntryId = Int
openFileLog :: LogKey object -> IO (FileLog object)
closeFileLog :: FileLog object -> IO ()
pushEntry :: SafeCopy object => FileLog object -> object -> IO () -> IO ()
pushAction :: FileLog object -> IO () -> IO ()
ensureLeastEntryId :: FileLog object -> EntryId -> IO ()
readEntriesFrom :: SafeCopy object => FileLog object -> EntryId -> IO [object]
rollbackTo :: SafeCopy object => LogKey object -> EntryId -> IO ()
rollbackWhile :: SafeCopy object => LogKey object -> (object -> Bool) -> IO ()
newestEntry :: SafeCopy object => LogKey object -> IO (Maybe object)
askCurrentEntryId :: FileLog object -> IO EntryId
cutFileLog :: FileLog object -> IO EntryId
archiveFileLog :: FileLog object -> EntryId -> IO ()


-- | 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))

-- | Same as scheduleLocalUpdate but does not immediately change the
--   localCopy and return the result mvar - returns an IO action to do this
--   instead. Take care to run actions of multiple Updates in the correct
--   order as otherwise Queries will operate on outdated state.
scheduleLocalUpdate' :: UpdateEvent event => LocalState (EventState event) -> event -> MVar (EventResult event) -> IO (IO ())

-- | Same as scheduleLocalColdUpdate but does not immediately change the
--   localCopy and return the result mvar - returns an IO action to do this
--   instead. Take care to run actions of multiple Updates in the correct
--   order as otherwise Queries will operate on outdated state.
scheduleLocalColdUpdate' :: LocalState st -> Tagged ByteString -> MVar ByteString -> IO (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, Typeable st) => AcidState st -> IO ()

-- | 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 LocalState st
LocalState :: Core st -> IORef st -> FileLog (Tagged ByteString) -> FileLog Checkpoint -> PrefixLock -> LocalState st
[localCore] :: LocalState st -> Core st
[localCopy] :: LocalState st -> IORef st
[localEvents] :: LocalState st -> FileLog (Tagged ByteString)
[localCheckpoints] :: LocalState st -> FileLog Checkpoint
[localLock] :: LocalState st -> PrefixLock
data Checkpoint
Checkpoint :: EntryId -> ByteString -> Checkpoint
instance Data.SafeCopy.SafeCopy.SafeCopy Data.Acid.Local.Checkpoint


-- | AcidState container using a transaction log on disk.
--   
--   To see how it all fits together, have a look at these example
--   <a>https://github.com/acid-state/acid-state/tree/master/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 ()

-- | 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 ()

-- | 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.
liftQuery :: Query st a -> Update st a
