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

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

module Data.Acid.Archive

-- | A bytestring that represents an entry in an archive.
type Entry = ByteString

-- | Result of unpacking an archive. This is essentially a list of
--   Entry, but may terminate in Fail if the archive format
--   is incorrect.
data Entries
Done :: Entries
Next :: Entry -> Entries -> Entries
Fail :: String -> Entries
putEntries :: [Entry] -> Builder
packEntries :: [Entry] -> ByteString
readEntries :: ByteString -> Entries

-- | Convert Entries to a normal list, calling error if there
--   was a failure in unpacking the archive.
entriesToList :: Entries -> [Entry]

-- | Convert Entries to a normal list, silently ignoring a failure
--   to unpack the archive and instead returning a truncated list.
entriesToListNoFail :: Entries -> [Entry]

-- | Interface for the lowest level of the serialisation layer, which
--   handles packing lists of Entry elements (essentially just
--   bytestrings) into a single bytestring, perhaps with error-checking.
--   
--   Any Archiver{archiveWrite, archiveRead}
--   must satisfy the round-trip property:
--   
--   
--   forall xs . entriesToList (archiveRead (archiveWrite xs)) == xs
--   
--   
--   Moreover, archiveWrite must be a monoid homomorphism, so that
--   concatenating archives is equivalent to concatenating the lists of
--   entries that they represent:
--   
--   
--   archiveWrite [] == empty
--   forall xs ys . archiveWrite xs <> archiveWrite ys == archiveWrite (xs ++ ys)
--   
data Archiver
Archiver :: ([Entry] -> ByteString) -> (ByteString -> Entries) -> Archiver

-- | Pack a list of entries into a bytestring.
[archiveWrite] :: Archiver -> [Entry] -> ByteString

-- | Unpack a bytestring as a list of Entries, including the
--   possibility of failure if the format is invalid.
[archiveRead] :: Archiver -> ByteString -> Entries

-- | Standard (and historically the only) implementation of the
--   Archiver interface. This represents each entry in the following
--   format:
--   
--   
--   | entry length | crc16   | entry   |
--   | 8 bytes      | 2 bytes | n bytes |
--   
defaultArchiver :: Archiver
instance GHC.Show.Show Data.Acid.Archive.Entries

-- | 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 Method 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 Method ev where {
    type family MethodResult ev;
    type family MethodState ev;
}
methodTag :: Method ev => ev -> Tag
methodTag :: (Method ev, Typeable ev) => ev -> Tag

