module Hasura.Backends.MSSQL.FromIr.Insert
( fromInsert,
toMerge,
toInsertValuesIntoTempTable,
)
where
import Data.HashMap.Strict.Extended qualified as HashMap
import Data.HashSet qualified as HS
import Hasura.Backends.MSSQL.FromIr (FromIr)
import Hasura.Backends.MSSQL.FromIr.Constants (tempTableNameInserted, tempTableNameValues)
import Hasura.Backends.MSSQL.FromIr.Expression (fromGBoolExp)
import Hasura.Backends.MSSQL.Instances.Types ()
import Hasura.Backends.MSSQL.Types.Insert (IfMatched (..))
import Hasura.Backends.MSSQL.Types.Internal as TSQL
import Hasura.Prelude
import Hasura.RQL.IR qualified as IR
import Hasura.RQL.Types.BackendType
import Hasura.RQL.Types.Column qualified as IR
fromInsert :: IR.AnnotatedInsert 'MSSQL Void Expression -> Insert
fromInsert :: AnnotatedInsert 'MSSQL Void Expression -> Insert
fromInsert IR.AnnotatedInsert {Bool
Maybe NamingCase
Text
MutationOutputG 'MSSQL Void Expression
MultiObjectInsert 'MSSQL Expression
_aiFieldName :: Text
_aiIsSingle :: Bool
_aiData :: MultiObjectInsert 'MSSQL Expression
_aiOutput :: MutationOutputG 'MSSQL Void Expression
_aiNamingConvention :: Maybe NamingCase
_aiFieldName :: forall (b :: BackendType) r v. AnnotatedInsert b r v -> Text
_aiIsSingle :: forall (b :: BackendType) r v. AnnotatedInsert b r v -> Bool
_aiData :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> MultiObjectInsert b v
_aiOutput :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> MutationOutputG b r v
_aiNamingConvention :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> Maybe NamingCase
..} =
let IR.AnnotatedInsertData {[AnnotatedInsertRow 'MSSQL Expression]
[ColumnInfo 'MSSQL]
Maybe (NESeq (Column 'MSSQL))
Maybe (ValidateInput ResolvedWebhook)
(AnnBoolExp 'MSSQL Expression,
Maybe (AnnBoolExp 'MSSQL Expression))
PreSetColsG 'MSSQL Expression
TableName 'MSSQL
ExtraTableMetadata 'MSSQL
BackendInsert 'MSSQL Expression
_aiInsertObject :: [AnnotatedInsertRow 'MSSQL Expression]
_aiTableName :: TableName 'MSSQL
_aiCheckCondition :: (AnnBoolExp 'MSSQL Expression,
Maybe (AnnBoolExp 'MSSQL Expression))
_aiTableColumns :: [ColumnInfo 'MSSQL]
_aiPrimaryKey :: Maybe (NESeq (Column 'MSSQL))
_aiExtraTableMetadata :: ExtraTableMetadata 'MSSQL
_aiPresetValues :: PreSetColsG 'MSSQL Expression
_aiBackendInsert :: BackendInsert 'MSSQL Expression
_aiValidateInput :: Maybe (ValidateInput ResolvedWebhook)
_aiInsertObject :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> f (AnnotatedInsertRow b v)
_aiTableName :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> TableName b
_aiCheckCondition :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v
-> (AnnBoolExp b v, Maybe (AnnBoolExp b v))
_aiTableColumns :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> [ColumnInfo b]
_aiPrimaryKey :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> Maybe (NESeq (Column b))
_aiExtraTableMetadata :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> ExtraTableMetadata b
_aiPresetValues :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> PreSetColsG b v
_aiBackendInsert :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> BackendInsert b v
_aiValidateInput :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> Maybe (ValidateInput ResolvedWebhook)
..} = MultiObjectInsert 'MSSQL Expression
_aiData
(HashSet ColumnName
insertColumnNames, [HashMap ColumnName Expression]
insertRows) = HashMap ColumnName Expression
-> [AnnotatedInsertRow 'MSSQL Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression])
normalizeInsertRows PreSetColsG 'MSSQL Expression
HashMap ColumnName Expression
_aiPresetValues ([AnnotatedInsertRow 'MSSQL Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression]))
-> [AnnotatedInsertRow 'MSSQL Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression])
forall a b. (a -> b) -> a -> b
$ [AnnotatedInsertRow 'MSSQL Expression]
_aiInsertObject
insertValues :: [Values]
insertValues = (HashMap ColumnName Expression -> Values)
-> [HashMap ColumnName Expression] -> [Values]
forall a b. (a -> b) -> [a] -> [b]
map ([Expression] -> Values
Values ([Expression] -> Values)
-> (HashMap ColumnName Expression -> [Expression])
-> HashMap ColumnName Expression
-> Values
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap ColumnName Expression -> [Expression]
forall k v. HashMap k v -> [v]
HashMap.elems) [HashMap ColumnName Expression]
insertRows
allColumnNames :: [ColumnName]
allColumnNames = (ColumnInfo 'MSSQL -> ColumnName)
-> [ColumnInfo 'MSSQL] -> [ColumnName]
forall a b. (a -> b) -> [a] -> [b]
map ColumnInfo 'MSSQL -> Column 'MSSQL
ColumnInfo 'MSSQL -> ColumnName
forall (b :: BackendType). ColumnInfo b -> Column b
IR.ciColumn [ColumnInfo 'MSSQL]
_aiTableColumns
insertOutput :: Output Inserted
insertOutput = Inserted -> [OutputColumn] -> Output Inserted
forall t. t -> [OutputColumn] -> Output t
Output Inserted
Inserted ([OutputColumn] -> Output Inserted)
-> [OutputColumn] -> Output Inserted
forall a b. (a -> b) -> a -> b
$ (ColumnName -> OutputColumn) -> [ColumnName] -> [OutputColumn]
forall a b. (a -> b) -> [a] -> [b]
map ColumnName -> OutputColumn
OutputColumn [ColumnName]
allColumnNames
tempTable :: TempTable
tempTable = TempTableName -> [ColumnName] -> TempTable
TempTable TempTableName
tempTableNameInserted [ColumnName]
allColumnNames
in TableName
-> [ColumnName]
-> Output Inserted
-> TempTable
-> [Values]
-> Insert
Insert TableName 'MSSQL
TableName
_aiTableName (HashSet ColumnName -> [ColumnName]
forall a. HashSet a -> [a]
HS.toList HashSet ColumnName
insertColumnNames) Output Inserted
insertOutput TempTable
tempTable [Values]
insertValues
normalizeInsertRows ::
HashMap.HashMap (Column 'MSSQL) Expression ->
[IR.AnnotatedInsertRow 'MSSQL Expression] ->
(HashSet (Column 'MSSQL), [HashMap.HashMap (Column 'MSSQL) Expression])
normalizeInsertRows :: HashMap ColumnName Expression
-> [AnnotatedInsertRow 'MSSQL Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression])
normalizeInsertRows HashMap ColumnName Expression
presets [AnnotatedInsertRow 'MSSQL Expression]
insertRows =
Expression
-> [HashMap ColumnName Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression])
forall a b.
Hashable a =>
b -> [HashMap a b] -> (HashSet a, [HashMap a b])
HashMap.homogenise
Expression
DefaultExpression
((AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression)
-> [AnnotatedInsertRow 'MSSQL Expression]
-> [HashMap ColumnName Expression]
forall a b. (a -> b) -> [a] -> [b]
map ((HashMap ColumnName Expression
presets HashMap ColumnName Expression
-> HashMap ColumnName Expression -> HashMap ColumnName Expression
forall a. Semigroup a => a -> a -> a
<>) (HashMap ColumnName Expression -> HashMap ColumnName Expression)
-> (AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression)
-> AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(ColumnName, Expression)] -> HashMap ColumnName Expression
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ColumnName, Expression)] -> HashMap ColumnName Expression)
-> (AnnotatedInsertRow 'MSSQL Expression
-> [(ColumnName, Expression)])
-> AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnnotatedInsertRow 'MSSQL Expression
-> [(Column 'MSSQL, Expression)]
AnnotatedInsertRow 'MSSQL Expression -> [(ColumnName, Expression)]
forall (b :: BackendType) v.
AnnotatedInsertRow b v -> [(Column b, v)]
IR.getInsertColumns) [AnnotatedInsertRow 'MSSQL Expression]
insertRows)
toMerge ::
TableName ->
[IR.AnnotatedInsertRow 'MSSQL Expression] ->
[IR.ColumnInfo 'MSSQL] ->
IfMatched Expression ->
FromIr Merge
toMerge :: TableName
-> [AnnotatedInsertRow 'MSSQL Expression]
-> [ColumnInfo 'MSSQL]
-> IfMatched Expression
-> FromIr Merge
toMerge TableName
tableName [AnnotatedInsertRow 'MSSQL Expression]
insertRows [ColumnInfo 'MSSQL]
allColumns IfMatched {[ColumnName]
HashMap ColumnName Expression
AnnBoolExp 'MSSQL Expression
_imMatchColumns :: [ColumnName]
_imUpdateColumns :: [ColumnName]
_imConditions :: AnnBoolExp 'MSSQL Expression
_imColumnPresets :: HashMap ColumnName Expression
_imMatchColumns :: forall v. IfMatched v -> [ColumnName]
_imUpdateColumns :: forall v. IfMatched v -> [ColumnName]
_imConditions :: forall v. IfMatched v -> AnnBoolExp 'MSSQL v
_imColumnPresets :: forall v. IfMatched v -> HashMap ColumnName v
..} = do
let insertColumnNames :: [ColumnName]
insertColumnNames =
HashSet ColumnName -> [ColumnName]
forall a. HashSet a -> [a]
HS.toList
(HashSet ColumnName -> [ColumnName])
-> HashSet ColumnName -> [ColumnName]
forall a b. (a -> b) -> a -> b
$ HashMap ColumnName Expression -> HashSet ColumnName
forall k a. HashMap k a -> HashSet k
HashMap.keysSet HashMap ColumnName Expression
_imColumnPresets
HashSet ColumnName -> HashSet ColumnName -> HashSet ColumnName
forall a. Semigroup a => a -> a -> a
<> [HashSet ColumnName] -> HashSet ColumnName
forall a. (Eq a, Hashable a) => [HashSet a] -> HashSet a
HS.unions ((AnnotatedInsertRow 'MSSQL Expression -> HashSet ColumnName)
-> [AnnotatedInsertRow 'MSSQL Expression] -> [HashSet ColumnName]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap ColumnName Expression -> HashSet ColumnName
forall k a. HashMap k a -> HashSet k
HashMap.keysSet (HashMap ColumnName Expression -> HashSet ColumnName)
-> (AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression)
-> AnnotatedInsertRow 'MSSQL Expression
-> HashSet ColumnName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(ColumnName, Expression)] -> HashMap ColumnName Expression
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ColumnName, Expression)] -> HashMap ColumnName Expression)
-> (AnnotatedInsertRow 'MSSQL Expression
-> [(ColumnName, Expression)])
-> AnnotatedInsertRow 'MSSQL Expression
-> HashMap ColumnName Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnnotatedInsertRow 'MSSQL Expression
-> [(Column 'MSSQL, Expression)]
AnnotatedInsertRow 'MSSQL Expression -> [(ColumnName, Expression)]
forall (b :: BackendType) v.
AnnotatedInsertRow b v -> [(Column b, v)]
IR.getInsertColumns) [AnnotatedInsertRow 'MSSQL Expression]
insertRows)
allColumnNames :: [ColumnName]
allColumnNames = (ColumnInfo 'MSSQL -> ColumnName)
-> [ColumnInfo 'MSSQL] -> [ColumnName]
forall a b. (a -> b) -> [a] -> [b]
map ColumnInfo 'MSSQL -> Column 'MSSQL
ColumnInfo 'MSSQL -> ColumnName
forall (b :: BackendType). ColumnInfo b -> Column b
IR.ciColumn [ColumnInfo 'MSSQL]
allColumns
Expression
matchConditions <-
(ReaderT EntityAlias FromIr Expression
-> EntityAlias -> FromIr Expression)
-> EntityAlias
-> ReaderT EntityAlias FromIr Expression
-> FromIr Expression
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT EntityAlias FromIr Expression
-> EntityAlias -> FromIr Expression
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (Text -> EntityAlias
EntityAlias Text
"target")
(ReaderT EntityAlias FromIr Expression -> FromIr Expression)
-> ReaderT EntityAlias FromIr Expression -> FromIr Expression
forall a b. (a -> b) -> a -> b
$ AnnBoolExp 'MSSQL Expression
-> ReaderT EntityAlias FromIr Expression
fromGBoolExp AnnBoolExp 'MSSQL Expression
_imConditions
Merge -> FromIr Merge
forall a. a -> FromIr a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(Merge -> FromIr Merge) -> Merge -> FromIr Merge
forall a b. (a -> b) -> a -> b
$ Merge
{ $sel:mergeTargetTable:Merge :: TableName
mergeTargetTable = TableName
tableName,
$sel:mergeUsing:Merge :: MergeUsing
mergeUsing = TempTableName -> [ColumnName] -> MergeUsing
MergeUsing TempTableName
tempTableNameValues [ColumnName]
insertColumnNames,
$sel:mergeOn:Merge :: MergeOn
mergeOn = [ColumnName] -> MergeOn
MergeOn [ColumnName]
_imMatchColumns,
$sel:mergeWhenMatched:Merge :: MergeWhenMatched
mergeWhenMatched = [ColumnName]
-> Expression -> HashMap ColumnName Expression -> MergeWhenMatched
MergeWhenMatched [ColumnName]
_imUpdateColumns Expression
matchConditions HashMap ColumnName Expression
_imColumnPresets,
$sel:mergeWhenNotMatched:Merge :: MergeWhenNotMatched
mergeWhenNotMatched = [ColumnName] -> MergeWhenNotMatched
MergeWhenNotMatched [ColumnName]
insertColumnNames,
$sel:mergeInsertOutput:Merge :: Output Inserted
mergeInsertOutput = Inserted -> [OutputColumn] -> Output Inserted
forall t. t -> [OutputColumn] -> Output t
Output Inserted
Inserted ([OutputColumn] -> Output Inserted)
-> [OutputColumn] -> Output Inserted
forall a b. (a -> b) -> a -> b
$ (ColumnName -> OutputColumn) -> [ColumnName] -> [OutputColumn]
forall a b. (a -> b) -> [a] -> [b]
map ColumnName -> OutputColumn
OutputColumn [ColumnName]
allColumnNames,
$sel:mergeOutputTempTable:Merge :: TempTable
mergeOutputTempTable = TempTableName -> [ColumnName] -> TempTable
TempTable TempTableName
tempTableNameInserted [ColumnName]
allColumnNames
}
toInsertValuesIntoTempTable :: TempTableName -> IR.AnnotatedInsert 'MSSQL Void Expression -> InsertValuesIntoTempTable
toInsertValuesIntoTempTable :: TempTableName
-> AnnotatedInsert 'MSSQL Void Expression
-> InsertValuesIntoTempTable
toInsertValuesIntoTempTable TempTableName
tempTable IR.AnnotatedInsert {Bool
Maybe NamingCase
Text
MutationOutputG 'MSSQL Void Expression
MultiObjectInsert 'MSSQL Expression
_aiFieldName :: forall (b :: BackendType) r v. AnnotatedInsert b r v -> Text
_aiIsSingle :: forall (b :: BackendType) r v. AnnotatedInsert b r v -> Bool
_aiData :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> MultiObjectInsert b v
_aiOutput :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> MutationOutputG b r v
_aiNamingConvention :: forall (b :: BackendType) r v.
AnnotatedInsert b r v -> Maybe NamingCase
_aiFieldName :: Text
_aiIsSingle :: Bool
_aiData :: MultiObjectInsert 'MSSQL Expression
_aiOutput :: MutationOutputG 'MSSQL Void Expression
_aiNamingConvention :: Maybe NamingCase
..} =
let IR.AnnotatedInsertData {[AnnotatedInsertRow 'MSSQL Expression]
[ColumnInfo 'MSSQL]
Maybe (NESeq (Column 'MSSQL))
Maybe (ValidateInput ResolvedWebhook)
(AnnBoolExp 'MSSQL Expression,
Maybe (AnnBoolExp 'MSSQL Expression))
PreSetColsG 'MSSQL Expression
TableName 'MSSQL
ExtraTableMetadata 'MSSQL
BackendInsert 'MSSQL Expression
_aiInsertObject :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> f (AnnotatedInsertRow b v)
_aiTableName :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> TableName b
_aiCheckCondition :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v
-> (AnnBoolExp b v, Maybe (AnnBoolExp b v))
_aiTableColumns :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> [ColumnInfo b]
_aiPrimaryKey :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> Maybe (NESeq (Column b))
_aiExtraTableMetadata :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> ExtraTableMetadata b
_aiPresetValues :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> PreSetColsG b v
_aiBackendInsert :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> BackendInsert b v
_aiValidateInput :: forall (b :: BackendType) (f :: * -> *) v.
AnnotatedInsertData b f v -> Maybe (ValidateInput ResolvedWebhook)
_aiInsertObject :: [AnnotatedInsertRow 'MSSQL Expression]
_aiTableName :: TableName 'MSSQL
_aiCheckCondition :: (AnnBoolExp 'MSSQL Expression,
Maybe (AnnBoolExp 'MSSQL Expression))
_aiTableColumns :: [ColumnInfo 'MSSQL]
_aiPrimaryKey :: Maybe (NESeq (Column 'MSSQL))
_aiExtraTableMetadata :: ExtraTableMetadata 'MSSQL
_aiPresetValues :: PreSetColsG 'MSSQL Expression
_aiBackendInsert :: BackendInsert 'MSSQL Expression
_aiValidateInput :: Maybe (ValidateInput ResolvedWebhook)
..} = MultiObjectInsert 'MSSQL Expression
_aiData
(HashSet ColumnName
insertColumnNames, [HashMap ColumnName Expression]
insertRows) = HashMap ColumnName Expression
-> [AnnotatedInsertRow 'MSSQL Expression]
-> (HashSet ColumnName, [HashMap ColumnName Expression])
normalizeInsertRows PreSetColsG 'MSSQL Expression
HashMap ColumnName Expression
_aiPresetValues [AnnotatedInsertRow 'MSSQL Expression]
_aiInsertObject
insertValues :: [Values]
insertValues = (HashMap ColumnName Expression -> Values)
-> [HashMap ColumnName Expression] -> [Values]
forall a b. (a -> b) -> [a] -> [b]
map ([Expression] -> Values
Values ([Expression] -> Values)
-> (HashMap ColumnName Expression -> [Expression])
-> HashMap ColumnName Expression
-> Values
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap ColumnName Expression -> [Expression]
forall k v. HashMap k v -> [v]
HashMap.elems) [HashMap ColumnName Expression]
insertRows
in InsertValuesIntoTempTable
{ $sel:ivittTempTableName:InsertValuesIntoTempTable :: TempTableName
ivittTempTableName = TempTableName
tempTable,
$sel:ivittColumns:InsertValuesIntoTempTable :: [ColumnName]
ivittColumns = HashSet ColumnName -> [ColumnName]
forall a. HashSet a -> [a]
HS.toList HashSet ColumnName
insertColumnNames,
$sel:ivittValues:InsertValuesIntoTempTable :: [Values]
ivittValues = [Values]
insertValues
}