@@ -26,6 +26,7 @@ import ProjectM36.ConcreteTypeRep
27type StringType = Text
27type StringType = Text
29+-- | Any data type represents as an 'Atom' in the database must adhere to the 'Atomable' typeclass.
29class (Read a,
30class (Read a,
30 Hashable a,
31 Hashable a,
31 Binary a,
32 Binary a,
@@ -54,6 +55,7 @@ instance Atomable Bool
54instance Atomable Relation
55instance Atomable Relation
55instance (Atomable a) => Atomable (Maybe a)
56instance (Atomable a) => Atomable (Maybe a)
58+-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
57data Atom = forall a. Atomable a => Atom a
59data Atom = forall a. Atomable a => Atom a
59instance Eq Atom where
61instance Eq Atom where
@@ -94,6 +96,7 @@ instance NFData Atom where
94instance Hashable Atom where
96instance Hashable Atom where
95 hashWithSalt salt (Atom a) = hashWithSalt salt a
97 hashWithSalt salt (Atom a) = hashWithSalt salt a
99+-- | Return the type of an 'Atom'.
97atomTypeForAtom :: Atom -> AtomType
100atomTypeForAtom :: Atom -> AtomType
98atomTypeForAtom (Atom atom) = case cast atom of
101atomTypeForAtom (Atom atom) = case cast atom of
99 Just (Relation attrs _) -> RelationAtomType attrs
102 Just (Relation attrs _) -> RelationAtomType attrs
@@ -116,12 +119,14 @@ data AtomType = AtomType ConcreteTypeRep |
116 AnyAtomType --wildcard used in Atom Functions
119 AnyAtomType --wildcard used in Atom Functions
117 deriving (Eq,NFData,Generic,Binary,Show)
120 deriving (Eq,NFData,Generic,Binary,Show)
122+-- | Return True iff the atom type argument is relation-valued. If True, this indicates that the Atom contains a relation.
119isRelationAtomType :: AtomType -> Bool
123isRelationAtomType :: AtomType -> Bool
120isRelationAtomType (RelationAtomType _) = True
124isRelationAtomType (RelationAtomType _) = True
121isRelationAtomType _ = False
125isRelationAtomType _ = False
123type AttributeName = StringType
127type AttributeName = StringType
129+-- | A relation's type is composed of attribute names and types.
125data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic)
130data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic)
127instance Hashable Attribute where
132instance Hashable Attribute where
@@ -131,8 +136,10 @@ instance NFData Attribute where rnf = genericRnf
132instance Binary Attribute
137instance Binary Attribute
139+-- | 'Attributes' represent the head of a relation.
134type Attributes = V.Vector Attribute
140type Attributes = V.Vector Attribute
142+-- | Equality function for a set of attributes.
136attributesEqual :: Attributes -> Attributes -> Bool
143attributesEqual :: Attributes -> Attributes -> Bool
137attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
144attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
@@ -141,6 +148,7 @@ attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
141sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
148sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
142sortedAttributesIndices attrs = L.sortBy (\(_, (Attribute name1 _)) (_,(Attribute name2 _)) -> compare name1 name2) $ V.toList (V.indexed attrs)
149sortedAttributesIndices attrs = L.sortBy (\(_, (Attribute name1 _)) (_,(Attribute name2 _)) -> compare name1 name2) $ V.toList (V.indexed attrs)
151+-- | The relation's tuple set is the body of the relation.
144newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Binary)
152newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Binary)
146instance Read Relation where
154instance Read Relation where
@@ -168,7 +176,7 @@ instance Hashable RelationTuple where
168 sortedAttrs = map snd sortedAttrsIndices
176 sortedAttrs = map snd sortedAttrsIndices
169 sortedTupVec = V.map (\(index, _) -> tupVec V.! index) $ V.fromList sortedAttrsIndices
177 sortedTupVec = V.map (\(index, _) -> tupVec V.! index) $ V.fromList sortedAttrsIndices
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.
172data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Generic)
180data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Generic)
174instance Binary RelationTuple
182instance Binary RelationTuple
@@ -202,22 +210,35 @@ instance Binary Relation
202data RelationCardinality = Uncountable | Countable Int deriving (Eq, Show, Generic, Ord)
210data RelationCardinality = Uncountable | Countable Int deriving (Eq, Show, Generic, Ord)
203data RelationSizeInfinite = RelationSizeInfinite
211data RelationSizeInfinite = RelationSizeInfinite
213+-- | Relation variables are identified by their names.
205type RelVarName = StringType
214type RelVarName = StringType
216+-- | A relational expression represents query (read) operations on a database.
207data RelationalExpr where
217data RelationalExpr where
218+ --- | Create and reference a relation from attributes and a tuple set.
208 MakeStaticRelation :: Attributes -> RelationTupleSet -> RelationalExpr
219 MakeStaticRelation :: Attributes -> RelationTupleSet -> RelationalExpr
220+ --- | Reference an existing relation in Haskell-space.
209 ExistingRelation :: Relation -> RelationalExpr
221 ExistingRelation :: Relation -> RelationalExpr
210 --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
222 --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
211 --in Tutorial D, relational variables pick up the type of the first relation assigned to them
223 --in Tutorial D, relational variables pick up the type of the first relation assigned to them
212 --relational variables should also be able to be explicitly-typed like in Haskell
224 --relational variables should also be able to be explicitly-typed like in Haskell
225+ --- | Reference a relation variable by its name.
213 RelationVariable :: RelVarName -> RelationalExpr
226 RelationVariable :: RelVarName -> RelationalExpr
227+ --- | Create a projection over attribute names. (Note that the 'AttributeNames' structure allows for the names to be inverted.)
214 Project :: AttributeNames -> RelationalExpr -> RelationalExpr
228 Project :: AttributeNames -> RelationalExpr -> RelationalExpr
229+ --- | Create a union of two relational expressions. The expressions should have identical attributes.
215 Union :: RelationalExpr -> RelationalExpr -> RelationalExpr
230 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.
216 Join :: RelationalExpr -> RelationalExpr -> RelationalExpr
232 Join :: RelationalExpr -> RelationalExpr -> RelationalExpr
233+ --- | Rename an attribute (first argument) to another (second argument).
217 Rename :: AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
234 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.>
218 Group :: AttributeNames -> AttributeName -> RelationalExpr -> RelationalExpr
236 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.
219 Ungroup :: AttributeName -> RelationalExpr -> RelationalExpr
238 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.
220 Restrict :: RestrictionPredicateExpr -> RelationalExpr -> RelationalExpr
240 Restrict :: RestrictionPredicateExpr -> RelationalExpr -> RelationalExpr
241+ --- | Returns the true relation iff
221 Equals :: RelationalExpr -> RelationalExpr -> RelationalExpr
242 Equals :: RelationalExpr -> RelationalExpr -> RelationalExpr
222 NotEquals :: RelationalExpr -> RelationalExpr -> RelationalExpr
243 NotEquals :: RelationalExpr -> RelationalExpr -> RelationalExpr
223 Extend :: TupleExpr -> RelationalExpr -> RelationalExpr
244 Extend :: TupleExpr -> RelationalExpr -> RelationalExpr
@@ -226,21 +247,21 @@ data RelationalExpr where
227instance Binary RelationalExpr
248instance Binary RelationalExpr
250+-- | The DatabaseContext is a snapshot of a database's evolving state and contains everything a database client can change over time.
229data DatabaseContext = DatabaseContext {
251data DatabaseContext = DatabaseContext {
230 inclusionDependencies :: M.Map IncDepName InclusionDependency,
252 inclusionDependencies :: M.Map IncDepName InclusionDependency,
231 relationVariables :: M.Map RelVarName Relation,
253 relationVariables :: M.Map RelVarName Relation,
232 atomFunctions :: AtomFunctions
254 atomFunctions :: AtomFunctions
233 } deriving (Show, Generic)
255 } deriving (Show, Generic)
235−--instance Binary DatabaseContext
237type IncDepName = StringType
257type IncDepName = StringType
259+-- | Inclusion dependencies represent every possible database constraints. Constraints enforce specific, arbitrarily-complex rules to which the database context must adhere.
239data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic)
260data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic)
241instance Binary InclusionDependency
262instance Binary InclusionDependency
243−--Database context expressions modify the database context while relational expressions do not
264+-- | Database context expressions modify the database context.
244data DatabaseExpr where
265data DatabaseExpr where
245 Define :: RelVarName -> Attributes -> DatabaseExpr
266 Define :: RelVarName -> Attributes -> DatabaseExpr
246 Undefine :: RelVarName -> DatabaseExpr --forget existence of relvar X
267 Undefine :: RelVarName -> DatabaseExpr --forget existence of relvar X
@@ -255,6 +276,7 @@ data DatabaseExpr where
256type DatabaseState a = State DatabaseContext a
277type DatabaseState a = State DatabaseContext a
279+-- | Restriction predicate are boolean algebra components which, when composed, indicate whether or not a tuple should be retained during a restriction (filtering) operation.
258data RestrictionPredicateExpr where
280data RestrictionPredicateExpr where
259 TruePredicate :: RestrictionPredicateExpr
281 TruePredicate :: RestrictionPredicateExpr
260 AndPredicate :: RestrictionPredicateExpr -> RestrictionPredicateExpr -> RestrictionPredicateExpr
282 AndPredicate :: RestrictionPredicateExpr -> RestrictionPredicateExpr -> RestrictionPredicateExpr
@@ -268,11 +290,12 @@ data RestrictionPredicateExpr where
268instance Binary RestrictionPredicateExpr
290instance Binary RestrictionPredicateExpr
270-- child + parent links
292-- 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.
272type HeadName = StringType
294type HeadName = StringType
274type TransactionHeads = M.Map HeadName Transaction
296type TransactionHeads = M.Map HeadName Transaction
298+-- | The transaction graph is the global database's state which references every committed transaction.
276data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
299data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
277 deriving (Show, Eq)
300 deriving (Show, Eq)
@@ -282,20 +305,20 @@ transactionsForGraph (TransactionGraph _ t) = t
282transactionHeadsForGraph :: TransactionGraph -> TransactionHeads
305transactionHeadsForGraph :: TransactionGraph -> TransactionHeads
283transactionHeadsForGraph (TransactionGraph heads _) = heads
306transactionHeadsForGraph (TransactionGraph heads _) = heads
308+-- | Every transaction has context-specific information attached to it.
285data TransactionInfo = TransactionInfo UUID (S.Set UUID) | -- 1 parent + n children
309data TransactionInfo = TransactionInfo UUID (S.Set UUID) | -- 1 parent + n children
286 MergeTransactionInfo UUID UUID (S.Set UUID) -- 2 parents, n children
310 MergeTransactionInfo UUID UUID (S.Set UUID) -- 2 parents, n children
287 deriving(Show, Generic)
311 deriving(Show, Generic)
289instance Binary TransactionInfo
313instance Binary TransactionInfo
315+-- | Every set of modifications made to the database are atomically committed to the transaction graph as a transaction.
291data Transaction = Transaction UUID TransactionInfo DatabaseContext -- self uuid
316data Transaction = Transaction UUID TransactionInfo DatabaseContext -- self uuid
292 deriving (Show, Generic)
317 deriving (Show, Generic)
294--instance Binary Transaction
319--instance Binary Transaction
296−--represents an "in-progress" transaction which has not yet been added to the transaction graph
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.
297−--one the transaction is "complete", it is committed and no longer can be changed
298−-- this is similar to the index in git
299data DisconnectedTransaction = DisconnectedTransaction UUID DatabaseContext --parentUUID, context
322data DisconnectedTransaction = DisconnectedTransaction UUID DatabaseContext --parentUUID, context
301transactionUUID :: Transaction -> UUID
324transactionUUID :: Transaction -> UUID
@@ -313,7 +336,7 @@ instance Eq Transaction where
313instance Ord Transaction where
336instance Ord Transaction where
314 compare (Transaction uuidA _ _) (Transaction uuidB _ _) = compare uuidA uuidB
337 compare (Transaction uuidA _ _) (Transaction uuidB _ _) = compare uuidA uuidB
316−--used on the right side of attribute assignments
339+-- | An atom expression represents an action to take when extending a relation.
317data AtomExpr = AttributeAtomExpr AttributeName |
340data AtomExpr = AttributeAtomExpr AttributeName |
318 NakedAtomExpr Atom |
341 NakedAtomExpr Atom |
319 FunctionAtomExpr AtomFunctionName [AtomExpr] |
342 FunctionAtomExpr AtomFunctionName [AtomExpr] |
@@ -322,7 +345,7 @@ data AtomExpr = AttributeAtomExpr AttributeName |
323instance Binary AtomExpr
346instance Binary AtomExpr
325−--used to extend a relation
348+-- | A tuple expression declares what action to take when extending a relation.
326data TupleExpr = AttributeTupleExpr AttributeName AtomExpr
349data TupleExpr = AttributeTupleExpr AttributeName AtomExpr
327 deriving (Show, Eq, Generic)
350 deriving (Show, Eq, Generic)
@@ -333,6 +356,7 @@ type AtomFunctions = HS.HashSet AtomFunction
334type AtomFunctionName = StringType
357type AtomFunctionName = StringType
359+-- | An AtomFunction has a name, a type, and a function body to execute when called.
336data AtomFunction = AtomFunction {
360data AtomFunction = AtomFunction {
337 atomFuncName :: AtomFunctionName,
361 atomFuncName :: AtomFunctionName,
338 atomFuncType :: [AtomType],
362 atomFuncType :: [AtomType],
@@ -350,16 +374,17 @@ instance Show AtomFunction where
351 showArgTypes = concat (L.intersperse "->" $ map show (atomFuncType aFunc))
375 showArgTypes = concat (L.intersperse "->" $ map show (atomFuncType aFunc))
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").
353data AttributeNames = AttributeNames (S.Set AttributeName) |
378data AttributeNames = AttributeNames (S.Set AttributeName) |
354 InvertedAttributeNames (S.Set AttributeName)
379 InvertedAttributeNames (S.Set AttributeName)
355 deriving (Eq, Show, Generic)
380 deriving (Eq, Show, Generic)
357instance Binary AttributeNames
382instance Binary AttributeNames
359−--used for global dbms configuration- per-transaction flag is elsewhere
384+-- | The persistence strategy is a global database option which represents how to persist the database in the filesystem, if at all.
360−data PersistenceStrategy = NoPersistence | --no filesystem persistence/memory-only database
385+data PersistenceStrategy = NoPersistence | -- ^ no filesystem persistence/memory-only database
361− MinimalPersistence FilePath | --fsync off
386+ MinimalPersistence FilePath | -- ^ fsync off, not crash-safe
362− CrashSafePersistence FilePath --full fsync- not yet implemented
387+ CrashSafePersistence FilePath -- ^ full fsync to disk (flushes kernel and physical drive buffers to ensure that the transaction is on non-volatile storage)
363 deriving (Show, Read)
388 deriving (Show, Read)