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


-- | Server-side implementation of the Avers storage model
--   
--   This is the server-side implementation of the Avers storage model. It
--   is a Haskell library, intended to be used by your application. The
--   library provides you with everything you need to write your own Avers
--   server. You can create and patch objects and collections thereof. It
--   has builtin support for sessions, authentication and managing blobs.
--   The database is not configurable. Avers is currently hardcoded to use
--   RethinkDB.
@package avers
@version 0.0.17.1

module Avers.Index
data Index a
Index :: Text -> (Exp Object -> Exp a) -> Index a
[indexName] :: Index a -> Text
[indexExpression] :: Index a -> Exp Object -> Exp a
data SomeIndex
[SomeIndex] :: IsDatum a => Index a -> SomeIndex

module Avers.Metrics.TH
toLabels :: [String] -> [[String]]
toMetrics :: [[String]] -> [[String]]
mkMeasurements :: Q [Dec]

module Avers.Metrics.Measurements
data Measurement
M_avers_storage_lookupObject_duration :: Measurement
M_avers_storage_lookupSnapshot_duration :: Measurement
M_avers_storage_lookupLatestSnapshot_duration :: Measurement
M_avers_storage_newestSnapshot_duration :: Measurement
M_avers_storage_patchesAfterRevision_duration :: Measurement
M_avers_storage_lookupPatch_duration :: Measurement
M_avers_storage_applyObjectUpdates_duration :: Measurement
M_avers_storage_applyObjectUpdates_numOperations :: Measurement
M_avers_storage_applyObjectUpdates_numPreviousPatches :: Measurement
M_avers_storage_exists_duration :: Measurement
measurementLabels :: Measurement -> [[Char]]

module Avers.TH

-- | Generates both <a>JSONFun</a> and <a>FromJSON</a> instance
--   declarations for the given data type or data family instance
--   constructor.
--   
--   This is a convienience function which is equivalent to calling both
--   <a>deriveToJSON</a> and <a>deriveFromJSON</a>.
deriveJSON :: Options -> Name -> Q [Dec]
deriveJSONOptions :: String -> Options
variantOptions :: String -> String -> String -> Options
defaultVariantOptions :: String -> Options
deriveEncoding :: Options -> Name -> Q [Dec]
deriveRecordEncoding :: Name -> String -> [(String, Q Exp)] -> Q [Dec]

-- | A type that can be converted from JSON, with the possibility of
--   failure.
--   
--   In many cases, you can get the compiler to generate parsing code for
--   you (see below). To begin, let's cover writing an instance by hand.
--   
--   There are various reasons a conversion could fail. For example, an
--   <a>Object</a> could be missing a required key, an <a>Array</a> could
--   be of the wrong size, or a value could be of an incompatible type.
--   
--   The basic ways to signal a failed conversion are as follows:
--   
--   <ul>
--   <li><tt>empty</tt> and <tt>mzero</tt> work, but are terse and
--   uninformative;</li>
--   <li><a>fail</a> yields a custom error message;</li>
--   <li><a>typeMismatch</a> produces an informative message for cases when
--   the value encountered is not of the expected type.</li>
--   </ul>
--   
--   An example type and instance using <a>typeMismatch</a>:
--   
--   <pre>
--   -- Allow ourselves to write <a>Text</a> literals.
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   data Coord = Coord { x :: Double, y :: Double }
--   
--   instance <a>FromJSON</a> Coord where
--       <a>parseJSON</a> (<a>Object</a> v) = Coord
--           <a>&lt;$&gt;</a> v <a>.:</a> "x"
--           <a>&lt;*&gt;</a> v <a>.:</a> "y"
--   
--       -- We do not expect a non-<a>Object</a> value here.
--       -- We could use <tt>mzero</tt> to fail, but <a>typeMismatch</a>
--       -- gives a much more informative error message.
--       <a>parseJSON</a> invalid    = <a>typeMismatch</a> "Coord" invalid
--   </pre>
--   
--   For this common case of only being concerned with a single type of
--   JSON value, the functions <a>withObject</a>, <tt>withNumber</tt>, etc.
--   are provided. Their use is to be preferred when possible, since they
--   are more terse. Using <a>withObject</a>, we can rewrite the above
--   instance (assuming the same language extension and data type) as:
--   
--   <pre>
--   instance <a>FromJSON</a> Coord where
--       <a>parseJSON</a> = <a>withObject</a> "Coord" $ \v -&gt; Coord
--           <a>&lt;$&gt;</a> v <a>.:</a> "x"
--           <a>&lt;*&gt;</a> v <a>.:</a> "y"
--   </pre>
--   
--   Instead of manually writing your <a>FromJSON</a> instance, there are
--   two options to do it automatically:
--   
--   <ul>
--   <li><a>Data.Aeson.TH</a> provides Template Haskell functions which
--   will derive an instance at compile time. The generated instance is
--   optimized for your type so it will probably be more efficient than the
--   following option.</li>
--   <li>The compiler can provide a default generic implementation for
--   <a>parseJSON</a>.</li>
--   </ul>
--   
--   To use the second, simply add a <tt>deriving <a>Generic</a></tt>
--   clause to your datatype and declare a <a>FromJSON</a> instance for
--   your datatype without giving a definition for <a>parseJSON</a>.
--   
--   For example, the previous example can be simplified to just:
--   
--   <pre>
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import <a>GHC.Generics</a>
--   
--   data Coord = Coord { x :: Double, y :: Double } deriving <a>Generic</a>
--   
--   instance <a>FromJSON</a> Coord
--   </pre>
--   
--   The default implementation will be equivalent to <tt>parseJSON =
--   <a>genericParseJSON</a> <a>defaultOptions</a></tt>; If you need
--   different options, you can customize the generic decoding by defining:
--   
--   <pre>
--   customOptions = <a>defaultOptions</a>
--                   { <a>fieldLabelModifier</a> = <a>map</a> <a>toUpper</a>
--                   }
--   
--   instance <a>FromJSON</a> Coord where
--       <a>parseJSON</a> = <a>genericParseJSON</a> customOptions
--   </pre>
class FromJSON a
parseJSON :: FromJSON a => Value -> Parser a
parseJSONList :: FromJSON a => Value -> Parser [a]

