{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Database.Bloodhound.Internal.Client.Doc ( DocVersion (..), ExternalDocVersion (..), mkDocVersion, VersionControl (..), ) where import Data.Aeson import Data.Maybe import GHC.Enum -- | 'DocVersion' is an integer version number for a document between 1 -- and 9.2e+18 used for <>. newtype DocVersion = DocVersion { docVersionNumber :: Int } deriving stock (Eq, Show, Ord) deriving newtype (ToJSON) -- | Smart constructor for in-range doc version mkDocVersion :: Int -> Maybe DocVersion mkDocVersion i | i >= docVersionNumber minBound && i <= docVersionNumber maxBound = Just $ DocVersion i | otherwise = Nothing instance Bounded DocVersion where minBound = DocVersion 1 maxBound = DocVersion 9200000000000000000 -- 9.2e+18 instance Enum DocVersion where succ x | x /= maxBound = DocVersion (succ $ docVersionNumber x) | otherwise = succError "DocVersion" pred x | x /= minBound = DocVersion (pred $ docVersionNumber x) | otherwise = predError "DocVersion" toEnum i = fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i fromEnum = docVersionNumber enumFrom = boundedEnumFrom enumFromThen = boundedEnumFromThen instance FromJSON DocVersion where parseJSON v = do i <- parseJSON v maybe (fail "DocVersion out of range") return $ mkDocVersion i -- | 'ExternalDocVersion' is a convenience wrapper if your code uses its -- own version numbers instead of ones from ES. newtype ExternalDocVersion = ExternalDocVersion DocVersion deriving (Eq, Show, Ord, Bounded, Enum, ToJSON) -- | 'VersionControl' is specified when indexing documents as a -- optimistic concurrency control. data VersionControl = -- | Don't send a version. This is a pure overwrite. NoVersionControl | -- | Use the default ES versioning scheme. Only -- index the document if the version is the same -- as the one specified. Only applicable to -- updates, as you should be getting Version from -- a search result. InternalVersion DocVersion | -- | Use your own version numbering. Only index -- the document if the version is strictly higher -- OR the document doesn't exist. The given -- version will be used as the new version number -- for the stored document. N.B. All updates must -- increment this number, meaning there is some -- global, external ordering of updates. ExternalGT ExternalDocVersion | -- | Use your own version numbering. Only index -- the document if the version is equal or higher -- than the stored version. Will succeed if there -- is no existing document. The given version will -- be used as the new version number for the -- stored document. Use with care, as this could -- result in data loss. ExternalGTE ExternalDocVersion | -- | The document will always be indexed and the -- given version will be the new version. This is -- typically used for correcting errors. Use with -- care, as this could result in data loss. ForceVersion ExternalDocVersion deriving (Eq, Show, Ord)