-- | -- Module : Database.Relational.SqlSyntax.Updates -- Copyright : 2013-2018 Kei Hibino -- License : BSD3 -- -- Maintainer : ex8k.hibino@gmail.com -- Stability : experimental -- Portability : unknown -- -- This module provides types and expanding operations of SQL update and insert structure. module Database.Relational.SqlSyntax.Updates ( -- * Update and Insert assignments AssignColumn, AssignTerm, Assignment, composeSets, composeChunkValues, composeChunkValuesWithColumns, composeValuesListWithColumns, ) where import Data.Monoid ((<>)) import Language.SQL.Keyword (Keyword(..), (|*|), (.=.)) import qualified Language.SQL.Keyword as SQL import Database.Relational.Internal.String (StringSQL, rowConsStringSQL) -- | Column SQL String of assignment type AssignColumn = StringSQL -- | Value SQL String of assignment type AssignTerm = StringSQL -- | Assignment pair type Assignment = (AssignColumn, AssignTerm) -- | Compose SET clause from ['Assignment']. composeSets :: [Assignment] -> StringSQL composeSets as = assigns where assignList = foldr (\ (col, term) r -> (col .=. term) : r) [] as assigns | null assignList = error "Update assignment list is null!" | otherwise = SET <> SQL.fold (|*|) assignList -- | Compose VALUES clause from a row of value expressions. composeChunkValues :: Int -- ^ record count per chunk -> [AssignTerm] -- ^ value expression list -> Keyword composeChunkValues n0 vs = VALUES <> cvs where n | n0 >= 1 = n0 | otherwise = error $ "Invalid record count value: " ++ show n0 cvs = SQL.fold (|*|) . replicate n $ rowConsStringSQL vs -- | Compose columns row and VALUES clause from a row of value expressions. composeChunkValuesWithColumns :: Int -- ^ record count per chunk -> [Assignment] -- ^ -> StringSQL composeChunkValuesWithColumns sz as = rowConsStringSQL cs <> composeChunkValues sz vs where (cs, vs) = unzip as -- | Compose columns row and VALUES clause from rows list of value expressions. composeValuesListWithColumns :: [[Assignment]] -> StringSQL composeValuesListWithColumns pss = rowConsStringSQL cs <> VALUES <> SQL.fold (|*|) (map rowConsStringSQL vss) where cs = case pss of [] -> error "insertValueList: no assignment chunks" ps:_ -> fst $ unzip ps vss = map (snd . unzip) pss