Find if version has edits

12-16-2016 05:48 AM
New Contributor II

Hi everyone,

I am currently trying to find out how I could get the information, if a specific version of my versioned workspace has changes or not. The purpose is to provide the information to a user over all versions avaliable. Therefor, i cannot use IVersionEdit.ModifiedClasses, as If I understand, this will only return something after reconcile.

Is there a way to find out, if a version has local changes?


0 Kudos
2 Replies
MVP Frequent Contributor

I don't know ArcObjects, but can throw out some ideas from the user side of versioned editing to see if that rings a bell and correlates with an ArcObject process/method.

  • In SDE, there is a Version Changes command and tool.  Maybe the ArcObjects part of this is exposed so it can be implemented?  Using the Version Changes command—ArcGIS Help | ArcGIS for Desktop 
  • Edits to Versioned data is tracked by Delta tables.  If you can access the Add and Delete tables and they have records, then the version was edited.  Maybe there is an ArcObjects way to query them?

Chris Donohue, GISP

0 Kudos
New Contributor

When looking through the documentation, this can be done with the IVersionedTable.Differences method. ( )

Basically you iterate through each version you want to check for edits and set up IVersion objects for the child and parent version...  for each versioned object in SDE (I only check tables and features in the example below), cast it to IVersionedTable and call Differences with the type of edits you are looking for.  I call it 6 times.  It will return a DifferenceCursor which you can use to iterate over to see the IRow objects with differences.

You have to verify you are working with a versioned dataset or you will receive an error when calling the Differences method, or you could call IsRegisteredAsVersioned from the IVersionedObject but I had very poor performance from this call.

The Differences method has 6 options for the table returned.  See esriDifferenceType

I've been developing the code below but I'm only checking versions with Default as the parent, which works for our environment.  I also check to see if the version has any potential conflicts without reconciling (esriDifferenceType 3 through 5).  The results have been accurate so far but I put this together pretty quickly.  This is part of a larger addin so you'll have to modify for your needs.

Good luck~

Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Geodatabase

Module FindVersionChanges

Private Sub writeLogLine(ByVal logLine As String)
Dim logFile As String = "C:\temp\test.csv"

Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(logFile, True)

End Sub

Friend Sub listVersionEdits()

writeLogLine("VersionName, VersionedObject, Inserts, Deletes, Updates, Conflict_Update_Update, Conflict_Update_Delete, Conflict_Delete_Update")

Dim connProp As IPropertySet = New PropertySetClass
With connProp
.SetProperty("DBCLIENT", "SQL")
.SetProperty("SERVER", String.Format("{0}\{1}", "<your sql server>", "<sql instance>"))
.SetProperty("INSTANCE", String.Format("sde:sqlserver:{0}", .GetProperty("SERVER")))
.SetProperty("DATABASE", "PODS")
.SetProperty("VERSION", "sde.DEFAULT")
End With

Dim sdeFactoryWkspType As Type = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory")
Dim sdeFactoryWksp As IWorkspaceFactory = CType(Activator.CreateInstance(sdeFactoryWkspType), IWorkspaceFactory)
Dim sdeWksp As IWorkspace = sdeFactoryWksp.Open(connProp, 0)
Dim clVersionWksp As IVersionedWorkspace4 = CType(sdeWksp, IVersionedWorkspace4)

Dim defaultVersion As IVersion = clVersionWksp.FindVersion("sde.DEFAULT")
Dim versionedDatasets As New List(Of String)

''get list of versioned data
Dim enumDatasets As IEnumDataset = sdeWksp.Datasets(esriDatasetType.esriDTAny)
Dim curDataset As IDataset = enumDatasets.Next()
While curDataset IsNot Nothing

If curDataset.Type = esriDatasetType.esriDTFeatureClass Or curDataset.Type = esriDatasetType.esriDTTable Then
Dim versionedObj As IVersionedObject3 = CType(curDataset, IVersionedObject3)
''If versionedObj.IsRegisteredAsVersioned Then versionedDatasets.Add(curDataset.Name)
versionedObj = Nothing
Catch ex As Exception

