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


-- | Store and retrieve data from an on-disk store
--   
--   This module provides a way to store and retrieve arbitrary data from
--   an on-disk store, similar to how a source control system works but
--   without the assumptions of such a system.
@package content-store
@version 0.2.1


-- | Manage the content store's internal config file.
module Data.ContentStore.Config

-- | Configuration information needed by the content store.
data Config
Config :: Bool -> Text -> Config

-- | Is the data in the content store compressed? If this option is missing
--   in a config file, we assume that the data is not compressed. This is
--   to keep backwards compatibility with previous versions of the content
--   store that did not support compression. New content stores are created
--   supporting compressed contents by default.
[confCompressed] :: Config -> Bool

-- | What <tt>DigestAlgorithm</tt> is in use by this content store? While
--   we do support several different algorithms, only one can ever be in
--   use by a single content store. Note that the <tt>ContentStore</tt>
--   record also stores this piece of information. The difference is that
--   here, we are only storing the text representation as given in a config
--   file.
[confHash] :: Config -> Text

-- | Construct a default <a>Config</a> record useful for when creating a
--   new <tt>ContentStore</tt>, as with <tt>mkContentStore</tt>. Among
--   other things, this is where the default hash algorithm is defined.
defaultConfig :: Config

-- | Read a config file on disk, returning the <a>Config</a> record on
--   success and an error message on error. This function is typically not
--   useful outside of content store internals.
readConfig :: FilePath -> IO (Either Text Config)

-- | Write a <a>Config</a> object to disk. This function is typically not
--   useful outside of content store internals.
writeConfig :: FilePath -> Config -> IO ()
instance Data.Aeson.Types.FromJSON.FromJSON Data.ContentStore.Config.Config
instance Data.Aeson.Types.ToJSON.ToJSON Data.ContentStore.Config.Config


-- | Functions for working with digest algorithms as used by the content
--   store
module Data.ContentStore.Digest

-- | A DigestAlgorithm represents one specific hash algorithm.
data DigestAlgorithm

