{-# LANGUAGE UndecidableInstances #-}

-- | Contains types that can be used by backends to structure updates
-- to batches of rows in a table
module Hasura.RQL.IR.Update.Batch
  ( UpdateBatch (..),
    updateBatchIsEmpty,
  )
where

import Data.HashMap.Strict qualified as HashMap
import Hasura.Prelude
import Hasura.RQL.IR.BoolExp
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.BackendType

-- | Represents a set of update operations ('_ubOperations') applied to a batch of rows selected
-- from a table by filtering it with a boolean expression ('_ubWhere').
--
-- This type may be used by specific backends as a part their 'UpdateVariant'.
-- See 'Hasura.Backends.Postgres.Types.Update.PgUpdateVariant' for an example.
--
-- The actual operators used to affect changes against columns in '_ubOperations' are abstract
-- here and are specified by the specific backends based on what they actually support
data UpdateBatch (b :: BackendType) updateOperators v = UpdateBatch
  { forall (b :: BackendType) (updateOperators :: * -> *) v.
UpdateBatch b updateOperators v
-> HashMap (Column b) (updateOperators v)
_ubOperations :: HashMap (Column b) (updateOperators v),
    forall (b :: BackendType) (updateOperators :: * -> *) v.
UpdateBatch b updateOperators v -> AnnBoolExp b v
_ubWhere :: AnnBoolExp b v
  }
  deriving stock ((forall a b.
 (a -> b)
 -> UpdateBatch b updateOperators a
 -> UpdateBatch b updateOperators b)
-> (forall a b.
    a
    -> UpdateBatch b updateOperators b
    -> UpdateBatch b updateOperators a)
-> Functor (UpdateBatch b updateOperators)
forall a b.
a
-> UpdateBatch b updateOperators b
-> UpdateBatch b updateOperators a
forall a b.
(a -> b)
-> UpdateBatch b updateOperators a
-> UpdateBatch b updateOperators b
forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Functor updateOperators) =>
a
-> UpdateBatch b updateOperators b
-> UpdateBatch b updateOperators a
forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Functor updateOperators) =>
(a -> b)
-> UpdateBatch b updateOperators a
-> UpdateBatch b updateOperators b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Functor updateOperators) =>
(a -> b)
-> UpdateBatch b updateOperators a
-> UpdateBatch b updateOperators b
fmap :: forall a b.
(a -> b)
-> UpdateBatch b updateOperators a
-> UpdateBatch b updateOperators b
$c<$ :: forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Functor updateOperators) =>
a
-> UpdateBatch b updateOperators b
-> UpdateBatch b updateOperators a
<$ :: forall a b.
a
-> UpdateBatch b updateOperators b
-> UpdateBatch b updateOperators a
Functor, (forall m. Monoid m => UpdateBatch b updateOperators m -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> UpdateBatch b updateOperators a -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> UpdateBatch b updateOperators a -> m)
-> (forall a b.
    (a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b)
-> (forall a b.
    (a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b)
-> (forall b a.
    (b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b)
-> (forall b a.
    (b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b)
-> (forall a.
    (a -> a -> a) -> UpdateBatch b updateOperators a -> a)
-> (forall a.
    (a -> a -> a) -> UpdateBatch b updateOperators a -> a)
-> (forall a. UpdateBatch b updateOperators a -> [a])
-> (forall a. UpdateBatch b updateOperators a -> Bool)
-> (forall a. UpdateBatch b updateOperators a -> Int)
-> (forall a. Eq a => a -> UpdateBatch b updateOperators a -> Bool)
-> (forall a. Ord a => UpdateBatch b updateOperators a -> a)
-> (forall a. Ord a => UpdateBatch b updateOperators a -> a)
-> (forall a. Num a => UpdateBatch b updateOperators a -> a)
-> (forall a. Num a => UpdateBatch b updateOperators a -> a)
-> Foldable (UpdateBatch b updateOperators)
forall a. Eq a => a -> UpdateBatch b updateOperators a -> Bool
forall a. Num a => UpdateBatch b updateOperators a -> a
forall a. Ord a => UpdateBatch b updateOperators a -> a
forall m. Monoid m => UpdateBatch b updateOperators m -> m
forall a. UpdateBatch b updateOperators a -> Bool
forall a. UpdateBatch b updateOperators a -> Int
forall a. UpdateBatch b updateOperators a -> [a]
forall a. (a -> a -> a) -> UpdateBatch b updateOperators a -> a
forall m a.
Monoid m =>
(a -> m) -> UpdateBatch b updateOperators a -> m
forall b a.
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
forall a b.
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Eq a) =>
a -> UpdateBatch b updateOperators a -> Bool
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Num a) =>
UpdateBatch b updateOperators a -> a
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Ord a) =>
UpdateBatch b updateOperators a -> a
forall (b :: BackendType) (updateOperators :: * -> *) m.
(Backend b, Foldable updateOperators, Monoid m) =>
UpdateBatch b updateOperators m -> m
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> Bool
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> Int
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> [a]
forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
(a -> a -> a) -> UpdateBatch b updateOperators a -> a
forall (b :: BackendType) (updateOperators :: * -> *) m a.
(Backend b, Foldable updateOperators, Monoid m) =>
(a -> m) -> UpdateBatch b updateOperators a -> m
forall (b :: BackendType) (updateOperators :: * -> *) b a.
(Backend b, Foldable updateOperators) =>
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Foldable updateOperators) =>
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall (b :: BackendType) (updateOperators :: * -> *) m.
(Backend b, Foldable updateOperators, Monoid m) =>
UpdateBatch b updateOperators m -> m
fold :: forall m. Monoid m => UpdateBatch b updateOperators m -> m
$cfoldMap :: forall (b :: BackendType) (updateOperators :: * -> *) m a.
(Backend b, Foldable updateOperators, Monoid m) =>
(a -> m) -> UpdateBatch b updateOperators a -> m
foldMap :: forall m a.
Monoid m =>
(a -> m) -> UpdateBatch b updateOperators a -> m
$cfoldMap' :: forall (b :: BackendType) (updateOperators :: * -> *) m a.
(Backend b, Foldable updateOperators, Monoid m) =>
(a -> m) -> UpdateBatch b updateOperators a -> m
foldMap' :: forall m a.
Monoid m =>
(a -> m) -> UpdateBatch b updateOperators a -> m
$cfoldr :: forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Foldable updateOperators) =>
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
foldr :: forall a b.
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
$cfoldr' :: forall (b :: BackendType) (updateOperators :: * -> *) a b.
(Backend b, Foldable updateOperators) =>
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
foldr' :: forall a b.
(a -> b -> b) -> b -> UpdateBatch b updateOperators a -> b
$cfoldl :: forall (b :: BackendType) (updateOperators :: * -> *) b a.
(Backend b, Foldable updateOperators) =>
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
foldl :: forall b a.
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
$cfoldl' :: forall (b :: BackendType) (updateOperators :: * -> *) b a.
(Backend b, Foldable updateOperators) =>
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
foldl' :: forall b a.
(b -> a -> b) -> b -> UpdateBatch b updateOperators a -> b
$cfoldr1 :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
(a -> a -> a) -> UpdateBatch b updateOperators a -> a
foldr1 :: forall a. (a -> a -> a) -> UpdateBatch b updateOperators a -> a
$cfoldl1 :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
(a -> a -> a) -> UpdateBatch b updateOperators a -> a
foldl1 :: forall a. (a -> a -> a) -> UpdateBatch b updateOperators a -> a
$ctoList :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> [a]
toList :: forall a. UpdateBatch b updateOperators a -> [a]
$cnull :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> Bool
null :: forall a. UpdateBatch b updateOperators a -> Bool
$clength :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators) =>
UpdateBatch b updateOperators a -> Int
length :: forall a. UpdateBatch b updateOperators a -> Int
$celem :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Eq a) =>
a -> UpdateBatch b updateOperators a -> Bool
elem :: forall a. Eq a => a -> UpdateBatch b updateOperators a -> Bool
$cmaximum :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Ord a) =>
UpdateBatch b updateOperators a -> a
maximum :: forall a. Ord a => UpdateBatch b updateOperators a -> a
$cminimum :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Ord a) =>
UpdateBatch b updateOperators a -> a
minimum :: forall a. Ord a => UpdateBatch b updateOperators a -> a
$csum :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Num a) =>
UpdateBatch b updateOperators a -> a
sum :: forall a. Num a => UpdateBatch b updateOperators a -> a
$cproduct :: forall (b :: BackendType) (updateOperators :: * -> *) a.
(Backend b, Foldable updateOperators, Num a) =>
UpdateBatch b updateOperators a -> a
product :: forall a. Num a => UpdateBatch b updateOperators a -> a
Foldable, Functor (UpdateBatch b updateOperators)
Foldable (UpdateBatch b updateOperators)
Functor (UpdateBatch b updateOperators)
-> Foldable (UpdateBatch b updateOperators)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b)
    -> UpdateBatch b updateOperators a
    -> f (UpdateBatch b updateOperators b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    UpdateBatch b updateOperators (f a)
    -> f (UpdateBatch b updateOperators a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b)
    -> UpdateBatch b updateOperators a
    -> m (UpdateBatch b updateOperators b))
