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