-- | A type that can be converted to JSON.
--   
--   Instances in general <i>must</i> specify <a>toJSON</a> and
--   <i>should</i> (but don't need to) specify <a>toEncoding</a>.
--   
--   An example type and instance:
--   
--   <pre>
--   -- Allow ourselves to write <a>Text</a> literals.
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   data Coord = Coord { x :: Double, y :: Double }
--   
--   instance <a>ToJSON</a> Coord where
--     <a>toJSON</a> (Coord x y) = <a>object</a> ["x" <a>.=</a> x, "y" <a>.=</a> y]
--   
--     <a>toEncoding</a> (Coord x y) = <tt>pairs</tt> ("x" <a>.=</a> x <a>&lt;&gt;</a> "y" <a>.=</a> y)
--   </pre>
--   
--   Instead of manually writing your <a>ToJSON</a> instance, there are two
--   options to do it automatically:
--   
--   <ul>
--   <li><a>Data.Aeson.TH</a> provides Template Haskell functions which
--   will derive an instance at compile time. The generated instance is
--   optimized for your type so it will probably be more efficient than the
--   following option.</li>
--   <li>The compiler can provide a default generic implementation for
--   <a>toJSON</a>.</li>
--   </ul>
--   
--   To use the second, simply add a <tt>deriving <a>Generic</a></tt>
--   clause to your datatype and declare a <a>ToJSON</a> instance. If you
--   require nothing other than <a>defaultOptions</a>, it is sufficient to
--   write (and this is the only alternative where the default
--   <a>toJSON</a> implementation is sufficient):
--   
--   <pre>
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import <a>GHC.Generics</a>
--   
--   data Coord = Coord { x :: Double, y :: Double } deriving <a>Generic</a>
--   
--   instance <a>ToJSON</a> Coord where
--       <a>toEncoding</a> = <a>genericToEncoding</a> <a>defaultOptions</a>
--   </pre>
--   
--   If on the other hand you wish to customize the generic decoding, you
--   have to implement both methods:
--   
--   <pre>
--   customOptions = <a>defaultOptions</a>
--                   { <a>fieldLabelModifier</a> = <a>map</a> <a>toUpper</a>
--                   }
--   
--   instance <a>ToJSON</a> Coord where
--       <a>toJSON</a>     = <a>genericToJSON</a> customOptions
--       <a>toEncoding</a> = <a>genericToEncoding</a> customOptions
--   </pre>
--   
--   Previous versions of this library only had the <a>toJSON</a> method.
--   Adding <a>toEncoding</a> had two reasons:
--   
--   <ol>
--   <li>toEncoding is more efficient for the common case that the output
--   of <a>toJSON</a> is directly serialized to a <tt>ByteString</tt>.
--   Further, expressing either method in terms of the other would be
--   non-optimal.</li>
--   <li>The choice of defaults allows a smooth transition for existing
--   users: Existing instances that do not define <a>toEncoding</a> still
--   compile and have the correct semantics. This is ensured by making the
--   default implementation of <a>toEncoding</a> use <a>toJSON</a>. This
--   produces correct results, but since it performs an intermediate
--   conversion to a <a>Value</a>, it will be less efficient than directly
--   emitting an <a>Encoding</a>. (this also means that specifying nothing
--   more than <tt>instance ToJSON Coord</tt> would be sufficient as a
--   generically decoding instance, but there probably exists no good
--   reason to not specify <a>toEncoding</a> in new instances.)</li>
--   </ol>
class ToJSON a

-- | Convert a Haskell value to a JSON-friendly intermediate type.
toJSON :: ToJSON a => a -> Value

-- | Encode a Haskell value as JSON.
--   
--   The default implementation of this method creates an intermediate
--   <a>Value</a> using <a>toJSON</a>. This provides source-level
--   compatibility for people upgrading from older versions of this
--   library, but obviously offers no performance advantage.
--   
--   To benefit from direct encoding, you <i>must</i> provide an
--   implementation for this method. The easiest way to do so is by having
--   your types implement <a>Generic</a> using the <tt>DeriveGeneric</tt>
--   extension, and then have GHC generate a method body as follows.
--   
--   <pre>
--   instance <a>ToJSON</a> Coord where
--       <a>toEncoding</a> = <a>genericToEncoding</a> <a>defaultOptions</a>
--   </pre>
toEncoding :: ToJSON a => a -> Encoding
toJSONList :: ToJSON a => [a] -> Value
toEncodingList :: ToJSON a => [a] -> Encoding

module Avers.Types

-- | Pk - Types which can be converted to a database primary key.
class Pk a
toPk :: Pk a => a -> Text

-- | Path
newtype Path
Path :: Text -> Path
[unPath] :: Path -> Text

-- | This path refers to the root of an object. It is only used in
--   <a>Set</a> operations.
rootPath :: Path

-- | ObjId
newtype ObjId
ObjId :: Text -> ObjId
[unObjId] :: ObjId -> Text

-- | The root object id is used for object created internally or when there
--   is no applicable creator.
rootObjId :: ObjId

-- | RevId
newtype RevId
RevId :: Int -> RevId
[unRevId] :: RevId -> Int

-- | The <a>RevId</a> which is used for the initial snapshot.
zeroRevId :: RevId

-- | ObjectId
data ObjectId

-- | The base object whose snapshots contain the actual content.
BaseObjectId :: !ObjId -> ObjectId

-- | An object describing a particualar release of the base object.
ReleaseObjectId :: !ObjId -> !RevId -> ObjectId

-- | Object which contains authorization rules.
AuthorizationObjectId :: !ObjId -> ObjectId
objectIdParser :: Parser ObjectId
parseObjectId :: Text -> Maybe ObjectId
objectIdBase :: ObjectId -> ObjId

-- | The operations that can be applied to JSON values.
data Operation

-- | Set is applied to <a>Object</a>s. It is used for adding, updating and
--   deleting properties from the object.
Set :: !Path -> !Maybe Value -> Operation
[opPath] :: Operation -> !Path
[opValue] :: Operation -> !Maybe Value

-- | Splice is used to manipulate <tt>Array</tt>s. It can remove and insert
--   multiple elements in a single operation.
Splice :: !Path -> !Int -> !Int -> ![Value] -> Operation
[opPath] :: Operation -> !Path
[opIndex] :: Operation -> !Int
[opRemove] :: Operation -> !Int
[opInsert] :: Operation -> ![Value]
data PatchError
UnknownPatchError :: !Text -> PatchError
type PatchM a = Either PatchError a
data Object
Object :: !ObjId -> !Text -> !UTCTime -> !ObjId -> !Maybe Bool -> Object
[objectId] :: Object -> !ObjId
[objectType] :: Object -> !Text
[objectCreatedAt] :: Object -> !UTCTime
[objectCreatedBy] :: Object -> !ObjId
[objectDeleted] :: Object -> !Maybe Bool

-- | Patch
data Patch
Patch :: !ObjectId -> !RevId -> !ObjId -> !UTCTime -> !Operation -> Patch
[patchObjectId] :: Patch -> !ObjectId
[patchRevisionId] :: Patch -> !RevId
[patchAuthorId] :: Patch -> !ObjId
[patchCreatedAt] :: Patch -> !UTCTime
[patchOperation] :: Patch -> !Operation

-- | Snapshot
data Snapshot
Snapshot :: !ObjectId -> !RevId -> !Value -> Snapshot
[snapshotObjectId] :: Snapshot -> !ObjectId
[snapshotRevisionId] :: Snapshot -> !RevId
[snapshotContent] :: Snapshot -> !Value

-- | The initial snapshot on top of which all future patches are applied.
initialSnapshot :: ObjectId -> Snapshot

-- | Release
data Release
Release :: Release

-- | SecretId
newtype SecretId
SecretId :: Text -> SecretId
[unSecretId] :: SecretId -> Text

-- | Secret
--   
--   A <a>Secret</a> is a password (encrypted with scrypt) that is attached
--   to a <a>SecretId</a> (for example the <a>ObjId</a> of an account).
--   
--   It is up to you to ensure that <a>SecretId</a>s are unique. If you use
--   <a>ObjId</a>s then they by definition are.
data Secret
Secret :: !SecretId -> !Text -> Secret
[secretId] :: Secret -> !SecretId
[secretValue] :: Secret -> !Text

-- | BlobId
newtype BlobId
BlobId :: Text -> BlobId
[unBlobId] :: BlobId -> Text

-- | Blob
data Blob
Blob :: !BlobId -> !Int -> !Text -> Blob
[blobId] :: Blob -> !BlobId
[blobSize] :: Blob -> !Int
[blobContentType] :: Blob -> !Text

-- | SessionId
newtype SessionId
SessionId :: Text -> SessionId
[unSessionId] :: SessionId -> Text

-- | The session record that is stored in the database.
--   
--   A session is a unique identifier attached to a particular object. It
--   contains the creation date and when it was last accessed. If you need
--   to store additional data for a session, we recommend to use cookies.
data Session
Session :: !SessionId -> !ObjId -> !UTCTime -> !UTCTime -> Session
[sessionId] :: Session -> !SessionId
[sessionObjId] :: Session -> !ObjId
[sessionCreatedAt] :: Session -> !UTCTime
[sessionLastAccessedAt] :: Session -> !UTCTime
data AversError
InternalError :: !AversError -> AversError
DatabaseError :: !Text -> AversError
PatchError :: !PatchError -> AversError
ParseError :: !Value -> !Text -> AversError
UnknownObjectType :: !Text -> AversError
ObjectNotFound :: !ObjId -> AversError
DocumentNotFound :: !Text -> AversError
AversError :: !Text -> AversError
NotAuthorized :: AversError
internalError :: AversError -> Avers a
internal :: Avers a -> Avers a
databaseError :: Text -> Avers a
patchError :: PatchError -> Avers a
parseError :: MonadError AversError m => Value -> Text -> m a
documentNotFound :: Text -> Avers a
strErr :: String -> Avers a

-- | An <a>ObjectType</a> describes a particular type of object that is
--   managed by Avers.
data ObjectType a
ObjectType :: !Text -> Avers ObjId -> [SomeView a] -> ObjectType a

-- | The value of the <tt>type</tt> field of the <a>Object</a>.
[otType] :: ObjectType a -> !Text

-- | Action which generates a new id. This is so that object types can have
--   different strategies how to generate ids.
[otId] :: ObjectType a -> Avers ObjId
[otViews] :: ObjectType a -> [SomeView a]
data SomeObjectType
[SomeObjectType] :: (ToDatum a, FromDatum a, FromJSON a, ToJSON a) => ObjectType a -> SomeObjectType
parseValueAs :: FromJSON a => ObjectType a -> Value -> Either AversError a

-- | Configuration of the <a>Avers</a> monad.
data Config
Config :: !URI -> (BlobId -> Text -> ByteString -> IO (Either AversError ())) -> ![SomeObjectType] -> (Measurement -> Double -> IO ()) -> Config

-- | <a>URI</a> which describes the connection details to the RethinkDB
--   database. The <a>URI</a> *MUST* include at least the hostname
--   (<a>uriRegName</a>) and database name (<a>uriPath</a> without the
--   leading slash). The port (<a>uriPort</a>) and credentials
--   (<a>uriUserInfo</a>) *MAY* be left empty. in that case the default
--   port will be used.
[databaseURI] :: Config -> !URI

-- | Function which saves the given blob in the blob store. This can be the
--   local filesystem or an external service such as Amazon S3.
[putBlob] :: Config -> BlobId -> Text -> ByteString -> IO (Either AversError ())

-- | All the object types which Avers knows about.
[objectTypes] :: Config -> ![SomeObjectType]

-- | This is called when the internal instrumentation code creates a
--   measurement.
[emitMeasurement] :: Config -> Measurement -> Double -> IO ()

-- | A change in the system, for example a new object, patch, release, blob
--   etc.
data Change

-- | A new patch was created.
CPatch :: !Patch -> Change
data Handle
Handle :: !Config -> !Pool Handle -> !TVar (Map ObjectId RevId) -> !TChan Change -> Handle

-- | A reference to the config, just in case we need it.
[hConfig] :: Handle -> !Config

-- | A pool of handles which are used to access the database.
[hDatabaseHandlePool] :: Handle -> !Pool Handle

-- | Map from <a>ObjectId</a> to a recent <a>RevId</a>. It may be the
--   latest or a few revisions behind.
[hRecentRevisionCache] :: Handle -> !TVar (Map ObjectId RevId)

-- | Changes in the system (new patches, objects, releases etc), even those
--   created through other handles, are streamed into this channel. If you
--   want to be informed of those changes, duplicate the channel and read
--   from the copy.
[hChanges] :: Handle -> !TChan Change
newtype Avers a
Avers :: StateT Handle (ExceptT AversError IO) a -> Avers a
[runAvers] :: Avers a -> StateT Handle (ExceptT AversError IO) a
class (Monad m) => MonadAvers m
liftAvers :: MonadAvers m => Avers a -> m a
evalAvers :: Handle -> Avers a -> IO (Either AversError a)
data View obj a
View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [SomeIndex] -> View obj a

-- | The table name is derived from the view name. Therefore it should be
--   unique amongst all views.
[viewName] :: View obj a -> Text

-- | Function which parses objects stored in this view.
[viewParser] :: View obj a -> Datum -> Either AversError a

-- | Function which transforms an Avers Object into a type stored in the
--   view.
[viewObjectTransformer] :: View obj a -> obj -> Avers (Maybe a)

-- | Secondary indices defined on the view.
[viewIndices] :: View obj a -> [SomeIndex]
data SomeView obj
[SomeView] :: (ToDatum a, FromDatum a, FromJSON obj, ToJSON a) => View obj a -> SomeView obj
instance Control.Monad.State.Class.MonadState Avers.Types.Handle Avers.Types.Avers
instance Control.Monad.Error.Class.MonadError Avers.Types.AversError Avers.Types.Avers
instance Control.Monad.IO.Class.MonadIO Avers.Types.Avers
instance GHC.Base.Monad Avers.Types.Avers
instance GHC.Base.Applicative Avers.Types.Avers
instance GHC.Base.Functor Avers.Types.Avers
instance GHC.Generics.Generic Avers.Types.Change
instance GHC.Show.Show Avers.Types.Change
instance GHC.Generics.Generic Avers.Types.AversError
instance GHC.Show.Show Avers.Types.AversError
instance Avers.Types.MonadAvers Avers.Types.Avers
instance Avers.Types.MonadAvers m => Avers.Types.MonadAvers (Control.Monad.Trans.State.Lazy.StateT s m)
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Change
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Session
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Session
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Session
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Session
instance GHC.Generics.Generic Avers.Types.Session
instance GHC.Generics.Generic Avers.Types.SessionId
instance Avers.Types.Pk Avers.Types.Session
instance Avers.Types.Pk Avers.Types.SessionId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.SessionId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.SessionId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.SessionId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.SessionId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Blob
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Blob
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Blob
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Blob
instance GHC.Generics.Generic Avers.Types.Blob
instance GHC.Show.Show Avers.Types.Blob
instance GHC.Generics.Generic Avers.Types.BlobId
instance GHC.Show.Show Avers.Types.BlobId
instance Avers.Types.Pk Avers.Types.Blob
instance Avers.Types.Pk Avers.Types.BlobId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.BlobId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.BlobId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.BlobId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.BlobId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Secret
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Secret
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Secret
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Secret
instance GHC.Generics.Generic Avers.Types.Secret
instance GHC.Generics.Generic Avers.Types.SecretId
instance GHC.Show.Show Avers.Types.SecretId
instance Avers.Types.Pk Avers.Types.Secret
instance Avers.Types.Pk Avers.Types.SecretId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.SecretId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.SecretId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.SecretId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.SecretId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Release
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Release
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Snapshot
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Snapshot
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Snapshot
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Snapshot
instance GHC.Generics.Generic Avers.Types.Snapshot
instance GHC.Show.Show Avers.Types.Snapshot
instance Avers.Types.Pk Avers.Types.Snapshot
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Patch
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Patch
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Patch
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Patch
instance GHC.Generics.Generic Avers.Types.Patch
instance GHC.Show.Show Avers.Types.Patch
instance Avers.Types.Pk Avers.Types.Patch
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Object
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Object
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Object
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Object
instance GHC.Generics.Generic Avers.Types.Object
instance GHC.Show.Show Avers.Types.Object
instance GHC.Generics.Generic Avers.Types.PatchError
instance GHC.Show.Show Avers.Types.PatchError
instance Avers.Types.Pk Avers.Types.Object
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Operation
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Operation
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Operation
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Operation
instance GHC.Generics.Generic Avers.Types.Operation
instance GHC.Show.Show Avers.Types.Operation
instance GHC.Classes.Eq Avers.Types.Operation
instance GHC.Generics.Generic Avers.Types.ObjectId
instance GHC.Show.Show Avers.Types.ObjectId
instance GHC.Classes.Ord Avers.Types.ObjectId
instance GHC.Classes.Eq Avers.Types.ObjectId
instance GHC.Generics.Generic Avers.Types.RevId
instance GHC.Show.Show Avers.Types.RevId
instance GHC.Classes.Ord Avers.Types.RevId
instance GHC.Classes.Eq Avers.Types.RevId
instance GHC.Generics.Generic Avers.Types.ObjId
instance GHC.Show.Show Avers.Types.ObjId
instance GHC.Classes.Ord Avers.Types.ObjId
instance GHC.Classes.Eq Avers.Types.ObjId
instance GHC.Generics.Generic Avers.Types.Path
instance GHC.Show.Show Avers.Types.Path
instance GHC.Classes.Ord Avers.Types.Path
instance GHC.Classes.Eq Avers.Types.Path
instance Avers.Types.Pk Avers.Types.ObjectId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.ObjectId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.ObjectId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.ObjectId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.ObjectId
instance GHC.Enum.Enum Avers.Types.RevId
instance Avers.Types.Pk Avers.Types.RevId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.RevId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.RevId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.RevId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.RevId
instance Avers.Types.Pk Avers.Types.ObjId
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.ObjId
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.ObjId
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.ObjId
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.ObjId
instance Data.String.IsString Avers.Types.Path
instance Data.Aeson.Types.ToJSON.ToJSON Avers.Types.Path
instance Data.Aeson.Types.FromJSON.FromJSON Avers.Types.Path
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Types.Path
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Types.Path
instance Avers.Types.Pk Data.Text.Internal.Text


-- | This module contains RethinkDB Expressions which are used to build
--   queries.
module Avers.Storage.Expressions
objectsTable :: Exp Table
sessionsTable :: Exp Table
snapshotsTable :: Exp Table
patchesTable :: Exp Table
secretsTable :: Exp Table
blobsTable :: Exp Table

-- | The primary key in all our documents is the default "id".
primaryKeyField :: Text

-- | Expression which represents the primary key field.
primaryKeyFieldE :: Exp Text

-- | Expression which represents the value of a field inside of an Object.
objectFieldE :: IsDatum a => Text -> Exp Object -> Exp a

-- | True if the object field matches the given value.
objectFieldEqE :: ToDatum a => Text -> a -> Exp Object -> Exp Bool

-- | True if the object's primary key matches the given string.
primaryKeyEqE :: Text -> Exp Object -> Exp Bool

-- | Take the first item out of a sequence. Beware that this throws an
--   error when the sequence is empty.
headE :: (IsSequence a, IsDatum r) => Exp a -> Exp r

-- | Limit a sequence to the first <tt>n</tt> items.
limitE :: IsSequence s => Int -> Exp s -> Exp s
mkBounds :: ObjectId -> Int -> Int -> (Bound, Bound)
mkBound :: ObjectId -> Int -> Bound
objectSnapshotSequenceE :: ObjectId -> Int -> Int -> Exp Table
objectPatchSequenceE :: ObjectId -> Int -> Int -> Exp Table


-- | Low-level implementation of the storage backend.
module Avers.Storage.Backend
parseValue :: (FromJSON a, MonadError AversError m) => Value -> m a
parseDatum :: (FromDatum a, MonadError AversError m) => Datum -> m a
runQuery :: FromResponse (Result a) => Exp a -> Avers (Result a)
runQueryDatum :: FromDatum a => Exp Datum -> Avers a
runQuerySingleSelection :: FromDatum a => Exp SingleSelection -> Avers a
runQueryCollect :: (FromDatum a, Result e ~ Sequence a) => Exp e -> Avers (Vector a)
existsDocument :: Pk k => Exp Table -> k -> Avers Bool
lookupDocument :: (Pk k, FromDatum a) => Exp Table -> k -> Avers (Maybe a)
insertDocument :: (ToDatum a, Pk a) => Exp Table -> a -> Avers ()
upsertDocument :: (ToDatum a, Pk a) => Exp Table -> a -> Avers ()
deleteDocument :: Pk k => Exp Table -> k -> Avers ()
instance Database.RethinkDB.Types.Datum.ToDatum Avers.Storage.Backend.WriteResponse
instance Database.RethinkDB.Types.Datum.FromDatum Avers.Storage.Backend.WriteResponse
instance GHC.Show.Show Avers.Storage.Backend.WriteResponse

module Avers.Patching

-- | Apply the given op on the value. Can throw an exception if the
--   operation is invalid.
applyOperation :: Value -> Operation -> PatchM Value
opOT :: Value -> Operation -> Operation -> Maybe Operation

-- | Given an <a>Operation</a> which was created against a particular
--   <a>Value</a> (content), rebase it on top of patches which were created
--   against the very same content in parallel.
--   
--   This function assumes that the patches apply cleanly to the content.
--   Failure to do so results in a fatal error.
rebaseOperation :: Value -> Operation -> [Patch] -> Maybe Operation

-- | Resolve the path in the object.
resolvePathIn :: Path -> Value -> Maybe Value

module Avers.Metrics
measureDuration :: Measurement -> Avers a -> Avers a
reportMeasurement :: Measurement -> Double -> Avers ()

module Avers.Views
viewTableName :: View obj a -> Text

-- | Construct the table name for the given view. The table names look
--   something like this: "view_openGames"
viewTable :: View obj a -> Exp Table
data Record a
Record :: ObjId -> a -> Record a
[recId] :: Record a -> ObjId
[recContent] :: Record a -> a
updateObjectViews :: ObjectType a -> ObjId -> Maybe a -> Avers ()
updateView :: ToDatum a => View obj a -> ObjId -> Maybe obj -> Avers ()
instance Avers.Types.Pk (Avers.Views.Record a)
instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Avers.Views.Record a)
instance Database.RethinkDB.Types.Datum.ToDatum a => Database.RethinkDB.Types.Datum.ToDatum (Avers.Views.Record a)


