avers 0.0.4 → 0.0.5
raw patch · 6 files changed
+85/−18 lines, 6 filesdep ~rethinkdb-client-driverPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: rethinkdb-client-driver
API changes (from Hackage documentation)
- Avers: sessionAccountId :: Session -> !ObjId
- Avers.Index: ArbitraryIndex :: (Exp ()) -> Bool -> IndexType
- Avers.Index: CompoundIndex :: [Exp ()] -> IndexType
- Avers.Index: MultiIndex :: (Exp ()) -> IndexType
- Avers.Index: SimpleIndex :: Text -> IndexType
- Avers.Index: data IndexType
- Avers.Index: indexType :: Index -> IndexType
- Avers.Types: sessionAccountId :: Session -> !ObjId
+ Avers: bootstrap :: Avers ()
+ Avers: sessionObjId :: Session -> !ObjId
+ Avers.Index: SomeIndex :: Index a -> SomeIndex
+ Avers.Index: data SomeIndex
+ Avers.Index: indexExpression :: Index a -> Exp Object -> Exp a
+ Avers.Storage: bootstrap :: Avers ()
+ Avers.Storage: createTable :: Text -> [SomeIndex] -> Avers ()
+ Avers.Storage: indexF :: Exp Object -> Exp (Array Datum)
+ Avers.Types: sessionObjId :: Session -> !ObjId
+ Avers.Views: viewTableName :: View obj a -> Text
- Avers: View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [Index] -> View obj a
+ Avers: View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [SomeIndex] -> View obj a
- Avers: viewIndices :: View obj a -> [Index]
+ Avers: viewIndices :: View obj a -> [SomeIndex]
- Avers.Index: Index :: Text -> IndexType -> Index
+ Avers.Index: Index :: Text -> (Exp Object -> Exp a) -> Index a
- Avers.Index: data Index
+ Avers.Index: data Index a
- Avers.Index: indexName :: Index -> Text
+ Avers.Index: indexName :: Index a -> Text
- Avers.Types: View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [Index] -> View obj a
+ Avers.Types: View :: Text -> (Datum -> Either AversError a) -> (obj -> Avers (Maybe a)) -> [SomeIndex] -> View obj a
- Avers.Types: viewIndices :: View obj a -> [Index]
+ Avers.Types: viewIndices :: View obj a -> [SomeIndex]
Files
- avers.cabal +2/−2
- src/Avers.hs +2/−0
- src/Avers/Index.hs +7/−9
- src/Avers/Storage.hs +55/−0
- src/Avers/Types.hs +13/−3
- src/Avers/Views.hs +6/−4
avers.cabal view
@@ -1,5 +1,5 @@ name: avers-version: 0.0.4+version: 0.0.5 license: GPL-3 license-file: LICENSE author: Tomas Carnecky@@ -63,5 +63,5 @@ , inflections , influxdb , resource-pool- , rethinkdb-client-driver >= 0.0.11+ , rethinkdb-client-driver >= 0.0.17 , scrypt
src/Avers.hs view
@@ -67,6 +67,8 @@ , strErr , parseValueAs + , bootstrap+ -- * Blob , BlobId(..) , Blob(..)
src/Avers/Index.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE GADTs #-}+ module Avers.Index where @@ -5,15 +7,11 @@ import qualified Database.RethinkDB as R --data Index = Index- { indexName :: Text- , indexType :: IndexType+data Index a = Index+ { indexName :: Text+ , indexExpression :: R.Exp R.Object -> R.Exp a } -data IndexType- = SimpleIndex Text- | CompoundIndex [R.Exp ()]- | MultiIndex (R.Exp ())- | ArbitraryIndex (R.Exp ()) Bool+data SomeIndex where+ SomeIndex :: (R.IsDatum a) => Index a -> SomeIndex
src/Avers/Storage.hs view
@@ -52,11 +52,14 @@ import Avers.Patching import Avers.TH import Avers.Views+import Avers.Index import Avers.Storage.Backend import Avers.Storage.Expressions +import Prelude + requireResult :: AversError -> Maybe a -> Avers a requireResult err Nothing = throwError err requireResult _ (Just v) = return v@@ -614,3 +617,55 @@ mapId:: R.Exp R.Object -> R.Exp Text mapId = R.GetField "id"+++++--------------------------------------------------------------------------------+-- | Bootstrap the Avers handle: Create necessary tables, indexes, views etc.+-- This operation is idempotent.++indexF :: R.Exp R.Object -> R.Exp (R.Array R.Datum)+indexF obj = R.lift [ R.GetField "objectId" obj, R.GetField "revisionId" obj ]+++bootstrap :: Avers ()+bootstrap = do+ createTable "objects" []+ createTable "sessions" []+ createTable "blobs" []+ createTable "secrets" []++ createTable "patches"+ [ SomeIndex $ Index "objectPatchSequence" indexF+ ]++ createTable "snapshots"+ [ SomeIndex $ Index "objectSnapshotSequence" indexF+ ]++ types <- objectTypes <$> gets config+ forM_ types $ \(SomeObjectType ObjectType{..}) -> do+ forM_ otViews $ \(SomeView v@View{..}) -> do+ createTable (viewTableName v) viewIndices++ return ()+++createTable :: Text -> [SomeIndex] -> Avers ()+createTable name indices = do+ let table = R.Table Nothing $ R.lift name+ db <- fmap R.Database $ fmap R.lift $ fmap databaseName $ gets config++ tables <- runQuery $ R.ListTables db+ when (name `V.notElem` tables) $ do+ liftIO $ putStrLn $ "Creating table '" <> T.unpack name <> "'"+ void $ runQuery $ R.CreateTable db (R.lift name)+ void $ runQuery $ R.WaitTable table++ existingIndices <- runQuery $ R.ListIndices table+ forM_ indices $ \(SomeIndex Index{..}) -> do+ when (indexName `V.notElem` existingIndices) $ do+ liftIO $ putStrLn $ "Creating index '" <> T.unpack indexName <> "' on table '" <> T.unpack name <> "'"+ void $ runQuery $ R.CreateIndex table (R.lift indexName) indexExpression+ void $ runQuery $ R.WaitIndex table [R.lift indexName]
src/Avers/Types.hs view
@@ -339,6 +339,12 @@ ----------------------------------------------------------------------------- -- | Secret+--+-- A 'Secret' is a password (encrypted with scrypt) that is attached to+-- a 'SecretId' (for example the 'ObjId' of an account).+--+-- It is up to you to ensure that 'SecretId's are unique. If you use 'ObjId's+-- then they by definition are. data Secret = Secret { secretId :: !SecretId@@ -414,11 +420,15 @@ -------------------------------------------------------------------------------- | The record that is stored in the database.+-- | 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 :: !SessionId- , sessionAccountId :: !ObjId+ , sessionObjId :: !ObjId , sessionCreatedAt :: !UTCTime , sessionLastAccessedAt :: !UTCTime }@@ -594,7 +604,7 @@ -- ^ Function which transforms an Avers Object into a type stored -- in the view. - , viewIndices :: [Index]+ , viewIndices :: [SomeIndex] -- ^ Secondary indices defined on the view. }
src/Avers/Views.hs view
@@ -10,6 +10,7 @@ import Control.Monad +import Data.Text (Text) import Data.Aeson as Aeson import Data.Monoid import qualified Data.HashMap.Strict as HMS@@ -21,13 +22,14 @@ +viewTableName :: View obj a -> Text+viewTableName View{..} = "view_" <> viewName++ -- | Construct the table name for the given view. The table names look -- something like this: "view_openGames" viewTable :: View obj a -> R.Exp R.Table-viewTable View{..} = R.Table Nothing $ R.lift $ mconcat- [ "view_"- , viewName- ]+viewTable view = R.Table Nothing $ R.lift $ viewTableName view data Record a = Record