-- |
-- Module      : Database.Relational.Internal.String
-- Copyright   : 2014-2019 Kei Hibino
-- License     : BSD3
--
-- Maintainer  : ex8k.hibino@gmail.com
-- Stability   : experimental
-- Portability : unknown
--
-- This module provides SQL string wrap interfaces.
module Database.Relational.Internal.String (
  StringSQL, stringSQL, showStringSQL,

  rowStringSQL, rowPlaceHolderStringSQL,

  rowConsStringSQL, listStringSQL,
  ) where

import Language.SQL.Keyword (Keyword, word, wordShow, fold, (|*|), paren)


-- | String wrap type for SQL strings.
type StringSQL = Keyword

-- | 'StringSQL' from 'String'.
stringSQL :: String -> StringSQL
stringSQL :: String -> StringSQL
stringSQL =  String -> StringSQL
word

-- | 'StringSQL' to 'String'.
showStringSQL :: StringSQL -> String
showStringSQL :: StringSQL -> String
showStringSQL =  StringSQL -> String
wordShow

-- | Row String of SQL values.
rowStringSQL :: [StringSQL] -> StringSQL
rowStringSQL :: [StringSQL] -> StringSQL
rowStringSQL =  [StringSQL] -> StringSQL
d  where
  d :: [StringSQL] -> StringSQL
d []  = String -> StringSQL
forall a. HasCallStack => String -> a
error String
"Record: no columns. empty row is not allowed in SQL."
  d [StringSQL
c] = StringSQL
c
  d [StringSQL]
cs  = StringSQL -> StringSQL
paren (StringSQL -> StringSQL) -> StringSQL -> StringSQL
forall a b. (a -> b) -> a -> b
$ (StringSQL -> StringSQL -> StringSQL) -> [StringSQL] -> StringSQL
fold StringSQL -> StringSQL -> StringSQL
(|*|) [StringSQL]
cs

-- | Place holder row String of SQL.
rowPlaceHolderStringSQL :: Int -> StringSQL
rowPlaceHolderStringSQL :: Int -> StringSQL
rowPlaceHolderStringSQL =  [StringSQL] -> StringSQL
rowStringSQL ([StringSQL] -> StringSQL)
-> (Int -> [StringSQL]) -> Int -> StringSQL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> StringSQL -> [StringSQL]
forall a. Int -> a -> [a]
`replicate` String -> StringSQL
stringSQL String
"?")

-- | List String of SQL.
rowConsStringSQL :: [StringSQL] -> StringSQL
rowConsStringSQL :: [StringSQL] -> StringSQL
rowConsStringSQL =  StringSQL -> StringSQL
paren (StringSQL -> StringSQL)
-> ([StringSQL] -> StringSQL) -> [StringSQL] -> StringSQL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StringSQL -> StringSQL -> StringSQL) -> [StringSQL] -> StringSQL
fold StringSQL -> StringSQL -> StringSQL
(|*|)

-- | List String of SQL.
listStringSQL :: [StringSQL] -> StringSQL
listStringSQL :: [StringSQL] -> StringSQL
listStringSQL =  StringSQL -> StringSQL
paren (StringSQL -> StringSQL)
-> ([StringSQL] -> StringSQL) -> [StringSQL] -> StringSQL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StringSQL -> StringSQL -> StringSQL) -> [StringSQL] -> StringSQL
fold StringSQL -> StringSQL -> StringSQL
(|*|)