-- | This module abstracts the storage engine and provides functions to
--   manipulate objects stored in it.
module Avers.Storage
requireResult :: AversError -> Maybe a -> Avers a

-- | True if the object exists.
exists :: ObjId -> Avers Bool

-- | Lookup an <a>Object</a> by its <a>ObjId</a>. Throws
--   <a>ObjectNotFound</a> if the object doesn't exist.
lookupObject :: ObjId -> Avers Object

-- | Create a new object of the given type. An initial snapshot
--   (<a>RevId</a> 0) is created from the supplied content.
createObject :: ToJSON a => ObjectType a -> ObjId -> a -> Avers ObjId

-- | A more low-level version of <a>createObject</a>, for use when you want
--   to generate your own ObjId or create objects at a specific time.
createObject' :: ToJSON a => ObjId -> UTCTime -> ObjectType a -> ObjId -> a -> Avers ()

-- | Mark the object as deleted.
deleteObject :: ObjId -> Avers ()

-- | Prune the object from the database. This is only allowed if the object
--   is marked as deleted. Note that this is a very dangerous operation, it
--   can not be undone.
--   
--   TODO: Prune related Release and Authoriation objects.
pruneObject :: ObjId -> Avers ()

-- | Create a checkpoint for for the given object. All patches (and of
--   course snapshots) before the checkpoint can be dropped. Use
--   <a>vacuumObject</a> to do that.
createCheckpoint :: ObjectId -> ObjId -> Avers RevId
isCheckpointPatch :: Patch -> Bool
latestCheckpointPatch :: ObjectId -> Avers (Maybe Patch)

