From 1ea040770eafcedeb0492d53325d32ceaafd27ad Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 19 Dec 2025 04:02:01 +0330 Subject: [PATCH] last ... --- Interfaces/IXBaseTagProvider.cs | 6 +- Providers/XBaseTagProvider.cs | 321 ++++++++++++++++---------------- 2 files changed, 163 insertions(+), 164 deletions(-) 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;