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


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


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

-- | 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 Typeable AcidRemoteException
instance Typeable1 RemoteState
instance Eq AcidRemoteException
instance Show AcidRemoteException
instance Serialize Response
instance Serialize Command
instance Exception AcidRemoteException


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