-- | Drop all patches and snapshots before the most recent checkpoint. This
--   effectively drops the object's history, and frees space in the
--   database.
vacuumObject :: ObjectId -> Avers ()

-- | Fetch the content of the object and try to parse it.
--   
--   This function will fail with a <a>ParseError</a> if the content can
--   not be decoded into the desired type.
objectContent :: FromJSON a => ObjectId -> Avers a

-- | Get the snapshot of the newest revision of the given object.
lookupLatestSnapshot :: ObjectId -> Avers Snapshot
applyPatchToSnapshot :: Snapshot -> Patch -> Avers Snapshot
applyPatches :: Snapshot -> [Patch] -> Avers Snapshot
lookupRecentRevision :: ObjectId -> Avers (Maybe RevId)
updateRecentRevision :: ObjectId -> RevId -> Avers ()

-- | Lookup the latest snapshot within the given range. The bounds are
--   inclusive.
latestSnapshotBetween :: ObjectId -> Int -> Int -> Avers Snapshot

-- | Get the newest snapshot which is stored in the database. The object
--   may be at a higher revision if the later snapshots are missing from
--   the database.
--   
--   This is an internal function. If you want the latest snapshot, you
--   should use <a>lookupLatestSnapshot</a>.
newestSnapshot :: ObjectId -> Avers Snapshot

