文章
Michael Lei · 六月 26 阅读大约需 5 分钟

跟踪数据更改 - 审计日志 - 下篇

前一篇文章中,我已经演示了一种简单的方法来记录数据的变化。在这个时候,我改变了负责记录审计数据的 "审计抽象类 "和记录审计日志的数据结构。

我已经将数据结构改为父子结构,其中将有两个表来记录 "交易 "和在该交易中改变的 "字段的值"。

看一下新的数据模型:

看看从 "审计类 "改变的代码吧:

Class Sample.AuditBase [ Abstract ]
{ Trigger SaveAuditAfter [ CodeMode = objectgenerator, Event = INSERT/UPDATE, Foreach = row/object, Order = 99999, Time = AFTER ]
{
          #dim %compiledclass As %Dictionary.CompiledClass
          #dim tProperty As %Dictionary.CompiledProperty
          #dim tAudit As Sample.Audit           Do %code.WriteLine($Char(9)_"; get username and ip adress")
          Do %code.WriteLine($Char(9)_"Set tSC = $$$OK")
          Do %code.WriteLine($Char(9)_"Set tUsername = $USERNAME")           Set tKey = ""
          Set tProperty = %compiledclass.Properties.GetNext(.tKey)
          Set tClassName = %compiledclass.Name           Do %code.WriteLine($Char(9)_"Try {")
          Do %code.WriteLine($Char(9,9)_"; Check if the operation is an update - %oper = UPDATE")
          Do %code.WriteLine($Char(9,9)_"if %oper = ""UPDATE"" { ")
          Do %code.WriteLine($Char(9,9,9)_"Set tAudit = ##class(Sample.Audit).%New()")
          Do %code.WriteLine($Char(9,9,9)_"Set tAudit.Date = +$Horolog")
          Do %code.WriteLine($Char(9,9,9)_"Set tAudit.UserName = tUsername")
          Do %code.WriteLine($Char(9,9,9)_"Set tAudit.ClassName = """_tClassName_"""")
          Do %code.WriteLine($Char(9,9,9)_"Set tAudit.Id = {id}")
          Do %code.WriteLine($Char(9,9,9)_"Set tSC = tAudit.%Save()")
          do %code.WriteLine($Char(9,9,9)_"If $$$ISERR(tSC) $$$ThrowStatus(tSC)")
          Do %code.WriteLine($Char(9,9,9)_"Set tAuditId = tAudit.%Id()")           While tKey '= "" {
                    set tColumnNbr = $Get($$$EXTPROPsqlcolumnnumber($$$pEXT,%classname,tProperty.Name))
                    Set tColumnName = $Get($$$EXTPROPsqlcolumnname($$$pEXT,%classname,tProperty.Name))                     If tColumnNbr '= "" {                               Do %code.WriteLine($Char(9,9,9)_";")
                              Do %code.WriteLine($Char(9,9,9)_";")
                              Do %code.WriteLine($Char(9,9,9)_"; Audit Field: "_tProperty.SqlFieldName)
                              Do %code.WriteLine($Char(9,9,9)_"if {" _ tProperty.SqlFieldName _ "*C} {")                               Do %code.WriteLine($Char(9,9,9,9)_"Set tAuditField = ##class(Sample.AuditField).%New()")
                              Do %code.WriteLine($Char(9,9,9,9)_"Set tAuditField.Field = """_tColumnName_"""")
                              Do %code.WriteLine($Char(9,9,9,9)_"Set tAuditField.OldValue = {"_tProperty.SqlFieldName_"*O}")
                              Do %code.WriteLine($Char(9,9,9,9)_"Set tAuditField.NewValue = {"_tProperty.SqlFieldName_"*N}")
                              Do %code.WriteLine($Char(9,9,9,9)_"Do tAuditField.AuditSetObjectId(tAuditId)")
                              Do %code.WriteLine($Char(9,9,9,9)_"Set tSC = tAuditField.%Save()")
                              do %code.WriteLine($Char(9,9,9,9)_"If $$$ISERR(tSC) $$$ThrowStatus(tSC)")
                              Do %code.WriteLine($Char(9,9,9)_"}")
                    }
                    Set tProperty = %compiledclass.Properties.GetNext(.tKey)
          }           Do %code.WriteLine($Char(9,9)_"}")           Do %code.WriteLine($Char(9)_"} Catch (tException) {")                     Do %code.WriteLine($Char(9,9)_"Set %msg = tException.AsStatus()")
                    Do %code.WriteLine($Char(9,9)_"Set %ok = 0")
                    Do %code.WriteLine($Char(9)_"}")                     Set %ok = 1
} }

通过Test()类方法改变数据,现在你可以看到审计类(Sample.Audit)中的 "父记录 "和 "审计字段 "类中的 "子字段 "被改变。(Sample.AuditField)。

d ##class(Sample.Person).Test(1)
INSERT INTO Sample.Person (Name, Age) VALUES ('TEST PARENT-CHILD', '01')
SQLCODE: 0
ID Age Name
1 01 TEST PARENT-CHILD 1 Rows(s) Affected
UPDATE Sample.Person SET Name = 'INTERSYSTEMS DEVELOPER COMMUNITY', Age = '100' WHERE Name = 'TEST PARENT-CHILD'
SQLCODE:0
ID Age Name
1 100 INTERSYSTEMS DEVELOPER COMMUNITY 1 Rows(s) Affected

审计类: 

注意Sample.AuditField记录通过Audit字段=1对Sample.Audit类进行了引用。你可以通过使用两个类的关系来查询数据,如下所示:

 这样就搞定了。这样,我们有一个不同的审计日志数据结构。

0
0 35
讨论 (0)1
登录或注册以继续