on master help sign in
add some haddock lines in the main modules of concern.

haddock does not yet support GADT constructor documentation

commitb3f3f024b233f23fd551f08c9d262a6ab59c8a99 authorAgentM <agentm@themactionfaction.com> dateWed 2 Dec 2015, 16:40 (11 years ago) parent4fea717
3 files changed+59−19
Database/Persist/ProjectM36.hs+1−1 ProjectM36/Base.hs+39−14 ProjectM36/Client.hs+19−4
Database/Persist/ProjectM36.hs+1−1
@@ -346,7 +346,7 @@ instance FromJSON C.ConnectionInfo where
346346 return ctype
347347
348348instance PersistConfig C.ConnectionInfo where
349− -- | Hold onto a connection as well a default session.
349+ --- | Hold onto a connection as well a default session.
350350 type PersistConfigBackend C.ConnectionInfo = ReaderT ProjectM36Backend
351351 type PersistConfigPool C.ConnectionInfo = ProjectM36Backend
352352
ProjectM36/Base.hs+39−14
@@ -26,6 +26,7 @@ import ProjectM36.ConcreteTypeRep
2626
2727type StringType = Text
2828
29+-- | Any data type represents as an 'Atom' in the database must adhere to the 'Atomable' typeclass.
2930class (Read a,
3031 Hashable a,
3132 Binary a,
@@ -54,6 +55,7 @@ instance Atomable Bool
5455instance Atomable Relation
5556instance (Atomable a) => Atomable (Maybe a)
5657
58+-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
5759data Atom = forall a. Atomable a => Atom a
5860
5961instance Eq Atom where
@@ -94,6 +96,7 @@ instance NFData Atom where
9496instance Hashable Atom where
9597 hashWithSalt salt (Atom a) = hashWithSalt salt a
9698
99+-- | Return the type of an 'Atom'.
97100atomTypeForAtom :: Atom -> AtomType
98101atomTypeForAtom (Atom atom) = case cast atom of
99102 Just (Relation attrs _) -> RelationAtomType attrs
@@ -116,12 +119,14 @@ data AtomType = AtomType ConcreteTypeRep |
116119 AnyAtomType --wildcard used in Atom Functions
117120 deriving (Eq,NFData,Generic,Binary,Show)
118121
122+-- | Return True iff the atom type argument is relation-valued. If True, this indicates that the Atom contains a relation.
119123isRelationAtomType :: AtomType -> Bool
120124isRelationAtomType (RelationAtomType _) = True
121125isRelationAtomType _ = False
122126
123127type AttributeName = StringType
124128
129+-- | A relation's type is composed of attribute names and types.
125130data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic)
126131
127132instance Hashable Attribute where
@@ -131,8 +136,10 @@ instance NFData Attribute where rnf = genericRnf
131136
132137instance Binary Attribute
133138
139+-- | 'Attributes' represent the head of a relation.
134140type Attributes = V.Vector Attribute
135141
142+-- | Equality function for a set of attributes.
136143attributesEqual :: Attributes -> Attributes -> Bool
137144attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
138145 where
@@ -141,6 +148,7 @@ attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
141148sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
142149sortedAttributesIndices attrs = L.sortBy (\(_, (Attribute name1 _)) (_,(Attribute name2 _)) -> compare name1 name2) $ V.toList (V.indexed attrs)
143150
151+-- | The relation's tuple set is the body of the relation.
144152newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Binary)
145153
146154instance Read Relation where
@@ -168,7 +176,7 @@ instance Hashable RelationTuple where
168176 sortedAttrs = map snd sortedAttrsIndices
169177 sortedTupVec = V.map (\(index, _) -> tupVec V.! index) $ V.fromList sortedAttrsIndices
170178
171−--maybe the attribute->int mapping should be stored once in the relation and then passed down when needed
179+-- | A tuple is a set of attributes mapped to their 'Atom' values.
172180data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Generic)
173181
174182instance Binary RelationTuple
@@ -202,22 +210,35 @@ instance Binary Relation
202210data RelationCardinality = Uncountable | Countable Int deriving (Eq, Show, Generic, Ord)
203211data RelationSizeInfinite = RelationSizeInfinite
204212
213+-- | Relation variables are identified by their names.
205214type RelVarName = StringType
206215
216+-- | A relational expression represents query (read) operations on a database.
207217data RelationalExpr where
218+ --- | Create and reference a relation from attributes and a tuple set.
208219 MakeStaticRelation :: Attributes -> RelationTupleSet -> RelationalExpr
220+ --- | Reference an existing relation in Haskell-space.
209221 ExistingRelation :: Relation -> RelationalExpr
210222 --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
211223 --in Tutorial D, relational variables pick up the type of the first relation assigned to them
212224 --relational variables should also be able to be explicitly-typed like in Haskell
225+ --- | Reference a relation variable by its name.
213226 RelationVariable :: RelVarName -> RelationalExpr
227+ --- | Create a projection over attribute names. (Note that the 'AttributeNames' structure allows for the names to be inverted.)
214228 Project :: AttributeNames -> RelationalExpr -> RelationalExpr
229+ --- | Create a union of two relational expressions. The expressions should have identical attributes.
215230 Union :: RelationalExpr -> RelationalExpr -> RelationalExpr
231+ --- | Create a join of two relational expressions. The join occurs on attributes which are identical. If the expressions have no overlapping attributes, the join becomes a cross-product of both tuple sets.
216232 Join :: RelationalExpr -> RelationalExpr -> RelationalExpr
233+ --- | Rename an attribute (first argument) to another (second argument).
217234 Rename :: AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
235+ --- | Create a sub-relation composed of the first argument's attributes which will become an attribute of the result expression. The unreferenced attributes are not altered in the result but duplicate tuples in the projection of the expression minus the attribute names are compressed into one. For more information, <https://github.com/agentm/project-m36/blob/master/docs/introduction_to_the_relational_algebra.markdown#group read the relational algebra tutorial.>
218236 Group :: AttributeNames -> AttributeName -> RelationalExpr -> RelationalExpr
237+ --- | Create an expression to unwrap a sub-relation contained within at an attribute's name. Note that this is not always an inverse of a group operation.
219238 Ungroup :: AttributeName -> RelationalExpr -> RelationalExpr
239+ --- | Filter the tuples of the relational expression to only retain the tuples which evaluate against the restriction predicate to true.
220240 Restrict :: RestrictionPredicateExpr -> RelationalExpr -> RelationalExpr
241+ --- | Returns the true relation iff
221242 Equals :: RelationalExpr -> RelationalExpr -> RelationalExpr
222243 NotEquals :: RelationalExpr -> RelationalExpr -> RelationalExpr
223244 Extend :: TupleExpr -> RelationalExpr -> RelationalExpr
@@ -226,21 +247,21 @@ data RelationalExpr where
226247
227248instance Binary RelationalExpr
228249
250+-- | The DatabaseContext is a snapshot of a database's evolving state and contains everything a database client can change over time.
229251data DatabaseContext = DatabaseContext {
230252 inclusionDependencies :: M.Map IncDepName InclusionDependency,
231253 relationVariables :: M.Map RelVarName Relation,
232254 atomFunctions :: AtomFunctions
233255 } deriving (Show, Generic)
234256
235−--instance Binary DatabaseContext
236−
237257type IncDepName = StringType
238258
259+-- | Inclusion dependencies represent every possible database constraints. Constraints enforce specific, arbitrarily-complex rules to which the database context must adhere.
239260data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic)
240261
241262instance Binary InclusionDependency
242263
243−--Database context expressions modify the database context while relational expressions do not
264+-- | Database context expressions modify the database context.
244265data DatabaseExpr where
245266 Define :: RelVarName -> Attributes -> DatabaseExpr
246267 Undefine :: RelVarName -> DatabaseExpr --forget existence of relvar X
@@ -255,6 +276,7 @@ data DatabaseExpr where
255276
256277type DatabaseState a = State DatabaseContext a
257278
279+-- | Restriction predicate are boolean algebra components which, when composed, indicate whether or not a tuple should be retained during a restriction (filtering) operation.
258280data RestrictionPredicateExpr where
259281 TruePredicate :: RestrictionPredicateExpr
260282 AndPredicate :: RestrictionPredicateExpr -> RestrictionPredicateExpr -> RestrictionPredicateExpr
@@ -268,11 +290,12 @@ data RestrictionPredicateExpr where
268290instance Binary RestrictionPredicateExpr
269291
270292-- child + parent links
271−-- the string represents the branch name and can be used to find the named HEADs
293+-- | A transaction graph's head name references the leaves of the transaction graph and can be used during session creation to indicate at which point in the graph commits should persist.
272294type HeadName = StringType
273295
274296type TransactionHeads = M.Map HeadName Transaction
275297
298+-- | The transaction graph is the global database's state which references every committed transaction.
276299data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
277300 deriving (Show, Eq)
278301
@@ -282,20 +305,20 @@ transactionsForGraph (TransactionGraph _ t) = t
282305transactionHeadsForGraph :: TransactionGraph -> TransactionHeads
283306transactionHeadsForGraph (TransactionGraph heads _) = heads
284307
308+-- | Every transaction has context-specific information attached to it.
285309data TransactionInfo = TransactionInfo UUID (S.Set UUID) | -- 1 parent + n children
286310 MergeTransactionInfo UUID UUID (S.Set UUID) -- 2 parents, n children
287311 deriving(Show, Generic)
288312
289313instance Binary TransactionInfo
290314
315+-- | Every set of modifications made to the database are atomically committed to the transaction graph as a transaction.
291316data Transaction = Transaction UUID TransactionInfo DatabaseContext -- self uuid
292317 deriving (Show, Generic)
293318
294319--instance Binary Transaction
295320
296−--represents an "in-progress" transaction which has not yet been added to the transaction graph
297−--one the transaction is "complete", it is committed and no longer can be changed
298−-- this is similar to the index in git
321+-- | The disconnected transaction represents an in-progress workspace used by sessions before changes are committed. This is similar to git's "index". After a transaction is committed, it is "connected" in the transaction graph and can no longer be modified.
299322data DisconnectedTransaction = DisconnectedTransaction UUID DatabaseContext --parentUUID, context
300323
301324transactionUUID :: Transaction -> UUID
@@ -313,7 +336,7 @@ instance Eq Transaction where
313336instance Ord Transaction where
314337 compare (Transaction uuidA _ _) (Transaction uuidB _ _) = compare uuidA uuidB
315338
316−--used on the right side of attribute assignments
339+-- | An atom expression represents an action to take when extending a relation.
317340data AtomExpr = AttributeAtomExpr AttributeName |
318341 NakedAtomExpr Atom |
319342 FunctionAtomExpr AtomFunctionName [AtomExpr] |
@@ -322,7 +345,7 @@ data AtomExpr = AttributeAtomExpr AttributeName |
322345
323346instance Binary AtomExpr
324347
325−--used to extend a relation
348+-- | A tuple expression declares what action to take when extending a relation.
326349data TupleExpr = AttributeTupleExpr AttributeName AtomExpr
327350 deriving (Show, Eq, Generic)
328351
@@ -333,6 +356,7 @@ type AtomFunctions = HS.HashSet AtomFunction
333356
334357type AtomFunctionName = StringType
335358
359+-- | An AtomFunction has a name, a type, and a function body to execute when called.
336360data AtomFunction = AtomFunction {
337361 atomFuncName :: AtomFunctionName,
338362 atomFuncType :: [AtomType],
@@ -350,16 +374,17 @@ instance Show AtomFunction where
350374 where
351375 showArgTypes = concat (L.intersperse "->" $ map show (atomFuncType aFunc))
352376
377+-- | The 'AttributeNames' structure represents a set of attribute names or the same set of names but inverted in the context of a relational expression. For example, if a relational expression has attributes named "a", "b", and "c", the 'InvertedAttributeNames' of ("a","c") is ("b").
353378data AttributeNames = AttributeNames (S.Set AttributeName) |
354379 InvertedAttributeNames (S.Set AttributeName)
355380 deriving (Eq, Show, Generic)
356381
357382instance Binary AttributeNames
358383
359−--used for global dbms configuration- per-transaction flag is elsewhere
360−data PersistenceStrategy = NoPersistence | --no filesystem persistence/memory-only database
361− MinimalPersistence FilePath | --fsync off
362− CrashSafePersistence FilePath --full fsync- not yet implemented
384+-- | The persistence strategy is a global database option which represents how to persist the database in the filesystem, if at all.
385+data PersistenceStrategy = NoPersistence | -- ^ no filesystem persistence/memory-only database
386+ MinimalPersistence FilePath | -- ^ fsync off, not crash-safe
387+ CrashSafePersistence FilePath -- ^ full fsync to disk (flushes kernel and physical drive buffers to ensure that the transaction is on non-volatile storage)
363388 deriving (Show, Read)
364389
365390
ProjectM36/Client.hs+19−4
@@ -97,10 +97,11 @@ defaultHeadName = "master"
9797defaultRemoteConnectionInfo :: ConnectionInfo
9898defaultRemoteConnectionInfo = RemoteProcessConnectionInfo defaultDatabaseName (createNodeId "127.0.0.1" defaultServerPort)
9999
100−
100+-- | The 'Connection' represents either local or remote access to a database. All operations flow through the connection.
101101data Connection = InProcessConnection PersistenceStrategy Sessions (TVar TransactionGraph) |
102102 RemoteProcessConnection LocalNode ProcessId
103103
104+-- | There are several reasons why a connection can fail.
104105data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
105106 IOExceptionError IOException |
106107 NoSuchDatabaseByNameError DatabaseName |
@@ -110,6 +111,7 @@ data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
110111remoteDBLookupName :: DatabaseName -> String
111112remoteDBLookupName = (++) "db-"
112113
114+
113115commonLocalNode :: IO (Either ConnectionError LocalNode)
114116commonLocalNode = do
115117 eLocalTransport <- createTransport "127.0.0.1" "0" defaultTCPParameters
@@ -117,7 +119,7 @@ commonLocalNode = do
117119 Left err -> pure (Left $ IOExceptionError err)
118120 Right localTransport -> newLocalNode localTransport initRemoteTable >>= pure . Right
119121
120−-- connect to an in-process database
122+-- | To create a 'Connection' to a remote or local database, create a connectionInfo and call 'connectProjectM36'.
121123connectProjectM36 :: ConnectionInfo -> IO (Either ConnectionError Connection)
122124--create a new in-memory database/transaction graph
123125connectProjectM36 (InProcessConnectionInfo strat) = do
@@ -195,6 +197,7 @@ createSessionAtCommit_ commitUUID newSessionId (InProcessConnection _ sessions g
195197 pure $ Right newSessionId
196198createSessionAtCommit_ _ _ (RemoteProcessConnection _ _) = error "createSessionAtCommit_ called on remote connection"
197199
200+-- | Call 'createSessionAtHead' with a transaction graph's head's name to create a new session pinned to that head. This function returns a 'SessionId' which can be used in other function calls to reference the point in the transaction graph.
198201createSessionAtHead :: HeadName -> Connection -> IO (Either RelationalError SessionId)
199202createSessionAtHead headn conn@(InProcessConnection _ _ tvar) = do
200203 newSessionId <- nextRandom
@@ -211,7 +214,7 @@ closeSession sessionId (InProcessConnection _ sessions _) = do
211214 atomically $ do
212215 STMMap.delete sessionId sessions
213216closeSession sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (CloseSession sessionId)
214−
217+-- | 'close' cleans up the database access connection. Note that sessions persist even after the connection is closed.
215218close :: Connection -> IO ()
216219close (InProcessConnection _ sessions _) = atomically $ do
217220 traverse_ (\(k,_) -> STMMap.delete k sessions) (STMMap.stream sessions)
@@ -241,6 +244,7 @@ sessionForSessionId sessionId sessions = do
241244 maybeSession <- STMMap.lookup sessionId sessions
242245 pure $ maybe (Left $ NoSuchSession sessionId) Right maybeSession
243246
247+-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
244248executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
245249executeRelationalExpr sessionId (InProcessConnection _ sessions _) expr = atomically $ do
246250 eSession <- sessionForSessionId sessionId sessions
@@ -249,6 +253,7 @@ executeRelationalExpr sessionId (InProcessConnection _ sessions _) expr = atomic
249253 Right (Session (DisconnectedTransaction _ context)) -> pure $ evalState (RE.evalRelationalExpr expr) context
250254executeRelationalExpr sessionId conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
251255
256+-- | Execute a database context expression in the context of the session and connection. Database expressions modify the current session's disconnected transaction but cannot modify the transaction graph.
252257executeDatabaseContextExpr :: SessionId -> Connection -> DatabaseExpr -> IO (Maybe RelationalError)
253258executeDatabaseContextExpr sessionId (InProcessConnection _ sessions _) expr = atomically $ do
254259 eSession <- sessionForSessionId sessionId sessions
@@ -263,6 +268,7 @@ executeDatabaseContextExpr sessionId (InProcessConnection _ sessions _) expr = a
263268 return Nothing
264269executeDatabaseContextExpr sessionId conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextExpr sessionId dbExpr)
265270
271+-- | Execute a transaction graph expression in the context of the session and connection. Transaction graph operators modify the transaction graph state.
266272executeGraphExpr :: SessionId -> Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
267273executeGraphExpr sessionId (InProcessConnection strat sessions graphTvar) graphExpr = do
268274 freshUUID <- nextRandom
@@ -287,10 +293,12 @@ executeGraphExpr sessionId (InProcessConnection strat sessions graphTvar) graphE
287293 return Nothing
288294executeGraphExpr sessionId conn@(RemoteProcessConnection _ _) graphExpr = remoteCall conn (ExecuteGraphExpr sessionId graphExpr)
289295
296+-- | After modifying a session, 'commit' the transaction to the transaction graph at the head which the session is referencing.
290297commit :: SessionId -> Connection -> IO (Maybe RelationalError)
291298commit sessionId conn@(InProcessConnection _ _ _) = executeGraphExpr sessionId conn Commit
292299commit sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr sessionId Commit)
293300
301+-- | Discard any changes made in the current session. This resets the disconnected transaction to reference the original database context of the parent transaction and is a very cheap operation.
294302rollback :: SessionId -> Connection -> IO (Maybe RelationalError)
295303rollback sessionId conn@(InProcessConnection _ _ _) = executeGraphExpr sessionId conn Rollback
296304rollback sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr sessionId Rollback)
@@ -300,6 +308,7 @@ processPersistence NoPersistence _ = return ()
300308processPersistence (MinimalPersistence dbdir) graph = transactionGraphPersist NoDiskSync dbdir graph
301309processPersistence (CrashSafePersistence dbdir) graph = transactionGraphPersist FsyncDiskSync dbdir graph
302310
311+-- | Return a relation whose type would match that of the relational expression if it were executed. This is useful for checking types and validating a relational expression's types.
303312typeForRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
304313typeForRelationalExpr sessionId conn@(InProcessConnection _ _ _) relExpr = atomically $ typeForRelationalExprSTM sessionId conn relExpr
305314typeForRelationalExpr sessionId conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteTypeForRelationalExpr sessionId relExpr)
@@ -313,6 +322,7 @@ typeForRelationalExprSTM sessionId (InProcessConnection _ sessions _) relExpr =
313322
314323typeForRelationalExprSTM _ _ _ = error "typeForRelationalExprSTM called on non-local connection"
315324
325+-- | Return a 'Map' of the database's constraints at the context of the session and connection.
316326inclusionDependencies :: SessionId -> Connection -> IO (Either RelationalError (M.Map IncDepName InclusionDependency))
317327inclusionDependencies sessionId (InProcessConnection _ sessions _) = do
318328 atomically $ do
@@ -323,7 +333,7 @@ inclusionDependencies sessionId (InProcessConnection _ sessions _) = do
323333
324334inclusionDependencies sessionId conn@(RemoteProcessConnection _ _) = remoteCall conn (RetrieveInclusionDependencies sessionId)
325335
326−
336+-- | Return an optimized database expression which is logically equivalent to the input database expression. This function can be used to determine which expression will actually be evaluated.
327337planForDatabaseContextExpr :: SessionId -> Connection -> DatabaseExpr -> IO (Either RelationalError DatabaseExpr)
328338planForDatabaseContextExpr sessionId (InProcessConnection _ sessions _) dbExpr = do
329339 atomically $ do
@@ -333,6 +343,11 @@ planForDatabaseContextExpr sessionId (InProcessConnection _ sessions _) dbExpr =
333343 Right session -> pure $ evalState (applyStaticDatabaseOptimization dbExpr) (sessionContext session)
334344planForDatabaseContextExpr sessionId conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (RetrievePlanForDatabaseContextExpr sessionId dbExpr)
335345
346+-- | Return a relation which represents the current state of the global transaction graph. The attributes are
347+-- * current- boolean attribute representing whether or not the current session references this transaction
348+-- * head- text attribute which is a non-empty 'HeadName' iff the transaction references a head.
349+-- * id- UUID attribute of the transaction
350+-- * parents- a relation-valued attribute which contains a relation of UUIDs which are parent transaction to the transaction
336351transactionGraphAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
337352transactionGraphAsRelation sessionId (InProcessConnection _ sessions tvar) = do
338353 atomically $ do