packages feed

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