module Hasura.Server.Migrate.Version
  ( MetadataCatalogVersion (..),
    SourceCatalogVersion (..),
  )
where

import Data.List (isPrefixOf)
import Hasura.Prelude
import Hasura.SQL.Backend (BackendType)
import Language.Haskell.TH.Lift (Lift)

-- | Represents the catalog version. This is stored in the database and then
-- compared with the latest version on startup.
data MetadataCatalogVersion
  = -- | A typical catalog version.
    MetadataCatalogVersion Int
  | -- | Maintained for compatibility with catalog version 0.8.
    MetadataCatalogVersion08
  deriving stock (MetadataCatalogVersion -> MetadataCatalogVersion -> Bool
(MetadataCatalogVersion -> MetadataCatalogVersion -> Bool)
-> (MetadataCatalogVersion -> MetadataCatalogVersion -> Bool)
-> Eq MetadataCatalogVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetadataCatalogVersion -> MetadataCatalogVersion -> Bool
$c/= :: MetadataCatalogVersion -> MetadataCatalogVersion -> Bool
== :: MetadataCatalogVersion -> MetadataCatalogVersion -> Bool
$c== :: MetadataCatalogVersion -> MetadataCatalogVersion -> Bool
Eq, MetadataCatalogVersion -> Q Exp
MetadataCatalogVersion -> Q (TExp MetadataCatalogVersion)
(MetadataCatalogVersion -> Q Exp)
-> (MetadataCatalogVersion -> Q (TExp MetadataCatalogVersion))
-> Lift MetadataCatalogVersion
forall t. (t -> Q Exp) -> (t -> Q (TExp t)) -> Lift t
liftTyped :: MetadataCatalogVersion -> Q (TExp MetadataCatalogVersion)
$cliftTyped :: MetadataCatalogVersion -> Q (TExp MetadataCatalogVersion)
lift :: MetadataCatalogVersion -> Q Exp
$clift :: MetadataCatalogVersion -> Q Exp
Lift)

instance Ord MetadataCatalogVersion where
  compare :: MetadataCatalogVersion -> MetadataCatalogVersion -> Ordering
