221 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Linq.Expressions;
 | |
| 
 | |
| using Microsoft.Extensions.Logging;
 | |
| 
 | |
| using MongoDB.Bson.Serialization;
 | |
| using MongoDB.Driver;
 | |
| 
 | |
| using DomainResults.Common;
 | |
| 
 | |
| using Core.Abstractions.DomainObjects;
 | |
| 
 | |
| namespace DataProviders.Abstractions {
 | |
| 
 | |
|   /// <summary>
 | |
|   /// 
 | |
|   /// </summary>
 | |
|   /// <typeparam name="T"></typeparam>
 | |
|   public abstract class CollectionDataProviderBase<T> : DataProviderBase<CollectionDataProviderBase<T>> where T : DomainObjectDocumentBase<T> {
 | |
| 
 | |
|     private protected readonly IIdGenerator _idGenerator;
 | |
|     private protected readonly ISessionService _sessionService;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Main constructor
 | |
|     /// </summary>
 | |
|     /// <param name="logger"></param>
 | |
|     /// <param name="client"></param>
 | |
|     /// <param name="idGenerator"></param>
 | |
|     /// <param name="dataProviderUtils"></param>
 | |
|     public CollectionDataProviderBase(
 | |
|       ILogger<CollectionDataProviderBase<T>> logger,
 | |
|       IMongoClient client,
 | |
|       IIdGenerator idGenerator,
 | |
|       ISessionService sessionService
 | |
|     ) : base (logger, client){
 | |
|       _idGenerator = idGenerator;
 | |
|       _sessionService = sessionService;
 | |
|     }
 | |
| 
 | |
|     #region Insert
 | |
|     private protected (Guid?, IDomainResult) Insert(T obj, string collectionName) =>
 | |
|       InsertAsync(obj, collectionName).Result;
 | |
| 
 | |
|     private protected (Guid?, IDomainResult) Insert(T obj, string collectionName, Guid sessionId) =>
 | |
|       InsertAsync(obj, collectionName, sessionId).Result;
 | |
| 
 | |
|     private protected Task<(Guid?, IDomainResult)> InsertAsync(T obj, string collectionName) =>
 | |
|       InsertAsyncCore(obj, collectionName, null);
 | |
| 
 | |
|     private protected Task<(Guid?, IDomainResult)> InsertAsync(T obj, string collectionName, Guid sessionId) =>
 | |
|       InsertAsyncCore(obj, collectionName, sessionId);
 | |
|     #endregion
 | |
| 
 | |
|     #region InsertMany
 | |
|     private protected (List<Guid>?, IDomainResult) InsertMany(List<T> objList, string collectionName) =>
 | |
|       InsertManyAsync(objList, collectionName).Result;
 | |
| 
 | |
|     private protected (List<Guid>?, IDomainResult) InsertMany(List<T> objList, string collectionName, Guid sessionId) =>
 | |
|       InsertManyAsync(objList, collectionName, sessionId).Result;
 | |
| 
 | |
|     private protected Task<(List<Guid>?, IDomainResult)> InsertManyAsync(List<T> objList, string collectionName) =>
 | |
|       InsertManyAsyncCore(objList, collectionName, null);
 | |
| 
 | |
|     private protected Task<(List<Guid>?, IDomainResult)> InsertManyAsync(List<T> objList, string collectionName, Guid sessionId) =>
 | |
|       InsertManyAsyncCore(objList, collectionName, sessionId);
 | |
|     #endregion
 | |
| 
 | |
|     #region Get
 | |
|     private protected (List<T>?, IDomainResult) GetWithPredicate(Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       GetWithPredicateCore(predicate, 0, 0, collectionName);
 | |
|     private protected (List<T>?, IDomainResult) GetWithPredicate(Expression<Func<T, bool>> predicate, int skip, int limit, string collectionName) =>
 | |
|       GetWithPredicateCore(predicate, skip, limit, collectionName);
 | |
|     #endregion
 | |
| 
 | |
|     #region Update
 | |
|     private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       UpdateWithPredicateAsync(obj, predicate, collectionName).Result;
 | |
| 
 | |
|     private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       UpdateWithPredicateAsync(obj, predicate, collectionName, sessionId).Result;
 | |
| 
 | |
|     private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       UpdateWithPredicateAsyncCore(obj, predicate, collectionName, null);
 | |
| 
 | |
|     private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       UpdateWithPredicateAsyncCore(obj, predicate, collectionName, sessionId);
 | |
|     #endregion
 | |
| 
 | |
|     #region Delete
 | |
|     private protected IDomainResult DeleteWithPredicate(Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       DeleteWithPredicateAsync(predicate, collectionName).Result;
 | |
| 
 | |
|     private protected IDomainResult DeleteWithPredicate(Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       DeleteWithPredicateAsync(predicate, collectionName, sessionId).Result;
 | |
| 
 | |
|     private protected Task<IDomainResult> DeleteWithPredicateAsync(Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       DeleteWithPredicateAsyncCore(predicate, collectionName, null);
 | |
| 
 | |
|     private protected Task<IDomainResult> DeleteWithPredicateAsync(Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       DeleteWithPredicateAsyncCore(predicate, collectionName, sessionId);
 | |
|     #endregion
 | |
| 
 | |
|     #region DeleteMany
 | |
|     private protected IDomainResult DeleteManyWithPredicate(Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       DeleteManyWithPredicateAsync(predicate, collectionName).Result;
 | |
| 
 | |
|     private protected IDomainResult DeleteManyWithPredicate(Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       DeleteManyWithPredicateAsync(predicate, collectionName, sessionId).Result;
 | |
| 
 | |
|     private protected Task<IDomainResult> DeleteManyWithPredicateAsync(Expression<Func<T, bool>> predicate, string collectionName) =>
 | |
|       DeleteManyWithPredicateAsyncCore(predicate, collectionName, null);
 | |
| 
 | |
|     private protected Task<IDomainResult> DeleteManyWithPredicateAsync(Expression<Func<T, bool>> predicate, string collectionName, Guid sessionId) =>
 | |
|       DeleteManyWithPredicateAsyncCore(predicate, collectionName, sessionId);
 | |
|     #endregion
 | |
| 
 | |
|     #region Core methods
 | |
|     private async protected Task<(Guid?, IDomainResult)> InsertAsyncCore(T obj, string collectionName, Guid? sessionId) {
 | |
|       try {
 | |
|         var collection = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName);
 | |
| 
 | |
|         if (sessionId != null)
 | |
|           await collection.InsertOneAsync(_sessionService.GetSession(sessionId.Value), obj);
 | |
|         else
 | |
|           collection.InsertOne(obj);
 | |
| 
 | |
|         return IDomainResult.Success(obj.Id);
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed<Guid?>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private async Task<(List<Guid>?, IDomainResult)> InsertManyAsyncCore(List<T> objList, string collectionName, Guid? sessionId) {
 | |
|       try {
 | |
|         var collection = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName);
 | |
| 
 | |
|         if (sessionId != null)
 | |
|           await collection.InsertManyAsync(_sessionService.GetSession(sessionId.Value), objList);
 | |
|         else
 | |
|           collection.InsertMany(objList);
 | |
| 
 | |
|         return IDomainResult.Success(objList.Select(x => x.Id).ToList());
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed<List<Guid>?>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private (List<T>?, IDomainResult) GetWithPredicateCore(Expression<Func<T, bool>> predicate, int skip, int limit, string collectionName) {
 | |
|       try {
 | |
|         var result = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName)
 | |
|            .Find(predicate).Skip(skip).Limit(limit).ToList();
 | |
| 
 | |
|         return result != null && result.Count > 0
 | |
|           ? IDomainResult.Success(result)
 | |
|           : IDomainResult.NotFound<List<T>?>();
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed<List<T>?>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private async Task<(Guid?, IDomainResult)> UpdateWithPredicateAsyncCore(T obj, Expression<Func<T, bool>> predicate, string collectionName, Guid? sessionId) {
 | |
|       try {
 | |
|        
 | |
|         var collection = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName);
 | |
| 
 | |
|         if (sessionId != null)
 | |
|           await collection.ReplaceOneAsync(_sessionService.GetSession(sessionId.Value), predicate, obj);
 | |
|         else
 | |
|           await collection.ReplaceOneAsync(predicate, obj);
 | |
| 
 | |
|         return IDomainResult.Success(obj.Id);
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed<Guid?>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private async Task<IDomainResult> DeleteWithPredicateAsyncCore(Expression<Func<T, bool>> predicate, string collectionName, Guid? sessionId) {
 | |
|       try {
 | |
|         var collection = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName);
 | |
| 
 | |
|         if (sessionId != null)
 | |
|           await collection.DeleteOneAsync<T>(_sessionService.GetSession(sessionId.Value), predicate);
 | |
|         else
 | |
|           await collection.DeleteOneAsync<T>(predicate);
 | |
| 
 | |
|         return IDomainResult.Success();
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private async Task<IDomainResult> DeleteManyWithPredicateAsyncCore(Expression<Func<T, bool>> predicate, string collectionName, Guid? sessionId) {
 | |
|       try {
 | |
|         var collection = _client.GetDatabase(_databaseName).GetCollection<T>(collectionName);
 | |
| 
 | |
|         if (sessionId != null)
 | |
|           await collection.DeleteManyAsync(_sessionService.GetSession(sessionId.Value), predicate);
 | |
|         else
 | |
|           await collection.DeleteManyAsync(predicate);
 | |
| 
 | |
|         return IDomainResult.Success();
 | |
|       }
 | |
|       catch (Exception ex) {
 | |
|         _logger.LogError(ex, "Data provider error");
 | |
|         return IDomainResult.Failed();
 | |
|       }
 | |
|     }
 | |
|     #endregion
 | |
|   }
 | |
| }
 |