22using  System . Net ; 
33using  System . Runtime . CompilerServices ; 
44using  JetBrains . Annotations ; 
5+ using  JsonApiDotNetCore . AtomicOperations ; 
56using  JsonApiDotNetCore . Configuration ; 
67using  JsonApiDotNetCore . Diagnostics ; 
78using  JsonApiDotNetCore . Errors ; 
@@ -30,11 +31,12 @@ public class JsonApiResourceService<TResource, TId> : IResourceService<TResource
3031    private  readonly  TraceLogWriter < JsonApiResourceService < TResource ,  TId > >  _traceWriter ; 
3132    private  readonly  IJsonApiRequest  _request ; 
3233    private  readonly  IResourceChangeTracker < TResource >  _resourceChangeTracker ; 
34+     private  readonly  IVersionTracker  _versionTracker ; 
3335    private  readonly  IResourceDefinitionAccessor  _resourceDefinitionAccessor ; 
3436
3537    public  JsonApiResourceService ( IResourceRepositoryAccessor  repositoryAccessor ,  IQueryLayerComposer  queryLayerComposer ,  IPaginationContext  paginationContext , 
3638        IJsonApiOptions  options ,  ILoggerFactory  loggerFactory ,  IJsonApiRequest  request ,  IResourceChangeTracker < TResource >  resourceChangeTracker , 
37-         IResourceDefinitionAccessor  resourceDefinitionAccessor ) 
39+         IVersionTracker   versionTracker ,   IResourceDefinitionAccessor  resourceDefinitionAccessor ) 
3840    { 
3941        ArgumentGuard . NotNull ( repositoryAccessor ,  nameof ( repositoryAccessor ) ) ; 
4042        ArgumentGuard . NotNull ( queryLayerComposer ,  nameof ( queryLayerComposer ) ) ; 
@@ -43,6 +45,7 @@ public JsonApiResourceService(IResourceRepositoryAccessor repositoryAccessor, IQ
4345        ArgumentGuard . NotNull ( loggerFactory ,  nameof ( loggerFactory ) ) ; 
4446        ArgumentGuard . NotNull ( request ,  nameof ( request ) ) ; 
4547        ArgumentGuard . NotNull ( resourceChangeTracker ,  nameof ( resourceChangeTracker ) ) ; 
48+         ArgumentGuard . NotNull ( versionTracker ,  nameof ( versionTracker ) ) ; 
4649        ArgumentGuard . NotNull ( resourceDefinitionAccessor ,  nameof ( resourceDefinitionAccessor ) ) ; 
4750
4851        _repositoryAccessor  =  repositoryAccessor ; 
@@ -51,6 +54,7 @@ public JsonApiResourceService(IResourceRepositoryAccessor repositoryAccessor, IQ
5154        _options  =  options ; 
5255        _request  =  request ; 
5356        _resourceChangeTracker  =  resourceChangeTracker ; 
57+         _versionTracker  =  versionTracker ; 
5458        _resourceDefinitionAccessor  =  resourceDefinitionAccessor ; 
5559        _traceWriter  =  new  TraceLogWriter < JsonApiResourceService < TResource ,  TId > > ( loggerFactory ) ; 
5660    } 
@@ -226,7 +230,8 @@ private async Task RetrieveResourceCountForNonPrimaryEndpointAsync(TId id, HasMa
226230            throw ; 
227231        } 
228232
229-         TResource  resourceFromDatabase  =  await  GetPrimaryResourceByIdAsync ( resourceForDatabase . Id ,  TopFieldSelection . WithAllAttributes ,  cancellationToken ) ; 
233+         TResource  resourceFromDatabase  = 
234+             await  GetPrimaryResourceAfterWriteAsync ( resourceForDatabase . Id ,  TopFieldSelection . WithAllAttributes ,  cancellationToken ) ; 
230235
231236        _resourceChangeTracker . SetFinallyStoredAttributeValues ( resourceFromDatabase ) ; 
232237
@@ -477,7 +482,7 @@ private async Task<TResource> GetForHasManyUpdateAsync(HasManyAttribute hasManyR
477482            throw ; 
478483        } 
479484
480-         TResource  afterResourceFromDatabase  =  await  GetPrimaryResourceByIdAsync ( id ,  TopFieldSelection . WithAllAttributes ,  cancellationToken ) ; 
485+         TResource  afterResourceFromDatabase  =  await  GetPrimaryResourceAfterWriteAsync ( id ,  TopFieldSelection . WithAllAttributes ,  cancellationToken ) ; 
481486
482487        _resourceChangeTracker . SetFinallyStoredAttributeValues ( afterResourceFromDatabase ) ; 
483488
@@ -522,6 +527,11 @@ public virtual async Task SetRelationshipAsync(TId leftId, string relationshipNa
522527            AssertIsNotResourceVersionMismatch ( exception ) ; 
523528            throw ; 
524529        } 
530+ 
531+         if  ( _versionTracker . RequiresVersionTracking ( ) ) 
532+         { 
533+             await  GetPrimaryResourceAfterWriteAsync ( leftId ,  TopFieldSelection . OnlyIdAttribute ,  cancellationToken ) ; 
534+         } 
525535    } 
526536
527537    /// <inheritdoc /> 
@@ -614,6 +624,24 @@ protected async Task<TResource> GetPrimaryResourceByIdAsync(TId id, TopFieldSele
614624        return  primaryResources . SingleOrDefault ( ) ; 
615625    } 
616626
627+     private  async  Task < TResource >  GetPrimaryResourceAfterWriteAsync ( TId  id ,  TopFieldSelection  fieldSelection ,  CancellationToken  cancellationToken ) 
628+     { 
629+         AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ; 
630+ 
631+         if  ( _versionTracker . RequiresVersionTracking ( ) ) 
632+         { 
633+             QueryLayer  queryLayer  =  _queryLayerComposer . ComposeForGetVersionsAfterWrite ( id ,  _request . PrimaryResourceType ,  fieldSelection ) ; 
634+             IReadOnlyCollection < TResource >  primaryResources  =  await  _repositoryAccessor . GetAsync < TResource > ( queryLayer ,  cancellationToken ) ; 
635+             TResource ?  primaryResource  =  primaryResources . SingleOrDefault ( ) ; 
636+             AssertPrimaryResourceExists ( primaryResource ) ; 
637+ 
638+             _versionTracker . CaptureVersions ( _request . PrimaryResourceType ,  primaryResource ) ; 
639+             return  primaryResource ; 
640+         } 
641+ 
642+         return  await  GetPrimaryResourceByIdAsync ( id ,  fieldSelection ,  cancellationToken ) ; 
643+     } 
644+ 
617645    protected  async  Task < TResource >  GetPrimaryResourceForUpdateAsync ( TId  id ,  CancellationToken  cancellationToken ) 
618646    { 
619647        AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ; 
0 commit comments