Reconcile_SDE_versions_in_batch_mode
frmBatchReconcile.frm
' Copyright 1995-2004 ESRI
' All rights reserved under the copyright laws of the United States.
' You may freely redistribute and use this sample code, with or without modification.
' Disclaimer: THE SAMPLE CODE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
' WARRANTIES, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
' FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ESRI OR
' CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
' OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
' SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
' INTERRUPTION) SUSTAINED BY YOU OR A THIRD PARTY, HOWEVER CAUSED AND ON ANY
' THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ARISING IN ANY
' WAY OUT OF THE USE OF THIS SAMPLE CODE, EVEN IF ADVISED OF THE POSSIBILITY OF
' SUCH DAMAGE.
' For additional information contact: Environmental Systems Research Institute, Inc.
' Attn: Contracts Dept.
' 380 New York Street
' Redlands, California, U.S.A. 92373
' Email: contracts@esri.com
Option Explicit
'API calls to set the cursor to the hourglass
Private Declare Function SetCursor Lib "user32" (ByVal hCursor As Long) As Long
Private Declare Function LoadCursorByIndex Lib "user32" Alias "LoadCursorA" (ByVal hInstance As Long, ByVal lpCursorIndex As Long) As Long
Private Const IDC_WAIT = 32514&
Private Const k_sDefaultVersion As String = "SDE.DEFAULT"
'Reference to the workspace the user originally selected
Private m_pVersionedWorkspace As IVersionedWorkspace
Private Sub Form_Load()
lstSdeConnectionInfo.AddItem "SERVER:"
lstSdeConnectionInfo.AddItem "INSTANCE:"
SetControlState
End Sub
'Ensures that controls are only enabled when they should be
Private Sub SetControlState()
'cmdStart isn't enabled unless you're connected to a workspace
'and a version is selected
cmdStart.Enabled = CBool(Not m_pVersionedWorkspace Is Nothing) And _
CBool(Not tvwVersions.SelectedItem Is Nothing)
'cmdRefresh isn't enabled unless you're connected to a workspace
cmdRefresh.Enabled = CBool(Not m_pVersionedWorkspace Is Nothing)
'Can't delete unless have posted first..
chkDeleteOnPost.Enabled = CBool(chkPost.Value = 1)
End Sub
Private Sub chkPost_Click()
SetControlState
End Sub
Private Sub tvwVersions_Click()
SetControlState
End Sub
Private Sub cmdClose_Click()
Unload Me
End Sub
'Reload the Version Tree to account for versions changing
Private Sub cmdRefresh_Click()
LoadVersionTree m_pVersionedWorkspace
End Sub
'Get connected to an SDE Database through the GxDialog
Private Sub cmdBrowse_Click()
On Error GoTo ErrorHandler
Dim pGXFilter As IGxObjectFilter
Dim pGXDialog As IGxDialog
Dim pGXEnum As IEnumGxObject
Dim pGxObject As IGxObject
Dim pGxDatabase2 As IGxDatabase2
Dim pPropset As IPropertySet
Dim vProp As Variant
'Create a GxDialog and GXFilter for workspaces
Set pGXDialog = New GxDialog
Set pGXFilter = New GxFilterWorkspaces
'Set up the GxDialog
With pGXDialog
.Title = "Browse for SDE Database"
.StartingLocation = "Database Connections"
.ButtonCaption = "OK"
.AllowMultiSelect = False
Set .ObjectFilter = pGXFilter
End With
'Open the GxDialog and get the selected SDE Workspace
pGXDialog.DoModalOpen Me.hWnd, pGXEnum
If Not pGXEnum Is Nothing Then
Set pGxObject = pGXEnum.Next
If Not pGxObject Is Nothing Then
If TypeOf pGxObject Is IGxDatabase2 Then
Set pGxDatabase2 = pGxObject
If pGxDatabase2.IsEnterpriseGeodatabase Then
If pGxDatabase2.IsConnected Then
Set m_pVersionedWorkspace = pGxDatabase2.Workspace
On Error Resume Next
Set pPropset = pGxDatabase2.WorkspaceName.ConnectionProperties
lstSdeConnectionInfo.Clear
lstSdeConnectionInfo.AddItem "SERVER: " & pPropset.GetProperty("SERVER")
lstSdeConnectionInfo.AddItem "INSTANCE: " & pPropset.GetProperty("INSTANCE")
lstSdeConnectionInfo.AddItem "DATABASE: " & pPropset.GetProperty("DATABASE")
lstSdeConnectionInfo.AddItem "USER: " & pPropset.GetProperty("USER")
'Load all the Versions into the treeview
LoadVersionTree m_pVersionedWorkspace
End If
End If
End If
End If
End If
Exit Sub
ErrorHandler:
MsgBox Err.Description
End Sub
'Load tvwVersions with all the Versions in m_pVersionedWorkspace
Private Sub LoadVersionTree(ByVal pVersionedWorkspace As IVersionedWorkspace)
tvwVersions.Nodes.Clear
AddVersionToTree pVersionedWorkspace.DefaultVersion.VersionInfo, Nothing
SetControlState
End Sub
'Recursive function that first adds the parent VersionInfo to tvwVersions and
'then calls itself recursively for each child VersionInfo
Private Sub AddVersionToTree(ByVal pVersionInfo As IVersionInfo, ByVal pParentNode As Node)
Dim pEnumVersionInfo As IEnumVersionInfo
Dim pNode As Node
'Add the parent VersionInfo to the TreeView
If pParentNode Is Nothing Then
Set pNode = tvwVersions.Nodes.Add(, , pVersionInfo.VersionName, pVersionInfo.VersionName)
Else
Set pNode = tvwVersions.Nodes.Add(pParentNode.Index, tvwChild, pVersionInfo.VersionName, pVersionInfo.VersionName)
End If
'Loop through calling this function for each child VersionInfo
'Add each VersionInfo to the Treeview of all versions
Set pEnumVersionInfo = pVersionInfo.Children
Set pVersionInfo = pEnumVersionInfo.Next
Do Until pVersionInfo Is Nothing
AddVersionToTree pVersionInfo, pNode
Set pVersionInfo = pEnumVersionInfo.Next
Loop
pNode.Expanded = True
Set pEnumVersionInfo = Nothing
Set pNode = Nothing
End Sub
'Starts Reconcile/Post/Delete or Reconcile/Post or Reconcile depending
'on what options are selected
Private Sub cmdStart_Click()
On Error GoTo ErrorHandler
Dim pVersion As IVersion
Dim sVersionName As String
'Set the cursor to be the Hourglass until the processing is finished
SetCursor LoadCursorByIndex(0, IDC_WAIT)
sVersionName = tvwVersions.SelectedItem.Text
'This returns an error if the version no longer exists.
Set pVersion = m_pVersionedWorkspace.FindVersion(sVersionName)
If (chkPost.Value = 1) Then
'Reconcile and Post all versions
ReconcileVersions pVersion.VersionInfo.Children, pVersion.VersionName, _
True, CBool(chkDeleteOnPost.Value = 1)
End If
'Reconcile all versions that are still out there to push changes down
'We do this even after Posting to ensure all non-deleted versions get
'updated with the latest changes to the ancestor versions
ReconcileVersions pVersion.VersionInfo.Children, pVersion.VersionName, _
False, False
OutputMessage "Finished"
Set pVersion = Nothing
Exit Sub
ErrorHandler:
MsgBox "Start Reconcile: " & Err.Description
End Sub
'This is a recursive function that
'If posting:
'1-Reconciles child versions of the versions passed in through pEnumVersionInfo
'2-Reconciles the versions passed in through pEnumVersionInfo
'If NOT posting:
'1-Reconciles the versions passed in through pEnumVersionInfo
'2-Reconciles child versions of the versions passed in through pEnumVersionInfo
Private Function ReconcileVersions(ByVal pEnumVersionInfo As IEnumVersionInfo, _
ByVal sParentVersionName As String, _
ByVal bPost As Boolean, _
ByVal bDeleteOnPost As Boolean) As Boolean
On Error GoTo ErrorHandler
Dim pVersionInfo As IVersionInfo
Dim pVersionEdit As IVersionEdit
ReconcileVersions = True
Set pVersionInfo = pEnumVersionInfo.Next
Do Until pVersionInfo Is Nothing
If bPost Then
'Reconcile child versions first to ensure current version get all of the changes of all the child versions
If Not ReconcileVersions(pVersionInfo.Children, pVersionInfo.VersionName, bPost, bDeleteOnPost) Then
ReconcileVersions = False
OutputMessage "Could not reconcile all children of " & pVersionInfo.VersionName
Else
'Finished reconciling Children of version, now reconcile current version
OutputMessage "Changing to " & pVersionInfo.VersionName
Set pVersionEdit = m_pVersionedWorkspace.FindVersion(pVersionInfo.VersionName)
If Not ReconcileVersion(pVersionEdit, sParentVersionName, bPost, bDeleteOnPost) Then
ReconcileVersions = False
End If
End If
Else '(not bPost)
'Reconcile version before child versions to ensure the children
'get all the changes in ancestor lineage
OutputMessage "Changing to " & pVersionInfo.VersionName
Set pVersionEdit = m_pVersionedWorkspace.FindVersion(pVersionInfo.VersionName)
'Reconcile pVersionInfo
If ReconcileVersion(pVersionEdit, sParentVersionName, bPost, bDeleteOnPost) Then
'Finished reconciling current version, Reconcile children of current version
ReconcileVersions pVersionInfo.Children, pVersionInfo.VersionName, bPost, bDeleteOnPost
End If
End If
Set pVersionInfo = pEnumVersionInfo.Next
Loop
Set pEnumVersionInfo = Nothing
Exit Function
ErrorHandler:
MsgBox "ReconcileVersions: " & Err.Description
ReconcileVersions = False
Exit Function
Resume
End Function
'This function tries to Reconcile/Post/Delete, Reconcile/Post, or Reconcile the
'Version passed in as pVersionEdit with it's parent version passed in as sParentVersionName.
'If sucessful, the changes are saved in the version. If there are conflicts,
'The changes introduced in reconcile are NOT saved.
Private Function ReconcileVersion(ByVal pVersionEdit As IVersionEdit, _
ByVal sParentVersionName As String, _
ByVal bPost As Boolean, _
ByVal bDeleteOnPost As Boolean) As Boolean
Dim pVersion As IVersion
ReconcileVersion = True
Set pVersion = pVersionEdit
SetImage pVersion, 1
'check to make sure nobody has it locked.
If IsLocked(pVersionEdit) Then
ReconcileVersion = False
Else
StartEditing pVersionEdit
On Error GoTo AbortOperation
OutputMessage "Reconciling " & pVersion.VersionName & " with " & sParentVersionName
If pVersionEdit.Reconcile(sParentVersionName) Then
'There were conflicts, get out without saving
OutputMessage "Found conflicts reconciling " & pVersion.VersionName & " with " & sParentVersionName
StopEditing pVersionEdit, False
ReconcileVersion = False
Else 'No Conflicts in reconcile
If pVersionEdit.CanPost And bPost Then
'Post and save edits
OutputMessage "Posting " & pVersion.VersionName
pVersionEdit.Post sParentVersionName
StopEditing pVersionEdit, True
'Delete version if specified
If bDeleteOnPost Then
DeleteVersion pVersionEdit
End If
Else
'Not posted, but save edits
StopEditing pVersionEdit, True
End If
End If
End If
If ReconcileVersion Then
SetImage pVersion, 3
Else
SetImage pVersion, 2
End If
Set pVersion = Nothing
Exit Function
AbortOperation:
StopEditing pVersionEdit, False
ReconcileVersion = False
OutputMessage "Error in ReconcileVersion: " & Err.Description
End Function
'Helper function to get the name of a Version's parent
Private Function GetParentVersionName(ByVal pVersion As IVersion) As String
Dim pVersionInfo As IVersionInfo
Dim pParentVersionInfo As IVersionInfo
If pVersion.HasParent Then
Set pVersionInfo = pVersion.VersionInfo
Set pParentVersionInfo = pVersionInfo.Parent
GetParentVersionName = pParentVersionInfo.VersionName
End If
Set pVersionInfo = Nothing
Set pParentVersionInfo = Nothing
End Function
'Helper function to identify is a version is locked by someone else
Private Function IsLocked(ByVal pVersion As IVersion) As Boolean
On Error GoTo ErrorHandler
Dim pEnumLockInfo As IEnumLockInfo
Dim pLockInfo As ILockInfo
Set pEnumLockInfo = pVersion.VersionLocks
Set pLockInfo = pEnumLockInfo.Next
Do Until pLockInfo Is Nothing
OutputMessage pVersion.VersionName & " is already in use by " & pLockInfo.UserName
Set pLockInfo = pEnumLockInfo.Next
IsLocked = True
Loop
Set pEnumLockInfo = Nothing
Exit Function
ErrorHandler:
IsLocked = True
OutputMessage "IsLocked: " & Err.Description
End Function
'Helper sub to display messages tracking progress
Private Sub OutputMessage(ByVal sMessage As String)
Debug.Print sMessage
StatusBar.SimpleText = sMessage
StatusBar.Refresh
End Sub
'Helper function to start editing
Private Sub StartEditing(ByVal pWorkspaceEdit As IWorkspaceEdit)
pWorkspaceEdit.StartEditing False
pWorkspaceEdit.StartEditOperation
End Sub
'Helper function to Stop Editing
Private Sub StopEditing(ByVal pWorkspaceEdit As IWorkspaceEdit, ByVal bSave As Boolean)
If bSave Then
pWorkspaceEdit.StopEditOperation
pWorkspaceEdit.StopEditing True
Else
pWorkspaceEdit.AbortEditOperation
pWorkspaceEdit.StopEditing False
End If
End Sub
'Helper function to delete the version both from the VersionedWorkspace
'as well as to remove it from tvwVersions
Private Sub DeleteVersion(ByVal pVersion As IVersion)
On Error GoTo ErrorHandler
Dim sVersionName As String
sVersionName = pVersion.VersionName
pVersion.Delete
tvwVersions.Nodes.Remove sVersionName
tvwVersions.Refresh
Exit Sub
ErrorHandler:
If Err.Number = -2147217144 Then
OutputMessage "Could not delete " & pVersion.VersionName & " because of lack of permissions"
Exit Sub
Else
OutputMessage "ERROR in DeleteVersion: " & Err.Description
End If
End Sub
Private Sub SetImage(ByVal pVersion As IVersion, ByVal Image As Variant)
On Error Resume Next
tvwVersions.Nodes.Item(pVersion.VersionName).Image = Image
tvwVersions.Refresh
End Sub