Skip to content

Commit

Permalink
Fixed deleting a table in the schema designer not deleting the table'…
Browse files Browse the repository at this point in the history
…s policies, rls statements, indices
  • Loading branch information
mpscholten committed Jan 8, 2022
1 parent e90f527 commit d0ea028
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
12 changes: 2 additions & 10 deletions IHP/IDE/SchemaDesigner/Controller/Tables.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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)

Expand Down
14 changes: 13 additions & 1 deletion IHP/IDE/SchemaDesigner/SchemaOperations.hs
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,16 @@ suggestPolicy schema (StatementCreateTable CreateTable { name = tableName, colum

isUserIdColumn :: Column -> Bool
isUserIdColumn Column { name = "user_id" } = True
isUserIdColumn otherwise = False
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
26 changes: 25 additions & 1 deletion Test/IDE/SchemaDesigner/SchemaOperationsSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
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

0 comments on commit d0ea028

Please sign in to comment.