-- | Method container structure that hides the exact type of the method.
data MethodContainer st
[Method] :: Method method => MethodBody method -> MethodSerialiser 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 and serialiser that correspond to an in-memory
--   method.
lookupHotMethodAndSerialiser :: Method method => MethodMap (MethodState method) -> method -> (State (MethodState method) (MethodResult method), MethodSerialiser 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 runHotMethod.
runColdMethod :: Core st -> Tagged ByteString -> IO ByteString

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

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

-- | Interface for (de)serialising values of type a.
--   
--   A Serialiser { serialiserEncode,
--   serialiserDecode } must satisfy the round-trip property:
--   
--   
--   forall x . serialiserDecode (serialiserEncode x) == Right x
--   
data Serialiser a
Serialiser :: (a -> ByteString) -> (ByteString -> Either String a) -> Serialiser a

-- | Serialise a value to a bytestring.
[serialiserEncode] :: Serialiser a -> a -> ByteString

-- | Deserialise a value, generating a string error message on failure.
[serialiserDecode] :: Serialiser a -> ByteString -> Either String a

-- | Default implementation of Serialiser interface using
--   SafeCopy.
safeCopySerialiser :: SafeCopy a => Serialiser a

-- | Interface for (de)serialising a method, namely Serialisers for
--   its arguments type and its result type.
data MethodSerialiser method
MethodSerialiser :: Serialiser method -> Serialiser (MethodResult method) -> MethodSerialiser method
[methodSerialiser] :: MethodSerialiser method -> Serialiser method
[resultSerialiser] :: MethodSerialiser method -> Serialiser (MethodResult method)

-- | Default implementation of MethodSerialiser interface using
--   SafeCopy.
safeCopyMethodSerialiser :: (SafeCopy method, SafeCopy (MethodResult method)) => MethodSerialiser method

-- | Encode the arguments of a method using the given serialisation
--   strategy.
encodeMethod :: MethodSerialiser method -> method -> ByteString

-- | Decode the arguments of a method using the given serialisation
--   strategy.
decodeMethod :: MethodSerialiser method -> ByteString -> Either String method

-- | Encode the result of a method using the given serialisation strategy.
encodeResult :: MethodSerialiser method -> MethodResult method -> ByteString

-- | Decode the result of a method using the given serialisation strategy.
decodeResult :: MethodSerialiser method -> ByteString -> Either String (MethodResult method)

-- | Common structures used by the various backends (local, memory).
module Data.Acid.Common
class IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | Context monad for Update events.
newtype Update st a
Update :: State st a -> Update st a
[unUpdate] :: Update st a -> State st a

-- | Context monad for Query events.
newtype Query st a
Query :: Reader st a -> Query st a
[unQuery] :: Query st a -> Reader st a

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

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

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

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

-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev
eventsToMethods :: [Event st] -> [MethodContainer st]
instance Control.Monad.Reader.Class.MonadReader st (Data.Acid.Common.Query st)
instance GHC.Base.Functor (Data.Acid.Common.Query st)
instance GHC.Base.Monad (Data.Acid.Common.Query st)
instance Control.Monad.State.Class.MonadState st (Data.Acid.Common.Update st)
instance GHC.Base.Functor (Data.Acid.Common.Update st)
instance GHC.Base.Monad (Data.Acid.Common.Update st)
instance GHC.Base.Applicative (Data.Acid.Common.Query st)
instance GHC.Base.Applicative (Data.Acid.Common.Update st)

module Data.Acid.Abstract

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive unexpected system shutdowns (both those caused by hardware
--   and software).
--   
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 Archive 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
--   Archive 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
--   update.
--   
--   If EventA is scheduled before EventB, EventA will be executed
--   before EventB:
--   
--   
--   do scheduleUpdate acid EventA
--      scheduleUpdate acid EventB
--      
--   
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 update 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 query 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
--   update.
--   
--   If EventA is scheduled before EventB, EventA will be executed
--   before EventB:
--   
--   
--   do scheduleUpdate acid EventA
--      scheduleUpdate acid EventB
--      
--   
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 update but lifted into any monad capable of doing IO.
update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)

-- | Same as query 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 Method ev where {
    type family MethodResult ev;
    type family MethodState ev;
}
methodTag :: Method ev => ev -> Tag
methodTag :: (Method ev, Typeable ev) => ev -> Tag
class 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)) -> MethodSerialiser ev -> Event (EventState ev)
[QueryEvent] :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> MethodSerialiser ev -> Event (EventState ev)

-- | Default implementation of Serialiser interface using
--   SafeCopy.
safeCopySerialiser :: SafeCopy a => Serialiser a

-- | Default implementation of MethodSerialiser interface using
--   SafeCopy.
safeCopyMethodSerialiser :: (SafeCopy method, SafeCopy (MethodResult method)) => MethodSerialiser method

-- | Standard (and historically the only) implementation of the
--   Archiver interface. This represents each entry in the following
--   format:
--   
--   
--   | entry length | crc16   | entry   |
--   | 8 bytes      | 2 bytes | n bytes |
--   
defaultArchiver :: Archiver

-- | 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 IsAcidic st
acidEvents :: IsAcidic st => [Event st]

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive system failure (both hardware and software).
--   
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)) -> MethodSerialiser ev -> Event (EventState ev)
[QueryEvent] :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> MethodSerialiser ev -> Event (EventState ev)