compare = Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Float -> Float -> Ordering)
-> (MetadataCatalogVersion -> Float)
-> MetadataCatalogVersion
-> MetadataCatalogVersion
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` MetadataCatalogVersion -> Float
toFloat
    where
      toFloat :: MetadataCatalogVersion -> Float
      toFloat :: MetadataCatalogVersion -> Float
toFloat (MetadataCatalogVersion Int
v) = Int -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
v
      toFloat MetadataCatalogVersion
MetadataCatalogVersion08 = Float
0.8

instance Enum MetadataCatalogVersion where
  toEnum :: Int -> MetadataCatalogVersion
toEnum = Int -> MetadataCatalogVersion
MetadataCatalogVersion
  fromEnum :: MetadataCatalogVersion -> Int
fromEnum (MetadataCatalogVersion Int
v) = Int
v
  fromEnum MetadataCatalogVersion
MetadataCatalogVersion08 = [Char] -> Int
forall a. HasCallStack => [Char] -> a
error [Char]
"Cannot enumerate unstable catalog versions."

instance Show MetadataCatalogVersion where
  show :: MetadataCatalogVersion -> [Char]
show (MetadataCatalogVersion Int
v) = Int -> [Char]
forall a. Show a => a -> [Char]
show Int
v
  show MetadataCatalogVersion
MetadataCatalogVersion08 = [Char]
"0.8"

instance Read MetadataCatalogVersion where
  readsPrec :: Int -> ReadS MetadataCatalogVersion
readsPrec Int
prec [Char]
s
    | [Char]
"0.8" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [Char]
s =
      [(MetadataCatalogVersion
MetadataCatalogVersion08, Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 [Char]
s)]
    | Bool
otherwise =
      ((Int, [Char]) -> (MetadataCatalogVersion, [Char]))
-> [(Int, [Char])] -> [(MetadataCatalogVersion, [Char])]
forall a b. (a -> b) -> [a] -> [b]
map ((Int -> MetadataCatalogVersion)
-> (Int, [Char]) -> (MetadataCatalogVersion, [Char])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Int -> MetadataCatalogVersion
MetadataCatalogVersion) ([(Int, [Char])] -> [(MetadataCatalogVersion, [Char])])
-> [(Int, [Char])] -> [(MetadataCatalogVersion, [Char])]
forall a b. (a -> b) -> a -> b
$ ((Int, [Char]) -> Bool) -> [(Int, [Char])] -> [(Int, [Char])]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (Int -> Bool) -> ((Int, [Char]) -> Int) -> (Int, [Char]) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, [Char]) -> Int
forall a b. (a, b) -> a
fst) ([(Int, [Char])] -> [(Int, [Char])])
-> [(Int, [Char])] -> [(Int, [Char])]
forall a b. (a -> b) -> a -> b
$ Int -> ReadS Int
forall a. Read a => Int -> ReadS a
readsPrec @Int Int
prec [Char]
s

-- | This is the source catalog version, used when deciding whether to (re-)create event triggers.
newtype SourceCatalogVersion (backend :: BackendType) = SourceCatalogVersion Int
  deriving newtype (SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
(SourceCatalogVersion backend
 -> SourceCatalogVersion backend -> Bool)
-> (SourceCatalogVersion backend
    -> SourceCatalogVersion backend -> Bool)
-> Eq (SourceCatalogVersion backend)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
/= :: SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
$c/= :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
== :: SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
$c== :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> Bool
Eq, Int -> SourceCatalogVersion backend
SourceCatalogVersion backend -> Int
SourceCatalogVersion backend -> [SourceCatalogVersion backend]
SourceCatalogVersion backend -> SourceCatalogVersion backend
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> [SourceCatalogVersion backend]
(SourceCatalogVersion backend -> SourceCatalogVersion backend)
-> (SourceCatalogVersion backend -> SourceCatalogVersion backend)
-> (Int -> SourceCatalogVersion backend)
-> (SourceCatalogVersion backend -> Int)
-> (SourceCatalogVersion backend -> [SourceCatalogVersion backend])
-> (SourceCatalogVersion backend
    -> SourceCatalogVersion backend -> [SourceCatalogVersion backend])
-> (SourceCatalogVersion backend
    -> SourceCatalogVersion backend -> [SourceCatalogVersion backend])
-> (SourceCatalogVersion backend
    -> SourceCatalogVersion backend
    -> SourceCatalogVersion backend
    -> [SourceCatalogVersion backend])
-> Enum (SourceCatalogVersion backend)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
forall (backend :: BackendType).
Int -> SourceCatalogVersion backend
forall (backend :: BackendType).
SourceCatalogVersion backend -> Int
forall (backend :: BackendType).
SourceCatalogVersion backend -> [SourceCatalogVersion backend]
forall (backend :: BackendType).
SourceCatalogVersion backend -> SourceCatalogVersion backend
forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> [SourceCatalogVersion backend]
enumFromThenTo :: SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> [SourceCatalogVersion backend]
$cenumFromThenTo :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> SourceCatalogVersion backend
-> [SourceCatalogVersion backend]
enumFromTo :: SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
$cenumFromTo :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
enumFromThen :: SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
$cenumFromThen :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> SourceCatalogVersion backend -> [SourceCatalogVersion backend]
enumFrom :: SourceCatalogVersion backend -> [SourceCatalogVersion backend]
$cenumFrom :: forall (backend :: BackendType).
SourceCatalogVersion backend -> [SourceCatalogVersion backend]
fromEnum :: SourceCatalogVersion backend -> Int
$cfromEnum :: forall (backend :: BackendType).
SourceCatalogVersion backend -> Int
toEnum :: Int -> SourceCatalogVersion backend
$ctoEnum :: forall (backend :: BackendType).
Int -> SourceCatalogVersion backend
pred :: SourceCatalogVersion backend -> SourceCatalogVersion backend
$cpred :: forall (backend :: BackendType).
SourceCatalogVersion backend -> SourceCatalogVersion backend
succ :: SourceCatalogVersion backend -> SourceCatalogVersion backend
$csucc :: forall (backend :: BackendType).
SourceCatalogVersion backend -> SourceCatalogVersion backend
Enum, Int -> SourceCatalogVersion backend -> ShowS
[SourceCatalogVersion backend] -> ShowS
SourceCatalogVersion backend -> [Char]
(Int -> SourceCatalogVersion backend -> ShowS)
-> (SourceCatalogVersion backend -> [Char])
-> ([SourceCatalogVersion backend] -> ShowS)
-> Show (SourceCatalogVersion backend)
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
forall (backend :: BackendType).
Int -> SourceCatalogVersion backend -> ShowS
forall (backend :: BackendType).
[SourceCatalogVersion backend] -> ShowS
forall (backend :: BackendType).
SourceCatalogVersion backend -> [Char]
showList :: [SourceCatalogVersion backend] -> ShowS
$cshowList :: forall (backend :: BackendType).
[SourceCatalogVersion backend] -> ShowS
show :: SourceCatalogVersion backend -> [Char]
$cshow :: forall (backend :: BackendType).
SourceCatalogVersion backend -> [Char]
showsPrec :: Int -> SourceCatalogVersion backend -> ShowS
$cshowsPrec :: forall (backend :: BackendType).
Int -> SourceCatalogVersion backend -> ShowS
Show, ReadPrec [SourceCatalogVersion backend]
ReadPrec (SourceCatalogVersion backend)
Int -> ReadS (SourceCatalogVersion backend)
ReadS [SourceCatalogVersion backend]
(Int -> ReadS (SourceCatalogVersion backend))
-> ReadS [SourceCatalogVersion backend]
-> ReadPrec (SourceCatalogVersion backend)
-> ReadPrec [SourceCatalogVersion backend]
-> Read (SourceCatalogVersion backend)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall (backend :: BackendType).
ReadPrec [SourceCatalogVersion backend]
forall (backend :: BackendType).
ReadPrec (SourceCatalogVersion backend)
forall (backend :: BackendType).
Int -> ReadS (SourceCatalogVersion backend)
forall (backend :: BackendType).
ReadS [SourceCatalogVersion backend]
readListPrec :: ReadPrec [SourceCatalogVersion backend]
$creadListPrec :: forall (backend :: BackendType).
ReadPrec [SourceCatalogVersion backend]
readPrec :: ReadPrec (SourceCatalogVersion backend)
$creadPrec :: forall (backend :: BackendType).
ReadPrec (SourceCatalogVersion backend)
readList :: ReadS [SourceCatalogVersion backend]
$creadList :: forall (backend :: BackendType).
ReadS [SourceCatalogVersion backend]
readsPrec :: Int -> ReadS (SourceCatalogVersion backend)
$creadsPrec :: forall (backend :: BackendType).
Int -> ReadS (SourceCatalogVersion backend)
Read)
  deriving stock (SourceCatalogVersion backend -> Q Exp
SourceCatalogVersion backend
-> Q (TExp (SourceCatalogVersion backend))
(SourceCatalogVersion backend -> Q Exp)
-> (SourceCatalogVersion backend
    -> Q (TExp (SourceCatalogVersion backend)))
-> Lift (SourceCatalogVersion backend)
forall t. (t -> Q Exp) -> (t -> Q (TExp t)) -> Lift t
forall (backend :: BackendType).
SourceCatalogVersion backend -> Q Exp
forall (backend :: BackendType).
SourceCatalogVersion backend
-> Q (TExp (SourceCatalogVersion backend))
liftTyped :: SourceCatalogVersion backend
-> Q (TExp (SourceCatalogVersion backend))
$cliftTyped :: forall (backend :: BackendType).
SourceCatalogVersion backend
-> Q (TExp (SourceCatalogVersion backend))
lift :: SourceCatalogVersion backend -> Q Exp
$clift :: forall (backend :: BackendType).
SourceCatalogVersion backend -> Q Exp
Lift)