Imports System.Collections.Generic Imports System.Text Namespace Database.Base Public Module TriggerBuilder Public Function GetForeignKeyTriggers(ByVal dt As TableSchema) As IList(Of TriggerSchema) Dim result As IList(Of TriggerSchema) = New List(Of TriggerSchema)() For Each fks As ForeignKeySchema In dt.ForeignKeys result.Add(GenerateInsertTrigger(fks)) result.Add(GenerateUpdateTrigger(fks)) result.Add(GenerateDeleteTrigger(fks)) Next Return result End Function Private Function MakeTriggerName(ByVal fks As ForeignKeySchema, ByVal prefix As String) As String Return prefix & "_" & fks.TableName & "_" & fks.ColumnName & "_" & fks.ForeignTableName & "_" & fks.ForeignColumnName End Function Public Function GenerateInsertTrigger(ByVal fks As ForeignKeySchema) As TriggerSchema Dim trigger As TriggerSchema = New TriggerSchema() trigger.Name = MakeTriggerName(fks, "fki") trigger.Type = TriggerType.Before trigger.Event = TriggerEvent.Insert trigger.Table = fks.TableName Dim nullString As String = "" If fks.IsNullable Then nullString = " NEW." & fks.ColumnName & " IS NOT NULL AND" End If trigger.Body = "SELECT RAISE(ROLLBACK, 'insert on table " & fks.TableName & " violates foreign key constraint " & trigger.Name & "')" & " WHERE" & nullString & " (SELECT " & fks.ForeignColumnName & " FROM " & fks.ForeignTableName & " WHERE " & fks.ForeignColumnName & " = NEW." & fks.ColumnName & ") IS NULL; " Return trigger End Function Public Function GenerateUpdateTrigger(ByVal fks As ForeignKeySchema) As TriggerSchema Dim trigger As TriggerSchema = New TriggerSchema() trigger.Name = MakeTriggerName(fks, "fku") trigger.Type = TriggerType.Before trigger.Event = TriggerEvent.Update trigger.Table = fks.TableName Dim triggerName As String = trigger.Name Dim nullString As String = "" If fks.IsNullable Then nullString = " NEW." & fks.ColumnName & " IS NOT NULL AND" End If trigger.Body = "SELECT RAISE(ROLLBACK, 'update on table " & fks.TableName & " violates foreign key constraint " & triggerName & "')" & " WHERE" & nullString & " (SELECT " & fks.ForeignColumnName & " FROM " & fks.ForeignTableName & " WHERE " & fks.ForeignColumnName & " = NEW." & fks.ColumnName & ") IS NULL; " Return trigger End Function Public Function GenerateDeleteTrigger(ByVal fks As ForeignKeySchema) As TriggerSchema Dim trigger As TriggerSchema = New TriggerSchema() trigger.Name = MakeTriggerName(fks, "fkd") trigger.Type = TriggerType.Before trigger.Event = TriggerEvent.Delete trigger.Table = fks.ForeignTableName Dim triggerName as String = trigger.Name If Not fks.CascadeOnDelete Then trigger.Body = "SELECT RAISE(ROLLBACK, 'delete on table " & fks.ForeignTableName & " violates foreign key constraint " & triggerName & "')" & " WHERE (SELECT " & fks.ColumnName & " FROM " & fks.TableName & " WHERE " & fks.ColumnName & " = OLD." & fks.ForeignColumnName & ") IS NOT NULL; " Else trigger.Body = "DELETE FROM [" & fks.TableName & "] WHERE " & fks.ColumnName & " = OLD." & fks.ForeignColumnName & "; " End If Return trigger End Function End Module End NameSpace