module PgSchema.DML.Delete where

import Data.String
import Data.Text as T
import PgSchema.DML.Select
import PgSchema.DML.Select.Types
import Database.PostgreSQL.Simple
import GHC.Int

import PgSchema.Schema
import PgSchema.Utils.Internal
import Data.Singletons


-- | Delete records in table by condition.
--
deleteByCond :: forall sch t -> SingI t =>
  Connection -> Cond sch t -> IO (Int64, (Text,[SomeToField]))
deleteByCond :: forall sch (t :: NameNSK) ->
SingI t =>
Connection -> Cond sch t -> IO (Int64, (Text, [SomeToField]))
deleteByCond sch t Connection
conn Cond sch t
cond = (Text, [SomeToField])
-> IO (Int64, (Text, [SomeToField]))
-> IO (Int64, (Text, [SomeToField]))
forall a b. Show a => a -> b -> b
traceShow' (Text
q,[SomeToField]
ps)
  (IO (Int64, (Text, [SomeToField]))
 -> IO (Int64, (Text, [SomeToField])))
-> IO (Int64, (Text, [SomeToField]))
-> IO (Int64, (Text, [SomeToField]))
forall a b. (a -> b) -> a -> b
$ (,(Text
q,[SomeToField]
ps)) (Int64 -> (Int64, (Text, [SomeToField])))
-> IO Int64 -> IO (Int64, (Text, [SomeToField]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Connection -> Query -> [SomeToField] -> IO Int64
forall q. ToRow q => Connection -> Query -> q -> IO Int64
execute Connection
conn (String -> Query
forall a. IsString a => String -> a
fromString (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
q) [SomeToField]
ps
  where
    (Text
q, [SomeToField]
ps) = forall sch (t :: NameNSK) s.
(IsString s, Monoid s, SingI t) =>
Cond sch t -> (s, [SomeToField])
deleteText @sch @t Cond sch t
cond

-- | Construct SQL text for deleting records by condition.
--
deleteText :: forall sch t s. (IsString s, Monoid s, SingI t) =>
  Cond sch t -> (s, [SomeToField])
deleteText :: forall sch (t :: NameNSK) s.
(IsString s, Monoid s, SingI t) =>
Cond sch t -> (s, [SomeToField])
deleteText Cond sch t
cond =
  (s
"delete from " s -> s -> s
forall a. Semigroup a => a -> a -> a
<> s
tn s -> s -> s
forall a. Semigroup a => a -> a -> a
<> s
" t0 " s -> s -> s
forall a. Semigroup a => a -> a -> a
<> Text -> s
forall t. IsString t => Text -> t
fromText Text
whereTxt, [SomeToField]
condParams )
  where
    tn :: s
tn = Text -> s
forall t. IsString t => Text -> t
fromText (Text -> s) -> Text -> s
forall a b. (a -> b) -> a -> b
$ NameNS -> Text
qualName (NameNS -> Text) -> NameNS -> Text
forall a b. (a -> b) -> a -> b
$ forall {k} (a :: k). (SingKind k, SingI a) => Demote k
forall (a :: NameNSK).
(SingKind NameNSK, SingI a) =>
Demote NameNSK
demote @t
    (Text
condTxt, [SomeToField]
condParams) = Int -> Cond sch t -> (Text, [SomeToField])
forall sch (t :: NameNSK).
Int -> Cond sch t -> (Text, [SomeToField])
pgCond Int
0 Cond sch t
cond
    whereTxt :: Text
whereTxt
      | Text -> Bool
T.null Text
condTxt = Text
forall a. Monoid a => a
mempty
      | Bool
otherwise = Text
" where " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
condTxt