-> (forall (m :: * -> *) a.
    Monad m =>
    UpdateBatch b updateOperators (m a)
    -> m (UpdateBatch b updateOperators a))
-> Traversable (UpdateBatch b updateOperators)
forall {b :: BackendType} {updateOperators :: * -> *}.
(Backend b, Traversable updateOperators) =>
Functor (UpdateBatch b updateOperators)
forall {b :: BackendType} {updateOperators :: * -> *}.
(Backend b, Traversable updateOperators) =>
Foldable (UpdateBatch b updateOperators)
forall (b :: BackendType) (updateOperators :: * -> *) (m :: * -> *)
       a.
(Backend b, Traversable updateOperators, Monad m) =>
UpdateBatch b updateOperators (m a)
-> m (UpdateBatch b updateOperators a)
forall (b :: BackendType) (updateOperators :: * -> *) (f :: * -> *)
       a.
(Backend b, Traversable updateOperators, Applicative f) =>
UpdateBatch b updateOperators (f a)
-> f (UpdateBatch b updateOperators a)
forall (b :: BackendType) (updateOperators :: * -> *) (m :: * -> *)
       a b.
(Backend b, Traversable updateOperators, Monad m) =>
(a -> m b)
-> UpdateBatch b updateOperators a
-> m (UpdateBatch b updateOperators b)
forall (b :: BackendType) (updateOperators :: * -> *) (f :: * -> *)
       a b.
