module IHP.IDE.SchemaDesigner.Controller.Columns where
import IHP.ControllerPrelude
import IHP.IDE.ToolServer.Types
import IHP.IDE.SchemaDesigner.View.Columns.New
import IHP.IDE.SchemaDesigner.View.Columns.Edit
import IHP.IDE.SchemaDesigner.View.Columns.NewForeignKey
import IHP.IDE.SchemaDesigner.View.Columns.EditForeignKey
import IHP.IDE.SchemaDesigner.Types
import IHP.IDE.SchemaDesigner.View.Layout (schemaDesignerLayout, findStatementByName, replace)
import IHP.IDE.SchemaDesigner.Controller.Helper
import IHP.IDE.SchemaDesigner.Controller.Validation
import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations
instance Controller ColumnsController where
beforeAction :: (?context::ControllerContext, ?modelContext::ModelContext,
?theAction::ColumnsController) =>
IO ()
beforeAction = (?context::ControllerContext) =>
((?context::ControllerContext) => Layout) -> IO ()
((?context::ControllerContext) => Layout) -> IO ()
setLayout (?context::ControllerContext) => Layout
Layout
Html -> Html
schemaDesignerLayout
action :: (?context::ControllerContext, ?modelContext::ModelContext,
?theAction::ColumnsController) =>
ColumnsController -> IO ()
action NewColumnAction { Text
tableName :: Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
tableName } = do
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let (Just Statement
table) = Text -> [Statement] -> Maybe Statement
forall {t :: * -> *}.
Foldable t =>
Text -> t Statement -> Maybe Statement
findStatementByName Text
tableName [Statement]
statements
let tableNames :: [Text]
tableNames = [CreateTable] -> [Text]
forall {a} {b}. HasField "name" a b => [a] -> [b]
nameList ([Statement] -> [CreateTable]
getCreateTable [Statement]
statements)
let enumNames :: [Text]
enumNames = [Statement] -> [Text]
forall {a} {b}. HasField "name" a b => [a] -> [b]
nameList ([Statement] -> [Statement]
getCreateEnum [Statement]
statements)
NewColumnView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render NewColumnView { [Text]
[Statement]
Text
tableName :: Text
statements :: [Statement]
tableNames :: [Text]
enumNames :: [Text]
$sel:statements:NewColumnView :: [Statement]
$sel:tableName:NewColumnView :: Text
$sel:tableNames:NewColumnView :: [Text]
$sel:enumNames:NewColumnView :: [Text]
.. }
action ColumnsController
CreateColumnAction = do
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnName :: Text
columnName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"name"
let validationResult :: ValidatorResult
validationResult = Text
columnName Text -> (Text -> ValidatorResult) -> ValidatorResult
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> Text -> ValidatorResult
validateColumn
case ValidatorResult
validationResult of
Failure Text
message ->
(?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setErrorMessage Text
message
ValidatorResult
Success -> do
let options :: AddColumnOptions
options = SchemaOperations.AddColumnOptions
{ Text
tableName :: Text
$sel:tableName:AddColumnOptions :: Text
tableName
, Text
columnName :: Text
$sel:columnName:AddColumnOptions :: Text
columnName
, $sel:columnType:AddColumnOptions :: PostgresType
columnType = ByteString -> PostgresType
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnType"
, $sel:defaultValue:AddColumnOptions :: Maybe Expression
defaultValue = ByteString -> Maybe Expression
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"defaultValue"
, $sel:isArray:AddColumnOptions :: Bool
isArray = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"isArray"
, $sel:allowNull:AddColumnOptions :: Bool
allowNull = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"allowNull"
, $sel:isUnique:AddColumnOptions :: Bool
isUnique = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"isUnique"
, $sel:isReference:AddColumnOptions :: Bool
isReference = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"isReference"
, $sel:referenceTable:AddColumnOptions :: Maybe Text
referenceTable = ByteString -> Maybe Text
forall paramType.
(?context::ControllerContext, ParamReader (Maybe paramType)) =>
ByteString -> Maybe paramType
paramOrNothing ByteString
"referenceTable"
, $sel:primaryKey:AddColumnOptions :: Bool
primaryKey = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"primaryKey"
, $sel:withIndex:AddColumnOptions :: Bool
withIndex = Bool -> ByteString -> Bool
forall a.
(?context::ControllerContext, ParamReader a) =>
a -> ByteString -> a
paramOrDefault Bool
False ByteString
"withIndex"
, $sel:autoPolicy:AddColumnOptions :: Bool
autoPolicy = Bool -> ByteString -> Bool
forall a.
(?context::ControllerContext, ParamReader a) =>
a -> ByteString -> a
paramOrDefault Bool
False ByteString
"autoPolicy"
}
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (([Statement] -> [Statement]) -> IO ())
-> ([Statement] -> [Statement]) -> IO ()
forall a b. (a -> b) -> a -> b
$ AddColumnOptions -> [Statement] -> [Statement]
SchemaOperations.addColumn AddColumnOptions
options
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
tableName :: Text
$sel:tableName:TablesAction :: Text
.. }
action EditColumnAction { Int
Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
tableName :: Text
columnId :: Int
$sel:columnId:NewColumnAction :: ColumnsController -> Int
.. } = do
let columnId :: Int
columnId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnId"
let name :: Text
name = Text
tableName
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let (Just Statement
table) = Text -> [Statement] -> Maybe Statement
forall {t :: * -> *}.
Foldable t =>
Text -> t Statement -> Maybe Statement
findStatementByName Text
name [Statement]
statements
let table :: Maybe Statement
table = Text -> [Statement] -> Maybe Statement
forall {t :: * -> *}.
Foldable t =>
Text -> t Statement -> Maybe Statement
findStatementByName Text
tableName [Statement]
statements
let columns :: [Column]
columns = [Column] -> (Statement -> [Column]) -> Maybe Statement -> [Column]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ((.columns) (CreateTable -> [Column])
-> (Statement -> CreateTable) -> Statement -> [Column]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Statement -> CreateTable
unsafeGetCreateTable) Maybe Statement
table
let column :: Column
column = [Column]
columns [Column] -> Int -> Column
forall a. HasCallStack => [a] -> Int -> a
!! Int
columnId
let enumNames :: [Text]
enumNames = [Statement] -> [Text]
forall {a} {b}. HasField "name" a b => [a] -> [b]
nameList ([Statement] -> [Statement]
getCreateEnum [Statement]
statements)
EditColumnView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render EditColumnView { Int
[Text]
[Statement]
Text
Column
tableName :: Text
columnId :: Int
statements :: [Statement]
column :: Column
enumNames :: [Text]
$sel:statements:EditColumnView :: [Statement]
$sel:tableName:EditColumnView :: Text
$sel:columnId:EditColumnView :: Int
$sel:column:EditColumnView :: Column
$sel:enumNames:EditColumnView :: [Text]
.. }
action ColumnsController
UpdateColumnAction = do
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnName :: Text
columnName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"name"
let validationResult :: ValidatorResult
validationResult = Text
columnName Text -> (Text -> ValidatorResult) -> ValidatorResult
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> Text -> ValidatorResult
validateColumn
case ValidatorResult
validationResult of
Failure Text
message ->
(?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setErrorMessage Text
message
ValidatorResult
Success -> do
let options :: UpdateColumnOptions
options = SchemaOperations.UpdateColumnOptions
{ Text
tableName :: Text
$sel:tableName:UpdateColumnOptions :: Text
tableName
, Text
columnName :: Text
$sel:columnName:UpdateColumnOptions :: Text
columnName
, $sel:columnId:UpdateColumnOptions :: Int
columnId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnId"
, $sel:defaultValue:UpdateColumnOptions :: Maybe Expression
defaultValue = ByteString -> Maybe Expression
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"defaultValue"
, $sel:isArray:UpdateColumnOptions :: Bool
isArray = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"isArray"
, $sel:columnType:UpdateColumnOptions :: PostgresType
columnType = ByteString -> PostgresType
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnType"
, $sel:allowNull:UpdateColumnOptions :: Bool
allowNull = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"allowNull"
, $sel:isUnique:UpdateColumnOptions :: Bool
isUnique = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"isUnique"
, $sel:primaryKey:UpdateColumnOptions :: Bool
primaryKey = ByteString -> Bool
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"primaryKey"
}
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (([Statement] -> [Statement]) -> IO ())
-> ([Statement] -> [Statement]) -> IO ()
forall a b. (a -> b) -> a -> b
$ UpdateColumnOptions -> [Statement] -> [Statement]
SchemaOperations.updateColumn UpdateColumnOptions
options
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
action DeleteColumnAction { Int
Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
$sel:columnId:NewColumnAction :: ColumnsController -> Int
tableName :: Text
columnId :: Int
columnName :: Text
$sel:columnName:NewColumnAction :: ColumnsController -> Text
.. } = do
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnId :: Int
columnId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnId"
let columnName :: Text
columnName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnName"
let options :: DeleteColumnOptions
options = SchemaOperations.DeleteColumnOptions
{ Text
tableName :: Text
$sel:tableName:DeleteColumnOptions :: Text
tableName
, Text
columnName :: Text
$sel:columnName:DeleteColumnOptions :: Text
columnName
, Int
columnId :: Int
$sel:columnId:DeleteColumnOptions :: Int
columnId
}
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (([Statement] -> [Statement]) -> IO ())
-> ([Statement] -> [Statement]) -> IO ()
forall a b. (a -> b) -> a -> b
$ DeleteColumnOptions -> [Statement] -> [Statement]
SchemaOperations.deleteColumn DeleteColumnOptions
options
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
action ToggleColumnUniqueAction { Int
Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
$sel:columnId:NewColumnAction :: ColumnsController -> Int
tableName :: Text
columnId :: Int
.. } = do
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnId :: Int
columnId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnId"
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema ((Statement -> Statement) -> [Statement] -> [Statement]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> Int -> Statement -> Statement
toggleUniqueInColumn Text
tableName Int
columnId))
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
action NewForeignKeyAction { Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
tableName :: Text
tableName, Text
$sel:columnName:NewColumnAction :: ColumnsController -> Text
columnName :: Text
columnName } = do
let name :: Text
name = Text
tableName
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let tableNames :: [Text]
tableNames = [CreateTable] -> [Text]
forall {a} {b}. HasField "name" a b => [a] -> [b]
nameList ([Statement] -> [CreateTable]
getCreateTable [Statement]
statements)
NewForeignKeyView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render NewForeignKeyView { [Text]
[Statement]
Text
tableName :: Text
columnName :: Text
statements :: [Statement]
tableNames :: [Text]
$sel:statements:NewForeignKeyView :: [Statement]
$sel:tableName:NewForeignKeyView :: Text
$sel:columnName:NewForeignKeyView :: Text
$sel:tableNames:NewForeignKeyView :: [Text]
.. }
action ColumnsController
CreateForeignKeyAction = do
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnName :: Text
columnName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnName"
let constraintName :: Text
constraintName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"constraintName"
let referenceTable :: Text
referenceTable = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"referenceTable"
let onDelete :: OnDelete
onDelete = OnDelete
NoAction
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (Text
-> Text -> Text -> Text -> OnDelete -> [Statement] -> [Statement]
SchemaOperations.addForeignKeyConstraint Text
tableName Text
columnName Text
constraintName Text
referenceTable OnDelete
onDelete)
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
action EditForeignKeyAction { Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
tableName :: Text
tableName, Text
$sel:columnName:NewColumnAction :: ColumnsController -> Text
columnName :: Text
columnName, Text
constraintName :: Text
$sel:constraintName:NewColumnAction :: ColumnsController -> Text
constraintName, Text
referenceTable :: Text
$sel:referenceTable:NewColumnAction :: ColumnsController -> Text
referenceTable } = do
let name :: Text
name = Text
tableName
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let tableNames :: [Text]
tableNames = [CreateTable] -> [Text]
forall {a} {b}. HasField "name" a b => [a] -> [b]
nameList ([Statement] -> [CreateTable]
getCreateTable [Statement]
statements)
let (Just Statement
statement) = (Statement -> Bool) -> [Statement] -> Maybe Statement
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\Statement
statement -> Statement
statement Statement -> Statement -> Bool
forall a. Eq a => a -> a -> Bool
== AddConstraint { $sel:tableName:StatementCreateTable :: Text
tableName = Text
tableName, $sel:deferrable:StatementCreateTable :: Maybe Bool
deferrable = Maybe Bool
forall a. Maybe a
Nothing, $sel:deferrableType:StatementCreateTable :: Maybe DeferrableType
deferrableType = Maybe DeferrableType
forall a. Maybe a
Nothing, $sel:constraint:StatementCreateTable :: Constraint
constraint = ForeignKeyConstraint { $sel:name:ForeignKeyConstraint :: Maybe Text
name = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
constraintName, $sel:columnName:ForeignKeyConstraint :: Text
columnName = Text
columnName, $sel:referenceTable:ForeignKeyConstraint :: Text
referenceTable = Text
referenceTable, $sel:referenceColumn:ForeignKeyConstraint :: Maybe Text
referenceColumn = Maybe Text
"id", $sel:onDelete:ForeignKeyConstraint :: Maybe OnDelete
onDelete = Statement
statement.constraint.onDelete }}) [Statement]
statements
Text
onDelete <- case Statement
statement.constraint.onDelete of
Just OnDelete
NoAction -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"NoAction"
Just OnDelete
Restrict -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"Restrict"
Just OnDelete
SetNull -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"SetNull"
Just OnDelete
SetDefault -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"SetDefault"
Just OnDelete
Cascade -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"Cascade"
Maybe OnDelete
Nothing -> do Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"NoAction"
EditForeignKeyView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render EditForeignKeyView { [Text]
[Statement]
Text
tableName :: Text
columnName :: Text
constraintName :: Text
referenceTable :: Text
statements :: [Statement]
tableNames :: [Text]
onDelete :: Text
$sel:statements:EditForeignKeyView :: [Statement]
$sel:tableName:EditForeignKeyView :: Text
$sel:columnName:EditForeignKeyView :: Text
$sel:tableNames:EditForeignKeyView :: [Text]
$sel:referenceTable:EditForeignKeyView :: Text
$sel:constraintName:EditForeignKeyView :: Text
$sel:onDelete:EditForeignKeyView :: Text
.. }
action ColumnsController
UpdateForeignKeyAction = do
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
let tableName :: Text
tableName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableName"
let columnName :: Text
columnName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"columnName"
let constraintName :: Text
constraintName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"constraintName"
let referenceTable :: Text
referenceTable = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"referenceTable"
let constraintId :: Maybe Int
constraintId = [Statement]
statements
[Statement] -> ([Statement] -> Maybe Int) -> Maybe Int
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> (Statement -> Bool) -> [Statement] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex \case
AddConstraint { $sel:tableName:StatementCreateTable :: Statement -> Text
tableName = Text
fkTable, $sel:constraint:StatementCreateTable :: Statement -> Constraint
constraint = ForeignKeyConstraint { $sel:columnName:ForeignKeyConstraint :: Constraint -> Text
columnName = Text
fkColumnName } } -> Text
tableName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fkTable Bool -> Bool -> Bool
&& Text
columnName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fkColumnName
Statement
otherwise -> Bool
False
let onDeleteParam :: Text
onDeleteParam = forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param @Text ByteString
"onDelete"
let onDelete :: OnDelete
onDelete = case Text
onDeleteParam of
Text
"Restrict" -> OnDelete
Restrict
Text
"SetNull" -> OnDelete
SetNull
Text
"SetDefault" -> OnDelete
SetDefault
Text
"Cascade" -> OnDelete
Cascade
Text
_ -> OnDelete
NoAction
case Maybe Int
constraintId of
Just Int
constraintId -> ([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (Text
-> Text
-> Text
-> Text
-> OnDelete
-> Int
-> [Statement]
-> [Statement]
updateForeignKeyConstraint Text
tableName Text
columnName Text
constraintName Text
referenceTable OnDelete
onDelete Int
constraintId)
Maybe Int
Nothing -> Text -> IO ()
putStrLn (Text
"Error")
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
action DeleteForeignKeyAction { Text
$sel:constraintName:NewColumnAction :: ColumnsController -> Text
constraintName :: Text
constraintName, Text
$sel:tableName:NewColumnAction :: ColumnsController -> Text
tableName :: Text
tableName } = do
[Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
IO [Statement]
readSchema
([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (Text -> [Statement] -> [Statement]
deleteForeignKeyConstraint Text
constraintName)
TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowTableAction { Text
$sel:tableName:TablesAction :: Text
tableName :: Text
.. }
toggleUniqueInColumn :: Text -> Int -> Statement -> Statement
toggleUniqueInColumn :: Text -> Int -> Statement -> Statement
toggleUniqueInColumn Text
tableName Int
columnId (StatementCreateTable table :: CreateTable
table@CreateTable { Text
name :: Text
$sel:name:CreateTable :: CreateTable -> Text
name, [Column]
columns :: [Column]
$sel:columns:CreateTable :: CreateTable -> [Column]
columns })
| Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
tableName = CreateTable -> Statement
StatementCreateTable (CreateTable -> Statement) -> CreateTable -> Statement
forall a b. (a -> b) -> a -> b
$
CreateTable
table { $sel:columns:CreateTable :: [Column]
columns = (Int -> Column -> [Column] -> [Column]
forall a. Int -> a -> [a] -> [a]
replace Int
columnId (([Column]
columns [Column] -> Int -> Column
forall a. HasCallStack => [a] -> Int -> a
!! Int
columnId) { $sel:isUnique:Column :: Bool
isUnique = (Bool -> Bool
not ([Column]
columns [Column] -> Int -> Column
forall a. HasCallStack => [a] -> Int -> a
!! Int
columnId).isUnique) }) [Column]
columns) }
toggleUniqueInColumn Text
tableName Int
columnId Statement
statement = Statement
statement
deleteColumnInTable :: Text -> Int -> Statement -> Statement
deleteColumnInTable :: Text -> Int -> Statement -> Statement
deleteColumnInTable Text
tableName Int
columnId (StatementCreateTable table :: CreateTable
table@CreateTable { Text
$sel:name:CreateTable :: CreateTable -> Text
name :: Text
name, [Column]
$sel:columns:CreateTable :: CreateTable -> [Column]
columns :: [Column]
columns })
| Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
tableName = CreateTable -> Statement
StatementCreateTable (CreateTable -> Statement) -> CreateTable -> Statement
forall a b. (a -> b) -> a -> b
$
CreateTable
table { $sel:columns:CreateTable :: [Column]
columns = Column -> [Column] -> [Column]
forall a. Eq a => a -> [a] -> [a]
delete ([Column]
columns [Column] -> Int -> Column
forall a. HasCallStack => [a] -> Int -> a
!! Int
columnId) [Column]
columns}
deleteColumnInTable Text
tableName Int
columnId Statement
statement = Statement
statement
updateForeignKeyConstraint :: Text -> Text -> Text -> Text -> OnDelete -> Int -> [Statement] -> [Statement]
updateForeignKeyConstraint :: Text
-> Text
-> Text
-> Text
-> OnDelete
-> Int
-> [Statement]
-> [Statement]
updateForeignKeyConstraint Text
tableName Text
columnName Text
constraintName Text
referenceTable OnDelete
onDelete Int
constraintId [Statement]
list = Int -> Statement -> [Statement] -> [Statement]
forall a. Int -> a -> [a] -> [a]
replace Int
constraintId AddConstraint { $sel:tableName:StatementCreateTable :: Text
tableName = Text
tableName, $sel:deferrable:StatementCreateTable :: Maybe Bool
deferrable = Maybe Bool
forall a. Maybe a
Nothing, $sel:deferrableType:StatementCreateTable :: Maybe DeferrableType
deferrableType = Maybe DeferrableType
forall a. Maybe a
Nothing, $sel:constraint:StatementCreateTable :: Constraint
constraint = ForeignKeyConstraint { $sel:name:ForeignKeyConstraint :: Maybe Text
name = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
constraintName, $sel:columnName:ForeignKeyConstraint :: Text
columnName = Text
columnName, $sel:referenceTable:ForeignKeyConstraint :: Text
referenceTable = Text
referenceTable, $sel:referenceColumn:ForeignKeyConstraint :: Maybe Text
referenceColumn = Maybe Text
"id", $sel:onDelete:ForeignKeyConstraint :: Maybe OnDelete
onDelete = (OnDelete -> Maybe OnDelete
forall a. a -> Maybe a
Just OnDelete
onDelete) } } [Statement]
list
deleteForeignKeyConstraint :: Text -> [Statement] -> [Statement]
deleteForeignKeyConstraint :: Text -> [Statement] -> [Statement]
deleteForeignKeyConstraint Text
constraintName = (Statement -> Bool) -> [Statement] -> [Statement]
forall a. (a -> Bool) -> [a] -> [a]
filter \case
AddConstraint { Constraint
$sel:constraint:StatementCreateTable :: Statement -> Constraint
constraint :: Constraint
constraint } | Constraint
constraint.name Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
constraintName -> Bool
False
Statement
otherwise -> Bool
True
deleteTableIndex :: Text -> [Statement] -> [Statement]
deleteTableIndex :: Text -> [Statement] -> [Statement]
deleteTableIndex Text
indexName [Statement]
list =
[Statement]
list
[Statement] -> ([Statement] -> [Statement]) -> [Statement]
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> (Statement -> Bool) -> [Statement] -> [Statement]
forall a. (a -> Bool) -> [a] -> [a]
filter \case
CreateIndex { $sel:indexName:StatementCreateTable :: Statement -> Text
indexName = Text
indexName' } -> Text
indexName' Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
indexName
Statement
otherwise -> Bool
True
getCreateTable :: [Statement] -> [CreateTable]
getCreateTable :: [Statement] -> [CreateTable]
getCreateTable [Statement]
statements = (Statement -> [CreateTable] -> [CreateTable])
-> [CreateTable] -> [Statement] -> [CreateTable]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Statement -> [CreateTable] -> [CreateTable]
step [] [Statement]
statements
where
step :: Statement -> [CreateTable] -> [CreateTable]
step (StatementCreateTable CreateTable
createTable) [CreateTable]
createTables = CreateTable
createTable CreateTable -> [CreateTable] -> [CreateTable]
forall a. a -> [a] -> [a]
: [CreateTable]
createTables
step Statement
_ [CreateTable]
createTables = [CreateTable]
createTables
getCreateEnum :: [Statement] -> [Statement]
getCreateEnum [Statement]
statements = (Statement -> Bool) -> [Statement] -> [Statement]
forall a. (a -> Bool) -> [a] -> [a]
filter Statement -> Bool
isCreateEnumType [Statement]
statements
isCreateEnumType :: Statement -> Bool
isCreateEnumType CreateEnumType {} = Bool
True
isCreateEnumType Statement
_ = Bool
False
nameList :: [a] -> [b]
nameList [a]
statements = (a -> b) -> [a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (.name) [a]
statements
validateColumn :: Validator Text
validateColumn :: Text -> ValidatorResult
validateColumn = Text -> [Text] -> Maybe Text -> Text -> ValidatorResult
validateNameInSchema Text
"column name" [] Maybe Text
forall a. Maybe a
Nothing
referencingColumnForeignKeyConstraints :: Text -> Text -> t Statement -> Maybe Statement
referencingColumnForeignKeyConstraints Text
tableName Text
columnName =
(Statement -> Bool) -> t Statement -> Maybe Statement
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find \case
AddConstraint { $sel:tableName:StatementCreateTable :: Statement -> Text
tableName = Text
constraintTable, $sel:constraint:StatementCreateTable :: Statement -> Constraint
constraint = ForeignKeyConstraint { $sel:columnName:ForeignKeyConstraint :: Constraint -> Text
columnName = Text
fkColumnName } } -> Text
constraintTable Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
tableName Bool -> Bool -> Bool
&& Text
fkColumnName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
columnName
Statement
otherwise -> Bool
False