1{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
4module ProjectM36.Base where
5import ProjectM36.DatabaseContextFunctionError
6import ProjectM36.AtomFunctionError
8import qualified Data.Map as M
9import qualified Data.HashSet as HS
10import Data.Hashable (Hashable, hashWithSalt)
11import qualified Data.Set as S
12import Data.UUID (UUID)
13import Control.DeepSeq (NFData, rnf)
14import Control.DeepSeq.Generics (genericRnf)
15import GHC.Generics (Generic)
16import qualified Data.Vector as V
17import qualified Data.List as L
18import Data.Text (Text,unpack)
20import Data.Vector.Binary()
22import Data.Time.Clock.POSIX
23import Data.Time.Calendar (Day,toGregorian,fromGregorian)
24import Data.Hashable.Time ()
26import Data.ByteString (ByteString)
29-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
30data Atom = IntegerAtom Integer |
35 DateTimeAtom UTCTime |
36 ByteStringAtom ByteString |
38 RelationAtom Relation |
39 ConstructedAtom DataConstructorName AtomType [Atom]
40 deriving (Eq, Show, Binary, Typeable, NFData, Generic)
42instance Hashable Atom where
43 hashWithSalt salt (ConstructedAtom dConsName _ atoms) = salt `hashWithSalt` atoms
44 `hashWithSalt` dConsName --AtomType is not hashable
45 hashWithSalt salt (IntAtom i) = salt `hashWithSalt` i
46 hashWithSalt salt (IntegerAtom i) = salt `hashWithSalt` i
47 hashWithSalt salt (DoubleAtom d) = salt `hashWithSalt` d
48 hashWithSalt salt (TextAtom t) = salt `hashWithSalt` t
49 hashWithSalt salt (DayAtom d) = salt `hashWithSalt` d
50 hashWithSalt salt (DateTimeAtom dt) = salt `hashWithSalt` dt
51 hashWithSalt salt (ByteStringAtom bs) = salt `hashWithSalt` bs
52 hashWithSalt salt (BoolAtom b) = salt `hashWithSalt` b
53 hashWithSalt salt (RelationAtom r) = salt `hashWithSalt` r
55instance Binary UTCTime where
56 put utc = put $ toRational (utcTimeToPOSIXSeconds utc)
57 get = posixSecondsToUTCTime . fromRational <$> (get :: Get Rational)
59instance Binary Day where
60 put day = put $ toGregorian day
62 (y,m,d) <- get :: Get (Integer, Int, Int)
63 return (fromGregorian y m d)
65-- I suspect the definition of ConstructedAtomType with its name alone is insufficient to disambiguate the cases; for example, one could create a type named X, remove a type named X, and re-add it using different constructors. However, as long as requests are served from only one DatabaseContext at-a-time, the type name is unambiguous. This will become a problem for time-travel, however.
66-- | The AtomType uniquely identifies the type of a atom.
67data AtomType = IntAtomType |
75 RelationAtomType Attributes |
76 ConstructedAtomType TypeConstructorName TypeVarMap |
77 TypeVariableType TypeVarName
78 --wildcard used in Atom Functions and tuples for data constructors which don't provide all arguments to the type constructor
79 deriving (Eq, NFData, Generic, Binary, Show)
81instance Ord AtomType where
83type TypeVarMap = M.Map TypeVarName AtomType
85instance Hashable TypeVarMap where
86 hashWithSalt salt tvmap = hashWithSalt salt (M.keys tvmap)
88-- | Return True iff the atom type argument is relation-valued. If True, this indicates that the Atom contains a relation.
89isRelationAtomType :: AtomType -> Bool
90isRelationAtomType (RelationAtomType _) = True
91isRelationAtomType _ = False
93-- | The AttributeName is the name of an attribute in a relation.
94type AttributeName = StringType
96-- | A relation's type is composed of attribute names and types.
97data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic, NFData, Binary)
99instance Hashable Attribute where
100 hashWithSalt salt (Attribute attrName _) = hashWithSalt salt attrName
102-- | 'Attributes' represent the head of a relation.
103type Attributes = V.Vector Attribute
105-- | Equality function for a set of attributes.
106attributesEqual :: Attributes -> Attributes -> Bool
107attributesEqual attrs1 attrs2 = attrsAsSet attrs1 == attrsAsSet attrs2
109 attrsAsSet = HS.fromList . V.toList
111sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
112sortedAttributesIndices attrs = L.sortBy (\(_, Attribute name1 _) (_,Attribute name2 _) -> compare name1 name2) $ V.toList (V.indexed attrs)
114-- | The relation's tuple set is the body of the relation.
115newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Binary)
117instance Read Relation where
118 readsPrec = error "relation read not supported"
120instance Eq RelationTupleSet where
121 set1 == set2 = hset set1 == hset set2
123 hset = HS.fromList . asList
125instance NFData RelationTupleSet where rnf = genericRnf
127--the same hash must be generated for equal tuples so that the hashset equality works
128instance Hashable RelationTuple where
129 --sanity check the tuple for attribute and tuple counts
130 --this bit me when tuples were being hashed before being verified
131 hashWithSalt salt (RelationTuple attrs tupVec) = if V.length attrs /= V.length tupVec then
132 error "invalid tuple: attributes and tuple count mismatch"
135 sortedAttrs `hashWithSalt`
136 V.toList sortedTupVec
138 sortedAttrsIndices = sortedAttributesIndices attrs
139 sortedAttrs = map snd sortedAttrsIndices
140 sortedTupVec = V.map (\(index, _) -> tupVec V.! index) $ V.fromList sortedAttrsIndices
142-- | A tuple is a set of attributes mapped to their 'Atom' values.
143data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Generic)
145instance Binary RelationTuple
147instance Eq RelationTuple where
148 (==) tuple1@(RelationTuple attrs1 _) tuple2@(RelationTuple attrs2 _) = attributesEqual attrs1 attrs2 && atomsEqual
150 atomForAttribute attr (RelationTuple attrs tupVec) = case V.findIndex (== attr) attrs of
152 Just index -> tupVec V.!? index
153 atomsEqual = V.all (== True) $ V.map (\attr -> atomForAttribute attr tuple1 == atomForAttribute attr tuple2) attrs1
155instance NFData RelationTuple where rnf = genericRnf
158data Relation = Relation Attributes RelationTupleSet deriving (Show, Generic,Typeable)
160instance Eq Relation where
161 Relation attrs1 tupSet1 == Relation attrs2 tupSet2 = attributesEqual attrs1 attrs2 && tupSet1 == tupSet2
163instance NFData Relation where rnf = genericRnf
165instance Hashable Relation where
166 hashWithSalt salt (Relation attrs tupSet) = salt `hashWithSalt`
167 sortedAttrs `hashWithSalt`
170 sortedAttrs = map snd (sortedAttributesIndices attrs)
172instance Binary Relation
174-- | Used to represent the number of tuples in a relation.
175data RelationCardinality = Countable | Finite Int deriving (Eq, Show, Generic, Ord)
177-- | Relation variables are identified by their names.
178type RelVarName = StringType
180type RelationalExpr = RelationalExprBase ()
182-- | A relational expression represents query (read) operations on a database.
183data RelationalExprBase a =
184 --- | Create a relation from tuple expressions.
185 MakeRelationFromExprs (Maybe [AttributeExprBase a]) [TupleExprBase a] |
186 --- | Create and reference a relation from attributes and a tuple set.
187 MakeStaticRelation Attributes RelationTupleSet |
188 --- | Reference an existing relation in Haskell-space.
189 ExistingRelation Relation |
190 --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
191 --in Tutorial D, relational variables pick up the type of the first relation assigned to them
192 --relational variables should also be able to be explicitly-typed like in Haskell
193 --- | Reference a relation variable by its name.
194 RelationVariable RelVarName a |
195 --- | Create a projection over attribute names. (Note that the 'AttributeNames' structure allows for the names to be inverted.)
196 Project (AttributeNamesBase a) (RelationalExprBase a) |
197 --- | Create a union of two relational expressions. The expressions should have identical attributes.
198 Union (RelationalExprBase a) (RelationalExprBase a) |
199 --- | 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.
200 Join (RelationalExprBase a) (RelationalExprBase a) |
201 --- | Rename an attribute (first argument) to another (second argument).
202 Rename AttributeName AttributeName (RelationalExprBase a) |
203 --- | Return a relation containing all tuples of the first argument which do not appear in the second argument (minus).
204 Difference (RelationalExprBase a) (RelationalExprBase a) |
205 --- | 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.>
206 Group (AttributeNamesBase a) AttributeName (RelationalExprBase a) |
207 --- | 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.
208 Ungroup AttributeName (RelationalExprBase a) |
209 --- | Filter the tuples of the relational expression to only retain the tuples which evaluate against the restriction predicate to true.
210 Restrict (RestrictionPredicateExprBase a) (RelationalExprBase a) |
211 --- | Returns the true relation iff
212 Equals (RelationalExprBase a) (RelationalExprBase a) |
213 NotEquals (RelationalExprBase a) (RelationalExprBase a) |
214 Extend (ExtendTupleExprBase a) (RelationalExprBase a) |
215 --Summarize :: AtomExpr -> AttributeName -> RelationalExpr -> RelationalExpr -> RelationalExpr -- a special case of Extend
216 --Evaluate relationalExpr with scoped views
217 With [(RelVarName,RelationalExprBase a)] (RelationalExprBase a)
218 deriving (Show, Eq, Generic, NFData)
220instance Binary RelationalExpr
222type NotificationName = StringType
223type Notifications = M.Map NotificationName Notification
225-- | When the changeExpr returns a different result in the database context, then the reportExpr is triggered and sent asynchronously to all clients.
226data Notification = Notification {
227 changeExpr :: RelationalExpr,
228 reportOldExpr :: RelationalExpr, --run the expression in the pre-change context
229 reportNewExpr :: RelationalExpr --run the expression in the post-change context
231 deriving (Show, Eq, Binary, Generic, NFData)
233type TypeVarName = StringType
235-- | Metadata definition for type constructors such as @data Either a b@.
236data TypeConstructorDef = ADTypeConstructorDef TypeConstructorName [TypeVarName] |
237 PrimitiveTypeConstructorDef TypeConstructorName AtomType
238 deriving (Show, Generic, Binary, Eq, NFData)
240-- | Found in data constructors and type declarations: Left (Either Int Text) | Right Int
241type TypeConstructor = TypeConstructorBase ()
242data TypeConstructorBase a = ADTypeConstructor TypeConstructorName [TypeConstructor] |
243 PrimitiveTypeConstructor TypeConstructorName AtomType |
244 RelationAtomTypeConstructor [AttributeExprBase a] |
245 TypeVariable TypeVarName
246 deriving (Show, Generic, Binary, Eq, NFData)
248type TypeConstructorMapping = [(TypeConstructorDef, DataConstructorDefs)]
250type TypeConstructorName = StringType
251type TypeConstructorArgName = StringType
252type DataConstructorName = StringType
253type AtomTypeName = StringType
255-- | Used to define a data constructor in a type constructor context such as @Left a | Right b@
256data DataConstructorDef = DataConstructorDef DataConstructorName [DataConstructorDefArg] deriving (Eq, Show, Binary, Generic, NFData)
258type DataConstructorDefs = [DataConstructorDef]
260data DataConstructorDefArg = DataConstructorDefTypeConstructorArg TypeConstructor |
261 DataConstructorDefTypeVarNameArg TypeVarName
262 deriving (Show, Generic, Binary, Eq, NFData)
264type InclusionDependencies = M.Map IncDepName InclusionDependency
265type RelationVariables = M.Map RelVarName Relation
267type SchemaName = StringType
269type Subschemas = M.Map SchemaName Schema
271-- | Every transaction has one concrete database context and any number of isomorphic subschemas.
272data Schemas = Schemas DatabaseContext Subschemas
274-- | The DatabaseContext is a snapshot of a database's evolving state and contains everything a database client can change over time.
275-- I spent some time thinking about whether the VirtualDatabaseContext/Schema and DatabaseContext data constructors should be the same constructor, but that would allow relation variables to be created in a "virtual" context which would appear to defeat the isomorphisms of the contexts. It should be possible to switch to an alternative schema to view the same equivalent information without information loss. However, allowing all contexts to reference another context while maintaining its own relation variables, new types, etc. could be interesting from a security perspective. For example, if a user creates a new relvar in a virtual context, then does it necessarily appear in all linked contexts? After deliberation, I think the relvar should appear in *all* linked contexts to retain the isomorphic properties, even when the isomorphism is for a subset of the context. This hints that the IsoMorphs should allow for "fall-through"; that is, when a relvar is not defined in the virtual context (for morphing), then the lookup should fall through to the underlying context.
276newtype Schema = Schema SchemaIsomorphs
277 deriving (Generic, Binary)
279data SchemaIsomorph = IsoRestrict RelVarName RestrictionPredicateExpr (RelVarName, RelVarName) |
280 IsoRename RelVarName RelVarName |
281 IsoUnion (RelVarName, RelVarName) RestrictionPredicateExpr RelVarName --maps two relvars to one relvar
282 -- IsoTypeConstructor in morphAttrExpr
283 deriving (Generic, Binary, Show)
285type SchemaIsomorphs = [SchemaIsomorph]
287data DatabaseContext = DatabaseContext {
288 inclusionDependencies :: InclusionDependencies,
289 relationVariables :: RelationVariables,
290 atomFunctions :: AtomFunctions,
291 dbcFunctions :: DatabaseContextFunctions,
292 notifications :: Notifications,
293 typeConstructorMapping :: TypeConstructorMapping
294 } deriving (NFData, Generic)
296type IncDepName = StringType
298-- | Inclusion dependencies represent every possible database constraint. Constraints enforce specific, arbitrarily-complex rules to which the database context's relation variables must adhere unconditionally.
299data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic, NFData)
301instance Binary InclusionDependency
303type AttributeNameAtomExprMap = M.Map AttributeName AtomExpr
305--used for returning information about individual expressions
306type DatabaseContextExprName = StringType
308-- | Database context expressions modify the database context.
309data DatabaseContextExpr =
311 Define RelVarName [AttributeExpr] |
312 Undefine RelVarName | --forget existence of relvar X
313 Assign RelVarName RelationalExpr |
314 Insert RelVarName RelationalExpr |
315 Delete RelVarName RestrictionPredicateExpr |
316 Update RelVarName AttributeNameAtomExprMap RestrictionPredicateExpr |
318 AddInclusionDependency IncDepName InclusionDependency |
319 RemoveInclusionDependency IncDepName |
321 AddNotification NotificationName RelationalExpr RelationalExpr RelationalExpr |
322 RemoveNotification NotificationName |
324 AddTypeConstructor TypeConstructorDef [DataConstructorDef] |
325 RemoveTypeConstructor TypeConstructorName |
327 --adding an AtomFunction is not a pure operation (required loading GHC modules)
328 RemoveAtomFunction AtomFunctionName |
330 RemoveDatabaseContextFunction DatabaseContextFunctionName |
332 ExecuteDatabaseContextFunction DatabaseContextFunctionName [AtomExpr] |
334 MultipleExpr [DatabaseContextExpr]
335 deriving (Show, Eq, Binary, Generic)
337type ObjModuleName = StringType
338type ObjFunctionName = StringType
339type Range = (Int,Int)
340-- | Adding an atom function should be nominally a DatabaseExpr except for the fact that it cannot be performed purely. Thus, we create the DatabaseContextIOExpr.
341data DatabaseContextIOExpr = AddAtomFunction AtomFunctionName [TypeConstructor] AtomFunctionBodyScript |
342 LoadAtomFunctions ObjModuleName ObjFunctionName FilePath |
343 AddDatabaseContextFunction DatabaseContextFunctionName [TypeConstructor] DatabaseContextFunctionBodyScript |
344 LoadDatabaseContextFunctions ObjModuleName ObjFunctionName FilePath |
345 CreateArbitraryRelation RelVarName [AttributeExpr] Range
346 deriving (Show, Eq, Generic, Binary)
348type RestrictionPredicateExpr = RestrictionPredicateExprBase ()
350-- | Restriction predicates are boolean algebra components which, when composed, indicate whether or not a tuple should be retained during a restriction (filtering) operation.
351data RestrictionPredicateExprBase a =
353 AndPredicate (RestrictionPredicateExprBase a) (RestrictionPredicateExprBase a) |
354 OrPredicate (RestrictionPredicateExprBase a) (RestrictionPredicateExprBase a) |
355 NotPredicate (RestrictionPredicateExprBase a) |
356 RelationalExprPredicate (RelationalExprBase a) | --type must be same as true and false relations (no attributes)
357 AtomExprPredicate (AtomExprBase a) | --atom must evaluate to boolean
358 AttributeEqualityPredicate AttributeName (AtomExprBase a) -- relationalexpr must result in relation with single tuple
359 deriving (Show, Eq, Generic, NFData)
361instance Binary RestrictionPredicateExpr
363-- child + parent links
364-- | 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.
365type HeadName = StringType
367type TransactionHeads = M.Map HeadName Transaction
369-- | The transaction graph is the global database's state which references every committed transaction.
370data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
372transactionsForGraph :: TransactionGraph -> S.Set Transaction
373transactionsForGraph (TransactionGraph _ t) = t
375transactionHeadsForGraph :: TransactionGraph -> TransactionHeads
376transactionHeadsForGraph (TransactionGraph heads _) = heads
378-- | Every transaction has context-specific information attached to it.
379data TransactionInfo = TransactionInfo TransactionId (S.Set TransactionId) UTCTime | -- 1 parent + n children
380 MergeTransactionInfo TransactionId TransactionId (S.Set TransactionId) UTCTime -- 2 parents, n children
381 deriving(Show, Generic)
383instance Binary TransactionInfo
385-- | Every set of modifications made to the database are atomically committed to the transaction graph as a transaction.
386type TransactionId = UUID
388data Transaction = Transaction TransactionId TransactionInfo Schemas
390--instance Binary Transaction
394-- | 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.
395data DisconnectedTransaction = DisconnectedTransaction TransactionId Schemas DirtyFlag --parentID, context- the context here represents the singular concrete context from the schema
396--the dirty flag indicates that the database context has diverged from its parent's context
398transactionId :: Transaction -> TransactionId
399transactionId (Transaction tid _ _) = tid
401transactionInfo :: Transaction -> TransactionInfo
402transactionInfo (Transaction _ info _) = info
404instance Eq Transaction where
405 (Transaction uuidA _ _) == (Transaction uuidB _ _) = uuidA == uuidB
407instance Ord Transaction where
408 compare (Transaction uuidA _ _) (Transaction uuidB _ _) = compare uuidA uuidB
410type AtomExpr = AtomExprBase ()
412-- | An atom expression represents an action to take when extending a relation or when statically defining a relation or a new tuple.
413data AtomExprBase a = AttributeAtomExpr AttributeName |
415 FunctionAtomExpr AtomFunctionName [AtomExprBase a] a |
416 RelationAtomExpr (RelationalExprBase a) |
417 ConstructedAtomExpr DataConstructorName [AtomExprBase a] a
418 deriving (Eq,Show,Generic, NFData)
420instance Binary AtomExpr
422-- | Used in tuple creation when creating a relation.
423data ExtendTupleExprBase a = AttributeExtendTupleExpr AttributeName (AtomExprBase a)
424 deriving (Show, Eq, Generic, NFData)
426type ExtendTupleExpr = ExtendTupleExprBase ()
428instance Binary ExtendTupleExpr
430--enumerates the list of functions available to be run as part of tuple expressions
431type AtomFunctions = HS.HashSet AtomFunction
433type AtomFunctionName = StringType
435type AtomFunctionBodyScript = StringType
437type AtomFunctionBodyType = [Atom] -> Either AtomFunctionError Atom
439data AtomFunctionBody = AtomFunctionBody (Maybe AtomFunctionBodyScript) AtomFunctionBodyType
441instance NFData AtomFunctionBody where
442 rnf (AtomFunctionBody mScript _) = rnf mScript
444instance Show AtomFunctionBody where
445 show (AtomFunctionBody mScript _) = case mScript of
446 Just script -> show (unpack script)
447 Nothing -> "<compiled>"
449-- | An AtomFunction has a name, a type, and a function body to execute when called.
450data AtomFunction = AtomFunction {
451 atomFuncName :: AtomFunctionName,
452 atomFuncType :: [AtomType],
453 atomFuncBody :: AtomFunctionBody
454 } deriving (Generic, NFData)
456instance Hashable AtomFunction where
457 hashWithSalt salt func = salt `hashWithSalt` atomFuncName func
459instance Eq AtomFunction where
460 f1 == f2 = atomFuncName f1 == atomFuncName f2
462instance Show AtomFunction where
463 show aFunc = unpack (atomFuncName aFunc) ++ "::" ++ showArgTypes ++ "; " ++ body
465 body = show (atomFuncBody aFunc)
466 showArgTypes = L.intercalate "->" (map show (atomFuncType aFunc))
468-- | 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").
469data AttributeNamesBase a = AttributeNames (S.Set AttributeName) |
470 InvertedAttributeNames (S.Set AttributeName) |
471 UnionAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
472 IntersectAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
473 RelationalExprAttributeNames (RelationalExprBase a) -- use attribute names from the relational expression's type
474 deriving (Eq, Show, Generic, NFData)
476type AttributeNames = AttributeNamesBase ()
477instance Binary AttributeNames
479-- | The persistence strategy is a global database option which represents how to persist the database in the filesystem, if at all.
480data PersistenceStrategy = NoPersistence | -- ^ no filesystem persistence/memory-only database
481 MinimalPersistence FilePath | -- ^ fsync off, not crash-safe
482 CrashSafePersistence FilePath -- ^ full fsync to disk (flushes kernel and physical drive buffers to ensure that the transaction is on non-volatile storage)
483 deriving (Show, Read)
485type AttributeExpr = AttributeExprBase ()
487-- | Create attributes dynamically.
488data AttributeExprBase a = AttributeAndTypeNameExpr AttributeName TypeConstructor a |
489 NakedAttributeExpr Attribute
490 deriving (Eq, Show, Generic, Binary, NFData)
492-- | Dynamically create a tuple from attribute names and 'AtomExpr's.
493newtype TupleExprBase a = TupleExpr (M.Map AttributeName (AtomExprBase a))
494 deriving (Eq, Show, Generic, NFData)
496instance Binary TupleExpr
498type TupleExpr = TupleExprBase ()
501 -- | After a union merge, the merge transaction is a result of union'ing relvars of the same name, introducing all uniquely-named relvars, union of constraints, union of atom functions, notifications, and types (unless the names and definitions collide, e.g. two types of the same name with different definitions)
503 -- | Similar to a union merge, but, on conflict, prefer the unmerged section (relvar, function, etc.) from the branch named as the argument.
504 UnionPreferMergeStrategy HeadName |
505 -- | Similar to the our/theirs merge strategy in git, the merge transaction's context is identical to that of the last transaction in the selected branch.
506 SelectedBranchMergeStrategy HeadName
507 deriving (Eq, Show, Binary, Generic, NFData)
509type DatabaseContextFunctionName = StringType
511type DatabaseContextFunctionBodyScript = StringType
513type DatabaseContextFunctionBodyType = [Atom] -> DatabaseContext -> Either DatabaseContextFunctionError DatabaseContext
515data DatabaseContextFunctionBody = DatabaseContextFunctionBody (Maybe DatabaseContextFunctionBodyScript) DatabaseContextFunctionBodyType
517instance NFData DatabaseContextFunctionBody where
518 rnf (DatabaseContextFunctionBody mScript _) = rnf mScript
520data DatabaseContextFunction = DatabaseContextFunction {
521 dbcFuncName :: DatabaseContextFunctionName,
522 dbcFuncType :: [AtomType],
523 dbcFuncBody :: DatabaseContextFunctionBody
524 } deriving (Generic, NFData)
526type DatabaseContextFunctions = HS.HashSet DatabaseContextFunction
528instance Hashable DatabaseContextFunction where
529 hashWithSalt salt func = salt `hashWithSalt` dbcFuncName func
531instance Eq DatabaseContextFunction where
532 f1 == f2 = dbcFuncName f1 == dbcFuncName f2
534attrTypeVars :: Attribute -> S.Set TypeVarName
535attrTypeVars (Attribute _ aType) = case aType of
536 IntAtomType -> S.empty
537 IntegerAtomType -> S.empty
538 DoubleAtomType -> S.empty
539 TextAtomType -> S.empty
540 DayAtomType -> S.empty
541 DateTimeAtomType -> S.empty
542 ByteStringAtomType -> S.empty
543 BoolAtomType -> S.empty
544 (RelationAtomType attrs) -> S.unions (map attrTypeVars (V.toList attrs))
545 (ConstructedAtomType _ tvMap) -> M.keysSet tvMap
546 (TypeVariableType nam) -> S.singleton nam
548typeVars :: TypeConstructor -> S.Set TypeVarName
549typeVars (PrimitiveTypeConstructor _ _) = S.empty
550typeVars (ADTypeConstructor _ args) = S.unions (map typeVars args)
551typeVars (TypeVariable v) = S.singleton v
552typeVars (RelationAtomTypeConstructor attrExprs) = S.unions (map attrExprTypeVars attrExprs)
554attrExprTypeVars :: AttributeExprBase a -> S.Set TypeVarName
555attrExprTypeVars (AttributeAndTypeNameExpr _ tCons _) = typeVars tCons
556attrExprTypeVars (NakedAttributeExpr attr) = attrTypeVars attr
558atomTypeVars :: AtomType -> S.Set TypeVarName
559atomTypeVars IntAtomType = S.empty
560atomTypeVars IntegerAtomType = S.empty
561atomTypeVars DoubleAtomType = S.empty
562atomTypeVars TextAtomType = S.empty
563atomTypeVars DayAtomType = S.empty
564atomTypeVars DateTimeAtomType = S.empty
565atomTypeVars ByteStringAtomType = S.empty
566atomTypeVars BoolAtomType = S.empty
567atomTypeVars (RelationAtomType attrs) = S.unions (map attrTypeVars (V.toList attrs))
568atomTypeVars (ConstructedAtomType _ tvMap) = M.keysSet tvMap
569atomTypeVars (TypeVariableType nam) = S.singleton nam
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list