-- | Lookup the snapshot at a particular revision.
lookupSnapshot :: ObjectId -> RevId -> Avers Snapshot
savePatch :: Patch -> Avers ()
saveSnapshot :: Snapshot -> Avers ()
updateSecret :: SecretId -> Text -> Avers ()

-- | Verify the value against the secret. If that fails, then this function
--   throws an error.
--   
--   This function automatically updates the secret in the database if the
--   scrypt params have changed.
verifySecret :: SecretId -> Text -> Avers ()

-- | Internal function which actually saves a secret in the database.
saveSecretValue :: SecretId -> EncryptedPass -> Avers ()
objectPatches :: ObjectId -> Avers [Patch]
patchesAfterRevision :: ObjectId -> RevId -> Avers [Patch]
lookupPatch :: ObjectId -> RevId -> Avers Patch

-- | Lookup an object type which is registered in the Avers monad.
lookupObjectType :: Text -> Avers SomeObjectType
applyObjectUpdates :: ObjectId -> RevId -> ObjId -> [Operation] -> Bool -> Avers ([Patch], Int, [Patch])
data PatchState a
PatchState :: ObjectType a -> ObjectId -> RevId -> ObjId -> [Operation] -> Int -> Snapshot -> Snapshot -> [Patch] -> [Patch] -> PatchState a
[psObjectType] :: PatchState a -> ObjectType a
[psObjectId] :: PatchState a -> ObjectId
[psRevisionId] :: PatchState a -> RevId
[psCommitterId] :: PatchState a -> ObjId
[psOperations] :: PatchState a -> [Operation]
[psNumConsumedOperations] :: PatchState a -> Int
[psBaseSnapshot] :: PatchState a -> Snapshot
[psLatestSnapshot] :: PatchState a -> Snapshot
[psPreviousPatches] :: PatchState a -> [Patch]
[psPatches] :: PatchState a -> [Patch]
type AversPatch a b = StateT (PatchState a) Avers b
patchHandler :: FromJSON a => Bool -> AversPatch a Snapshot
existsBlob :: BlobId -> Avers Bool
lookupBlob :: BlobId -> Avers Blob
insertBlob :: Blob -> Avers ()
saveBlobContent :: Blob -> ByteString -> Avers ()
saveSession :: Session -> Avers ()
lookupSession :: SessionId -> Avers Session
dropSession :: SessionId -> Avers ()
newId :: Int -> IO Text
validateObject :: Text -> Value -> Avers ()
validateWithType :: FromJSON a => ObjectType a -> Value -> Avers ()
lookupRelease :: ObjId -> RevId -> Avers Release

