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

79 lines
2.4 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
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 GHasColumnNames f where
gColumnNames :: f p -> [SQLName]
class HasColumnNames a where
columnNames :: a -> [SQLName]
default columnNames :: (Generic a, GHasColumnNames (Rep a)) => a -> [SQLName]
columnNames = gColumnNames . from
class HasTableName t where
tableName :: SQLName
class HasColumnName a where
columnName :: SQLName
instance HasColumnNames [SQLName] where
columnNames = id
instance HasColumnNames SQLName where
columnNames n = [n]
instance (Generic a, GHasColumnNames (Rep a)) => HasColumnNames a
instance GHasColumnNames U1 where
gColumnNames U1 = []
instance (GHasColumnNames a, GHasColumnNames b) => GHasColumnNames (a :*: b) where
gColumnNames (a :*: b) = gColumnNames a <> gColumnNames b
instance (GHasColumnNames a, GHasColumnNames b) => GHasColumnNames (a :+: b) where
gColumnNames _ = [] -- Не используется для нашего случая.
instance HasColumnName c => GHasColumnNames (K1 i c) where
gColumnNames (K1 c) = [columnName @c]
instance GHasColumnNames a => GHasColumnNames (M1 i t a) where
gColumnNames (M1 a) = gColumnNames a
columnListPart :: forall a . HasColumnNames a => a -> SQLPart
columnListPart w = SQLPart $ Text.intercalate "," [ coerce @_ @Text x | x <- columnNames w ]
bindListPart :: forall a . HasColumnNames a => a -> SQLPart
bindListPart w = SQLPart $ Text.intercalate "," [ "?" | _ <- columnNames w ]
class (HasTableName t, HasColumnNames b) => Insert t b where
insert :: b -> SQLPart
instance (HasTableName t, HasColumnNames b) => Insert t b where
insert values = [qc|insert into {tableName @t} values({v}) ({n})|]
where
n = bindListPart values
v = columnListPart values