-- | Given the <tt>Text</tt> name of a digest algorithm, return a
--   <a>DigestAlgorithm</a> (or Nothing if we don't recognize the
--   DigestAlgorithm's name).
getDigestAlgorithm :: Text -> Maybe DigestAlgorithm

-- | Get the name of this <a>DigestAlgorithm</a>.
digestName :: DigestAlgorithm -> String

-- | The size of the <a>ObjectDigest</a> returned by this
--   <a>DigestAlgorithm</a>.
digestSize :: DigestAlgorithm -> Int

-- | Initialize a new <a>DigestContext</a> for this <a>DigestAlgorithm</a>.
digestInit :: DigestAlgorithm -> DigestContext

-- | Holds the context for a given instance of a <a>DigestAlgorithm</a>.
data DigestContext

-- | Update the <a>DigestContext</a> with one 'ByteString'/'Bytes'/etc
--   item.
digestUpdate :: ByteArrayAccess ba => DigestContext -> ba -> DigestContext

-- | Update the <a>DigestContext</a> with many 'ByteString'/'Bytes'/etc.
--   items.
digestUpdates :: ByteArrayAccess ba => DigestContext -> [ba] -> DigestContext

-- | Finish the digest, returning an <a>ObjectDigest</a>.
digestFinalize :: DigestContext -> ObjectDigest

-- | Hash a strict <tt>ByteString</tt> into an <a>ObjectDigest</a>.
digestByteString :: DigestAlgorithm -> ByteString -> ObjectDigest

-- | Hash a lazy <a>ByteString</a> into an <a>ObjectDigest</a>.
digestLazyByteString :: DigestAlgorithm -> ByteString -> ObjectDigest

-- | ObjectDigest is the (binary) representation of a digest.
data ObjectDigest

-- | Convert an <a>ObjectDigest</a> to its hex representation. TODO:
--   probably more efficient if we can just coerce the converted Bytes..
toHex :: ObjectDigest -> String

-- | Check and convert a <tt>ByteString</tt> into an <a>ObjectDigest</a>.
fromByteString :: ByteArrayAccess ba => DigestAlgorithm -> ba -> Maybe ObjectDigest
instance Data.ByteArray.Types.ByteArrayAccess Data.ContentStore.Digest.ObjectDigest
instance GHC.Classes.Ord Data.ContentStore.Digest.ObjectDigest
instance GHC.Classes.Eq Data.ContentStore.Digest.ObjectDigest
instance GHC.Show.Show Data.ContentStore.Digest.ObjectDigest


-- | Create content stores, put objects into them, and retrieve objects
--   from them.
module Data.ContentStore

-- | The ContentStore is an opaque type that contains various pieces of
--   information used to describe an on-disk content store. Values of this
--   type are constructed via <a>mkContentStore</a> and
--   <a>openContentStore</a>, depending on which operation you need to
--   perform. Users should not need to concern themselves with the
--   internals of this type.
data ContentStore

-- | A type to represent various errors that can occur during content store
--   operations.
data CsError

-- | Miscellaneous, uncategorized errors. The string is the exact error
--   message.
CsError :: String -> CsError

-- | An object with this digest already exists in the content store. This
--   error is not typically raised during write operations, because
--   attempting to write the same thing twice is not really an error.
CsErrorCollision :: String -> CsError

-- | A parse error occurred reading the content store's internal config
--   file. This generally represents either a programming error or that
--   someone has been modifying the internals. The string contains the
--   error message.
CsErrorConfig :: String -> CsError

-- | The content store directory is invalid. This usually occurs because
--   some file or directory is missing. The string is the name of what is
--   missing.
CsErrorInvalid :: String -> CsError

-- | The content store does not exist.
CsErrorMissing :: CsError

-- | The requested object does not exist in the content store. The string
--   contains the object digest requested.
CsErrorNoSuchObject :: String -> CsError

-- | The hashing algorithm is not supported by the content store. Not all
--   possible algorithms are supported. The string contains the name of the
--   algorithm requested.
CsErrorUnsupportedHash :: String -> CsError

-- | Working with a <a>ContentStore</a> requires a lot of behind-the-scenes
--   management of <a>ResourceT</a>, <a>ExceptT</a>, and <a>IO</a>. Along
--   with <a>runCsMonad</a>, this provides a type and function for doing
--   much of that management for you. These two can be used like so:
--   
--   <pre>
--   result &lt;- runCsMonad $ do
--       cs &lt;- mkContentStore "/tmp/cs.repo"
--       storeDirectory cs "/tmp/test-data"
--   
--   case result of
--       Left e  -&gt; print e
--       Right d -&gt; do putStrLn "Stored objects: "
--                     mapM_ print d
--   </pre>
--   
--   Most functions in this module do not explicitly require use of
--   <a>CsMonad</a>, but any that have a return type including <tt>m</tt>
--   can be run inside it.
data CsMonad a

-- | See the documentation for <a>CsMonad</a>.
runCsMonad :: CsMonad a -> IO (Either CsError a)

-- | Return the digest type used by a content store.
contentStoreDigest :: ContentStore -> DigestAlgorithm

-- | Check that a content store exists and contains everything it's
--   supposed to. This does not check the validity of all the contents,
--   however. A <a>CsError</a> will be thrown if there are any problems.
--   Otherwise, this function returns True.
contentStoreValid :: (MonadError CsError m, MonadIO m) => FilePath -> m Bool

-- | Lookup and return some previously stored object as a strict
--   <tt>ByteString</tt>. Note that you'll probably need to use
--   <a>fromByteString</a> to produce an <a>ObjectDigest</a> from whatever
--   text or binary representation you've got from the user<i>mddb</i>etc.
fetchByteString :: (MonadBaseControl IO m, MonadError CsError m, MonadIO m, MonadThrow m) => ContentStore -> ObjectDigest -> m ByteString

-- | Given an opened <a>ContentStore</a> and a <a>Conduit</a> of
--   <a>ObjectDigest</a>s, load each one into a strict <tt>ByteString</tt>
--   and put it into the conduit. This is useful for stream many objects
--   out of the content store at a time, like with exporting an RPM or
--   other package format.
fetchByteStringC :: (MonadError CsError m, MonadResource m) => ContentStore -> Conduit ObjectDigest m ByteString

-- | Find some object in the content store and write it to a destination.
--   If the destination already exists, it will be overwritten. If the
--   object does not already exist, a <a>CsErrorNoSuchObject</a> will be
--   thrown.
fetchFile :: (MonadBaseControl IO m, MonadError CsError m, MonadResource m) => ContentStore -> ObjectDigest -> FilePath -> m ()

-- | Like <a>fetchByteString</a>, but uses lazy <a>ByteString</a>s instead.
fetchLazyByteString :: (MonadBaseControl IO m, MonadError CsError m, MonadIO m, MonadThrow m) => ContentStore -> ObjectDigest -> m ByteString

-- | Like <a>fetchByteStringC</a>, but uses lazy <a>ByteString</a>s
--   instead.
fetchLazyByteStringC :: (MonadError CsError m, MonadResource m) => ContentStore -> Conduit ObjectDigest m ByteString

-- | Create a new <a>ContentStore</a> on disk, rooted at the path given,
--   and return it as if <a>openContentStore</a> had also been called. If a
--   content store already exists at the given root and is valid, return
--   that as if <a>openContentStore</a> had been called. Various
--   <a>CsError</a>s could be thrown by this process.
mkContentStore :: (MonadError CsError m, MonadIO m) => FilePath -> m ContentStore

-- | Return an already existing <a>ContentStore</a>, after checking that it
--   is valid. Various <a>CsError</a>s could be thrown by this process.
openContentStore :: (MonadError CsError m, MonadIO m) => FilePath -> m ContentStore

-- | Store some object into the content store and return its
--   <a>ObjectDigest</a>. If an object with the same digest already exists
--   in the content store, this is a duplicate. Simply return the digest of
--   the already stored object and do nothing else. A
--   <a>CsErrorCollision</a> will NOT be thrown.
storeByteString :: (MonadBaseControl IO m, MonadError CsError m, MonadIO m, MonadThrow m) => ContentStore -> ByteString -> m ObjectDigest

-- | Like <a>storeByteString</a>, but read strict <tt>ByteString</tt>s from
--   a <a>Conduit</a> and put their <a>ObjectDigest</a>s into the conduit.
--   This is useful for storing many objects at a time, like with importing
--   an RPM or other package format.
storeByteStringC :: (MonadError CsError m, MonadResource m) => ContentStore -> Conduit ByteString m ObjectDigest

-- | Read in a <a>Conduit</a> of strict <tt>ByteString</tt>s, store the
--   stream into an object in an already opened <a>ContentStore</a>, and
--   return the final digest. This is useful for storing a stream of data
--   as a single object.
storeByteStringSink :: MonadResource m => ContentStore -> Sink ByteString m ObjectDigest

-- | Store all objects in a directory tree in the content store, returning
--   the name and <a>ObjectDigest</a> of each. Note that directories will
--   not be stored. The content store only contains things that have
--   content. If you need to store directory information, that should be
--   handled externally to this module.
storeDirectory :: (MonadBaseControl IO m, MonadError CsError m, MonadResource m) => ContentStore -> FilePath -> m [(FilePath, ObjectDigest)]

-- | Store an already existing file in the content store, returning its
--   <a>ObjectDigest</a>. The original file will be left on disk.
storeFile :: (MonadBaseControl IO m, MonadError CsError m, MonadResource m) => ContentStore -> FilePath -> m ObjectDigest

-- | Like <a>storeByteString</a>, but uses lazy <a>ByteString</a>s instead.
storeLazyByteString :: (MonadBaseControl IO m, MonadError CsError m, MonadIO m, MonadThrow m) => ContentStore -> ByteString -> m ObjectDigest

-- | Like <a>storeByteStringC</a>, but uses lazy <a>ByteString</a>s
--   instead.
storeLazyByteStringC :: (MonadError CsError m, MonadResource m) => ContentStore -> Conduit ByteString m ObjectDigest

-- | Like <a>storeByteStringSink</a>, but uses lazy <a>ByteString</a>s
--   instead.
storeLazyByteStringSink :: MonadResource m => ContentStore -> Sink ByteString m ObjectDigest
instance Control.Monad.Catch.MonadThrow Data.ContentStore.CsMonad
instance Control.Monad.Trans.Resource.Internal.MonadResource Data.ContentStore.CsMonad
instance Control.Monad.IO.Class.MonadIO Data.ContentStore.CsMonad
instance Control.Monad.Error.Class.MonadError Data.ContentStore.CsError Data.ContentStore.CsMonad
instance Control.Monad.Base.MonadBase GHC.Types.IO Data.ContentStore.CsMonad
instance GHC.Base.Monad Data.ContentStore.CsMonad
instance GHC.Base.Functor Data.ContentStore.CsMonad
instance GHC.Base.Applicative Data.ContentStore.CsMonad
instance GHC.Show.Show Data.ContentStore.CsError
instance GHC.Classes.Eq Data.ContentStore.CsError
instance Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO Data.ContentStore.CsMonad