(Backend b, Traversable updateOperators, Applicative f) =>
(a -> f b)
-> UpdateBatch b updateOperators a
-> f (UpdateBatch b updateOperators b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
UpdateBatch b updateOperators (m a)
-> m (UpdateBatch b updateOperators a)
forall (f :: * -> *) a.
Applicative f =>
UpdateBatch b updateOperators (f a)
-> f (UpdateBatch b updateOperators a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> UpdateBatch b updateOperators a
-> m (UpdateBatch b updateOperators b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> UpdateBatch b updateOperators a
-> f (UpdateBatch b updateOperators b)
$ctraverse :: forall (b :: BackendType) (updateOperators :: * -> *) (f :: * -> *)
       a b.
(Backend b, Traversable updateOperators, Applicative f) =>
(a -> f b)
-> UpdateBatch b updateOperators a
-> f (UpdateBatch b updateOperators b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> UpdateBatch b updateOperators a
-> f (UpdateBatch b updateOperators b)
$csequenceA :: forall (b :: BackendType) (updateOperators :: * -> *) (f :: * -> *)
       a.
(Backend b, Traversable updateOperators, Applicative f) =>
UpdateBatch b updateOperators (f a)
-> f (UpdateBatch b updateOperators a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
UpdateBatch b updateOperators (f a)
-> f (UpdateBatch b updateOperators a)
$cmapM :: forall (b :: BackendType) (updateOperators :: * -> *) (m :: * -> *)
       a b.
(Backend b, Traversable updateOperators, Monad m) =>
(a -> m b)
-> UpdateBatch b updateOperators a
-> m (UpdateBatch b updateOperators b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> UpdateBatch b updateOperators a
-> m (UpdateBatch b updateOperators b)
$csequence :: forall (b :: BackendType) (updateOperators :: * -> *) (m :: * -> *)
       a.
(Backend b, Traversable updateOperators, Monad m) =>
UpdateBatch b updateOperators (m a)
-> m (UpdateBatch b updateOperators a)
sequence :: forall (m :: * -> *) a.
Monad m =>
UpdateBatch b updateOperators (m a)
-> m (UpdateBatch b updateOperators a)
Traversable)

deriving stock instance
  ( Backend b,
    Show v,
    Show (updateOperators v),
    Show (AnnBoolExp b v)
  ) =>
  Show (UpdateBatch b updateOperators v)

deriving stock instance
  ( Backend b,
    Eq v,
    Eq (updateOperators v),
    Eq (AnnBoolExp b v)
  ) =>
  Eq (UpdateBatch b updateOperators v)

-- | Are we actually updating anything in the batch?
updateBatchIsEmpty :: UpdateBatch b updateOperators v -> Bool
updateBatchIsEmpty :: forall (b :: BackendType) (updateOperators :: * -> *) v.
UpdateBatch b updateOperators v -> Bool
updateBatchIsEmpty UpdateBatch {HashMap (Column b) (updateOperators v)
AnnBoolExp b v
_ubOperations :: forall (b :: BackendType) (updateOperators :: * -> *) v.
UpdateBatch b updateOperators v
-> HashMap (Column b) (updateOperators v)
_ubWhere :: forall (b :: BackendType) (updateOperators :: * -> *) v.
UpdateBatch b updateOperators v -> AnnBoolExp b v
_ubOperations :: HashMap (Column b) (updateOperators v)
_ubWhere :: AnnBoolExp b v
..} =
  HashMap (Column b) (updateOperators v) -> Bool
forall k v. HashMap k v -> Bool
HashMap.null HashMap (Column b) (updateOperators v)
_ubOperations