687
public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
687
public void MergeIn(PwDatabase pdSource, PwMergeMethod mm)
689
MergeIn(pwSource, mm, null);
689
MergeIn(pdSource, mm, null);
693
693
/// Synchronize the current database with another one.
695
/// <param name="pwSource">Input database to synchronize with. This input
695
/// <param name="pdSource">Input database to synchronize with. This input
696
696
/// database is used to update the current one, but is not modified! You
697
697
/// must copy the current object if you want a second instance of the
698
698
/// synchronized database. The input database must not be seen as valid
700
700
/// <param name="mm">Merge method.</param>
701
701
/// <param name="slStatus">Logger to report status messages to.
702
702
/// May be <c>null</c>.</param>
703
public void MergeIn(PwDatabase pwSource, PwMergeMethod mm,
703
public void MergeIn(PwDatabase pdSource, PwMergeMethod mm,
704
704
IStatusLogger slStatus)
706
if(pwSource == null) throw new ArgumentNullException("pwSource");
706
if(pdSource == null) throw new ArgumentNullException("pdSource");
708
708
PwGroup pgOrgStructure = m_pgRootGroup.CloneStructure();
709
PwGroup pgSrcStructure = pwSource.m_pgRootGroup.CloneStructure();
709
PwGroup pgSrcStructure = pdSource.m_pgRootGroup.CloneStructure();
711
711
if(mm == PwMergeMethod.CreateNewUuids)
712
pwSource.RootGroup.CreateNewItemUuids(true, true, true);
712
pdSource.RootGroup.CreateNewItemUuids(true, true, true);
714
714
GroupHandler gh = delegate(PwGroup pg)
716
if(pg == pwSource.m_pgRootGroup) return true;
716
// if(pg == pdSource.m_pgRootGroup) return true;
718
718
PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
719
719
if(pgLocal == null)
721
721
PwGroup pgSourceParent = pg.ParentGroup;
722
722
PwGroup pgLocalContainer;
723
if(pgSourceParent == pwSource.m_pgRootGroup)
723
if(pgSourceParent == null)
725
// pg is the root group of pdSource, and no corresponding
726
// local group was found; create the group within the
728
Debug.Assert(pg == pdSource.m_pgRootGroup);
729
pgLocalContainer = m_pgRootGroup;
731
else if(pgSourceParent == pdSource.m_pgRootGroup)
724
732
pgLocalContainer = m_pgRootGroup;
726
734
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
757
765
PwGroup pgSourceParent = pe.ParentGroup;
758
766
PwGroup pgLocalContainer;
759
if(pgSourceParent == pwSource.m_pgRootGroup)
767
if(pgSourceParent == pdSource.m_pgRootGroup)
760
768
pgLocalContainer = m_pgRootGroup;
762
770
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
803
811
return ((slStatus != null) ? slStatus.ContinueWork() : true);
806
if(!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
814
gh(pdSource.RootGroup);
815
if(!pdSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
807
816
throw new InvalidOperationException();
809
818
IStatusLogger slPrevStatus = m_slStatus;
812
821
if(mm == PwMergeMethod.Synchronize)
814
ApplyDeletions(pwSource.m_vDeletedObjects, true);
823
ApplyDeletions(pdSource.m_vDeletedObjects, true);
815
824
ApplyDeletions(m_vDeletedObjects, false);
817
826
PwObjectPool ppOrgGroups = PwObjectPool.FromGroupRecursive(
833
842
// Must be called *after* merging groups, because group UUIDs
834
843
// are required for recycle bin and entry template UUIDs
835
MergeInDbProperties(pwSource, mm);
844
MergeInDbProperties(pdSource, mm);
837
MergeInCustomIcons(pwSource);
846
MergeInCustomIcons(pdSource);
839
848
MaintainBackups();
841
850
m_slStatus = slPrevStatus;
844
private void MergeInCustomIcons(PwDatabase pwSource)
853
private void MergeInCustomIcons(PwDatabase pdSource)
846
foreach(PwCustomIcon pwci in pwSource.CustomIcons)
855
foreach(PwCustomIcon pwci in pdSource.CustomIcons)
848
857
if(GetCustomIconIndex(pwci.Uuid) >= 0) continue;
1249
private void MergeInDbProperties(PwDatabase pwSource, PwMergeMethod mm)
1258
private void MergeInDbProperties(PwDatabase pdSource, PwMergeMethod mm)
1251
if(pwSource == null) { Debug.Assert(false); return; }
1260
if(pdSource == null) { Debug.Assert(false); return; }
1252
1261
if((mm == PwMergeMethod.KeepExisting) || (mm == PwMergeMethod.None))
1255
1264
bool bForce = (mm == PwMergeMethod.OverwriteExisting);
1257
if(bForce || (pwSource.m_dtNameChanged > m_dtNameChanged))
1259
m_strName = pwSource.m_strName;
1260
m_dtNameChanged = pwSource.m_dtNameChanged;
1263
if(bForce || (pwSource.m_dtDescChanged > m_dtDescChanged))
1265
m_strDesc = pwSource.m_strDesc;
1266
m_dtDescChanged = pwSource.m_dtDescChanged;
1269
if(bForce || (pwSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged))
1271
m_strDefaultUserName = pwSource.m_strDefaultUserName;
1272
m_dtDefaultUserChanged = pwSource.m_dtDefaultUserChanged;
1275
if(bForce) m_clr = pwSource.m_clr;
1277
PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pwSource.m_pwRecycleBin;
1278
if(bForce || (pwSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged))
1280
pwPrefBin = pwSource.m_pwRecycleBin;
1266
if(bForce || (pdSource.m_dtNameChanged > m_dtNameChanged))
1268
m_strName = pdSource.m_strName;
1269
m_dtNameChanged = pdSource.m_dtNameChanged;
1272
if(bForce || (pdSource.m_dtDescChanged > m_dtDescChanged))
1274
m_strDesc = pdSource.m_strDesc;
1275
m_dtDescChanged = pdSource.m_dtDescChanged;
1278
if(bForce || (pdSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged))
1280
m_strDefaultUserName = pdSource.m_strDefaultUserName;
1281
m_dtDefaultUserChanged = pdSource.m_dtDefaultUserChanged;
1284
if(bForce) m_clr = pdSource.m_clr;
1286
PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pdSource.m_pwRecycleBin;
1287
if(bForce || (pdSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged))
1289
pwPrefBin = pdSource.m_pwRecycleBin;
1281
1290
pwAltBin = m_pwRecycleBin;
1282
m_bUseRecycleBin = pwSource.m_bUseRecycleBin;
1283
m_dtRecycleBinChanged = pwSource.m_dtRecycleBinChanged;
1291
m_bUseRecycleBin = pdSource.m_bUseRecycleBin;
1292
m_dtRecycleBinChanged = pdSource.m_dtRecycleBinChanged;
1285
1294
if(m_pgRootGroup.FindGroup(pwPrefBin, true) != null)
1286
1295
m_pwRecycleBin = pwPrefBin;
1288
1297
m_pwRecycleBin = pwAltBin;
1289
1298
else m_pwRecycleBin = PwUuid.Zero; // Debug.Assert(false);
1291
PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pwSource.m_pwEntryTemplatesGroup;
1292
if(bForce || (pwSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged))
1300
PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pdSource.m_pwEntryTemplatesGroup;
1301
if(bForce || (pdSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged))
1294
pwPrefTmp = pwSource.m_pwEntryTemplatesGroup;
1303
pwPrefTmp = pdSource.m_pwEntryTemplatesGroup;
1295
1304
pwAltTmp = m_pwEntryTemplatesGroup;
1296
m_dtEntryTemplatesChanged = pwSource.m_dtEntryTemplatesChanged;
1305
m_dtEntryTemplatesChanged = pdSource.m_dtEntryTemplatesChanged;
1298
1307
if(m_pgRootGroup.FindGroup(pwPrefTmp, true) != null)
1299
1308
m_pwEntryTemplatesGroup = pwPrefTmp;
1377
1386
/// <param name="strFile">Source file.</param>
1378
1387
public void Synchronize(string strFile)
1380
PwDatabase pwSource = new PwDatabase();
1389
PwDatabase pdSource = new PwDatabase();
1382
1391
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
1383
pwSource.Open(ioc, m_pwUserKey, null);
1392
pdSource.Open(ioc, m_pwUserKey, null);
1385
MergeIn(pwSource, PwMergeMethod.Synchronize);
1394
MergeIn(pdSource, PwMergeMethod.Synchronize);