-- | Create a new release of the given revision. If the object doesn't
--   exist, it will fail with <a>ObjectNotFound</a>.
createRelease :: ObjId -> RevId -> Avers ()
lookupLatestRelease :: ObjId -> Avers (Maybe RevId)
createBlob :: ByteString -> Text -> Avers Blob
objectsOfType :: ObjectType a -> Avers (Vector ObjId)
allObjectsOfType :: ObjectType a -> Avers (Vector ObjId)
isNotDeleted :: Exp Object -> Exp Bool
mapId :: Exp Object -> Exp Text

-- | Bootstrap the Avers handle: Create necessary tables, indexes, views
--   etc. This operation is idempotent.
indexF :: Exp Object -> Exp (Array Datum)
bootstrap :: Avers ()
createTable :: Text -> [SomeIndex] -> Avers ()

-- | Stream new patches from the database into the channel.
streamPatches :: Pool Handle -> TChan Change -> IO ()

-- | Return a <a>TChan</a> to which all changes in the system are streamed.
--   Make sure to continuously drain items from the <a>TChan</a>, otherwise
--   they will accumulate in memory and you will run OOM eventually.
--   
--   Do not write into the channel!
changeChannel :: Handle -> IO (TChan Change)

module Avers.Handle
newHandle :: Config -> IO (Either AversError Handle)

-- | <i>Deprecated: Use <a>newHandle</a> instead</i>
newState :: Config -> IO (Either AversError Handle)

module Avers
data Avers a
evalAvers :: Handle -> Avers a -> IO (Either AversError a)

-- | Path
newtype Path
Path :: Text -> Path
[unPath] :: Path -> Text

-- | Pk - Types which can be converted to a database primary key.
class Pk a
toPk :: Pk a => a -> Text

-- | ObjId
newtype ObjId
ObjId :: Text -> ObjId
[unObjId] :: ObjId -> Text

-- | The root object id is used for object created internally or when there
--   is no applicable creator.
rootObjId :: ObjId

-- | RevId
newtype RevId
RevId :: Int -> RevId
[unRevId] :: RevId -> Int

-- | The <a>RevId</a> which is used for the initial snapshot.
zeroRevId :: RevId

-- | ObjectId
data ObjectId

-- | The base object whose snapshots contain the actual content.
BaseObjectId :: !ObjId -> ObjectId