End Try

ElseIf curDataset.Type = esriDatasetType.esriDTFeatureDataset Then
Dim enumFeatDataset As IEnumDataset = curDataset.Subsets()
Dim subDataset As IDataset = enumFeatDataset.Next()
While subDataset IsNot Nothing
If subDataset.Type = esriDatasetType.esriDTFeatureClass Then
Dim versionedObj As IVersionedObject3 = CType(subDataset, IVersionedObject3)
''If versionedObj.IsRegisteredAsVersioned Then versionedDatasets.Add(curDataset.Name)
versionedObj = Nothing
End If
Catch ex As Exception

End Try

subDataset = enumFeatDataset.Next()
End While
If subDataset IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(subDataset)
If enumFeatDataset IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(enumFeatDataset)

End If

curDataset = enumDatasets.Next()
End While

If curDataset IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(curDataset)
If enumDatasets IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(enumDatasets)

'sort versioned objects

Dim allVersions As IEnumVersionInfo = clVersionWksp.Versions
Dim curVersion As IVersionInfo = allVersions.Next()
While curVersion IsNot Nothing
If curVersion.Parent.VersionName = "sde.DEFAULT" Then 

Dim curVersionVersion As IVersion = clVersionWksp.FindVersion(curVersion.VersionName)

For Each vDataset As String In versionedDatasets

Dim defaultFWS As IFeatureWorkspace = CType(defaultVersion, IFeatureWorkspace)
Dim curVersionFWS As IFeatureWorkspace = CType(curVersionVersion, IFeatureWorkspace)

Dim defaultTable As ITable = defaultFWS.OpenTable(vDataset)
Dim curVerTable As ITable = curVersionFWS.OpenTable(vDataset)

'Create a difference cursor.
Dim versionedTable As IVersionedTable = CType(curVerTable, IVersionedTable)

Dim editCountInVersion As New Dictionary(Of String, Integer) From {{"INSERT", 0}, {"UPDATE", 0}, {"DELETE", 0}} ''update type : count
Dim conflictCount As New Dictionary(Of String, Integer) From {{"UPD_UPD", 0}, {"UPD_DEL", 0}, {"DEL_UPD", 0}} ''CurVersion_DefaultVersion

For x = 0 To 5

Dim differenceCursor As IDifferenceCursor = versionedTable.Differences(defaultTable, x, Nothing)

Dim oid As Integer = -99
Dim differenceRow As IRow = Nothing
differenceCursor.Next(oid, differenceRow)
While oid <> -1
Select Case x
Case 0
editCountInVersion("INSERT") += 1
Case 1
editCountInVersion("DELETE") += 1
Case 2
editCountInVersion("UPDATE") += 1
Case 3
conflictCount("UPD_UPD") += 1
editCountInVersion("UPDATE") += 1
Case 4
conflictCount("UPD_DEL") += 1
editCountInVersion("UPDATE") += 1
Case 5
conflictCount("DEL_UPD") += 1
editCountInVersion("DELETE") += 1
End Select

differenceCursor.Next(oid, differenceRow)
End While

differenceRow = Nothing
differenceCursor = Nothing
Catch ex As Exception
'Debug.Print(String.Format("{0}, Error: {1}", vDataset, ex.Message))
End Try


Dim logStr As String = String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", curVersion.VersionName, vDataset,
editCountInVersion("INSERT"), editCountInVersion("DELETE"), editCountInVersion("UPDATE"),
conflictCount("UPD_UPD"), conflictCount("UPD_DEL"), conflictCount("DEL_UPD"))


versionedTable = Nothing
curVerTable = Nothing
defaultTable = Nothing
curVersionFWS = Nothing
defaultFWS = Nothing


curVersionVersion = Nothing

Debug.Print(String.Format("{0}, Version not child of Default... skipping", curVersion.VersionName))
End If

curVersion = allVersions.Next()
End While

End Sub

End Module