-- | Events return the same thing as Methods. The exact type of
--   EventResult 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 update 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 Update monad in a pure environment.
runUpdate :: Update s r -> s -> (r, s)

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

-- | This module provides the ability perform update and
--   query calls from a remote process.
--   
--   On the server-side you:
--   
--   
--   
- open your AcidState normally
--   
- then use acidServer to share the state
--   
--   
--   On the client-side you:
--   
--   
--   
- use openRemoteState to connect to the remote state
--   
- use the returned AcidState like any other AcidState
--   handle
--   
--   
--   openRemoteState and acidServer communicate over an
--   unencrypted socket. If you need an encrypted connection, see
--   acid-state-tls.
--   
--   On Unix®-like systems you can use SockAddrUnix 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
--   sharedSecretCheck and sharedSecretPerform. Keep in mind
--   that secrets will be sent in plain-text if you do not use
--   acid-state-tls. If you are using a SockAddrUnix
--   additional authentication may not be required, so you can use
--   skipAuthenticationCheck and skipAuthenticationPerform.
--   
--   Working with a remote AcidState is nearly identical to working
--   with a local AcidState with a few important differences.
--   
--   The connection to the remote AcidState can be lost. The client
--   will automatically attempt to reconnect every second. Because
--   query events do not affect the state, an aborted query
--   will be retried automatically after the server is reconnected.
--   
--   If the connection was lost during an update event, the event
--   will not be retried. Instead RemoteConnectionError 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 AcidState, 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 acidServer and openRemoteState.
--   
--   It is also possible to create alternative communication layers using
--   CommChannel, process, and processRemoteState.
module Data.Acid.Remote

-- | Accept connections on port and handle requests using the
--   given AcidState. This call doesn't return.
--   
--   see also: acidServerSockAddr, openRemoteState and
--   sharedSecretCheck.
acidServer :: (CommChannel -> IO Bool) -> PortNumber -> AcidState st -> IO ()

-- | Accept connections on sockAddr and handle requests using the
--   given AcidState. This call doesn't return.
--   
--   see also: acidServer, openRemoteState and
--   sharedSecretCheck.
acidServerSockAddr :: (CommChannel -> IO Bool) -> SockAddr -> AcidState st -> IO ()

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

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

-- | Connect to an acid-state server which is sharing an AcidState.
openRemoteStateSockAddr :: IsAcidic st => (CommChannel -> IO ()) -> SockAddr -> 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 Set of shared secrets. If a client knows
--   any of them, it is considered to be trusted.
--   
--   The shared secret is any ByteString of your choice.
--   
--   If you give each client a different shared secret then you can revoke
--   access individually.
--   
--   see also: sharedSecretPerform
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

-- | CommChannel 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 :: 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.TemplateHaskell

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

-- | Specifies how to customise the IsAcidic instance and event data
--   type serialisation instances for a particular serialisation layer.
data SerialiserSpec
SerialiserSpec :: Name -> Name -> (Name -> Type -> DecQ) -> SerialiserSpec

-- | Class for serialisable types, e.g. ''Safecopy.
[serialisationClassName] :: SerialiserSpec -> Name

-- | Name of the MethodSerialiser to use in the list of events in
--   the IsAcidic instance.
[methodSerialiserName] :: SerialiserSpec -> Name

-- | Function to generate an instance of the class named by
--   serialisationClassName, given the event name and its type.
[makeEventSerialiser] :: SerialiserSpec -> Name -> Type -> DecQ

-- | Default implementation of SerialiserSpec that uses
--   SafeCopy for serialising events.
safeCopySerialiserSpec :: SerialiserSpec

-- | A variant on makeAcidic that makes it possible to explicitly
--   choose the serialisation implementation to be used for methods.
makeAcidicWithSerialiser :: SerialiserSpec -> Name -> [Name] -> Q [Dec]
makeAcidic' :: SerialiserSpec -> [Name] -> Name -> [TyVarBndr] -> [Con] -> Q [Dec]