-- | An object describing a particualar release of the base object.
ReleaseObjectId :: !ObjId -> !RevId -> ObjectId

-- | Object which contains authorization rules.
AuthorizationObjectId :: !ObjId -> ObjectId

-- | The operations that can be applied to JSON values.
data Operation

-- | Set is applied to <a>Object</a>s. It is used for adding, updating and
--   deleting properties from the object.
Set :: !Path -> !Maybe Value -> Operation
[opPath] :: Operation -> !Path
[opValue] :: Operation -> !Maybe Value

-- | Splice is used to manipulate <tt>Array</tt>s. It can remove and insert
--   multiple elements in a single operation.
Splice :: !Path -> !Int -> !Int -> ![Value] -> Operation
[opPath] :: Operation -> !Path
[opIndex] :: Operation -> !Int
[opRemove] :: Operation -> !Int
[opInsert] :: Operation -> ![Value]
data Object
Object :: !ObjId -> !Text -> !UTCTime -> !ObjId -> !Maybe Bool -> Object
[objectId] :: Object -> !ObjId
[objectType] :: Object -> !Text
[objectCreatedAt] :: Object -> !UTCTime
[objectCreatedBy] :: Object -> !ObjId
[objectDeleted] :: Object -> !Maybe Bool

-- | True if the object exists.
exists :: ObjId -> Avers Bool

-- | Create a new object of the given type. An initial snapshot
--   (<a>RevId</a> 0) is created from the supplied content.
createObject :: ToJSON a => ObjectType a -> ObjId -> a -> Avers ObjId

-- | A more low-level version of <a>createObject</a>, for use when you want
--   to generate your own ObjId or create objects at a specific time.
createObject' :: ToJSON a => ObjId -> UTCTime -> ObjectType a -> ObjId -> a -> Avers ()

-- | Lookup an <a>Object</a> by its <a>ObjId</a>. Throws
--   <a>ObjectNotFound</a> if the object doesn't exist.
lookupObject :: ObjId -> Avers Object

-- | Mark the object as deleted.
deleteObject :: ObjId -> Avers ()

-- | Prune the object from the database. This is only allowed if the object
--   is marked as deleted. Note that this is a very dangerous operation, it
--   can not be undone.
--   
--   TODO: Prune related Release and Authoriation objects.
pruneObject :: ObjId -> Avers ()
objectsOfType :: ObjectType a -> Avers (Vector ObjId)
allObjectsOfType :: ObjectType a -> Avers (Vector ObjId)

-- | Create a checkpoint for for the given object. All patches (and of
--   course snapshots) before the checkpoint can be dropped. Use
--   <a>vacuumObject</a> to do that.
createCheckpoint :: ObjectId -> ObjId -> Avers RevId

-- | Drop all patches and snapshots before the most recent checkpoint. This
--   effectively drops the object's history, and frees space in the
--   database.
vacuumObject :: ObjectId -> Avers ()

-- | Patch
data Patch
Patch :: !ObjectId -> !RevId -> !ObjId -> !UTCTime -> !Operation -> Patch
[patchObjectId] :: Patch -> !ObjectId
[patchRevisionId] :: Patch -> !RevId
[patchAuthorId] :: Patch -> !ObjId
[patchCreatedAt] :: Patch -> !UTCTime
[patchOperation] :: Patch -> !Operation
data PatchError
UnknownPatchError :: !Text -> PatchError
lookupPatch :: ObjectId -> RevId -> Avers Patch

-- | Snapshot
data Snapshot
Snapshot :: !ObjectId -> !RevId -> !Value -> Snapshot
[snapshotObjectId] :: Snapshot -> !ObjectId
[snapshotRevisionId] :: Snapshot -> !RevId
[snapshotContent] :: Snapshot -> !Value

-- | Get the snapshot of the newest revision of the given object.
lookupLatestSnapshot :: ObjectId -> Avers Snapshot

-- | Fetch the content of the object and try to parse it.
--   
--   This function will fail with a <a>ParseError</a> if the content can
--   not be decoded into the desired type.
objectContent :: FromJSON a => ObjectId -> Avers a

-- | Release
data Release
Release :: Release
lookupRelease :: ObjId -> RevId -> Avers Release

-- | Create a new release of the given revision. If the object doesn't
--   exist, it will fail with <a>ObjectNotFound</a>.
createRelease :: ObjId -> RevId -> Avers ()
lookupLatestRelease :: ObjId -> Avers (Maybe RevId)

-- | Resolve the path in the object.
resolvePathIn :: Path -> Value -> Maybe Value

-- | SessionId
newtype SessionId
SessionId :: Text -> SessionId
[unSessionId] :: SessionId -> Text

-- | The session record that is stored in the database.
--   
--   A session is a unique identifier attached to a particular object. It
--   contains the creation date and when it was last accessed. If you need
--   to store additional data for a session, we recommend to use cookies.
data Session
Session :: !SessionId -> !ObjId -> !UTCTime -> !UTCTime -> Session
[sessionId] :: Session -> !SessionId
[sessionObjId] :: Session -> !ObjId
[sessionCreatedAt] :: Session -> !UTCTime
[sessionLastAccessedAt] :: Session -> !UTCTime
saveSession :: Session -> Avers ()
lookupSession :: SessionId -> Avers Session
dropSession :: SessionId -> Avers ()

-- | An <a>ObjectType</a> describes a particular type of object that is
--   managed by Avers.
data ObjectType a
ObjectType :: !Text -> Avers ObjId -> [SomeView a] -> ObjectType a

-- | The value of the <tt>type</tt> field of the <a>Object</a>.
[otType] :: ObjectType a -> !Text

-- | Action which generates a new id. This is so that object types can have
--   different strategies how to generate ids.
[otId] :: ObjectType a -> Avers ObjId
[otViews] :: ObjectType a -> [SomeView a]
data SomeObjectType
[SomeObjectType] :: (ToDatum a, FromDatum a, FromJSON a, ToJSON a) => ObjectType a -> SomeObjectType

