module Database.Sql.Type
( module Database.Sql.Type
, module Database.Sql.Type.Names
, module Database.Sql.Type.TableProps
, module Database.Sql.Type.Schema
, module Database.Sql.Type.Scope
, module Database.Sql.Type.Query
, module Database.Sql.Type.Unused
) where
import Database.Sql.Type.Names
import Database.Sql.Type.Schema
import Database.Sql.Type.Query
import Database.Sql.Type.TableProps
import Database.Sql.Type.Scope
import Database.Sql.Type.Unused
import Control.Applicative ((<|>))
import Data.Aeson (ToJSON (..), FromJSON (..), (.:), (.:?), (.=))
import qualified Data.Aeson as JSON
import Data.List.NonEmpty (NonEmpty ((:|)), nonEmpty, toList)
import qualified Data.List.NonEmpty as NE
import qualified Data.Text.Lazy.Encoding as TL
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as BL
import Data.Proxy (Proxy (..))
import Data.Data (Data)
import GHC.Generics (Generic)
import GHC.Exts (Constraint)
import Test.QuickCheck
type ConstrainSDialectParts (c :: * -> Constraint) d r a = (c a, c (DialectCreateTableExtra d r a), c (DialectColumnDefinitionExtra d a))
type ConstrainSASDialectParts (c :: (* -> *) -> Constraint) d r = (c (DialectCreateTableExtra d r), c (DialectColumnDefinitionExtra d))
type ConstrainSAll (c :: * -> Constraint) d r a = (ConstrainSNames c r a, ConstrainSDialectParts c d r a)
type ConstrainSASAll (c :: (* -> *) -> Constraint) d r = (ConstrainSASNames c r, ConstrainSASDialectParts c d r)
class Dialect d where
type DialectCreateTableExtra d r :: * -> *
type DialectCreateTableExtra d r = Unused
type DialectColumnDefinitionExtra d :: * -> *
type DialectColumnDefinitionExtra d = Unused
shouldCTEsShadowTables :: Proxy d -> Bool
areLcolumnsVisibleInLateralViews :: Proxy d -> Bool
getSelectScope :: forall a . Proxy d -> FromColumns a -> SelectionAliases a -> SelectScope a
resolveCreateTableExtra :: Proxy d -> DialectCreateTableExtra d RawNames a -> Resolver (DialectCreateTableExtra d ResolvedNames) a
data Unparsed a = Unparsed a deriving (Show, Eq)
data Statement
d
r
a
= QueryStmt (Query r a)
| InsertStmt (Insert r a)
| UpdateStmt (Update r a)
| DeleteStmt (Delete r a)
| TruncateStmt (Truncate r a)
| CreateTableStmt (CreateTable d r a)
| AlterTableStmt (AlterTable r a)
| DropTableStmt (DropTable r a)
| CreateViewStmt (CreateView r a)
| DropViewStmt (DropView r a)
| CreateSchemaStmt (CreateSchema r a)
| GrantStmt (Grant a)
| RevokeStmt (Revoke a)
| BeginStmt a
| CommitStmt a
| RollbackStmt a
| ExplainStmt a (Statement d r a)
| EmptyStmt a
deriving instance (ConstrainSAll Data d r a, Data d, Data r) => Data (Statement d r a)
deriving instance Generic (Statement d r a)
deriving instance ConstrainSAll Eq d r a => Eq (Statement d r a)
deriving instance ConstrainSAll Show d r a => Show (Statement d r a)
deriving instance ConstrainSASAll Functor d r => Functor (Statement d r)
deriving instance ConstrainSASAll Foldable d r => Foldable (Statement d r)
deriving instance ConstrainSASAll Traversable d r => Traversable (Statement d r)
data Insert r a = Insert
{ insertInfo :: a
, insertBehavior :: InsertBehavior a
, insertTable :: TableName r a
, insertColumns :: Maybe (NonEmpty (ColumnRef r a))
, insertValues :: InsertValues r a
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (Insert r a)
deriving instance Generic (Insert r a)
deriving instance ConstrainSNames Eq r a => Eq (Insert r a)
deriving instance ConstrainSNames Show r a => Show (Insert r a)
deriving instance ConstrainSASNames Functor r => Functor (Insert r)
deriving instance ConstrainSASNames Foldable r => Foldable (Insert r)
deriving instance ConstrainSASNames Traversable r => Traversable (Insert r)
type TablePartition = ()
data InsertBehavior a
= InsertOverwrite a
| InsertAppend a
| InsertOverwritePartition a TablePartition
| InsertAppendPartition a TablePartition
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data InsertValues r a
= InsertExprValues a (NonEmpty (NonEmpty (DefaultExpr r a)))
| InsertSelectValues (Query r a)
| InsertDefaultValues a
| InsertDataFromFile a ByteString
deriving instance (ConstrainSNames Data r a, Data r) => Data (InsertValues r a)
deriving instance Generic (InsertValues r a)
deriving instance ConstrainSNames Eq r a => Eq (InsertValues r a)
deriving instance ConstrainSNames Show r a => Show (InsertValues r a)
deriving instance ConstrainSASNames Functor r => Functor (InsertValues r)
deriving instance ConstrainSASNames Foldable r => Foldable (InsertValues r)
deriving instance ConstrainSASNames Traversable r => Traversable (InsertValues r)
data DefaultExpr r a
= DefaultValue a
| ExprValue (Expr r a)
deriving instance (ConstrainSNames Data r a, Data r) => Data (DefaultExpr r a)
deriving instance Generic (DefaultExpr r a)
deriving instance ConstrainSNames Eq r a => Eq (DefaultExpr r a)
deriving instance ConstrainSNames Show r a => Show (DefaultExpr r a)
deriving instance ConstrainSASNames Functor r => Functor (DefaultExpr r)
deriving instance ConstrainSASNames Foldable r => Foldable (DefaultExpr r)
deriving instance ConstrainSASNames Traversable r => Traversable (DefaultExpr r)
data Update r a = Update
{ updateInfo :: a
, updateTable :: TableName r a
, updateAlias :: Maybe (TableAlias a)
, updateSetExprs :: NonEmpty (ColumnRef r a, DefaultExpr r a)
, updateFrom :: Maybe (Tablish r a)
, updateWhere :: Maybe (Expr r a)
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (Update r a)
deriving instance Generic (Update r a)
deriving instance ConstrainSNames Eq r a => Eq (Update r a)
deriving instance ConstrainSNames Show r a => Show (Update r a)
deriving instance ConstrainSASNames Functor r => Functor (Update r)
deriving instance ConstrainSASNames Foldable r => Foldable (Update r)
deriving instance ConstrainSASNames Traversable r => Traversable (Update r)
data Delete r a
= Delete a (TableName r a) (Maybe (Expr r a))
deriving instance (ConstrainSNames Data r a, Data r) => Data (Delete r a)
deriving instance Generic (Delete r a)
deriving instance ConstrainSNames Eq r a => Eq (Delete r a)
deriving instance ConstrainSNames Show r a => Show (Delete r a)
deriving instance ConstrainSASNames Functor r => Functor (Delete r)
deriving instance ConstrainSASNames Foldable r => Foldable (Delete r)
deriving instance ConstrainSASNames Traversable r => Traversable (Delete r)
data Truncate r a
= Truncate a (TableName r a)
deriving instance (ConstrainSNames Data r a, Data r) => Data (Truncate r a)
deriving instance Generic (Truncate r a)
deriving instance ConstrainSNames Eq r a => Eq (Truncate r a)
deriving instance ConstrainSNames Show r a => Show (Truncate r a)
deriving instance ConstrainSASNames Functor r => Functor (Truncate r)
deriving instance ConstrainSASNames Foldable r => Foldable (Truncate r)
deriving instance ConstrainSASNames Traversable r => Traversable (Truncate r)
data CreateTable d r a = CreateTable
{ createTableInfo :: a
, createTablePersistence :: Persistence a
, createTableExternality :: Externality a
, createTableIfNotExists :: Maybe a
, createTableName :: CreateTableName r a
, createTableDefinition :: TableDefinition d r a
, createTableExtra :: Maybe (DialectCreateTableExtra d r a)
}
deriving instance (ConstrainSAll Data d r a, Data d, Data r) => Data (CreateTable d r a)
deriving instance Generic (CreateTable d r a)
deriving instance ConstrainSAll Eq d r a => Eq (CreateTable d r a)
deriving instance ConstrainSAll Show d r a => Show (CreateTable d r a)
deriving instance ConstrainSASAll Functor d r => Functor (CreateTable d r)
deriving instance ConstrainSASAll Foldable d r => Foldable (CreateTable d r)
deriving instance ConstrainSASAll Traversable d r => Traversable (CreateTable d r)
data AlterTable r a
= AlterTableRenameTable a (TableName r a) (TableName r a)
| AlterTableRenameColumn a (TableName r a) (UQColumnName a) (UQColumnName a)
| AlterTableAddColumns a (TableName r a) (NonEmpty (UQColumnName a))
deriving instance (ConstrainSNames Data r a, Data r) => Data (AlterTable r a)
deriving instance Generic (AlterTable r a)
deriving instance ConstrainSNames Eq r a => Eq (AlterTable r a)
deriving instance ConstrainSNames Show r a => Show (AlterTable r a)
deriving instance ConstrainSASNames Functor r => Functor (AlterTable r)
deriving instance ConstrainSASNames Foldable r => Foldable (AlterTable r)
deriving instance ConstrainSASNames Traversable r => Traversable (AlterTable r)
data DropTable r a = DropTable
{ dropTableInfo :: a
, dropTableIfExists :: Maybe a
, dropTableNames :: NonEmpty (DropTableName r a)
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (DropTable r a)
deriving instance Generic (DropTable r a)
deriving instance ConstrainSNames Eq r a => Eq (DropTable r a)
deriving instance ConstrainSNames Show r a => Show (DropTable r a)
deriving instance ConstrainSASNames Functor r => Functor (DropTable r)
deriving instance ConstrainSASNames Foldable r => Foldable (DropTable r)
deriving instance ConstrainSASNames Traversable r => Traversable (DropTable r)
data CreateView r a = CreateView
{ createViewInfo :: a
, createViewPersistence :: Persistence a
, createViewIfNotExists :: Maybe a
, createViewColumns :: Maybe (NonEmpty (UQColumnName a))
, createViewName :: CreateTableName r a
, createViewQuery :: Query r a
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (CreateView r a)
deriving instance Generic (CreateView r a)
deriving instance ConstrainSNames Eq r a => Eq (CreateView r a)
deriving instance ConstrainSNames Show r a => Show (CreateView r a)
deriving instance ConstrainSASNames Functor r => Functor (CreateView r)
deriving instance ConstrainSASNames Foldable r => Foldable (CreateView r)
deriving instance ConstrainSASNames Traversable r => Traversable (CreateView r)
data DropView r a = DropView
{ dropViewInfo :: a
, dropViewIfExists :: Maybe a
, dropViewName :: DropTableName r a
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (DropView r a)
deriving instance Generic (DropView r a)
deriving instance ConstrainSNames Eq r a => Eq (DropView r a)
deriving instance ConstrainSNames Show r a => Show (DropView r a)
deriving instance ConstrainSASNames Functor r => Functor (DropView r)
deriving instance ConstrainSASNames Foldable r => Foldable (DropView r)
deriving instance ConstrainSASNames Traversable r => Traversable (DropView r)
data CreateSchema r a = CreateSchema
{ createSchemaInfo :: a
, createSchemaIfNotExists :: Maybe a
, createSchemaName :: CreateSchemaName r a
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (CreateSchema r a)
deriving instance Generic (CreateSchema r a)
deriving instance ConstrainSNames Eq r a => Eq (CreateSchema r a)
deriving instance ConstrainSNames Show r a => Show (CreateSchema r a)
deriving instance ConstrainSASNames Functor r => Functor (CreateSchema r)
deriving instance ConstrainSASNames Foldable r => Foldable (CreateSchema r)
deriving instance ConstrainSASNames Traversable r => Traversable (CreateSchema r)
data Grant a = Grant a
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data Revoke a = Revoke a
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data TableDefinition d r a
= TableColumns a (NonEmpty (ColumnOrConstraint d r a))
| TableLike a (TableName r a)
| TableAs a (Maybe (NonEmpty (UQColumnName a))) (Query r a)
| TableNoColumnInfo a
deriving instance (ConstrainSAll Data d r a, Data d, Data r) => Data (TableDefinition d r a)
deriving instance Generic (TableDefinition d r a)
deriving instance ConstrainSAll Eq d r a => Eq (TableDefinition d r a)
deriving instance ConstrainSAll Show d r a => Show (TableDefinition d r a)
deriving instance ConstrainSASAll Functor d r => Functor (TableDefinition d r)
deriving instance ConstrainSASAll Foldable d r => Foldable (TableDefinition d r)
deriving instance ConstrainSASAll Traversable d r => Traversable (TableDefinition d r)
data ColumnOrConstraint d r a
= ColumnOrConstraintColumn (ColumnDefinition d r a)
| ColumnOrConstraintConstraint (ConstraintDefinition a)
deriving instance (ConstrainSAll Data d r a, Data d, Data r) => Data (ColumnOrConstraint d r a)
deriving instance Generic (ColumnOrConstraint d r a)
deriving instance ConstrainSAll Eq d r a => Eq (ColumnOrConstraint d r a)
deriving instance ConstrainSAll Show d r a => Show (ColumnOrConstraint d r a)
deriving instance ConstrainSASAll Functor d r => Functor (ColumnOrConstraint d r)
deriving instance ConstrainSASAll Foldable d r => Foldable (ColumnOrConstraint d r)
deriving instance ConstrainSASAll Traversable d r => Traversable (ColumnOrConstraint d r)
data ColumnDefinition d r a = ColumnDefinition
{ columnDefinitionInfo :: a
, columnDefinitionName :: UQColumnName a
, columnDefinitionType :: DataType a
, columnDefinitionNull :: Maybe (NullConstraint a)
, columnDefinitionDefault :: Maybe (Expr r a)
, columnDefinitionExtra :: Maybe (DialectColumnDefinitionExtra d a)
}
deriving instance (ConstrainSAll Data d r a, Data d, Data r) => Data (ColumnDefinition d r a)
deriving instance Generic (ColumnDefinition d r a)
deriving instance ConstrainSAll Eq d r a => Eq (ColumnDefinition d r a)
deriving instance ConstrainSAll Show d r a => Show (ColumnDefinition d r a)
deriving instance ConstrainSASAll Functor d r => Functor (ColumnDefinition d r)
deriving instance ConstrainSASAll Foldable d r => Foldable (ColumnDefinition d r)
deriving instance ConstrainSASAll Traversable d r => Traversable (ColumnDefinition d r)
data NullConstraint a
= Nullable a
| NotNull a
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data ConstraintDefinition a = ConstraintDefinition
{ constraintDefinitionInfo :: a
} deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
instance ConstrainSAll ToJSON d r a => ToJSON (Statement d r a) where
toJSON (QueryStmt query) = JSON.object
[ "tag" .= JSON.String "QueryStmt"
, "query" .= query
]
toJSON (InsertStmt insert) = JSON.object
[ "tag" .= JSON.String "InsertStmt"
, "insert" .= insert
]
toJSON (UpdateStmt update) = JSON.object
[ "tag" .= JSON.String "UpdateStmt"
, "update" .= update
]
toJSON (DeleteStmt delete) = JSON.object
[ "tag" .= JSON.String "DeleteStmt"
, "delete" .= delete
]
toJSON (TruncateStmt truncate') = JSON.object
[ "tag" .= JSON.String "TruncateStmt"
, "truncate" .= truncate'
]
toJSON (CreateTableStmt create) = JSON.object
[ "tag" .= JSON.String "CreateTableStmt"
, "create" .= create
]
toJSON (AlterTableStmt alter) = JSON.object
[ "tag" .= JSON.String "AlterTableStmt"
, "alter" .= alter
]
toJSON (DropTableStmt drop') = JSON.object
[ "tag" .= JSON.String "DropTableStmt"
, "drop" .= drop'
]
toJSON (CreateViewStmt create) = JSON.object
[ "tag" .= JSON.String "CreateViewStmt"
, "create" .= create
]
toJSON (DropViewStmt drop') = JSON.object
[ "tag" .= JSON.String "DropViewStmt"
, "drop" .= drop'
]
toJSON (CreateSchemaStmt create) = JSON.object
[ "tag" .= JSON.String "CreateSchemaStmt"
, "create" .= create
]
toJSON (GrantStmt grant) = JSON.object
[ "tag" .= JSON.String "GrantStmt"
, "grant" .= grant
]
toJSON (RevokeStmt revoke) = JSON.object
[ "tag" .= JSON.String "RevokeStmt"
, "revoke" .= revoke
]
toJSON (BeginStmt begin) = JSON.object
[ "tag" .= JSON.String "BeginStmt"
, "begin" .= begin
]
toJSON (CommitStmt info) = JSON.object
[ "tag" .= JSON.String "CommitStmt"
, "info" .= info
]
toJSON (RollbackStmt info) = JSON.object
[ "tag" .= JSON.String "RollbackStmt"
, "info" .= info
]
toJSON (ExplainStmt info stmt) = JSON.object
[ "tag" .= JSON.String "ExplainStmt"
, "info" .= info
, "stmt" .= stmt
]
toJSON (EmptyStmt info) = JSON.object
[ "tag" .= JSON.String "EmptyStmt"
, "info" .= info
]
instance ConstrainSAll ToJSON d r a => ToJSON (CreateTable d r a) where
toJSON CreateTable{..} = JSON.object
[ "tag" .= JSON.String "CreateTable"
, "info" .= createTableInfo
, "persistence" .= createTablePersistence
, "ifnotexists" .= case createTableIfNotExists of
Just info -> JSON.object ["info" .= info, "value" .= True]
Nothing -> JSON.Null
, "table" .= createTableName
, "definition" .= createTableDefinition
, "extra" .= createTableExtra
]
instance ( ToJSON a
, ToJSON (TableName r a)
) => ToJSON (AlterTable r a) where
toJSON (AlterTableRenameTable info from to) = JSON.object
[ "tag" .= JSON.String "AlterTableRenameTable"
, "info" .= info
, "from" .= from
, "to" .= to
]
toJSON (AlterTableRenameColumn info table from to) = JSON.object
[ "tag" .= JSON.String "AlterTableRenameColumn"
, "info" .= info
, "table" .= table
, "from" .= from
, "to" .= to
]
toJSON (AlterTableAddColumns info table (c:|cs)) = JSON.object
[ "tag" .= JSON.String "AlterTableAddColumns"
, "info" .= info
, "table" .= table
, "columns" .= (c:cs)
]
instance (ToJSON a, ToJSON (DropTableName r a)) => ToJSON (DropTable r a) where
toJSON DropTable{..} = JSON.object
[ "tag" .= JSON.String "DropTable"
, "info" .= dropTableInfo
, "ifexists" .= case dropTableIfExists of
Just info -> JSON.object ["info" .= info, "value" .= True]
Nothing -> JSON.Null
, "tables" .= NE.toList dropTableNames
]
instance ConstrainSNames ToJSON r a => ToJSON (CreateView r a) where
toJSON CreateView{..} = JSON.object
[ "tag" .= JSON.String "CreateView"
, "info" .= createViewInfo
, "persistence" .= createViewPersistence
, "ifnotexists" .= case createViewIfNotExists of
Just info -> JSON.object ["info" .= info, "value" .= True]
Nothing -> JSON.Null
, "columns" .= case createViewColumns of
Just (c:|cs) -> toJSON (c:cs)
Nothing -> JSON.Null
, "table" .= createViewName
, "query" .= createViewQuery
]
instance ConstrainSNames ToJSON r a => ToJSON (DropView r a) where
toJSON DropView{..} = JSON.object
[ "tag" .= JSON.String "DropView"
, "info" .= dropViewInfo
, "ifexists" .= case dropViewIfExists of
Just info -> JSON.object ["info" .= info, "value" .= True]
Nothing -> JSON.Null
, "table" .= dropViewName
]
instance (ToJSON a, ToJSON (CreateSchemaName r a)) => ToJSON (CreateSchema r a) where
toJSON (CreateSchema {..}) = JSON.object
[ "tag" .= JSON.String "CreateSchema"
, "info" .= createSchemaInfo
, "ifnotexists" .= case createSchemaIfNotExists of
Just info -> JSON.object ["info" .= info, "value" .= True]
Nothing -> JSON.Null
, "schema" .= createSchemaName
]
instance ToJSON a => ToJSON (Grant a) where
toJSON (Grant a) = JSON.object
[ "tag" .= JSON.String "Grant"
, "info" .= a
]
instance ToJSON a => ToJSON (Revoke a) where
toJSON (Revoke a) = JSON.object
[ "tag" .= JSON.String "Revoke"
, "info" .= a
]
instance ConstrainSAll ToJSON d r a => ToJSON (TableDefinition d r a) where
toJSON (TableColumns info (c:|cs)) = JSON.object
[ "tag" .= JSON.String "TableColumns"
, "info" .= info
, "columns" .= (c:cs)
]
toJSON (TableLike info table) = JSON.object
[ "tag" .= JSON.String "TableLike"
, "info" .= info
, "table" .= table
]
toJSON (TableAs info columns query) = JSON.object
[ "tag" .= JSON.String "TableAs"
, "info" .= info
, "columns" .= case columns of
Just (c:|cs) -> toJSON (c:cs)
Nothing -> JSON.Null
, "query" .= query
]
toJSON (TableNoColumnInfo info) = JSON.object
[ "tag" .= JSON.String "TableNoColumnInfo"
, "info" .= info
]
instance ConstrainSAll ToJSON d r a => ToJSON (ColumnOrConstraint d r a) where
toJSON (ColumnOrConstraintColumn column) = toJSON column
toJSON (ColumnOrConstraintConstraint constraint) = toJSON constraint
instance ConstrainSAll ToJSON d r a => ToJSON (ColumnDefinition d r a) where
toJSON (ColumnDefinition{..}) = JSON.object
[ "tag" .= JSON.String "ColumnDefinition"
, "info" .= columnDefinitionInfo
, "name" .= columnDefinitionName
, "type" .= columnDefinitionType
, "nullable" .= columnDefinitionNull
, "default" .= columnDefinitionDefault
, "extra" .= columnDefinitionExtra
]
instance ToJSON a => ToJSON (NullConstraint a) where
toJSON (Nullable info) = JSON.object
[ "tag" .= JSON.String "Nullable"
, "info" .= info
]
toJSON (NotNull info) = JSON.object
[ "tag" .= JSON.String "NotNull"
, "info" .= info
]
instance ToJSON a => ToJSON (ConstraintDefinition a) where
toJSON (ConstraintDefinition{..}) = JSON.object
[ "tag" .= JSON.String "ConstraintDefinition"
, "info" .= constraintDefinitionInfo
]
instance ConstrainSNames ToJSON r a => ToJSON (Insert r a) where
toJSON Insert{..} = JSON.object
[ "tag" .= JSON.String "Insert"
, "info" .= insertInfo
, "table" .= insertTable
, "values" .= insertValues
, "behavior" .= insertBehavior
]
instance ToJSON a => ToJSON (InsertBehavior a) where
toJSON (InsertOverwrite info) = JSON.object
[ "tag" .= JSON.String "Overwrite"
, "info" .= info
]
toJSON (InsertAppend info) = JSON.object
[ "tag" .= JSON.String "Append"
, "info" .= info
]
toJSON (InsertOverwritePartition info partition) = JSON.object
[ "tag" .= JSON.String "OverwritePartition"
, "info" .= info
, "partition" .= partition
]
toJSON (InsertAppendPartition info partition) = JSON.object
[ "tag" .= JSON.String "AppendPartition"
, "info" .= info
, "partition" .= partition
]
instance ConstrainSNames ToJSON r a => ToJSON (InsertValues r a) where
toJSON (InsertExprValues info values) = JSON.object
[ "tag" .= JSON.String "InsertExprValues"
, "info" .= info
, "values" .= (map toList $ toList values)
]
toJSON (InsertSelectValues query) = JSON.object
[ "tag" .= JSON.String "InsertSelectValues"
, "query" .= query
]
toJSON (InsertDefaultValues info) = JSON.object
[ "tag" .= JSON.String "InsertDefaultValues"
, "info" .= info
]
toJSON (InsertDataFromFile info path) = JSON.object
[ "tag" .= JSON.String "InsertDataFromFile"
, "info" .= info
, case TL.decodeUtf8' path of
Left _ -> "path" .= BL.unpack path
Right str -> "path" .= str
]
instance ConstrainSNames ToJSON r a => ToJSON (DefaultExpr r a) where
toJSON (DefaultValue info) = JSON.object
[ "tag" .= JSON.String "DefaultValue"
, "info" .= info
]
toJSON (ExprValue expr) = JSON.object
[ "tag" .= JSON.String "ExprValue"
, "expr" .= expr
]
instance ConstrainSNames ToJSON r a => ToJSON (Update r a) where
toJSON Update{..} = JSON.object
[ "tag" .= JSON.String "Update"
, "info" .= updateInfo
, "table" .= updateTable
, "alias" .= updateAlias
, "set_exprs" .= toList updateSetExprs
, "from" .= updateFrom
, "where" .= updateWhere
]
instance ConstrainSNames ToJSON r a => ToJSON (Delete r a) where
toJSON (Delete info table expr) = JSON.object
[ "tag" .= JSON.String "Delete"
, "info" .= info
, "table" .= table
, "expr" .= expr
]
instance ConstrainSNames ToJSON r a => ToJSON (Truncate r a) where
toJSON (Truncate info table) = JSON.object
[ "tag" .= JSON.String "Truncate"
, "info" .= info
, "table" .= table
]
instance ConstrainSAll FromJSON d r a => FromJSON (Statement d r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "QueryStmt" -> QueryStmt <$> o .: "query"
JSON.String "InsertStmt" -> InsertStmt <$> o .: "insert"
JSON.String "UpdateStmt" -> UpdateStmt <$> o .: "update"
JSON.String "DeleteStmt" -> DeleteStmt <$> o .: "delete"
JSON.String "TruncateStmt" -> TruncateStmt <$> o .: "truncate"
JSON.String "CreateTableStmt" -> CreateTableStmt <$> o .: "create"
JSON.String "AlterTableStmt" -> AlterTableStmt <$> o .: "alter"
JSON.String "DropTableStmt" -> DropTableStmt <$> o .: "drop"
JSON.String "CreateSchemaStmt" -> CreateSchemaStmt <$> o .: "create"
JSON.String "GrantStmt" -> GrantStmt <$> o .: "grant"
JSON.String "RevokeStmt" -> RevokeStmt <$> o .: "revoke"
JSON.String "BeginStmt" -> BeginStmt <$> o .: "begin"
JSON.String "CommitStmt" -> CommitStmt <$> o .: "info"
JSON.String "RollbackStmt" -> RollbackStmt <$> o .: "info"
JSON.String "ExplainStmt" -> ExplainStmt <$> o .: "info" <*> o .: "stmt"
JSON.String "EmptyStmt" -> EmptyStmt <$> o .: "info"
_ -> fail "unrecognized tag on statement object"
parseJSON v = fail $ unwords
[ "don't know how to parse as Statement:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (Insert r a) where
parseJSON (JSON.Object o) = do
JSON.String "Insert" <- o .: "tag"
insertInfo <- o .: "info"
insertTable <- o .: "table"
columns <- o .:? "columns"
let insertColumns = nonEmpty =<< columns
insertValues <- o .: "values"
insertBehavior <- o .: "behavior"
pure Insert{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as Insert:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (Update r a) where
parseJSON (JSON.Object o) = do
JSON.String "Update" <- o .: "tag"
updateInfo <- o .: "info"
updateTable <- o .: "table"
updateAlias <- o .:? "alias"
updateSetExprs <- NE.fromList <$> o .: "set_exprs"
updateFrom <- o .:? "from"
updateWhere <- o .:? "where"
pure Update{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as Update:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (Delete r a) where
parseJSON (JSON.Object o) = do
JSON.String "Delete" <- o .: "tag"
info <- o .: "info"
table <- o .: "table"
expr <- o .: "expr"
pure $ Delete info table expr
parseJSON v = fail $ unwords
[ "don't know how to parse as Delete:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (Truncate r a) where
parseJSON (JSON.Object o) = do
JSON.String "Truncate" <- o .: "tag"
info <- o .: "info"
table <- o .: "table"
pure $ Truncate info table
parseJSON v = fail $ unwords
[ "don't know how to parse as Truncate:"
, show v
]
instance ConstrainSAll FromJSON d r a => FromJSON (CreateTable d r a) where
parseJSON (JSON.Object o) = do
JSON.String "CreateTable" <- o .: "tag"
createTableInfo <- o .: "info"
createTablePersistence <- o .: "persistence"
createTableExternality <- o .: "externality"
createTableIfNotExists <- o .:? "ifnotexists" >>= \case
Just o' -> do
JSON.Bool True <- o' .: "value"
o' .: "info"
Nothing -> pure Nothing
createTableName <- o .: "table"
createTableDefinition <- o .: "definition"
createTableExtra <- o .: "extra"
pure CreateTable{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as CreateTable:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (AlterTable r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "AlterTableRenameTable" -> do
info <- o .: "info"
from <- o .: "from"
to <- o .: "to"
pure $ AlterTableRenameTable info from to
JSON.String "AlterTableRenameColumn" -> do
info <- o .: "info"
table <- o .: "table"
from <- o .: "from"
to <- o .: "to"
pure $ AlterTableRenameColumn info table from to
JSON.String "AlterTableAddColumns" -> do
info <- o .: "info"
table <- o .: "table"
columns <- o .: "columns" >>= \case
[] -> fail "expected at least one column in column list for AlterTableAddColumns"
(c:cs) -> pure (c:|cs)
pure $ AlterTableAddColumns info table columns
_ -> fail "unrecognized tag on AlterTable object"
parseJSON v = fail $ unwords
[ "don't know how to parse as AlterTable:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (DropTable r a) where
parseJSON (JSON.Object o) = do
JSON.String "DropTable" <- o .: "tag"
dropTableInfo <- o .: "info"
dropTableIfExists <- o .:? "ifexists" >>= \case
Just o' -> do
JSON.Bool True <- o' .: "value"
o' .: "info"
Nothing -> pure Nothing
dropTableNames <- NE.fromList <$> o .: "tables"
pure $ DropTable{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as DropTable:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (CreateView r a) where
parseJSON (JSON.Object o) = do
JSON.String "CreateView" <- o .: "tag"
createViewInfo <- o .: "info"
createViewPersistence <- o .: "persistence"
createViewIfNotExists <- o .:? "ifnotexists" >>= \case
Just o' -> do
JSON.Bool True <- o' .: "value"
o' .: "info"
Nothing -> pure Nothing
createViewColumns <- o .:? "columns" >>= \case
Just [] -> fail "expected at least one column in column list for CreateView (or no column list)"
Just (c:cs) -> pure $ Just (c:|cs)
Nothing -> pure Nothing
createViewName <- o .: "table"
createViewQuery <- o .: "query"
pure $ CreateView{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as CreateView:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (DropView r a) where
parseJSON (JSON.Object o) = do
JSON.String "DropView" <- o .: "tag"
dropViewInfo <- o .: "info"
dropViewIfExists <- o .:? "ifexists" >>= \case
Just o' -> do
JSON.Bool True <- o' .: "value"
o' .: "info"
Nothing -> pure Nothing
dropViewName <- o .: "table"
pure $ DropView{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as DropView:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (CreateSchema r a) where
parseJSON (JSON.Object o) = do
JSON.String "CreateSchema" <- o .: "tag"
createSchemaInfo <- o .: "info"
createSchemaIfNotExists <- o .:? "ifnotexists" >>= \case
Just o' -> do
JSON.Bool True <- o' .: "value"
o' .: "info"
Nothing -> pure Nothing
createSchemaName <- o .: "schema"
pure $ CreateSchema{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as CreateSchema:"
, show v
]
instance FromJSON a => FromJSON (Grant a) where
parseJSON (JSON.Object o) = do
JSON.String "Grant" <- o .: "tag"
info <- o .: "info"
pure $ Grant info
parseJSON v = fail $ unwords
[ "don't know how to parse as Grant:"
, show v
]
instance FromJSON a => FromJSON (Revoke a) where
parseJSON (JSON.Object o) = do
JSON.String "Revoke" <- o .: "tag"
info <- o .: "info"
pure $ Revoke info
parseJSON v = fail $ unwords
[ "don't know how to parse as Revoke:"
, show v
]
instance FromJSON a => FromJSON (InsertBehavior a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "Append" -> do
info <- o .: "info"
pure $ InsertAppend info
JSON.String "Overwrite" -> do
info <- o .: "info"
pure $ InsertOverwrite info
JSON.String "AppendPartition" -> do
info <- o .: "info"
partition <- o .: "partition"
pure $ InsertAppendPartition info partition
JSON.String "OverwritePartition" -> do
info <- o .: "info"
partition <- o .: "partition"
pure $ InsertOverwritePartition info partition
_ -> fail "unrecognized tag on InsertBehavior object"
parseJSON v = fail $ unwords
[ "don't know how to parse as InsertBehavior:"
, show v
]
instance ConstrainSAll FromJSON d r a => FromJSON (TableDefinition d r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "TableColumns" -> do
info <- o .: "info"
o .: "columns" >>= \case
[] -> fail "expected at least one column in TableColumns object"
(c:cs) -> pure $ TableColumns info (c:|cs)
JSON.String "TableLike" -> do
info <- o .: "info"
table <- o .: "table"
pure $ TableLike info table
JSON.String "TableAs" -> do
info <- o .: "info"
columns <- o .: "columns" >>= \case
Just [] -> fail "expected at least one column in column list for TableAs (or no column list)"
Just (c:cs) -> pure $ Just (c:|cs)
Nothing -> pure Nothing
query <- o .: "query"
pure $ TableAs info columns query
JSON.String "TableNoColumnInfo" -> do
info <- o .: "info"
pure $ TableNoColumnInfo info
_ -> fail "unrecognized tag on table definition object"
parseJSON v = fail $ unwords
[ "don't know how to parse as TableDefinition:"
, show v
]
instance ConstrainSAll FromJSON d r a => FromJSON (ColumnOrConstraint d r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "ColumnDefinition" -> ColumnOrConstraintColumn <$> parseJSON (JSON.Object o)
JSON.String "ConstraintDefinition" -> ColumnOrConstraintConstraint <$> parseJSON (JSON.Object o)
_ -> fail "unrecognized tag on column or constraint object"
parseJSON v = fail $ unwords
[ "don't know how to parse as ColumnOrConstraint:"
, show v
]
instance ConstrainSAll FromJSON d r a => FromJSON (ColumnDefinition d r a) where
parseJSON (JSON.Object o) = do
JSON.String "ColumnDefinition" <- o .: "tag"
columnDefinitionInfo <- o .: "info"
columnDefinitionName <- o .: "name"
columnDefinitionType <- o .: "type"
columnDefinitionNull <- o .: "nullable"
columnDefinitionDefault <- o .: "default"
columnDefinitionExtra <- o .: "extra"
pure ColumnDefinition{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as ColumnDefinition:"
, show v
]
instance FromJSON a => FromJSON (NullConstraint a) where
parseJSON (JSON.Object o) = do
info <- o .: "info"
o .: "tag" >>= \case
JSON.String "Nullable" -> pure $ Nullable info
JSON.String "NotNull" -> pure $ NotNull info
_ -> fail "unrecognized tag on null constraint object"
parseJSON v = fail $ unwords
[ "don't know how to parse as NullConstraint:"
, show v
]
instance FromJSON a => FromJSON (ConstraintDefinition a) where
parseJSON (JSON.Object o) = do
JSON.String "ConstraintDefinition" <- o .: "tag"
constraintDefinitionInfo <- o .: "info"
pure ConstraintDefinition{..}
parseJSON v = fail $ unwords
[ "don't know how to parse as ConstraintDefinition:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (InsertValues r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "InsertExprValues" -> do
info <- o .: "info"
values <- o .: "values"
let fromList xs = if null xs
then fail "empty list of values for row in insert statement"
else NE.fromList xs
rows = map fromList values
maybe (fail "empty list of rows for insert statement")
(pure . InsertExprValues info) $ nonEmpty rows
JSON.String "InsertSelectValues" -> InsertSelectValues <$> o .: "query"
JSON.String "InsertDefaultValues" -> InsertDefaultValues <$> o .: "info"
JSON.String "InsertDataFromFile" -> do
info <- o .: "info"
path <- TL.encodeUtf8 <$> o .: "path"
<|> BL.pack <$> o .: "path"
<|> fail "expected string or array for path"
pure $ InsertDataFromFile info path
_ -> fail "unrecognized tag on insert values object"
parseJSON v = fail $ unwords
[ "don't know how to parse as InsertValues:"
, show v
]
instance ConstrainSNames FromJSON r a => FromJSON (DefaultExpr r a) where
parseJSON (JSON.Object o) = o .: "tag" >>= \case
JSON.String "DefaultValue" -> DefaultValue <$> o .: "info"
JSON.String "ExprValue" -> ExprValue <$> o .: "expr"
_ -> fail "unrecognized tag on default expression object"
parseJSON v = fail $ unwords
[ "don't know how to parse as DefaultExpr:"
, show v
]
instance Arbitrary a => Arbitrary (InsertBehavior a) where
arbitrary = do
info <- arbitrary
elements [ InsertOverwrite info
, InsertAppend info
, InsertOverwritePartition info ()
, InsertAppendPartition info ()
]
shrink (InsertAppend _) = []
shrink (InsertOverwrite x) = [InsertAppend x]
shrink (InsertAppendPartition x _) = [InsertAppend x]
shrink (InsertOverwritePartition x t) =
[ InsertAppend x
, InsertOverwrite x
, InsertAppendPartition x t
]