mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Partial identity matches can now be considered as full matches, fixing a bug where import files would create duplicate items if imported several times.
This commit is contained in:
@@ -39,6 +39,30 @@ namespace Orchard.Tests.ContentManagement {
|
||||
var identity2 = new ContentIdentity(@"/foo=bar/abaz=quux\/fr\\ed=foo/yarg=yiu=foo");
|
||||
Assert.That(comparer.Equals(identity2, new ContentIdentity(identity2.ToString())));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContentIdentityCanSeePartialMatchesAreEquivalent() {
|
||||
var identity1 = new ContentIdentity("/bar=baz/a=b");
|
||||
var identity2 = new ContentIdentity(@"/foo=bar/bar=baz/glop=glop");
|
||||
Assert.That(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity1, identity2));
|
||||
Assert.That(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity2, identity1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContentIdentityCanSeeFullMatchesAreEquivalent() {
|
||||
var identity1 = new ContentIdentity(@"/foo=bar/bar=baz/glop=glop");
|
||||
var identity2 = new ContentIdentity(@"/foo=bar/bar=baz/glop=glop");
|
||||
Assert.That(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity1, identity2));
|
||||
Assert.That(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity2, identity1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContentIdentityCanSeeNonMatchesAreNotEquivalent() {
|
||||
var identity1 = new ContentIdentity(@"/a=b/foo=baz");
|
||||
var identity2 = new ContentIdentity(@"/foo=bar/bar=baz/glop=glop");
|
||||
Assert.IsFalse(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity1, identity2));
|
||||
Assert.IsFalse(ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(identity2, identity1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ namespace Orchard.Core.Common.Services {
|
||||
return null;
|
||||
}
|
||||
|
||||
var comparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
return _contentManager
|
||||
.Query<IdentityPart, IdentityPartRecord>()
|
||||
.Where(p => p.Identifier == identifier)
|
||||
.List<ContentItem>()
|
||||
.Where(c => comparer.Equals(identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
.Where(c => ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(
|
||||
identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace Orchard.Recipes.RecipeHandlers {
|
||||
|
||||
//Populate import session with all identities to be imported
|
||||
foreach (var identity in elementDictionary.Keys) {
|
||||
importContentSession.Set(identity.ToString(), elementDictionary[identity].Name.LocalName);
|
||||
importContentSession.Set(identity, elementDictionary[identity].Name.LocalName);
|
||||
}
|
||||
|
||||
//Determine if the import is to be batched in multiple transactions
|
||||
@@ -45,16 +45,17 @@ namespace Orchard.Recipes.RecipeHandlers {
|
||||
int batchSize = GetBatchSizeForDataStep(recipeContext.RecipeStep.Step);
|
||||
|
||||
//Run the import
|
||||
ContentIdentity nextIdentity = null;
|
||||
try {
|
||||
while (startIndex < elementDictionary.Count) {
|
||||
importContentSession.InitializeBatch(startIndex, batchSize);
|
||||
|
||||
//the session determines which items are included in the current batch
|
||||
//so that dependencies can be managed within the same transaction
|
||||
nextIdentity = importContentSession.GetNextInBatch();
|
||||
var nextIdentity = importContentSession.GetNextInBatch();
|
||||
while (nextIdentity != null) {
|
||||
_orchardServices.ContentManager.Import(elementDictionary[nextIdentity], importContentSession);
|
||||
_orchardServices.ContentManager.Import(
|
||||
elementDictionary[nextIdentity.ToString()],
|
||||
importContentSession);
|
||||
nextIdentity = importContentSession.GetNextInBatch();
|
||||
}
|
||||
|
||||
@@ -75,13 +76,14 @@ namespace Orchard.Recipes.RecipeHandlers {
|
||||
recipeContext.Executed = true;
|
||||
}
|
||||
|
||||
private Dictionary<ContentIdentity, XElement> CreateElementDictionary(XElement step) {
|
||||
var elementDictionary = new Dictionary<ContentIdentity, XElement>(new ContentIdentity.ContentIdentityEqualityComparer());
|
||||
private Dictionary<string, XElement> CreateElementDictionary(XElement step) {
|
||||
var elementDictionary = new Dictionary<string, XElement>();
|
||||
foreach (var element in step.Elements()) {
|
||||
if (element.Attribute("Id") == null || string.IsNullOrEmpty(element.Attribute("Id").Value))
|
||||
if (element.Attribute("Id") == null
|
||||
|| string.IsNullOrEmpty(element.Attribute("Id").Value))
|
||||
continue;
|
||||
|
||||
var identity = new ContentIdentity(element.Attribute("Id").Value);
|
||||
var identity = new ContentIdentity(element.Attribute("Id").Value).ToString();
|
||||
elementDictionary[identity] = element;
|
||||
}
|
||||
return elementDictionary;
|
||||
|
||||
@@ -29,12 +29,12 @@ namespace Orchard.Users.Services {
|
||||
return null;
|
||||
}
|
||||
|
||||
var comparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
return _contentManager
|
||||
.Query<UserPart, UserPartRecord>()
|
||||
.Where(p => p.UserName == identifier)
|
||||
.List<ContentItem>()
|
||||
.Where(c => comparer.Equals(identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
.Where(c => ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(
|
||||
identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@ namespace Orchard.Widgets.Services {
|
||||
return null;
|
||||
}
|
||||
|
||||
var comparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
return _contentManager
|
||||
.Query<LayerPart, LayerPartRecord>()
|
||||
.Where(p => p.Name == identifier)
|
||||
.List<ContentItem>()
|
||||
.Where(c => comparer.Equals(identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
.Where(c => ContentIdentity.ContentIdentityEqualityComparer.AreEquivalent(
|
||||
identity, _contentManager.GetItemMetadata(c).Identity));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,17 @@ namespace Orchard.ContentManagement {
|
||||
|
||||
|
||||
public class ContentIdentityEqualityComparer : IEqualityComparer<ContentIdentity> {
|
||||
public static bool AreEquivalent(ContentIdentity contentIdentity1, ContentIdentity contentIdentity2) {
|
||||
if (contentIdentity1 == null) return contentIdentity2 == null;
|
||||
if (contentIdentity2 == null) return false;
|
||||
return contentIdentity1._dictionary.Keys
|
||||
.Any(k => {
|
||||
var other = contentIdentity2.Get(k);
|
||||
if (other == null) return false;
|
||||
return contentIdentity1._dictionary[k] == other;
|
||||
});
|
||||
}
|
||||
|
||||
public bool Equals(ContentIdentity contentIdentity1, ContentIdentity contentIdentity2) {
|
||||
if (contentIdentity1._dictionary.Keys.Count != contentIdentity2._dictionary.Keys.Count)
|
||||
return false;
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Orchard.ContentManagement {
|
||||
// Maps content identities to content items on the importer.
|
||||
public class ImportContentSession {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ContentIdentity.ContentIdentityEqualityComparer _identityComparer;
|
||||
|
||||
private readonly Dictionary<ContentIdentity, int> _identities;
|
||||
private readonly Dictionary<ContentIdentity, string> _contentTypes;
|
||||
@@ -21,15 +20,15 @@ namespace Orchard.ContentManagement {
|
||||
private int _currentIndex;
|
||||
|
||||
public ImportContentSession(IContentManager contentManager) {
|
||||
_identityComparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
var identityComparer = new ContentIdentity.ContentIdentityEqualityComparer();
|
||||
_contentManager = contentManager;
|
||||
|
||||
_identities = new Dictionary<ContentIdentity, int>(_identityComparer);
|
||||
_contentTypes = new Dictionary<ContentIdentity, string>(_identityComparer);
|
||||
_identities = new Dictionary<ContentIdentity, int>(identityComparer);
|
||||
_contentTypes = new Dictionary<ContentIdentity, string>(identityComparer);
|
||||
_draftVersionRecordIds = new Dictionary<int, int>();
|
||||
|
||||
_allIdentitiesForImport = new List<ContentIdentity>();
|
||||
_allIdentitiesForImportStatus = new Dictionary<ContentIdentity, bool>(_identityComparer);
|
||||
_allIdentitiesForImportStatus = new Dictionary<ContentIdentity, bool>(identityComparer);
|
||||
_dependencyIdentities = new Queue<ContentIdentity>();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user