From d0ea028c291e0c68051411230a95db89506c0a9b Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Sat, 8 Jan 2022 11:32:25 +0100 Subject: [PATCH] Fixed deleting a table in the schema designer not deleting the table's policies, rls statements, indices --- IHP/IDE/SchemaDesigner/Controller/Tables.hs | 12 ++------- IHP/IDE/SchemaDesigner/SchemaOperations.hs | 14 +++++++++- .../SchemaDesigner/SchemaOperationsSpec.hs | 26 ++++++++++++++++++- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/IHP/IDE/SchemaDesigner/Controller/Tables.hs b/IHP/IDE/SchemaDesigner/Controller/Tables.hs index 29d9533d2..79174ed08 100644 --- a/IHP/IDE/SchemaDesigner/Controller/Tables.hs +++ b/IHP/IDE/SchemaDesigner/Controller/Tables.hs @@ -73,8 +73,8 @@ instance Controller TablesController where action DeleteTableAction { .. } = do let tableId = param "tableId" let tableName = param "tableName" - updateSchema (deleteTable tableId) - updateSchema (deleteForeignKeyConstraints tableName) + + updateSchema (SchemaOperations.deleteTable tableName) redirectTo TablesAction @@ -83,14 +83,6 @@ updateTable :: Int -> Text -> [Statement] -> [Statement] updateTable tableId tableName list = replace tableId (StatementCreateTable CreateTable { name = tableName, columns = get #columns table, primaryKeyConstraint = get #primaryKeyConstraint table, constraints = get #constraints table }) list where table = unsafeGetCreateTable (list !! tableId) -deleteTable :: Int -> [Statement] -> [Statement] -deleteTable tableId list = delete (list !! tableId) list - -deleteForeignKeyConstraints :: Text -> [Statement] -> [Statement] -deleteForeignKeyConstraints tableName = filter \case - AddConstraint { tableName = constraintTable } | constraintTable == tableName -> False - otherwise -> True - validateTable :: [Statement] -> Maybe Text -> Validator Text validateTable statements = validateNameInSchema "table name" (getAllObjectNames statements) diff --git a/IHP/IDE/SchemaDesigner/SchemaOperations.hs b/IHP/IDE/SchemaDesigner/SchemaOperations.hs index 040e2bb36..68ca0d91b 100644 --- a/IHP/IDE/SchemaDesigner/SchemaOperations.hs +++ b/IHP/IDE/SchemaDesigner/SchemaOperations.hs @@ -307,4 +307,16 @@ suggestPolicy schema (StatementCreateTable CreateTable { name = tableName, colum isUserIdColumn :: Column -> Bool isUserIdColumn Column { name = "user_id" } = True -isUserIdColumn otherwise = False \ No newline at end of file +isUserIdColumn otherwise = False + + +deleteTable :: Text -> Schema -> Schema +deleteTable tableName statements = + statements + |> filter \case + StatementCreateTable CreateTable { name } | name == tableName -> False + AddConstraint { tableName = constraintTable } | constraintTable == tableName -> False + CreateIndex { tableName = indexTable } | indexTable == tableName -> False + EnableRowLevelSecurity { tableName = rlsTable } | rlsTable == tableName -> False + CreatePolicy { tableName = policyTable } | policyTable == tableName -> False + otherwise -> True \ No newline at end of file diff --git a/Test/IDE/SchemaDesigner/SchemaOperationsSpec.hs b/Test/IDE/SchemaDesigner/SchemaOperationsSpec.hs index 1dc0664cc..7c597c069 100644 --- a/Test/IDE/SchemaDesigner/SchemaOperationsSpec.hs +++ b/Test/IDE/SchemaDesigner/SchemaOperationsSpec.hs @@ -4,6 +4,8 @@ import Test.Hspec import IHP.Prelude import IHP.IDE.SchemaDesigner.Types import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations +import qualified IHP.IDE.SchemaDesigner.Parser as Parser +import qualified Text.Megaparsec as Megaparsec tests = do describe "IHP.IDE.SchemaDesigner.SchemaOperations" do @@ -82,6 +84,22 @@ tests = do (SchemaOperations.disableRowLevelSecurityIfNoPolicies "a" inputSchema) `shouldBe` inputSchema + describe "deleteTable" do + it "delete a table with all it's indices, constraints, policies, enable RLS statements" do + let inputSchema = parseSqlStatements [trimming| + CREATE TABLE users (); + CREATE TABLE tasks (); + CREATE INDEX tasks_user_id_index ON tasks (user_id); + ALTER TABLE tasks ADD CONSTRAINT tasks_ref_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE NO ACTION; + CREATE POLICY "Users can manage their tasks" ON tasks USING (user_id = ihp_user_id()) WITH CHECK (user_id = ihp_user_id()); + ALTER TABLE tasks ENABLE ROW LEVEL SECURITY; + |] + let outputSchema = parseSqlStatements [trimming| + CREATE TABLE users (); + |] + + SchemaOperations.deleteTable "tasks" inputSchema `shouldBe` outputSchema + describe "suggestPolicy" do it "should suggest a policy if a user_id column exists" do let table = StatementCreateTable CreateTable @@ -152,4 +170,10 @@ tests = do , check = Just (ExistsExpression (SelectExpression (Select {columns = [IntExpression 1], from = DotExpression (VarExpression "public") "task_lists", whereClause = EqExpression (DotExpression (VarExpression "task_lists") "id") (DotExpression (VarExpression "tasks") "task_list_id")}))) } - SchemaOperations.suggestPolicy schema tasksTable `shouldBe` expectedPolicy \ No newline at end of file + SchemaOperations.suggestPolicy schema tasksTable `shouldBe` expectedPolicy + +parseSqlStatements :: Text -> [Statement] +parseSqlStatements sql = + case Megaparsec.runParser Parser.parseDDL "input" sql of + Left parserError -> error (cs $ Megaparsec.errorBundlePretty parserError) -- For better error reporting in hspec + Right statements -> statements \ No newline at end of file