-- | Lookup an object type which is registered in the Avers monad.
lookupObjectType :: Text -> Avers SomeObjectType
data AversError
InternalError :: !AversError -> AversError
DatabaseError :: !Text -> AversError
PatchError :: !PatchError -> AversError
ParseError :: !Value -> !Text -> AversError
UnknownObjectType :: !Text -> AversError
ObjectNotFound :: !ObjId -> AversError
DocumentNotFound :: !Text -> AversError
AversError :: !Text -> AversError
NotAuthorized :: AversError

-- | Configuration of the <a>Avers</a> monad.
data Config
Config :: !URI -> (BlobId -> Text -> ByteString -> IO (Either AversError ())) -> ![SomeObjectType] -> (Measurement -> Double -> IO ()) -> Config

-- | <a>URI</a> which describes the connection details to the RethinkDB
--   database. The <a>URI</a> *MUST* include at least the hostname
--   (<a>uriRegName</a>) and database name (<a>uriPath</a> without the
--   leading slash). The port (<a>uriPort</a>) and credentials
--   (<a>uriUserInfo</a>) *MAY* be left empty. in that case the default
--   port will be used.
[databaseURI] :: Config -> !URI

-- | Function which saves the given blob in the blob store. This can be the
--   local filesystem or an external service such as Amazon S3.
[putBlob] :: Config -> BlobId -> Text -> ByteString -> IO (Either AversError ())

-- | All the object types which Avers knows about.
[objectTypes] :: Config -> ![SomeObjectType]

-- | This is called when the internal instrumentation code creates a
--   measurement.
[emitMeasurement] :: Config -> Measurement -> Double -> IO ()
data Handle
newHandle :: Config -> IO (Either AversError Handle)

-- | <i>Deprecated: Use <a>newHandle</a> instead</i>
newState :: Config -> IO (Either AversError Handle)
strErr :: String -> Avers a
parseValueAs :: FromJSON a => ObjectType a -> Value -> Either AversError a
bootstrap :: Avers ()

-- | BlobId
newtype BlobId
BlobId :: Text -> BlobId
[unBlobId] :: BlobId -> Text

-- | Blob
data Blob
Blob :: !BlobId -> !Int -> !Text -> Blob
[blobId] :: Blob -> !BlobId
[blobSize] :: Blob -> !Int
[blobContentType] :: Blob -> !Text
createBlob :: ByteString -> Text -> Avers Blob
lookupBlob :: BlobId -> Avers Blob

-- | SecretId
newtype SecretId
SecretId :: Text -> SecretId
[unSecretId] :: SecretId -> Text

-- | Secret
--   
--   A <a>Secret</a> is a password (encrypted with scrypt) that is attached
--   to a <a>SecretId</a> (for example the <a>ObjId</a> of an account).
--   
--   It is up to you to ensure that <a>SecretId</a>s are unique. If you use
--   <a>ObjId</a>s then they by definition are.
data Secret
Secret :: !SecretId -> !Text -> Secret
[secretId] :: Secret -> !SecretId
[secretValue] :: Secret -> !Text
updateSecret :: SecretId -> Text -> Avers ()

-- | Verify the value against the secret. If that fails, then this function
--   throws an error.
--   
--   This function automatically updates the secret in the database if the
--   scrypt params have changed.
verifySecret :: SecretId -> Text -> Avers ()
applyObjectUpdates :: ObjectId -> RevId -> ObjId -> [Operation] -> Bool -> Avers ([Patch], Int, [Patch])
runQuery :: FromResponse (Result a) => Exp a -> Avers (Result a)
runQueryCollect :: (FromDatum a, Result e ~ Sequence a) => Exp e -> Avers (Vector a)
parseValue :: (FromJSON a, MonadError AversError m) => Value -> m a
parseDatum :: (FromDatum a, MonadError AversError m) => Datum -> m a
newId :: Int -> IO Text
objectsTable :: Exp Table
blobsTable :: Exp Table
validateObject :: Text -> Value -> Avers ()
data View obj a
View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [SomeIndex] -> View obj a

-- | The table name is derived from the view name. Therefore it should be
--   unique amongst all views.
[viewName] :: View obj a -> Text

-- | Function which parses objects stored in this view.
[viewParser] :: View obj a -> Datum -> Either AversError a

-- | Function which transforms an Avers Object into a type stored in the
--   view.
[viewObjectTransformer] :: View obj a -> obj -> Avers (Maybe a)

-- | Secondary indices defined on the view.
[viewIndices] :: View obj a -> [SomeIndex]
data SomeView obj
[SomeView] :: (ToDatum a, FromDatum a, FromJSON obj, ToJSON a) => View obj a -> SomeView obj

-- | Construct the table name for the given view. The table names look
--   something like this: "view_openGames"
viewTable :: View obj a -> Exp Table
updateView :: ToDatum a => View obj a -> ObjId -> Maybe obj -> Avers ()
data Index a
Index :: Text -> (Exp Object -> Exp a) -> Index a
[indexName] :: Index a -> Text
[indexExpression] :: Index a -> Exp Object -> Exp a
data SomeIndex
[SomeIndex] :: IsDatum a => Index a -> SomeIndex
data Measurement
M_avers_storage_lookupObject_duration :: Measurement
M_avers_storage_lookupSnapshot_duration :: Measurement
M_avers_storage_lookupLatestSnapshot_duration :: Measurement
M_avers_storage_newestSnapshot_duration :: Measurement
M_avers_storage_patchesAfterRevision_duration :: Measurement
M_avers_storage_lookupPatch_duration :: Measurement
M_avers_storage_applyObjectUpdates_duration :: Measurement
M_avers_storage_applyObjectUpdates_numOperations :: Measurement
M_avers_storage_applyObjectUpdates_numPreviousPatches :: Measurement
M_avers_storage_exists_duration :: Measurement
measurementLabels :: Measurement -> [[Char]]

-- | A change in the system, for example a new object, patch, release, blob
--   etc.
data Change

-- | A new patch was created.
CPatch :: !Patch -> Change

-- | Return a <a>TChan</a> to which all changes in the system are streamed.
--   Make sure to continuously drain items from the <a>TChan</a>, otherwise
--   they will accumulate in memory and you will run OOM eventually.
--   
--   Do not write into the channel!
changeChannel :: Handle -> IO (TChan Change)
