GUACAMOLE-363: Add triggers to handle cascading deletes/updates where SQL 
Server does not support doing so automatically via ON DELETE actions.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/56da0b0c
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/56da0b0c
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/56da0b0c

Branch: refs/heads/master
Commit: 56da0b0c756f59b06f6647653388a5448fadb9bd
Parents: 317c76b
Author: Michael Jumper <mjum...@apache.org>
Authored: Sat Nov 25 19:57:31 2017 -0800
Committer: Michael Jumper <mjum...@apache.org>
Committed: Sun Nov 26 13:01:48 2017 -0800

----------------------------------------------------------------------
 .../schema/001-create-schema.sql                | 122 ++++++++++++++++---
 1 file changed, 108 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/56da0b0c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
----------------------------------------------------------------------
diff --git 
a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
 
b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
index fd576e5..be955ac 100644
--- 
a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
+++ 
b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
@@ -124,12 +124,10 @@ CREATE TABLE [guacamole_connection_group] (
     CONSTRAINT [AK_guacamole_connection_group_name_parent]
         UNIQUE ([connection_group_name], [parent_id]),
 
-    -- NOTE: SQL Server does not allow ON DELETE CASCADE for this column
-    -- due to the potential for cycles. Lacking this, deletion of connection
-    -- groups will fail if they contain other connection groups.
     CONSTRAINT [FK_guacamole_connection_group_parent_id]
         FOREIGN KEY ([parent_id])
         REFERENCES [guacamole_connection_group] ([connection_group_id])
+        -- ON DELETE CASCADE handled by guacamole_delete_connection_group 
trigger
 
 );
 
@@ -171,7 +169,7 @@ CREATE TABLE [guacamole_connection] (
     CONSTRAINT [FK_guacamole_connection_parent_id]
         FOREIGN KEY ([parent_id])
         REFERENCES [guacamole_connection_group] ([connection_group_id])
-        ON DELETE CASCADE
+        -- ON DELETE CASCADE handled by guacamole_delete_connection_group 
trigger
 
 );
 
@@ -249,7 +247,7 @@ CREATE TABLE [guacamole_sharing_profile] (
     CONSTRAINT [FK_guacamole_sharing_profile_primary_connection_id]
         FOREIGN KEY ([primary_connection_id])
         REFERENCES [guacamole_connection] ([connection_id])
-        ON DELETE CASCADE
+        -- ON DELETE CASCADE handled by guacamole_delete_connection trigger
 
 );
 
@@ -446,17 +444,15 @@ CREATE TABLE [guacamole_user_permission] (
     CONSTRAINT [PK_guacamole_user_permission]
         PRIMARY KEY CLUSTERED ([user_id], [affected_user_id], [permission]),
 
-    -- NOTE: SQL Server does not allow ON DELETE CASCADE for this column
-    -- due to the potential for multiple deletion paths. Lacking this, deletion
-    -- of users associated with permissions granted to other users will fail.
     CONSTRAINT [FK_guacamole_user_permission_affected_user_id]
         FOREIGN KEY ([affected_user_id])
         REFERENCES [guacamole_user] ([user_id]),
+        -- ON DELETE CASCADE handled by guacamole_delete_user trigger
 
     CONSTRAINT [FK_guacamole_user_permission_user_id]
         FOREIGN KEY ([user_id])
         REFERENCES [guacamole_user] ([user_id])
-        ON DELETE CASCADE
+        -- ON DELETE CASCADE handled by guacamole_delete_user trigger
 
 );
 
@@ -499,13 +495,10 @@ CREATE TABLE [guacamole_connection_history] (
         REFERENCES [guacamole_connection] ([connection_id])
         ON DELETE SET NULL,
 
-    -- NOTE: SQL Server does not allow ON DELETE SET NULL for this column
-    -- due to the potential for multiple deletion paths. Lacking this, deletion
-    -- of sharing profiles which have previously been used (and thus have
-    -- existing history records) will fail.
     CONSTRAINT [FK_guacamole_connection_history_sharing_profile_id]
         FOREIGN KEY ([sharing_profile_id])
         REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
+        -- ON DELETE SET NULL handled by guacamole_delete_sharing profile 
trigger
 
 );
 
