V10: fix build warnings infrastructure (#12369)
* Run code cleanup * Run dotnet format * Start manual fixes * Manual fixing of warnings * Fix nullability in columnalias * Fix tests * Fix up after merge * Start updating after review * Update editorconfig to contain new static & const rules * Fix up editorconfig to not contain duplicate rules * Fix up static member names * Fix up according to review * Update src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.DistributedCache.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ContentIndexPopulator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ContentIndexPopulator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ContentValueSetValidator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ContentValueSetValidator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ContentValueSetValidator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/ExamineUmbracoIndexingHandler.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Examine/PublishedContentIndexPopulator.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Extensions/InstanceIdentifiableExtensions.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Macros/MacroTagParser.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Macros/MacroTagParser.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Macros/MacroTagParser.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Migrations/Expressions/Alter/Table/IAlterTableColumnOptionBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_0_0/AddMemberPropertiesAsColumns.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/ModelsBuilder/Building/TextBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Dtos/ExternalLoginDto.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/AccessMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/AuditEntryMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/MediaMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/MemberMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/PropertyGroupMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/PropertyTypeMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Mappers/RelationTypeMapper.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/NPocoMapperCollectionBuilder.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Querying/ExpressionVisitorBase.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Update src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ExternalLoginRepository.cs Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Fix [..] to substring * Fix after merge with 10/dev * Fox ContentValueSetValidator.cs * Update LoggerConfigExtensions Co-authored-by: Nikolaj Geisle <niko737@edu.ucl.dk> Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NPoco;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -15,383 +12,358 @@ using Umbraco.Cms.Infrastructure.Persistence.Querying;
|
||||
using Umbraco.Cms.Infrastructure.Scoping;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a repository for doing CRUD operations for <see cref="DictionaryItem"/>
|
||||
/// </summary>
|
||||
internal class DictionaryRepository : EntityRepositoryBase<int, IDictionaryItem>, IDictionaryRepository
|
||||
{
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
|
||||
|
||||
public DictionaryRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger<DictionaryRepository> logger, ILoggerFactory loggerFactory)
|
||||
: base(scopeAccessor, cache, logger)
|
||||
/// <summary>
|
||||
/// Represents a repository for doing CRUD operations for <see cref="DictionaryItem" />
|
||||
/// </summary>
|
||||
internal class DictionaryRepository : EntityRepositoryBase<int, IDictionaryItem>, IDictionaryRepository
|
||||
{
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
public DictionaryRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger<DictionaryRepository> logger,
|
||||
ILoggerFactory loggerFactory)
|
||||
: base(scopeAccessor, cache, logger) =>
|
||||
_loggerFactory = loggerFactory;
|
||||
|
||||
public IDictionaryItem? Get(Guid uniqueId)
|
||||
{
|
||||
var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, ScopeAccessor, AppCaches,
|
||||
_loggerFactory.CreateLogger<DictionaryByUniqueIdRepository>());
|
||||
return uniqueIdRepo.Get(uniqueId);
|
||||
}
|
||||
|
||||
public IDictionaryItem? Get(string key)
|
||||
{
|
||||
var keyRepo = new DictionaryByKeyRepository(this, ScopeAccessor, AppCaches,
|
||||
_loggerFactory.CreateLogger<DictionaryByKeyRepository>());
|
||||
return keyRepo.Get(key);
|
||||
}
|
||||
|
||||
public Dictionary<string, Guid> GetDictionaryItemKeyMap()
|
||||
{
|
||||
var columns = new[] { "key", "id" }.Select(x => (object)SqlSyntax.GetQuotedColumnName(x)).ToArray();
|
||||
Sql<ISqlContext> sql = Sql().Select(columns).From<DictionaryDto>();
|
||||
return Database.Fetch<DictionaryItemKeyIdDto>(sql).ToDictionary(x => x.Key, x => x.Id);
|
||||
}
|
||||
|
||||
public IEnumerable<IDictionaryItem> GetDictionaryItemDescendants(Guid? parentId)
|
||||
{
|
||||
// This methods will look up children at each level, since we do not store a path for dictionary (ATM), we need to do a recursive
|
||||
// lookup to get descendants. Currently this is the most efficient way to do it
|
||||
Func<Guid[], IEnumerable<IEnumerable<IDictionaryItem>>> getItemsFromParents = guids =>
|
||||
{
|
||||
_loggerFactory = loggerFactory;
|
||||
return guids.InGroupsOf(Constants.Sql.MaxParameterCount)
|
||||
.Select(group =>
|
||||
{
|
||||
Sql<ISqlContext> sqlClause = GetBaseQuery(false)
|
||||
.Where<DictionaryDto>(x => x.Parent != null)
|
||||
.WhereIn<DictionaryDto>(x => x.Parent, group);
|
||||
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, Query<IDictionaryItem>());
|
||||
Sql<ISqlContext> sql = translator.Translate();
|
||||
sql.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
});
|
||||
};
|
||||
|
||||
IEnumerable<IEnumerable<IDictionaryItem>> childItems = parentId.HasValue == false
|
||||
? new[] { GetRootDictionaryItems() }
|
||||
: getItemsFromParents(new[] { parentId.Value });
|
||||
|
||||
return childItems.SelectRecursive(items => getItemsFromParents(items.Select(x => x.Key).ToArray()))
|
||||
.SelectMany(items => items);
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, int> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
// allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true,
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, int>(GlobalIsolatedCache, ScopeAccessor,
|
||||
options);
|
||||
}
|
||||
|
||||
protected IDictionaryItem ConvertFromDto(DictionaryDto dto)
|
||||
{
|
||||
IDictionaryItem entity = DictionaryItemFactory.BuildEntity(dto);
|
||||
|
||||
entity.Translations = dto.LanguageTextDtos.EmptyNull()
|
||||
.Where(x => x.LanguageId > 0)
|
||||
.Select(x => DictionaryTranslationFactory.BuildEntity(x, dto.UniqueId))
|
||||
.ToList();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,DictionaryItem>
|
||||
|
||||
protected override IDictionaryItem? PerformGet(int id)
|
||||
{
|
||||
Sql<ISqlContext> sql = GetBaseQuery(false)
|
||||
.Where(GetBaseWhereClause(), new { id })
|
||||
.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
DictionaryDto? dto = Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, int> CreateCachePolicy()
|
||||
IDictionaryItem entity = ConvertFromDto(dto);
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
((EntityBase)entity).ResetDirtyProperties(false);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private IEnumerable<IDictionaryItem> GetRootDictionaryItems()
|
||||
{
|
||||
IQuery<IDictionaryItem> query = Query<IDictionaryItem>().Where(x => x.ParentId == null);
|
||||
return Get(query);
|
||||
}
|
||||
|
||||
private class DictionaryItemKeyIdDto
|
||||
{
|
||||
public string Key { get; } = null!;
|
||||
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
private class DictionaryByUniqueIdRepository : SimpleGetRepository<Guid, IDictionaryItem, DictionaryDto>
|
||||
{
|
||||
private readonly DictionaryRepository _dictionaryRepository;
|
||||
|
||||
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IScopeAccessor scopeAccessor,
|
||||
AppCaches cache, ILogger<DictionaryByUniqueIdRepository> logger)
|
||||
: base(scopeAccessor, cache, logger) =>
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
|
||||
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql) =>
|
||||
Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql);
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount) => _dictionaryRepository.GetBaseQuery(isCount);
|
||||
|
||||
protected override string GetBaseWhereClause() =>
|
||||
"cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " = @id";
|
||||
|
||||
protected override IDictionaryItem ConvertToEntity(DictionaryDto dto) =>
|
||||
_dictionaryRepository.ConvertFromDto(dto);
|
||||
|
||||
protected override object GetBaseWhereClauseArguments(Guid id) => new { id };
|
||||
|
||||
protected override string GetWhereInClauseForGetAll() =>
|
||||
"cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " in (@ids)";
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, Guid> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
//allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true
|
||||
// allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true,
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, int>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, Guid>(GlobalIsolatedCache, ScopeAccessor,
|
||||
options);
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,DictionaryItem>
|
||||
private class DictionaryByKeyRepository : SimpleGetRepository<string, IDictionaryItem, DictionaryDto>
|
||||
{
|
||||
private readonly DictionaryRepository _dictionaryRepository;
|
||||
|
||||
protected override IDictionaryItem? PerformGet(int id)
|
||||
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IScopeAccessor scopeAccessor,
|
||||
AppCaches cache, ILogger<DictionaryByKeyRepository> logger)
|
||||
: base(scopeAccessor, cache, logger) =>
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
|
||||
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql) =>
|
||||
Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql);
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount) => _dictionaryRepository.GetBaseQuery(isCount);
|
||||
|
||||
protected override string GetBaseWhereClause() =>
|
||||
"cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " = @id";
|
||||
|
||||
protected override IDictionaryItem ConvertToEntity(DictionaryDto dto) =>
|
||||
_dictionaryRepository.ConvertFromDto(dto);
|
||||
|
||||
protected override object GetBaseWhereClauseArguments(string? id) => new { id };
|
||||
|
||||
protected override string GetWhereInClauseForGetAll() =>
|
||||
"cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " in (@ids)";
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, string> CreateCachePolicy()
|
||||
{
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where(GetBaseWhereClause(), new { id = id })
|
||||
.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
var dto = Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dto == null)
|
||||
return null;
|
||||
|
||||
var entity = ConvertFromDto(dto);
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
((EntityBase)entity).ResetDirtyProperties(false);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IDictionaryItem> PerformGetAll(params int[]? ids)
|
||||
{
|
||||
var sql = GetBaseQuery(false).Where<DictionaryDto>(x => x.PrimaryKey > 0);
|
||||
if (ids?.Any() ?? false)
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
sql.WhereIn<DictionaryDto>(x => x.PrimaryKey, ids);
|
||||
}
|
||||
// allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true,
|
||||
};
|
||||
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, string>(GlobalIsolatedCache, ScopeAccessor,
|
||||
options);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IDictionaryItem> PerformGetAll(params int[]? ids)
|
||||
{
|
||||
Sql<ISqlContext> sql = GetBaseQuery(false).Where<DictionaryDto>(x => x.PrimaryKey > 0);
|
||||
if (ids?.Any() ?? false)
|
||||
{
|
||||
sql.WhereIn<DictionaryDto>(x => x.PrimaryKey, ids);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IDictionaryItem> PerformGetByQuery(IQuery<IDictionaryItem> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
sql.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
}
|
||||
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
protected override IEnumerable<IDictionaryItem> PerformGetByQuery(IQuery<IDictionaryItem> query)
|
||||
{
|
||||
Sql<ISqlContext> sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, query);
|
||||
Sql<ISqlContext> sql = translator.Translate();
|
||||
sql.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides of EntityRepositoryBase<int,DictionaryItem>
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
{
|
||||
Sql<ISqlContext> sql = Sql();
|
||||
if (isCount)
|
||||
{
|
||||
sql.SelectCount()
|
||||
.From<DictionaryDto>();
|
||||
}
|
||||
else
|
||||
{
|
||||
sql.SelectAll()
|
||||
.From<DictionaryDto>()
|
||||
.LeftJoin<LanguageTextDto>()
|
||||
.On<DictionaryDto, LanguageTextDto>(left => left.UniqueId, right => right.UniqueId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
return sql;
|
||||
}
|
||||
|
||||
#region Overrides of EntityRepositoryBase<int,DictionaryItem>
|
||||
protected override string GetBaseWhereClause() => $"{Constants.DatabaseSchema.Tables.DictionaryEntry}.pk = @id";
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
protected override IEnumerable<string> GetDeleteClauses() => new List<string>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unit of Work Implementation
|
||||
|
||||
protected override void PersistNewItem(IDictionaryItem entity)
|
||||
{
|
||||
var dictionaryItem = (DictionaryItem)entity;
|
||||
|
||||
dictionaryItem.AddingEntity();
|
||||
|
||||
foreach (IDictionaryTranslation translation in dictionaryItem.Translations)
|
||||
{
|
||||
var sql = Sql();
|
||||
if (isCount)
|
||||
translation.Value = translation.Value.ToValidXmlString();
|
||||
}
|
||||
|
||||
DictionaryDto dto = DictionaryItemFactory.BuildDto(dictionaryItem);
|
||||
|
||||
var id = Convert.ToInt32(Database.Insert(dto));
|
||||
dictionaryItem.Id = id;
|
||||
|
||||
foreach (IDictionaryTranslation translation in dictionaryItem.Translations)
|
||||
{
|
||||
LanguageTextDto textDto = DictionaryTranslationFactory.BuildDto(translation, dictionaryItem.Key);
|
||||
translation.Id = Convert.ToInt32(Database.Insert(textDto));
|
||||
translation.Key = dictionaryItem.Key;
|
||||
}
|
||||
|
||||
dictionaryItem.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IDictionaryItem entity)
|
||||
{
|
||||
entity.UpdatingEntity();
|
||||
|
||||
foreach (IDictionaryTranslation translation in entity.Translations)
|
||||
{
|
||||
translation.Value = translation.Value.ToValidXmlString();
|
||||
}
|
||||
|
||||
DictionaryDto dto = DictionaryItemFactory.BuildDto(entity);
|
||||
|
||||
Database.Update(dto);
|
||||
|
||||
foreach (IDictionaryTranslation translation in entity.Translations)
|
||||
{
|
||||
LanguageTextDto textDto = DictionaryTranslationFactory.BuildDto(translation, entity.Key);
|
||||
if (translation.HasIdentity)
|
||||
{
|
||||
sql.SelectCount()
|
||||
.From<DictionaryDto>();
|
||||
Database.Update(textDto);
|
||||
}
|
||||
else
|
||||
{
|
||||
sql.SelectAll()
|
||||
.From<DictionaryDto>()
|
||||
.LeftJoin<LanguageTextDto>()
|
||||
.On<DictionaryDto, LanguageTextDto>(left => left.UniqueId, right => right.UniqueId);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return $"{Constants.DatabaseSchema.Tables.DictionaryEntry}.pk = @id";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unit of Work Implementation
|
||||
|
||||
protected override void PersistNewItem(IDictionaryItem entity)
|
||||
{
|
||||
var dictionaryItem = ((DictionaryItem) entity);
|
||||
|
||||
dictionaryItem.AddingEntity();
|
||||
|
||||
foreach (var translation in dictionaryItem.Translations)
|
||||
translation.Value = translation.Value.ToValidXmlString();
|
||||
|
||||
var dto = DictionaryItemFactory.BuildDto(dictionaryItem);
|
||||
|
||||
var id = Convert.ToInt32(Database.Insert(dto));
|
||||
dictionaryItem.Id = id;
|
||||
|
||||
foreach (var translation in dictionaryItem.Translations)
|
||||
{
|
||||
var textDto = DictionaryTranslationFactory.BuildDto(translation, dictionaryItem.Key);
|
||||
translation.Id = Convert.ToInt32(Database.Insert(textDto));
|
||||
translation.Key = dictionaryItem.Key;
|
||||
}
|
||||
|
||||
dictionaryItem.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IDictionaryItem entity)
|
||||
{
|
||||
entity.UpdatingEntity();
|
||||
|
||||
foreach (var translation in entity.Translations)
|
||||
translation.Value = translation.Value.ToValidXmlString();
|
||||
|
||||
var dto = DictionaryItemFactory.BuildDto(entity);
|
||||
|
||||
Database.Update(dto);
|
||||
|
||||
foreach (var translation in entity.Translations)
|
||||
{
|
||||
var textDto = DictionaryTranslationFactory.BuildDto(translation, entity.Key);
|
||||
if (translation.HasIdentity)
|
||||
{
|
||||
Database.Update(textDto);
|
||||
}
|
||||
else
|
||||
{
|
||||
translation.Id = Convert.ToInt32(Database.Insert(textDto));
|
||||
translation.Key = entity.Key;
|
||||
}
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(entity.Key));
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(IDictionaryItem entity)
|
||||
{
|
||||
RecursiveDelete(entity.Key);
|
||||
|
||||
Database.Delete<LanguageTextDto>("WHERE UniqueId = @Id", new { Id = entity.Key });
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = entity.Key });
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(entity.Key));
|
||||
|
||||
entity.DeleteDate = DateTime.Now;
|
||||
}
|
||||
|
||||
private void RecursiveDelete(Guid parentId)
|
||||
{
|
||||
var list = Database.Fetch<DictionaryDto>("WHERE parent = @ParentId", new { ParentId = parentId });
|
||||
foreach (var dto in list)
|
||||
{
|
||||
RecursiveDelete(dto.UniqueId);
|
||||
|
||||
Database.Delete<LanguageTextDto>("WHERE UniqueId = @Id", new { Id = dto.UniqueId });
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = dto.UniqueId });
|
||||
|
||||
//Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(dto.Key));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(dto.UniqueId));
|
||||
translation.Key = entity.Key;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
entity.ResetDirtyProperties();
|
||||
|
||||
protected IDictionaryItem ConvertFromDto(DictionaryDto dto)
|
||||
// Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(entity.Key));
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(IDictionaryItem entity)
|
||||
{
|
||||
RecursiveDelete(entity.Key);
|
||||
|
||||
Database.Delete<LanguageTextDto>("WHERE UniqueId = @Id", new { Id = entity.Key });
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = entity.Key });
|
||||
|
||||
// Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(entity.ItemKey));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(entity.Key));
|
||||
|
||||
entity.DeleteDate = DateTime.Now;
|
||||
}
|
||||
|
||||
private void RecursiveDelete(Guid parentId)
|
||||
{
|
||||
List<DictionaryDto>? list =
|
||||
Database.Fetch<DictionaryDto>("WHERE parent = @ParentId", new { ParentId = parentId });
|
||||
foreach (DictionaryDto? dto in list)
|
||||
{
|
||||
var entity = DictionaryItemFactory.BuildEntity(dto);
|
||||
RecursiveDelete(dto.UniqueId);
|
||||
|
||||
entity.Translations = dto.LanguageTextDtos.EmptyNull()
|
||||
.Where(x => x.LanguageId > 0)
|
||||
.Select(x => DictionaryTranslationFactory.BuildEntity(x, dto.UniqueId))
|
||||
.ToList();
|
||||
Database.Delete<LanguageTextDto>("WHERE UniqueId = @Id", new { Id = dto.UniqueId });
|
||||
Database.Delete<DictionaryDto>("WHERE id = @Id", new { Id = dto.UniqueId });
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public IDictionaryItem? Get(Guid uniqueId)
|
||||
{
|
||||
var uniqueIdRepo = new DictionaryByUniqueIdRepository(this, ScopeAccessor, AppCaches, _loggerFactory.CreateLogger<DictionaryByUniqueIdRepository>());
|
||||
return uniqueIdRepo.Get(uniqueId);
|
||||
}
|
||||
|
||||
public IDictionaryItem? Get(string key)
|
||||
{
|
||||
var keyRepo = new DictionaryByKeyRepository(this, ScopeAccessor, AppCaches, _loggerFactory.CreateLogger<DictionaryByKeyRepository>());
|
||||
return keyRepo.Get(key);
|
||||
}
|
||||
|
||||
private IEnumerable<IDictionaryItem>? GetRootDictionaryItems()
|
||||
{
|
||||
var query = Query<IDictionaryItem>().Where(x => x.ParentId == null);
|
||||
return Get(query);
|
||||
}
|
||||
|
||||
public Dictionary<string, Guid> GetDictionaryItemKeyMap()
|
||||
{
|
||||
var columns = new[] { "key", "id" }.Select(x => (object) SqlSyntax.GetQuotedColumnName(x)).ToArray();
|
||||
var sql = Sql().Select(columns).From<DictionaryDto>();
|
||||
return Database.Fetch<DictionaryItemKeyIdDto>(sql).ToDictionary(x => x.Key, x => x.Id);
|
||||
}
|
||||
|
||||
private class DictionaryItemKeyIdDto
|
||||
{
|
||||
public string Key { get; set; } = null!;
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
public IEnumerable<IDictionaryItem> GetDictionaryItemDescendants(Guid? parentId)
|
||||
{
|
||||
//This methods will look up children at each level, since we do not store a path for dictionary (ATM), we need to do a recursive
|
||||
// lookup to get descendants. Currently this is the most efficient way to do it
|
||||
|
||||
Func<Guid[], IEnumerable<IEnumerable<IDictionaryItem>>> getItemsFromParents = guids =>
|
||||
{
|
||||
return guids.InGroupsOf(Constants.Sql.MaxParameterCount)
|
||||
.Select(group =>
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false)
|
||||
.Where<DictionaryDto>(x => x.Parent != null)
|
||||
.WhereIn<DictionaryDto>(x => x.Parent, group);
|
||||
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, Query<IDictionaryItem>());
|
||||
var sql = translator.Translate();
|
||||
sql.OrderBy<DictionaryDto>(x => x.UniqueId);
|
||||
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x=> x.LanguageTextDtos, sql)
|
||||
.Select(ConvertFromDto);
|
||||
});
|
||||
};
|
||||
|
||||
var childItems = parentId.HasValue == false
|
||||
? new[] { GetRootDictionaryItems()! }
|
||||
: getItemsFromParents(new[] { parentId.Value });
|
||||
|
||||
return childItems.SelectRecursive(items => getItemsFromParents(items.Select(x => x.Key).ToArray())).SelectMany(items => items);
|
||||
|
||||
}
|
||||
|
||||
private class DictionaryByUniqueIdRepository : SimpleGetRepository<Guid, IDictionaryItem, DictionaryDto>
|
||||
{
|
||||
private readonly DictionaryRepository _dictionaryRepository;
|
||||
|
||||
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IScopeAccessor scopeAccessor, AppCaches cache, ILogger<DictionaryByUniqueIdRepository> logger)
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
}
|
||||
|
||||
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql)
|
||||
{
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql);
|
||||
}
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
{
|
||||
return _dictionaryRepository.GetBaseQuery(isCount);
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " = @id";
|
||||
}
|
||||
|
||||
protected override IDictionaryItem ConvertToEntity(DictionaryDto dto)
|
||||
{
|
||||
return _dictionaryRepository.ConvertFromDto(dto);
|
||||
}
|
||||
|
||||
protected override object GetBaseWhereClauseArguments(Guid id)
|
||||
{
|
||||
return new { id = id };
|
||||
}
|
||||
|
||||
protected override string GetWhereInClauseForGetAll()
|
||||
{
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " in (@ids)";
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, Guid> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
//allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, Guid>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
}
|
||||
}
|
||||
|
||||
private class DictionaryByKeyRepository : SimpleGetRepository<string, IDictionaryItem, DictionaryDto>
|
||||
{
|
||||
private readonly DictionaryRepository _dictionaryRepository;
|
||||
|
||||
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IScopeAccessor scopeAccessor, AppCaches cache, ILogger<DictionaryByKeyRepository> logger)
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{
|
||||
_dictionaryRepository = dictionaryRepository;
|
||||
}
|
||||
|
||||
protected override IEnumerable<DictionaryDto> PerformFetch(Sql sql)
|
||||
{
|
||||
return Database
|
||||
.FetchOneToMany<DictionaryDto>(x => x.LanguageTextDtos, sql);
|
||||
}
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
{
|
||||
return _dictionaryRepository.GetBaseQuery(isCount);
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " = @id";
|
||||
}
|
||||
|
||||
protected override IDictionaryItem ConvertToEntity(DictionaryDto dto)
|
||||
{
|
||||
return _dictionaryRepository.ConvertFromDto(dto);
|
||||
}
|
||||
|
||||
protected override object GetBaseWhereClauseArguments(string? id)
|
||||
{
|
||||
return new { id = id };
|
||||
}
|
||||
|
||||
protected override string GetWhereInClauseForGetAll()
|
||||
{
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " in (@ids)";
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, string> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
//allow zero to be cached
|
||||
GetAllCacheAllowZeroCount = true
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, string>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
}
|
||||
// Clear the cache entries that exist by uniqueid/item key
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, string>(dto.Key));
|
||||
IsolatedCache.Clear(RepositoryCacheKeys.GetKey<IDictionaryItem, Guid>(dto.UniqueId));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user