-- | Given an event name (e.g. 'myUpdate), produce a data type
--   like
--   
--   
--   data MyUpdate = MyUpdate Argument
--   
--   
--   along with the Method class instance, Event class
--   instance and the instance of the appropriate serialisation class.
--   
--   However, if the event data type already exists, this will generate the
--   serialisation instance only. This makes it possible to call
--   makeAcidicWithSerialiser multiple times on the same events but
--   with different SerialiserSpecs, to support multiple
--   serialisation backends.
makeEvent :: SerialiserSpec -> Name -> Q [Dec]
getEventType :: Name -> Q Type
makeIsAcidic :: SerialiserSpec -> [Name] -> Name -> [TyVarBndr] -> p -> Q Dec

-- | This function analyses an event function and extracts any additional
--   class contexts which need to be added to the IsAcidic instance.
--   
--   For example, if we have:
--   
--   
--   data State a = ...
--   
--   
--   
--   setState :: (Ord a) => a -> UpdateEvent (State a) ()
--   
--   
--   Then we need to generate an IsAcidic instance like:
--   
--   
--   instance (SafeCopy a, Typeable a, Ord a) => IsAcidic (State a)
--   
--   
--   Note that we can only add constraints for type variables which appear
--   in the State type. If we tried to do this:
--   
--   
--   setState :: (Ord a, Ord b) => a -> b -> UpdateEvent (State a) ()
--   
--   
--   We will get an ambigious type variable when trying to create the
--   IsAcidic instance, because there is no way to figure out what
--   type b should be.
--   
--   The tricky part of this code is that we need to unify the type
--   variables.
--   
--   Let's say the user writes their code using b instead of
--   a:
--   
--   
--   setState :: (Ord b) => b -> UpdateEvent (State b) ()
--   
--   
--   In the IsAcidic instance, we are still going to use a.
--   So we need to rename the variables in the context to match.
--   
--   The contexts returned by this function will have the variables
--   renamed.
--   
--   Additionally, if the event uses MonadReader or MonadState it might
--   look like this:
--   
--   
--   setState :: (MonadState x m, IsFoo x) => m ()
--   
--   
--   In this case we have to rename x to the actual state we're
--   going to use. This is done by renameState.
eventCxts :: Type -> [TyVarBndr] -> Name -> Type -> [Pred]

-- | See the end of comment for eventCxts.
renameState :: Type -> Type -> Cxt -> Cxt
makeEventHandler :: SerialiserSpec -> Name -> Type -> ExpQ
makeEventDataType :: Name -> Type -> DecQ
makeSafeCopyInstance :: Name -> Type -> DecQ
mkCxtFromTyVars :: [Name] -> [TyVarBndr] -> [Pred] -> CxtQ
makeMethodInstance :: Name -> Type -> DecQ
makeEventInstance :: Name -> Type -> DecQ
data TypeAnalysis
TypeAnalysis :: [TyVarBndr] -> Cxt -> [Type] -> Type -> Type -> Bool -> TypeAnalysis
[tyvars] :: TypeAnalysis -> [TyVarBndr]
[context] :: TypeAnalysis -> Cxt
[argumentTypes] :: TypeAnalysis -> [Type]
[stateType] :: TypeAnalysis -> Type
[resultType] :: TypeAnalysis -> Type
[isUpdate] :: TypeAnalysis -> Bool
analyseType :: Name -> Type -> TypeAnalysis

-- | find the type variables | e.g. State a b ==> [a,b]
findTyVars :: Type -> [Name]

-- | extract the Name from a TyVarBndr
tyVarBndrName :: TyVarBndr -> Name
allTyVarBndrNames :: [TyVarBndr] -> [Name]

-- | Convert the Name of the event function into the name of the
--   corresponding data constructor.
toStructName :: Name -> Name
instance GHC.Show.Show Data.Acid.TemplateHaskell.TypeAnalysis
instance GHC.Classes.Eq Data.Acid.TemplateHaskell.TypeAnalysis

-- | A log is a stack of entries that supports efficient pushing of new
--   entries and fetching of old. It can be considered an extendible array
--   of entries.
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 -> Serialiser object -> Archiver -> LogKey object
[logDirectory] :: LogKey object -> FilePath
[logPrefix] :: LogKey object -> String
[logSerialiser] :: LogKey object -> Serialiser object
[logArchiver] :: LogKey object -> Archiver
type EntryId = Int
openFileLog :: LogKey object -> IO (FileLog object)
closeFileLog :: FileLog object -> IO ()

-- | Schedule a new log entry. This call does not block. The given IO
--   action runs once the object is durable. The IO action blocks the
--   serialization of events so it should be swift.
pushEntry :: FileLog object -> object -> IO () -> IO ()

-- | The given IO action is executed once all previous entries are durable.
pushAction :: FileLog object -> IO () -> IO ()
ensureLeastEntryId :: FileLog object -> EntryId -> IO ()

-- | Read all durable entries younger than the given EntryId. Note
--   that entries written during or after this call won't be included in
--   the returned list.
readEntriesFrom :: FileLog object -> EntryId -> IO [object]

-- | Obliterate log entries younger than or equal to the EntryId.
--   Very unsafe, can't be undone
rollbackTo :: LogKey object -> EntryId -> IO ()

-- | Obliterate log entries as long as the filter function returns
--   True.
rollbackWhile :: LogKey object -> (object -> Bool) -> IO ()

-- | Finds the newest entry in the log. Doesn't work on open logs. Do not
--   use after the log has been opened.
--   
--   Implementation:
--   
--   
--   
- Search the newest log files first.
--   
- Once a file containing at least one valid entry is found, return
--   the last entry in that file.
--   
newestEntry :: LogKey object -> IO (Maybe object)
askCurrentEntryId :: FileLog object -> IO EntryId
cutFileLog :: FileLog object -> IO EntryId

-- | Move all log files that do not contain entries equal or higher than
--   the given entryId into an Archive/ directory.
archiveFileLog :: FileLog object -> EntryId -> IO ()
findLogFiles :: LogKey object -> IO [(EntryId, FilePath)]

-- | 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
--   Data.Acid.Core).
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, SafeCopy 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 directory. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: (IsAcidic st, SafeCopy st) => FilePath -> st -> IO (AcidState st)

