@@ -1,4 +1,4 @@
1−{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveTraversable #-}
1+{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveTraversable, DerivingVia #-}
22{-# OPTIONS_GHC -fno-warn-orphans #-}
33
44module ProjectM36.Base where
@@ -18,15 +18,15 @@ import GHC.Stack
1818import qualified Data.Vector as V
1919import qualified Data.List as L
2020import Data.Text (Text,unpack)
21−import Data.Binary
2221import Data.Vector.Binary()
2322import Data.Time.Clock
24−import Data.Time.Clock.POSIX
25−import Data.Time.Calendar (Day,toGregorian,fromGregorian)
2623import Data.Hashable.Time ()
24+import Data.Time.Calendar (Day)
2725import Data.Typeable
2826import Data.ByteString (ByteString)
2927import qualified Data.List.NonEmpty as NE
28+--import Codec.Winery
29+
3030type StringType = Text
3131
3232-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
@@ -40,7 +40,7 @@ data Atom = IntegerAtom Integer |
4040 BoolAtom Bool |
4141 RelationAtom Relation |
4242 ConstructedAtom DataConstructorName AtomType [Atom]
43− deriving (Eq, Show, Binary, Typeable, NFData, Generic)
43+ deriving (Eq, Show, Typeable, NFData, Generic)
4444
4545instance Hashable Atom where
4646 hashWithSalt salt (ConstructedAtom dConsName _ atoms) = salt `hashWithSalt` atoms
@@ -55,16 +55,6 @@ instance Hashable Atom where
5555 hashWithSalt salt (BoolAtom b) = salt `hashWithSalt` b
5656 hashWithSalt salt (RelationAtom r) = salt `hashWithSalt` r
5757
58−instance Binary UTCTime where
59− put utc = put $ toRational (utcTimeToPOSIXSeconds utc)
60− get = posixSecondsToUTCTime . fromRational <$> (get :: Get Rational)
61−
62−instance Binary Day where
63− put day = put $ toGregorian day
64− get = do
65− (y,m,d) <- get :: Get (Integer, Int, Int)
66− return (fromGregorian y m d)
67−
6858-- 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.
6959-- | The AtomType uniquely identifies the type of a atom.
7060data AtomType = IntAtomType |
@@ -79,7 +69,7 @@ data AtomType = IntAtomType |
7969 ConstructedAtomType TypeConstructorName TypeVarMap |
8070 TypeVariableType TypeVarName
8171 --wildcard used in Atom Functions and tuples for data constructors which don't provide all arguments to the type constructor
82− deriving (Eq, NFData, Generic, Binary, Show)
72+ deriving (Eq, NFData, Generic, Show)
8373
8474instance Ord AtomType where
8575 compare = undefined
@@ -98,7 +88,7 @@ isRelationAtomType _ = False
9888type AttributeName = StringType
9989
10090-- | A relation's type is composed of attribute names and types.
101−data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic, NFData, Binary)
91+data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Generic, NFData)
10292
10393instance Hashable Attribute where
10494 hashWithSalt salt (Attribute attrName _) = hashWithSalt salt attrName
@@ -116,10 +106,7 @@ sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
116106sortedAttributesIndices attrs = L.sortBy (\(_, Attribute name1 _) (_,Attribute name2 _) -> compare name1 name2) $ V.toList (V.indexed attrs)
117107
118108-- | The relation's tuple set is the body of the relation.
119−newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Binary)
120−
121−instance Read Relation where
122− readsPrec = error "relation read not supported"
109+newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic)
123110
124111instance Eq RelationTupleSet where
125112 set1 == set2 = hset set1 == hset set2
@@ -146,8 +133,6 @@ instance Hashable RelationTuple where
146133-- | A tuple is a set of attributes mapped to their 'Atom' values.
147134data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Generic)
148135
149−instance Binary RelationTuple
150−
151136instance Eq RelationTuple where
152137 (==) tuple1@(RelationTuple attrs1 _) tuple2@(RelationTuple attrs2 _) = attributesEqual attrs1 attrs2 && atomsEqual
153138 where
@@ -158,7 +143,6 @@ instance Eq RelationTuple where
158143
159144instance NFData RelationTuple where rnf = genericRnf
160145
161−
162146data Relation = Relation Attributes RelationTupleSet deriving (Show, Generic,Typeable)
163147
164148instance Eq Relation where
@@ -173,8 +157,6 @@ instance Hashable Relation where
173157 where
174158 sortedAttrs = map snd (sortedAttributesIndices attrs)
175159
176−instance Binary Relation
177−
178160-- | Used to represent the number of tuples in a relation.
179161data RelationCardinality = Countable | Finite Int deriving (Eq, Show, Generic, Ord)
180162
@@ -221,15 +203,11 @@ data RelationalExprBase a =
221203 With [(WithNameExprBase a, RelationalExprBase a)] (RelationalExprBase a)
222204 deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
223205
224−instance Binary RelationalExpr
225−
226206data WithNameExprBase a = WithNameExpr RelVarName a
227207 deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
228208
229209type WithNameExpr = WithNameExprBase ()
230210
231−instance Binary WithNameExpr
232−
233211type GraphRefWithNameExpr = WithNameExprBase GraphRefTransactionMarker
234212
235213type NotificationName = StringType
@@ -241,14 +219,14 @@ data Notification = Notification {
241219 reportOldExpr :: RelationalExpr, --run the expression in the pre-change context
242220 reportNewExpr :: RelationalExpr --run the expression in the post-change context
243221 }
244− deriving (Show, Eq, Binary, Generic, NFData)
222+ deriving (Show, Eq, Generic, NFData)
245223
246224type TypeVarName = StringType
247225
248226-- | Metadata definition for type constructors such as @data Either a b@.
249227data TypeConstructorDef = ADTypeConstructorDef TypeConstructorName [TypeVarName] |
250228 PrimitiveTypeConstructorDef TypeConstructorName AtomType
251− deriving (Show, Generic, Binary, Eq, NFData)
229+ deriving (Show, Generic, Eq, NFData)
252230
253231-- | Found in data constructors and type declarations: Left (Either Int Text) | Right Int
254232type TypeConstructor = TypeConstructorBase ()
@@ -256,7 +234,7 @@ data TypeConstructorBase a = ADTypeConstructor TypeConstructorName [TypeConstruc
256234 PrimitiveTypeConstructor TypeConstructorName AtomType |
257235 RelationAtomTypeConstructor [AttributeExprBase a] |
258236 TypeVariable TypeVarName
259− deriving (Show, Generic, Binary, Eq, NFData)
237+ deriving (Show, Generic, Eq, NFData)
260238
261239type TypeConstructorMapping = [(TypeConstructorDef, DataConstructorDefs)]
262240
@@ -266,20 +244,20 @@ type DataConstructorName = StringType
266244type AtomTypeName = StringType
267245
268246-- | Used to define a data constructor in a type constructor context such as @Left a | Right b@
269−data DataConstructorDef = DataConstructorDef DataConstructorName [DataConstructorDefArg] deriving (Eq, Show, Binary, Generic, NFData)
247+data DataConstructorDef = DataConstructorDef DataConstructorName [DataConstructorDefArg] deriving (Eq, Show, Generic, NFData)
270248
271249type DataConstructorDefs = [DataConstructorDef]
272250
273251data DataConstructorDefArg = DataConstructorDefTypeConstructorArg TypeConstructor |
274252 DataConstructorDefTypeVarNameArg TypeVarName
275− deriving (Show, Generic, Binary, Eq, NFData)
253+ deriving (Show, Generic, Eq, NFData)
276254
277255type InclusionDependencies = M.Map IncDepName InclusionDependency
278256type RelationVariables = M.Map RelVarName GraphRefRelationalExpr
279257
280258data GraphRefTransactionMarker = TransactionMarker TransactionId |
281259 UncommittedContextMarker
282− deriving (Eq, Show, Binary, Generic, NFData, Ord)
260+ deriving (Eq, Show, Generic, NFData, Ord)
283261
284262-- a fundamental relational expr to which other relational expressions compile
285263type GraphRefRelationalExpr = RelationalExprBase GraphRefTransactionMarker
@@ -290,17 +268,18 @@ type Subschemas = M.Map SchemaName Schema
290268
291269-- | Every transaction has one concrete database context and any number of isomorphic subschemas.
292270data Schemas = Schemas DatabaseContext Subschemas
271+ deriving (Generic)
293272
294273-- | The DatabaseContext is a snapshot of a database's evolving state and contains everything a database client can change over time.
295274-- 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.
296275newtype Schema = Schema SchemaIsomorphs
297− deriving (Generic, Binary)
276+ deriving (Generic)
298277
299278data SchemaIsomorph = IsoRestrict RelVarName RestrictionPredicateExpr (RelVarName, RelVarName) |
300279 IsoRename RelVarName RelVarName |
301280 IsoUnion (RelVarName, RelVarName) RestrictionPredicateExpr RelVarName --maps two relvars to one relvar
302281 -- IsoTypeConstructor in morphAttrExpr
303− deriving (Generic, Binary, Show)
282+ deriving (Generic, Show)
304283
305284type SchemaIsomorphs = [SchemaIsomorph]
306285
@@ -318,8 +297,6 @@ type IncDepName = StringType
318297-- | Inclusion dependencies represent every possible database constraint. Constraints enforce specific, arbitrarily-complex rules to which the database context's relation variables must adhere unconditionally.
319298data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic, NFData)
320299
321−instance Binary InclusionDependency
322−
323300type AttributeNameAtomExprMap = M.Map AttributeName AtomExpr
324301
325302--used for returning information about individual expressions
@@ -329,8 +306,6 @@ type DatabaseContextExpr = DatabaseContextExprBase ()
329306
330307type GraphRefDatabaseContextExpr = DatabaseContextExprBase GraphRefTransactionMarker
331308
332−instance Binary GraphRefDatabaseContextExpr
333−
334309-- | Database context expressions modify the database context.
335310data DatabaseContextExprBase a =
336311 NoOperation |
@@ -360,8 +335,6 @@ data DatabaseContextExprBase a =
360335 MultipleExpr [DatabaseContextExprBase a]
361336 deriving (Show, Eq, Generic)
362337
363−instance Binary DatabaseContextExpr
364−
365338type ObjModuleName = StringType
366339type ObjFunctionName = StringType
367340type Range = (Int,Int)
@@ -372,7 +345,7 @@ data DatabaseContextIOExprBase a =
372345 AddDatabaseContextFunction DatabaseContextFunctionName [TypeConstructor] DatabaseContextFunctionBodyScript |
373346 LoadDatabaseContextFunctions ObjModuleName ObjFunctionName FilePath |
374347 CreateArbitraryRelation RelVarName [AttributeExprBase a] Range
375− deriving (Show, Eq, Generic, Binary)
348+ deriving (Show, Eq, Generic)
376349
377350type GraphRefDatabaseContextIOExpr = DatabaseContextIOExprBase GraphRefTransactionMarker
378351
@@ -393,8 +366,6 @@ data RestrictionPredicateExprBase a =
393366 AttributeEqualityPredicate AttributeName (AtomExprBase a) -- relationalexpr must result in relation with single tuple
394367 deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
395368
396−instance Binary RestrictionPredicateExpr
397−
398369-- child + parent links
399370-- | 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.
400371type HeadName = StringType
@@ -403,6 +374,7 @@ type TransactionHeads = M.Map HeadName Transaction
403374
404375-- | The transaction graph is the global database's state which references every committed transaction.
405376data TransactionGraph = TransactionGraph TransactionHeads (S.Set Transaction)
377+ deriving Generic
406378
407379transactionHeadsForGraph :: TransactionGraph -> TransactionHeads
408380transactionHeadsForGraph (TransactionGraph hs _) = hs
@@ -425,12 +397,11 @@ data TransactionInfo = TransactionInfo TransactionId TransactionDiffs UTCTime |
425397 deriving (Show, Generic)
426398-}
427399
428−instance Binary TransactionInfo
429−
430400-- | Every set of modifications made to the database are atomically committed to the transaction graph as a transaction.
431401type TransactionId = UUID
432402
433403data Transaction = Transaction TransactionId TransactionInfo Schemas
404+ deriving Generic
434405
435406-- | 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.
436407data DisconnectedTransaction = DisconnectedTransaction TransactionId Schemas DirtyFlag
@@ -464,8 +435,6 @@ data AtomExprBase a = AttributeAtomExpr AttributeName |
464435 ConstructedAtomExpr DataConstructorName [AtomExprBase a] a
465436 deriving (Eq,Show,Generic, NFData, Foldable, Functor, Traversable)
466437
467−instance Binary AtomExpr
468−
469438-- | Used in tuple creation when creating a relation.
470439data ExtendTupleExprBase a = AttributeExtendTupleExpr AttributeName (AtomExprBase a)
471440 deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
@@ -473,8 +442,6 @@ data ExtendTupleExprBase a = AttributeExtendTupleExpr AttributeName (AtomExprBas
473442type ExtendTupleExpr = ExtendTupleExprBase ()
474443type GraphRefExtendTupleExpr = ExtendTupleExprBase GraphRefTransactionMarker
475444
476−instance Binary ExtendTupleExpr
477−
478445--enumerates the list of functions available to be run as part of tuple expressions
479446type AtomFunctions = HS.HashSet AtomFunction
480447
@@ -485,6 +452,7 @@ type AtomFunctionBodyScript = StringType
485452type AtomFunctionBodyType = [Atom] -> Either AtomFunctionError Atom
486453
487454data AtomFunctionBody = AtomFunctionBody (Maybe AtomFunctionBodyScript) AtomFunctionBodyType
455+ deriving Generic
488456
489457instance NFData AtomFunctionBody where
490458 rnf (AtomFunctionBody mScript _) = rnf mScript
@@ -525,8 +493,6 @@ type AttributeNames = AttributeNamesBase ()
525493
526494type GraphRefAttributeNames = AttributeNamesBase GraphRefTransactionMarker
527495
528−instance Binary AttributeNames
529−
530496-- | The persistence strategy is a global database option which represents how to persist the database in the filesystem, if at all.
531497data PersistenceStrategy = NoPersistence | -- ^ no filesystem persistence/memory-only database
532498 MinimalPersistence FilePath | -- ^ fsync off, not crash-safe
@@ -539,14 +505,12 @@ type GraphRefAttributeExpr = AttributeExprBase GraphRefTransactionMarker
539505-- | Create attributes dynamically.
540506data AttributeExprBase a = AttributeAndTypeNameExpr AttributeName TypeConstructor a |
541507 NakedAttributeExpr Attribute
542− deriving (Eq, Show, Generic, Binary, NFData, Foldable, Functor, Traversable)
508+ deriving (Eq, Show, Generic, NFData, Foldable, Functor, Traversable)
543509
544510-- | Dynamically create a tuple from attribute names and 'AtomExpr's.
545511newtype TupleExprBase a = TupleExpr (M.Map AttributeName (AtomExprBase a))
546512 deriving (Eq, Show, Generic, NFData, Foldable, Functor, Traversable)
547513
548−instance Binary TupleExpr
549−
550514type TupleExpr = TupleExprBase ()
551515
552516type GraphRefTupleExpr = TupleExprBase GraphRefTransactionMarker
@@ -558,8 +522,6 @@ type GraphRefTupleExprs = TupleExprsBase GraphRefTransactionMarker
558522
559523type TupleExprs = TupleExprsBase ()
560524
561−instance Binary TupleExprs
562−
563525data MergeStrategy =
564526 -- | 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)
565527 UnionMergeStrategy |
@@ -567,7 +529,7 @@ data MergeStrategy =
567529 UnionPreferMergeStrategy HeadName |
568530 -- | 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.
569531 SelectedBranchMergeStrategy HeadName
570− deriving (Eq, Show, Binary, Generic, NFData)
532+ deriving (Eq, Show, Generic, NFData)
571533
572534type DatabaseContextFunctionName = StringType
573535
@@ -635,20 +597,5 @@ unimplemented :: HasCallStack => a
635597unimplemented = undefined
636598
637599--for serializing GraphRefRelationalExpr as part of transaction serialization
638−instance Binary (TupleExprsBase GraphRefTransactionMarker)
639−
640−instance Binary (TupleExprBase GraphRefTransactionMarker)
641−
642−instance Binary GraphRefRelationalExpr
643−
644−instance Binary (AtomExprBase GraphRefTransactionMarker)
645−
646−instance Binary (AttributeNamesBase GraphRefTransactionMarker)
647−
648−instance Binary (RestrictionPredicateExprBase GraphRefTransactionMarker)
649−
650−instance Binary (ExtendTupleExprBase GraphRefTransactionMarker)
651−
652−instance Binary GraphRefWithNameExpr
653600
654601