module IHP.IDE.SchemaDesigner.Controller.Tables where import IHP.ControllerPrelude import IHP.IDE.ToolServer.Types import IHP.IDE.SchemaDesigner.View.Tables.New import IHP.IDE.SchemaDesigner.View.Tables.Show import IHP.IDE.SchemaDesigner.View.Tables.Index import IHP.IDE.SchemaDesigner.View.Tables.Edit import IHP.IDE.SchemaDesigner.Types import IHP.IDE.SchemaDesigner.View.Layout (findStatementByName, schemaDesignerLayout) import qualified IHP.SchemaCompiler as SchemaCompiler import IHP.IDE.SchemaDesigner.Controller.Helper import IHP.IDE.SchemaDesigner.Controller.Validation import IHP.IDE.SchemaDesigner.Controller.Columns (updateForeignKeyConstraint) import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations instance Controller TablesController where beforeAction = setLayout schemaDesignerLayout action TablesAction = do statements <- readSchema let tableNames = statements |> mapMaybe \case StatementCreateTable CreateTable { name } -> Just name otherwise -> Nothing case headMay tableNames of Just tableName -> redirectTo ShowTableAction { tableName } otherwise -> render IndexView { .. } action ShowTableAction { tableName } = do let name = tableName statements <- readSchema let (Just table) = findStatementByName name statements let generatedHaskellCode = SchemaCompiler.compileStatementPreview statements table render ShowView { .. } action NewTableAction = do statements <- readSchema render NewTableView { .. } action CreateTableAction = do statements <- readSchema let tableName = param "tableName" let validationResult = tableName |> validateTable statements Nothing case validationResult of Failure message -> do setErrorMessage message redirectTo TablesAction Success -> do updateSchema (SchemaOperations.addTable tableName) redirectTo ShowTableAction { .. } action EditTableAction { .. } = do statements <- readSchema let tableId = param "tableId" render EditTableView { .. } action UpdateTableAction = do statements <- readSchema let tableName = param "tableName" let tableId = param "tableId" let oldTableName = ((.name) . unsafeGetCreateTable) (statements !! tableId) let validationResult = tableName |> validateTable statements (Just oldTableName) case validationResult of Failure message -> do setErrorMessage message redirectTo ShowTableAction { tableName = oldTableName } Success -> do updateSchema (SchemaOperations.updateTable tableId tableName) redirectTo ShowTableAction { .. } action DeleteTableAction { .. } = do let tableName = param "tableName" updateSchema (SchemaOperations.deleteTable tableName) redirectTo TablesAction validateTable :: [Statement] -> Maybe Text -> Validator Text validateTable statements = validateNameInSchema "table name" (getAllObjectNames statements) updateReferenceTableOfForeignKeyConstraint constraint newTableName statements = let Just constraintId = elemIndex constraint statements tableName = constraint.tableName columnName = constraint.constraint.columnName constraintName = constraint.constraintName referenceTable = newTableName Just onDelete = constraint.constraint.onDelete in updateForeignKeyConstraint tableName columnName constraintName referenceTable onDelete constraintId