-- | Create an AcidState given a log directory, an initial value and a
--   serialisation layer.
--   
--   This will create or resume a log found in directory. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateWithSerialiser :: IsAcidic st => FilePath -> st -> SerialisationLayer 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, SafeCopy st) => st -> IO (IO (AcidState st))

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

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

-- | Directory to load the state from unless otherwise specified, namely
--   "state/[typeOf state]/".
defaultStateDirectory :: Typeable st => st -> FilePath

-- | 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 :: (IsAcidic st, Typeable st) => AcidState st -> IO ()

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive system failure (both hardware and software).
--   
data LocalState st
LocalState :: Core st -> IORef st -> FileLog (Tagged ByteString) -> FileLog (Checkpoint st) -> FileLock -> LocalState st
[localCore] :: LocalState st -> Core st
[localCopy] :: LocalState st -> IORef st
[localEvents] :: LocalState st -> FileLog (Tagged ByteString)
[localCheckpoints] :: LocalState st -> FileLog (Checkpoint st)
[localLock] :: LocalState st -> FileLock
data Checkpoint s
Checkpoint :: EntryId -> s -> Checkpoint s
data SerialisationLayer st
SerialisationLayer :: Serialiser (Checkpoint st) -> Serialiser (Tagged ByteString) -> Archiver -> SerialisationLayer st

-- | Serialisation strategy for checkpoints.
--   
--   Use safeCopySerialiser for the backwards-compatible
--   implementation using Data.SafeCopy.
[checkpointSerialiser] :: SerialisationLayer st -> Serialiser (Checkpoint st)

