hbs2/hbs2-git/hbs2-git-oracle/lib/DBPipe/SQLite/Generic.hs

81 lines
2.7 KiB
Haskell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# Language AllowAmbiguousTypes #-}
{-# Language UndecidableInstances #-}
{-# LANGUAGE DefaultSignatures #-}
module DBPipe.SQLite.Generic where
import GHC.Generics
import Data.Text qualified as Text
import Data.Text (Text)
import Data.String (IsString(..))
import Text.InterpolatedString.Perl6 (qc)
import Data.Coerce
-- FIXME: move-to-DBPipe
newtype SQLName = SQLName Text
deriving stock (Eq,Ord,Show)
deriving newtype (IsString,Monoid,Semigroup)
newtype SQLPart = SQLPart Text
deriving stock (Eq,Ord,Show)
deriving newtype (IsString,Monoid,Semigroup)
class ToSQL a where
toSQL :: a -> SQLPart
instance ToSQL SQLName where
toSQL (SQLName a) = SQLPart a
class HasTableName a where
tableName :: SQLName
class HasTableName t => GHasColumnNames t f where
gColumnNames :: f p -> [SQLName]
class HasTableName t => HasColumnNames t a where
columnNames :: a -> [SQLName]
default columnNames :: (Generic a, HasTableName t, GHasColumnNames t (Rep a)) => a -> [SQLName]
columnNames = gColumnNames @t . from
class HasTableName t => HasColumnName t a where
columnName :: SQLName
instance HasTableName t => HasColumnNames t [SQLName] where
columnNames = id
instance HasTableName t => HasColumnNames t SQLName where
columnNames n = [n]
instance (HasTableName t, Generic a, GHasColumnNames t (Rep a)) => HasColumnNames t a
instance HasTableName t => GHasColumnNames t U1 where
gColumnNames U1 = []
instance (GHasColumnNames t a, GHasColumnNames t b) => GHasColumnNames t (a :*: b) where
gColumnNames (a :*: b) = gColumnNames @t a <> gColumnNames @t b
instance (GHasColumnNames t a, GHasColumnNames t b) => GHasColumnNames t (a :+: b) where
gColumnNames _ = [] -- Не применяется для нашего случая, так как у нас нет вариантов.
instance (HasTableName t, HasColumnName t c) => GHasColumnNames t (K1 i c) where
gColumnNames (K1 c) = [columnName @t @c]
instance GHasColumnNames t a => GHasColumnNames t (M1 i t a) where
gColumnNames (M1 a) = gColumnNames @t a
columnListPart :: forall t a . (HasTableName t, HasColumnNames t a) => a -> SQLPart
columnListPart w = SQLPart $ Text.intercalate "," [ coerce @_ @Text x | x <- columnNames @t w ]
bindListPart :: forall t a . (HasTableName t, HasColumnNames t a) => a -> SQLPart
bindListPart w = SQLPart $ Text.intercalate "," [ "?" | _ <- columnNames @t w ]
class (HasTableName t, HasColumnNames t b) => Insert t b where
insert :: b -> SQLPart
instance (HasTableName t, HasColumnNames t b) => Insert t b where
insert values = [qc|insert into {tableName @t} values({n}) ({v})|]
where
n = bindListPart @t values
v = columnListPart @t values