Timestamper Class Extension
TimestampClassExtension.cls

' Copyright 2006 ESRI
'                 
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
' 
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
' 
' See the use restrictions.

Option Explicit

Implements IClassExtension
Implements IObjectClassExtension
Implements IObjectClassEvents
Implements ITimestampClassExtension

Private m_pClassHelper As IClassHelper
Private m_sCreFieldName As String ' Creation Date column name
Private m_sModFieldName As String ' Modification Date column name
Private m_sUsrFieldName As String ' User column name
' Following globals avoid recalculation every time a row is updated
Private m_lCreField As Long   ' Creation Date column position
Private m_lModField As Long   ' Modification Date column position
Private m_lUsrField As Long   ' User column position
Private m_sUsrName As String  ' User name

Private Const E_FAIL As Long = &H80004005 ' HRESULT constant for returning errors
 
Private Sub IClassExtension_Init(ByVal pClassHelper As esriGeoDatabase.IClassHelper, ByVal pExtensionProperties As esriSystem.IPropertySet)

  Set m_pClassHelper = pClassHelper
  m_sUsrName = Environ("USERNAME")
  
  ' If object class has been just created then, if the default fields are present,
  ' use them
  If pExtensionProperties Is Nothing Then
    Call TryDefaultProperties
  Else
    ' Load extension properties into the module variables
    ' Turn off errors so that if the property is not present the module variables
    ' will remain as a null string
    On Error Resume Next
    m_sCreFieldName = pExtensionProperties.GetProperty(c_sCreFieldPropName)
    m_sModFieldName = pExtensionProperties.GetProperty(c_sModFieldPropName)
    m_sUsrFieldName = pExtensionProperties.GetProperty(c_sUsrFieldPropName)
    On Error GoTo 0
  End If

  ' Check that the required fields are there
  Call GetFieldPositions

End Sub
 
Private Sub IClassExtension_Shutdown()
  Set m_pClassHelper = Nothing
End Sub
 
 
Private Sub IObjectClassEvents_OnCreate(ByVal obj As esriGeoDatabase.IObject)
  ' Set the creation date and user name
  ' NOTE: there is no need to call IRow::Store
  '
  ' For Enterprise geodatabases, it is preferable to use the database
  ' date and username, but for simplicity this sample will just use the
  ' client OS date and username.
  Dim pRow As IRow
  Set pRow = obj
  
  If Len(m_sCreFieldName) > 0 Then
    pRow.Value(m_lCreField) = Now
  End If
  
  If Len(m_sUsrFieldName) > 0 Then
    pRow.Value(m_lUsrField) = m_sUsrName
  End If

End Sub
 
Private Sub IObjectClassEvents_OnDelete(ByVal obj As esriGeoDatabase.IObject)
End Sub
 
Private Sub IObjectClassEvents_OnChange(ByVal obj As esriGeoDatabase.IObject)
  ' Set the Modification date and user name
  ' NOTE: there is no need to call IRow::Store
  '
  ' For Enterprise geodatabases, it is preferable to use the database
  ' date and username, but for simplicity this sample will just use the
  ' client OS date and username.
  
  Dim pRow As IRow
  Set pRow = obj
  
  If Len(m_sModFieldName) > 0 Then
    pRow.Value(m_lModField) = Now
  End If
  
  If Len(m_sUsrFieldName) > 0 Then
    pRow.Value(m_lUsrField) = m_sUsrName
  End If

End Sub

Public Property Get ITimestampClassExtension_CreationFieldName() As String
  ITimestampClassExtension_CreationFieldName = m_sCreFieldName
End Property

Public Property Let ITimestampClassExtension_CreationFieldName(ByVal RHS As String)
  m_sCreFieldName = RHS
End Property

Public Property Get ITimestampClassExtension_ModificationFieldName() As String
  ITimestampClassExtension_ModificationFieldName = m_sModFieldName
End Property

Public Property Let ITimestampClassExtension_ModificationFieldName(ByVal RHS As String)
  m_sModFieldName = RHS
End Property

Public Property Get ITimestampClassExtension_UserFieldName() As String
  ITimestampClassExtension_UserFieldName = m_sUsrFieldName
End Property

Public Property Let ITimestampClassExtension_UserFieldName(ByVal RHS As String)
  m_sUsrFieldName = RHS
End Property

Public Sub ITimestampClassExtension_UpdateProperties()
  ' Note that user should have an exclusive schema lock
  ' before calling this method
  
  ' Check if the specified fields exist
  Call GetFieldPositions
  
  ' Make the property set
  Dim pPropSet As IPropertySet
  Set pPropSet = New esriSystem.PropertySet
  
  pPropSet.SetProperty c_sCreFieldPropName, m_sCreFieldName
  pPropSet.SetProperty c_sModFieldPropName, m_sModFieldName
  pPropSet.SetProperty c_sUsrFieldPropName, m_sUsrFieldName
  
  ' Update the schema
  Dim pClassSchemaEdit2 As IClassSchemaEdit2
  Set pClassSchemaEdit2 = m_pClassHelper.Class
  pClassSchemaEdit2.AlterClassExtensionProperties pPropSet
End Sub

Private Sub TryDefaultProperties()
  ' If any of the default fields are present then
  ' put them to an 'in-use' state and update the
  ' extension properties accordingly.
  ' No need for a schema lock as this is guaranteed to run straight after the
  ' object class is created (if no extension properties are provided).
  Dim pClass As IClass
  Set pClass = m_pClassHelper.Class
  
  If pClass.FindField(c_sCreFieldDefaultName) <> -1 Then
    m_sCreFieldName = c_sCreFieldDefaultName
  End If
  If pClass.FindField(c_sModFieldDefaultName) <> -1 Then
    m_sModFieldName = c_sModFieldDefaultName
  End If
  If pClass.FindField(c_sUsrFieldDefaultName) <> -1 Then
    m_sUsrFieldName = c_sUsrFieldDefaultName
  End If
  
  If Len(m_sCreFieldName) > 0 _
  Or Len(m_sModFieldName) > 0 _
  Or Len(m_sUsrFieldName) > 0 Then
    Call ITimestampClassExtension_UpdateProperties
  End If
End Sub


Private Sub GetFieldPositions()

  Dim pClass As IClass
  Set pClass = m_pClassHelper.Class
  
  If Len(m_sCreFieldName) > 0 Then
    m_lCreField = pClass.FindField(m_sCreFieldName)
    If m_lCreField = -1 Then
      Err.Raise E_FAIL, , "Creation timestamp field not found: " & m_sCreFieldName
    End If
  Else
    m_lCreField = -1
  End If
  
  If Len(m_sModFieldName) > 0 Then
    m_lModField = pClass.FindField(m_sModFieldName)
    If m_lModField = -1 Then
      Err.Raise E_FAIL, , "Modification timestamp field not found: " & m_sModFieldName
    End If
  Else
    m_lModField = -1
  End If

  If Len(m_sUsrFieldName) > 0 Then
    m_lUsrField = pClass.FindField(m_sUsrFieldName)
    If m_lUsrField = -1 Then
      Err.Raise E_FAIL, , "User timestamp field not found: " & m_sUsrFieldName
    End If
  Else
    m_lUsrField = -1
  End If

End Sub