-- | Serialisation strategy for events.
--   
--   Use safeCopySerialiser for the backwards-compatible
--   implementation using Data.SafeCopy.
[eventSerialiser] :: SerialisationLayer st -> Serialiser (Tagged ByteString)

-- | Serialisation strategy for archive log files.
--   
--   Use defaultArchiver for the backwards-compatible implementation
--   using Data.Serialize.
[archiver] :: SerialisationLayer st -> Archiver

-- | Standard (and historically the only) serialisation layer, using
--   safeCopySerialiser and defaultArchiver.
defaultSerialisationLayer :: SafeCopy st => SerialisationLayer st
mkEventsLogKey :: FilePath -> SerialisationLayer object -> LogKey (Tagged ByteString)
mkCheckpointsLogKey :: FilePath -> SerialisationLayer object -> LogKey (Checkpoint object)
instance GHC.Show.Show Data.Acid.Local.StateIsLocked
instance Data.SafeCopy.SafeCopy.SafeCopy s => Data.SafeCopy.SafeCopy.SafeCopy (Data.Acid.Local.Checkpoint s)
instance GHC.Exception.Type.Exception Data.Acid.Local.StateIsLocked

module Data.Acid.Repair

-- | repairFile path will truncate the entries in
--   file until there are only valid entries (if a corrupted entry
--   is found, then the rest of the file is truncated).
--   
--   The old file will be copied to path.bak (or
--   path.bak.1, etc… if the file already exists).
--   
--   repairFile tries very hard to avoid leaving files in an
--   inconsistent state: the truncated file is written in a temporary file,
--   which is then moved into place, similarly copies are performed with
--   moves instead. Still this is not fully atomic: there are two
--   consecutive moves, so repairFile may, in case of crash, yield a
--   state where the path.bak file is there but no path
--   is there anymore, this would require manual intervention.
repairFile :: FilePath -> IO ()

-- | Repairs the WAL files with the following strategy:
--   
--   
--   
- Let f be the oldest corrupted file.
--   
- All files older than f is left untouched
--   
- f is repaired with repairFile
--   
- Old files younger than f is dropped (and saved to
--   `path.bak`, or `path.bak.1`, etc…)
--   
--   
--   In other words, all the log entries after the first corrupted entry is
--   dropped. The reasoning is that newer entries are likely not to make
--   sense after some entries have been removed from the log. This strategy
--   guarantees a consistent state, albeit a potentially old one.
repairEvents :: FilePath -> IO ()

-- | Repairs the checkpoints file using the following strategy:
--   
--   
--   
- Every checkpoints file is repaired with repairFile
--   
--   
--   Checkpoints are mostly independent. Contrary to repairEvents,
--   dropping a checkpoint doesn't affect the consistency of later
--   checkpoints.
repairCheckpoints :: FilePath -> IO ()

-- | AcidState container using a transaction log on disk.
--   
--   To see how it all fits together, have a look at these example
--   https://github.com/acid-state/acid-state/tree/master/examples.
module Data.Acid

-- | State container offering full ACID (Atomicity, Consistency, Isolation
--   and Durability) guarantees.
--   
--   
--   
- Atomicity State changes are all-or-nothing. This
--   is what you'd expect of any state variable in Haskell and AcidState
--   doesn't change that.
--   
- Consistency No event or set of events will break
--   your data invariants.
--   
- Isolation Transactions cannot interfere with each
--   other even when issued in parallel.
--   
- Durability Successful transaction are guaranteed
--   to survive unexpected system shutdowns (both those caused by hardware
--   and software).
--   
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, SafeCopy 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 directory. Running
--   two AcidState's from the same directory is an error but will not
--   result in dataloss.
openLocalStateFrom :: (IsAcidic st, SafeCopy 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 Archive 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
--   Archive 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
--   EventResult 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 IsAcidic st

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

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