diff --git a/Interfaces/IXBaseTagProvider.cs b/Interfaces/IXBaseTagProvider.cs
index e423dba..d60554a 100644
--- a/Interfaces/IXBaseTagProvider.cs
+++ b/Interfaces/IXBaseTagProvider.cs
@@ -26,13 +26,11 @@ namespace xTagService.Interfaces
///
///
///
- ///
///
///
Task AddReference(
string tag,
TKey providedForId,
- int forIndex = 0,
string connectionId = null
);
@@ -47,20 +45,18 @@ namespace xTagService.Interfaces
string tag,
XReference reference,
string connectionId = null
- );
+ );
///
/// Remove Reference a Tag for Specific Provided ID ...
///
///
///
- /// if null, removes all
///
///
Task RemoveReference(
string tag,
TKey providedForId,
- int? forIndex = null,
string connectionId = null
);
diff --git a/Providers/XBaseTagProvider.cs b/Providers/XBaseTagProvider.cs
index 4816057..741b413 100644
--- a/Providers/XBaseTagProvider.cs
+++ b/Providers/XBaseTagProvider.cs
@@ -40,14 +40,6 @@ namespace xTagService.Providers
}
#endregion
- //
- #region Identifier ...
- public async Task LastIndex(TKey providedForId)
- {
- return await Task.FromResult(GetLastIndex(providedForId));
- }
- #endregion
-
//
#region Referenced Actions ...
///
@@ -77,8 +69,8 @@ namespace xTagService.Providers
//
// Retrieve Last Index ...
- var lastIndex = GetLastIndex(providedForId);
- if (forIndex > lastIndex)
+ var referencesCount = await CountReferences(providedForId);
+ if (forIndex > referencesCount - 1)
{
XException.NotFound.Throw();
}
@@ -140,6 +132,32 @@ namespace xTagService.Providers
return await Task.FromResult(result);
}
+ ///
+ /// Count References ...
+ ///
+ ///
+ ///
+ public async Task CountReferences(TKey providedForId)
+ {
+ //
+ // Validate ...
+ var isValid = !providedForId.IsNull();
+ if (!isValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+
+ //
+ var identifier = GetProvidedID(providedForId);
+ var result = TagProvider.Repository
+ .AsQueryable()
+ .Where(t => t.References.Contains(identifier))
+ .Count();
+
+ //
+ return await Task.FromResult(result);
+ }
+
///
/// Retrieve References of Specific Provided ID as Query ...
///
@@ -232,7 +250,6 @@ namespace xTagService.Providers
public async Task AddReference(
XTagDto model,
TKey providedForId,
- int forIndex = 0,
string connectionId = null
)
{
@@ -263,34 +280,32 @@ namespace xTagService.Providers
model = await TagProvider.Get(model.Id);
//
- var lastIndex = GetLastIndex(providedForId);
- if (lastIndex == -1)
- {
- //
- // This Means there isnot any Reference ...
- forIndex = 0;
- model.References.Add(new XReference
- {
- Index = forIndex,
- ProvidedFor = Provider,
- ReferencedTo = $"{providedForId}"
- });
- }
- else
- {
- //
- forIndex = lastIndex + 1;
+ // Retrieve all References ...
+ var references = await GetAllReferences(providedForId);
- //
- // Add New Reference ...
- model.References.Add(new XReference
- {
- Index = forIndex,
- ProvidedFor = Provider,
- ReferencedTo = $"{providedForId}"
- });
+ //
+ // Check isReferenced or not ...
+ result = references.Any(r => r.Id == model.Id &&
+ r.References.Any(rf => rf.ProvidedFor == Provider &&
+ rf.ReferencedTo == $"{providedForId}"));
+ if (result)
+ {
+ return result;
}
+ //
+ // Here means there is not any reference to ProvidedForId ...
+ int forIndex = await CountReferences(providedForId);
+
+ //
+ // Add Reference to Model ...
+ model.References.Add(new XReference
+ {
+ Index = forIndex,
+ ProvidedFor = Provider,
+ ReferencedTo = $"{providedForId}"
+ });
+
//
// Update Data Base ...
model = await TagProvider
@@ -321,15 +336,18 @@ namespace xTagService.Providers
//
// Validate ...
// Since other Validations Handled in Calling, we Ignore them here ...
- if (model.IsNull() ||
- reference.IsNullOrDefault() ||
- (!reference.ProvidedFor.IsNullOrEmpty() && reference.ProvidedFor != Provider))
+ var result =
+ !model.IsNull() &&
+ !reference.IsNullOrDefault() &&
+ reference.ProvidedFor == Provider &&
+ !reference.ReferencedTo.IsNull();
+ if (!result)
{
XException.InvalidArgs.Throw();
}
//
- var result = await AddReference(
+ result = await AddReference(
model: model,
connectionId: connectionId,
providedForId: reference.ReferencedTo
@@ -350,15 +368,16 @@ namespace xTagService.Providers
public async Task RemoveReference(
XTagDto model,
TKey providedForId,
- int? forIndex = null,
string connectionId = null
)
{
//
// Validate ...
- if (model.IsNull() ||
- providedForId.IsNull() ||
- !model.Id.IsValidIntId())
+ var result =
+ !providedForId.IsNull() &&
+ !model.IsNullOrDefault() &&
+ model.Id.IsValidIntId();
+ if (!result)
{
XException.InvalidArgs.Throw();
}
@@ -366,37 +385,95 @@ namespace xTagService.Providers
//
// Retrieve Model ...
model = await TagProvider.Get(model.Id);
- if (model.IsNullOrDefault())
+ result = !model.IsNullOrDefault();
+ if (!result)
{
XException.NotFound.Throw();
}
//
// Check Model Reference to ID ...
- var isReferenced = model.References
- .Any(r => r.ProvidedFor == Provider &&
- r.ReferencedTo == $"{providedForId}" &&
- (!forIndex.HasValue || r.Index == forIndex.Value));
-
- //
- var result = false;
- if (isReferenced)
+ var referencesCount = await CountReferences(providedForId);
+ result = referencesCount == 0;
+ if (result)
{
//
- model.References = model.References
- .Where(r => r.ProvidedFor != Provider ||
- (r.ProvidedFor == Provider &&
- r.ReferencedTo != $"{providedForId}" &&
- (!forIndex.HasValue || r.Index == forIndex.Value)))
- .ToList();
+ // There is not any Reference to Remove ...
+ return result;
+ }
+ //
+ // Check Model is Trully Referenced to ProvidedForId or not ...
+ var reference = model.References
+ .FirstOrDefault(r => r.ProvidedFor == Provider &&
+ r.ReferencedTo == $"{providedForId}");
+ result = !model.IsNullOrDefault();
+ if (!result)
+ {
+ XException.ActionFailed.Throw();
+ }
+
+ //
+ // Remove Referenced Item from Model ...
+ model.References = model.References
+ .Where(r => !(r.ProvidedFor == Provider &&
+ r.ReferencedTo == $"{providedForId}"))
+ .ToList();
+
+ //
+ // Update DataBase ...
+ model = await TagProvider.Update(
+ id: model.Id,
+ model: model,
+ connectionId: connectionId
+ );
+
+ //
+ result = !model.IsNullOrDefault();
+ if (!result)
+ {
+ XException.ActionFailed.Throw();
+ }
+
+ //
+ // Here We Have to Re Arrange Indexed ...
+ if (reference.Index < referencesCount - 1)
+ {
//
- model = await TagProvider.Update(
- id: model.Id,
- model: model,
- connectionId: connectionId
- );
- result = !model.IsNullOrDefault();
+ var startIndex = reference.Index + 1;
+ for (int i = startIndex; i < referencesCount; i++)
+ {
+ //
+ var dto = await GetReference(
+ forIndex: i,
+ providedForId: providedForId
+ );
+ if (!dto.IsNullOrDefault())
+ {
+ //
+ dto.References
+ .ToList()
+ .ForEach(iref =>
+ {
+ //
+ if (
+ iref.Index == i &&
+ iref.ProvidedFor == Provider &&
+ iref.ReferencedTo == reference.ReferencedTo
+ )
+ {
+ iref.Index = i - 1;
+ }
+ });
+
+ //
+ dto = await TagProvider.Update(
+ id: dto.Id,
+ model: dto,
+ connectionId: connectionId
+ );
+ }
+ }
}
//
@@ -428,7 +505,6 @@ namespace xTagService.Providers
//
var result = await RemoveReference(
model: model,
- forIndex: reference.Index,
connectionId: connectionId,
providedForId: reference.ReferencedTo
);
@@ -501,7 +577,6 @@ namespace xTagService.Providers
public async Task AddReference(
string tag,
TKey providedForId,
- int forIndex = 0,
string connectionId = null
)
{
@@ -549,7 +624,6 @@ namespace xTagService.Providers
//
result = await AddReference(
model: dto,
- forIndex: forIndex,
connectionId: connectionId,
providedForId: providedForId
);
@@ -576,33 +650,21 @@ namespace xTagService.Providers
//
// Validate ...
- result = !tag.IsNullOrEmpty();
+ result =
+ !tag.IsNullOrEmpty() &&
+ !reference.IsNullOrDefault() &&
+ reference.ProvidedFor == Provider &&
+ !reference.ReferencedTo.IsNull();
if (!result)
{
XException.InvalidArgs.Throw();
}
- //
- // Check Tag Exists ...
- result = IsExists(tag);
- if (!result)
- {
- XException.NotFound.Throw();
- }
-
- //
- var dto = GetTagByTag(tag);
- result = !dto.IsNullOrDefault();
- if (!result)
- {
- XException.ActionFailed.Throw();
- }
-
//
result = await AddReference(
- model: dto,
- reference: reference,
- connectionId: connectionId
+ tag: tag,
+ connectionId: connectionId,
+ providedForId: reference.ReferencedTo
);
//
@@ -620,7 +682,6 @@ namespace xTagService.Providers
public async Task RemoveReference(
string tag,
TKey providedForId,
- int? forIndex = null,
string connectionId = null
)
{
@@ -629,7 +690,9 @@ namespace xTagService.Providers
//
// Validate ...
- result = !tag.IsNullOrEmpty();
+ result =
+ !tag.IsNullOrEmpty() &&
+ !providedForId.IsNull();
if (!result)
{
XException.InvalidArgs.Throw();
@@ -680,33 +743,21 @@ namespace xTagService.Providers
//
// Validate ...
- result = !tag.IsNullOrEmpty();
+ result =
+ !tag.IsNullOrEmpty() &&
+ !reference.IsNullOrDefault() &&
+ !reference.ReferencedTo.IsNull() &&
+ reference.ProvidedFor == Provider;
if (!result)
{
XException.InvalidArgs.Throw();
}
- //
- // Check Tag Exists ...
- result = IsExists(tag);
- if (!result)
- {
- XException.NotFound.Throw();
- }
-
- //
- var dto = GetTagByTag(tag);
- result = !dto.IsNullOrDefault();
- if (!result)
- {
- XException.ActionFailed.Throw();
- }
-
//
result = await RemoveReference(
- model: dto,
- reference: reference,
- connectionId: connectionId
+ tag: tag,
+ connectionId: connectionId,
+ providedForId: reference.ReferencedTo
);
//
@@ -740,55 +791,7 @@ namespace xTagService.Providers
)
{
//
- var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{providedForId}";
-
- //
- return result;
- }
-
- private int GetLastIndex(TKey providedForId)
- {
- //
- var result = -1;
-
- //
- // Validate ...
- var isValid = !providedForId.IsNull();
- if (!isValid)
- {
- XException.InvalidArgs.Throw();
- }
-
- //
- var identifier = GetProvidedID(providedForId);
-
- //
- var all = TagProvider.Repository
- .AsQueryable()
- .Where(t => t.References
- .Contains(identifier))
- .Select(t => t.References)
- .AsEnumerable();
- if (all.IsNull() || !all.HasChild())
- {
- result = -1;
- }
- else
- {
- //
- var references = all
- .SelectMany(a => a.ParseXReferenceList())
- .OrderByDescending(r => r.Index)
- .ToList();
- if (!references.IsNull() && references.HasChild())
- {
- result = references[0].Index;
- }
- else
- {
- result = -1;
- }
- }
+ var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{forIndex}";
//
return result;