@@ -3,12 +3,14 @@
4module Data.Schematic.Migration where
4module Data.Schematic.Migration where
6import Data.Schematic.Path
7import Data.Schematic.Path
7import Data.Schematic.Schema
8import Data.Schematic.Schema
8import Data.Schematic.Utils
9import Data.Schematic.Utils
9import Data.Singletons.Prelude hiding (All)
10import Data.Singletons.Prelude hiding (All)
10import Data.Singletons.TypeLits
11import Data.Singletons.TypeLits
11−import Data.Vinyl
12+import Data.Vinyl hiding (Dict)
14 = PKey Symbol -- traverse into the object by key
16 = PKey Symbol -- traverse into the object by key
@@ -70,14 +72,65 @@ type family SchemaByRevision (r :: Revision) (vd :: Versioned) :: Schema where
70 SchemaByRevision r ('Versioned s (m ': ms)) =
72 SchemaByRevision r ('Versioned s (m ': ms)) =
71 SchemaByRevision r ('Versioned (Snd (ApplyMigration m s)) ms)
73 SchemaByRevision r ('Versioned (Snd (ApplyMigration m s)) ms)
73−type family TopVersion (vd :: Versioned) :: Schema where
75+-- type family Reverse (acc :: [(Revision, Schema)]) (rs :: [(Revision, Schema)]) :: [(Revision, Schema)] where
74− TopVersion ('Versioned s '[]) = s
76+-- Reverse acc '[] = acc
75− TopVersion ('Versioned s (m ': ms)) =
77+-- Reverse acc (h ': tl) = Reverse (h ': acc) tl
76− TopVersion ('Versioned (Snd (ApplyMigration m s)) ms)
78+
79+type family Migratable (rs :: [(Revision, Schema)]) :: Constraint where
80+ -- constraint duplication
81+ Migratable ('(r,s) ': '(r', s') ': tl) =
82+ (Known (Sing s), MigrateSchema s s', TopLevel s, Migratable ('(r',s') ': tl))
83+ Migratable ('(r,s) ': '[]) = (TopLevel s, Known (Sing s))
84+ -- Migratable '[] = ('True ~ 'False)
86+-- data NonEmpty a = a :| [a]
88+-- data instance Sing (ne :: NonEmpty a) where
89+-- SNECons :: Known (Sing e), Known (Sing l))=> Sing (e :: k) -> Sing (l :: [k]) -> Sing (e ':| l)
91+data Revisions = Revisions
92+ Schema -- top version
95+data instance Sing (rs :: Revisions) where
97+ :: (Known (Sing schema), Known (Sing rps), Known (Dict (ElemOf schema prs)))
100+ -> Sing ('Revisions schema rps)
102+-- -- | Heterogenous list with a proof of element schema included in the list itself.
103+-- data ElemList :: k -> [k] -> Type where
104+-- Singl :: Known (Sing schema) => Sing schema -> ElemList schema '[schema]
105+-- KeepProof :: Known (Sing new) => Sing new -> ElemList schema ss -> ElemList schema (new ': ss)
106+-- NewProof :: Known (Sing new) => Sing new -> ElemList schema ss -> ElemList new (new ': ss)
108+type family ElemOf (e :: k) (l :: [(a,k)]) :: Constraint where
109+ ElemOf e '[] = 'True ~ 'False
110+ ElemOf e ( '(a, e) ': es) = ()
111+ ElemOf e (n ': es) = ElemOf e es
113+-- | Extracts revision/schema pairs from @Versioned@ in reverse order.
114+type family AllVersions (vd :: Versioned) :: Revisions where
115+ AllVersions ('Versioned s ms) = AllVersions' ('Revisions s '[ '("initial", s) ]) ms
117+type family AllVersions' (acc :: Revisions) (ms :: [Migration]) :: Revisions where
118+ AllVersions' acc '[] = acc
119+ AllVersions' ('Revisions tv rs) (m ': ms) =
120+ AllVersions' ('Revisions (Snd (ApplyMigration m tv)) (rs :++ '[(ApplyMigration m tv)])) ms
122+type family TopVersion (rs :: Revisions) :: Schema where
123+ TopVersion ('Revisions s rs) = s
125+type family SchemaPairs (rs :: Revisions) :: [(Revision, Schema)] where
126+ SchemaPairs ('Revisions s rs) = rs
78class MigrateSchema (a :: Schema) (b :: Schema) where
128class MigrateSchema (a :: Schema) (b :: Schema) where
79 migrate :: JsonRepr a -> JsonRepr b
129 migrate :: JsonRepr a -> JsonRepr b
131+instance MigrateSchema a a where
81data Action = AddKey Symbol Schema | Update Schema | DeleteKey Symbol
134data Action = AddKey Symbol Schema | Update Schema | DeleteKey Symbol
83data instance Sing (a :: Action) where
136data instance Sing (a :: Action) where
@@ -137,7 +190,7 @@ type VS =
137 '[ 'Migration "test_revision"
190 '[ 'Migration "test_revision"
138 '[ 'Diff '[ 'PKey "foo" ] ('Update ('SchemaText '[])) ] ]
191 '[ 'Diff '[ 'PKey "foo" ] ('Update ('SchemaText '[])) ] ]
140−jsonExample :: JsonRepr (TopVersion VS)
193+jsonExample :: JsonRepr (TopVersion (AllVersions VS))
141jsonExample = ReprObject $
194jsonExample = ReprObject $
142 FieldRepr (ReprText "foo")
195 FieldRepr (ReprText "foo")
143 :& FieldRepr (ReprOptional (Just (ReprText "bar")))
196 :& FieldRepr (ReprOptional (Just (ReprText "bar")))