@@ -553,4 +546,105 @@ CREATE TABLE [guacamole_user_password_history] (
 
 CREATE NONCLUSTERED INDEX [IX_guacamole_user_password_history_user_id]
     ON [guacamole_user_password_history] ([user_id]);
-GO
\ No newline at end of file
+GO
+
+--
+-- Handle cascading deletion/updates of records in response to deletion of
+-- guacamole_user records, where such deletion is not already covered by
+-- ON DELETE CASCADE or ON DELETE SET NULL.
+--
+
+CREATE TRIGGER [guacamole_delete_user]
+   ON [guacamole_user]
+   INSTEAD OF DELETE
+AS BEGIN
+
+    -- Delete all associated permissions not covered by ON DELETE CASCADE
+    DELETE FROM [guacamole_user_permission]
+    WHERE
+           [user_id] IN (SELECT [user_id] FROM DELETED)
+        OR [user_id] IN (SELECT [user_id] FROM DELETED);
+
+    -- Perform original deletion
+    DELETE FROM [guacamole_user]
+    WHERE [user_id] IN (SELECT [user_id] FROM DELETED);
+
+END
+GO
+
+--
+-- Handle cascading deletion/updates of records in response to deletion of
+-- guacamole_connection records, where such deletion is not already covered by
+-- ON DELETE CASCADE or ON DELETE SET NULL.
+--
+
+CREATE TRIGGER [guacamole_delete_connection]
+   ON [guacamole_connection]
+   INSTEAD OF DELETE
+AS BEGIN
+
+    -- Delete associated sharing profiles
+    DELETE FROM [guacamole_sharing_profile]
+    WHERE [primary_connection_id] IN (SELECT [connection_id] FROM DELETED);
+
+    -- Perform original deletion
+    DELETE FROM [guacamole_connection]
+    WHERE [connection_id] IN (SELECT [connection_id] FROM DELETED);
+
+END
+GO
+
+--
+-- Handle cascading deletion/updates of records in response to deletion of
+-- guacamole_connection_group records, where such deletion is not already
+-- covered by ON DELETE CASCADE or ON DELETE SET NULL.
+--
+
+CREATE TRIGGER [guacamole_delete_connection_group]
+   ON [guacamole_connection_group]
+   INSTEAD OF DELETE
+AS BEGIN
+
+    -- Delete all requested connection groups, including descendants
+    WITH [connection_groups] ([connection_group_id]) AS (
+        SELECT [connection_group_id] FROM DELETED
+    UNION ALL
+        SELECT [guacamole_connection_group].[connection_group_id]
+        FROM [guacamole_connection_group]
+        JOIN [connection_groups] ON [connection_groups].[connection_group_id] 
= [guacamole_connection_group].[parent_id]
+    )
+    DELETE FROM [guacamole_connection_group]
+    WHERE [connection_group_id] IN (
+        SELECT [connection_group_id]
+        FROM [connection_groups]
+    );
+
+    -- Delete all child connections
+    DELETE FROM [guacamole_connection]
+    WHERE [parent_id] IN (SELECT [connection_group_id] FROM DELETED);
+
+END
+GO
+
+--
+-- Handle cascading deletion/updates of records in response to deletion of
+-- guacamole_sharing_profile records, where such deletion is not already
+-- covered by ON DELETE CASCADE or ON DELETE SET NULL.
+--
+
+CREATE TRIGGER [guacamole_delete_sharing_profile]
+   ON [guacamole_sharing_profile]
+   INSTEAD OF DELETE
+AS BEGIN
+
+    -- Delete all associated permissions not covered by ON DELETE CASCADE
+    UPDATE [guacamole_connection_history]
+    SET [sharing_profile_id] = NULL
+    WHERE [sharing_profile_id] IN (SELECT [sharing_profile_id] FROM DELETED);
+
+    -- Perform original deletion
+    DELETE FROM [guacamole_sharing_profile]
+    WHERE [sharing_profile_id] IN (SELECT [sharing_profile_id] FROM DELETED);
+
+END
+GO

Reply via email to