2015-01-21 18:35:08 +11:00
using System.Data ;
2020-09-17 09:42:55 +02:00
using Microsoft.Extensions.Logging ;
2016-04-12 15:11:07 +02:00
using NPoco ;
2021-08-11 19:11:35 +02:00
using Umbraco.Cms.Core ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Cache ;
using Umbraco.Cms.Core.Models ;
using Umbraco.Cms.Core.Persistence.Querying ;
using Umbraco.Cms.Core.Persistence.Repositories ;
2021-02-12 13:36:50 +01:00
using Umbraco.Cms.Infrastructure.Persistence.Dtos ;
2023-02-14 10:35:45 +01:00
using Umbraco.Cms.Infrastructure.Persistence.Factories ;
2022-01-13 17:44:11 +00:00
using Umbraco.Cms.Infrastructure.Scoping ;
2021-02-09 11:26:22 +01:00
using Umbraco.Extensions ;
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement ;
2015-08-04 15:42:44 +02:00
2022-06-02 08:18:31 +02:00
internal class DomainRepository : EntityRepositoryBase < int , IDomain > , IDomainRepository
{
public DomainRepository ( IScopeAccessor scopeAccessor , AppCaches cache , ILogger < DomainRepository > logger )
: base ( scopeAccessor , cache , logger )
2023-02-14 10:35:45 +01:00
{ }
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
public IDomain ? GetByName ( string domainName )
= > GetMany ( ) . FirstOrDefault ( x = > x . DomainName . InvariantEquals ( domainName ) ) ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
public bool Exists ( string domainName )
= > GetMany ( ) . Any ( x = > x . DomainName . InvariantEquals ( domainName ) ) ;
2015-07-27 12:53:09 +02:00
2023-02-14 10:35:45 +01:00
public IEnumerable < IDomain > GetAll ( bool includeWildcards )
= > GetMany ( ) . Where ( x = > includeWildcards | | x . IsWildcard = = false ) ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
public IEnumerable < IDomain > GetAssignedDomains ( int contentId , bool includeWildcards )
= > GetMany ( ) . Where ( x = > x . RootContentId = = contentId ) . Where ( x = > includeWildcards | | x . IsWildcard = = false ) ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
protected override IRepositoryCachePolicy < IDomain , int > CreateCachePolicy ( )
= > new FullDataSetRepositoryCachePolicy < IDomain , int > ( GlobalIsolatedCache , ScopeAccessor , GetEntityId , false ) ;
2017-07-20 11:21:28 +02:00
2023-02-14 10:35:45 +01:00
protected override IDomain ? PerformGet ( int id )
// Use the underlying GetAll which will force cache all domains
= > GetMany ( ) . FirstOrDefault ( x = > x . Id = = id ) ;
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
protected override IEnumerable < IDomain > PerformGetAll ( params int [ ] ? ids )
{
Sql < ISqlContext > sql = GetBaseQuery ( false ) . Where < DomainDto > ( x = > x . Id > 0 ) ;
if ( ids ? . Any ( ) ? ? false )
2015-01-21 17:03:56 +11:00
{
2022-06-02 08:18:31 +02:00
sql . WhereIn < DomainDto > ( x = > x . Id , ids ) ;
2015-01-21 17:03:56 +11:00
}
2023-02-14 10:35:45 +01:00
sql . OrderBy < DomainDto > ( dto = > dto . SortOrder ) ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
return Database . Fetch < DomainDto > ( sql ) . Select ( DomainFactory . BuildEntity ) ;
2022-06-02 08:18:31 +02:00
}
2023-02-14 10:35:45 +01:00
protected override IEnumerable < IDomain > PerformGetByQuery ( IQuery < IDomain > query )
= > throw new NotSupportedException ( "This repository does not support this method" ) ;
2022-06-02 08:18:31 +02:00
protected override Sql < ISqlContext > GetBaseQuery ( bool isCount )
{
Sql < ISqlContext > sql = Sql ( ) ;
if ( isCount )
2015-01-21 17:03:56 +11:00
{
2022-06-02 08:18:31 +02:00
sql . SelectCount ( ) . From < DomainDto > ( ) ;
2015-01-21 17:03:56 +11:00
}
2022-06-02 08:18:31 +02:00
else
2015-01-21 17:03:56 +11:00
{
2023-02-14 10:35:45 +01:00
sql . Select ( $"{Constants.DatabaseSchema.Tables.Domain}.*, {Constants.DatabaseSchema.Tables.Language}.languageISOCode" )
2022-06-02 08:18:31 +02:00
. From < DomainDto > ( )
. LeftJoin < LanguageDto > ( )
. On < DomainDto , LanguageDto > ( dto = > dto . DefaultLanguage , dto = > dto . Id ) ;
}
2015-01-21 18:35:08 +11:00
2022-06-02 08:18:31 +02:00
return sql ;
}
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
protected override string GetBaseWhereClause ( )
= > $"{Constants.DatabaseSchema.Tables.Domain}.id = @id" ;
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
protected override IEnumerable < string > GetDeleteClauses ( )
2023-02-14 10:35:45 +01:00
= > new [ ]
{
$"DELETE FROM {Constants.DatabaseSchema.Tables.Domain} WHERE id = @id" ,
} ;
2015-08-04 15:42:44 +02:00
2022-06-02 08:18:31 +02:00
protected override void PersistNewItem ( IDomain entity )
{
var exists = Database . ExecuteScalar < int > (
2023-02-14 10:35:45 +01:00
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Domain} WHERE domainName = @domainName" ,
2022-06-02 08:18:31 +02:00
new { domainName = entity . DomainName } ) ;
if ( exists > 0 )
{
2023-02-14 10:35:45 +01:00
throw new DuplicateNameException ( $"The domain name {entity.DomainName} is already assigned." ) ;
2015-01-21 17:03:56 +11:00
}
2022-06-02 08:18:31 +02:00
if ( entity . RootContentId . HasValue )
2015-01-21 17:03:56 +11:00
{
2022-06-02 08:18:31 +02:00
var contentExists = Database . ExecuteScalar < int > (
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Content} WHERE nodeId = @id" ,
new { id = entity . RootContentId . Value } ) ;
if ( contentExists = = 0 )
2015-01-21 17:03:56 +11:00
{
2023-02-14 10:35:45 +01:00
throw new NullReferenceException ( $"No content exists with id {entity.RootContentId.Value}." ) ;
2015-07-16 18:09:56 +02:00
}
2022-06-02 08:18:31 +02:00
}
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
if ( entity . LanguageId . HasValue )
{
var languageExists = Database . ExecuteScalar < int > (
2023-02-14 10:35:45 +01:00
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Language} WHERE id = @id" ,
2022-06-02 08:18:31 +02:00
new { id = entity . LanguageId . Value } ) ;
if ( languageExists = = 0 )
2015-07-16 18:09:56 +02:00
{
2023-02-14 10:35:45 +01:00
throw new NullReferenceException ( $"No language exists with id {entity.LanguageId.Value}." ) ;
2015-01-21 17:03:56 +11:00
}
2022-06-02 08:18:31 +02:00
}
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
entity . AddingEntity ( ) ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
// Get sort order
entity . SortOrder = GetNewSortOrder ( entity . RootContentId , entity . IsWildcard ) ;
DomainDto dto = DomainFactory . BuildDto ( entity ) ;
2015-08-04 15:42:44 +02:00
2022-06-02 08:18:31 +02:00
var id = Convert . ToInt32 ( Database . Insert ( dto ) ) ;
entity . Id = id ;
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
// If the language changed, we need to resolve the ISO code
2022-06-02 08:18:31 +02:00
if ( entity . LanguageId . HasValue )
2015-07-27 12:53:09 +02:00
{
2022-06-02 08:18:31 +02:00
( ( UmbracoDomain ) entity ) . LanguageIsoCode = Database . ExecuteScalar < string > (
2023-02-14 10:35:45 +01:00
$"SELECT languageISOCode FROM {Constants.DatabaseSchema.Tables.Language} WHERE id = @langId" ,
new { langId = entity . LanguageId } ) ;
2015-01-21 17:03:56 +11:00
}
2022-06-02 08:18:31 +02:00
entity . ResetDirtyProperties ( ) ;
}
protected override void PersistUpdatedItem ( IDomain entity )
{
entity . UpdatingEntity ( ) ;
2023-02-14 10:35:45 +01:00
// Ensure there is no other domain with the same name on another entity
2022-06-02 08:18:31 +02:00
var exists = Database . ExecuteScalar < int > (
2023-02-14 10:35:45 +01:00
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Domain} WHERE domainName = @domainName AND umbracoDomain.id <> @id" ,
2022-06-02 08:18:31 +02:00
new { domainName = entity . DomainName , id = entity . Id } ) ;
if ( exists > 0 )
2015-01-21 17:03:56 +11:00
{
2023-02-14 10:35:45 +01:00
throw new DuplicateNameException ( $"The domain name {entity.DomainName} is already assigned." ) ;
2015-07-27 12:53:09 +02:00
}
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
if ( entity . RootContentId . HasValue )
2015-07-27 12:53:09 +02:00
{
2022-06-02 08:18:31 +02:00
var contentExists = Database . ExecuteScalar < int > (
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Content} WHERE nodeId = @id" ,
new { id = entity . RootContentId . Value } ) ;
if ( contentExists = = 0 )
{
2023-02-14 10:35:45 +01:00
throw new NullReferenceException ( $"No content exists with id {entity.RootContentId.Value}." ) ;
2022-06-02 08:18:31 +02:00
}
2015-07-27 12:53:09 +02:00
}
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
if ( entity . LanguageId . HasValue )
2015-07-27 12:53:09 +02:00
{
2022-06-02 08:18:31 +02:00
var languageExists = Database . ExecuteScalar < int > (
2023-02-14 10:35:45 +01:00
$"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Language} WHERE id = @id" ,
2022-06-02 08:18:31 +02:00
new { id = entity . LanguageId . Value } ) ;
if ( languageExists = = 0 )
{
2023-02-14 10:35:45 +01:00
throw new NullReferenceException ( $"No language exists with id {entity.LanguageId.Value}." ) ;
2022-06-02 08:18:31 +02:00
}
2015-07-27 12:53:09 +02:00
}
2015-01-21 17:03:56 +11:00
2023-02-14 10:35:45 +01:00
DomainDto dto = DomainFactory . BuildDto ( entity ) ;
2022-06-02 08:18:31 +02:00
Database . Update ( dto ) ;
2023-02-14 10:35:45 +01:00
// If the language changed, we need to resolve the ISO code
2022-06-02 08:18:31 +02:00
if ( entity . WasPropertyDirty ( "LanguageId" ) )
2015-07-27 12:53:09 +02:00
{
2022-06-02 08:18:31 +02:00
( ( UmbracoDomain ) entity ) . LanguageIsoCode = Database . ExecuteScalar < string > (
2023-02-14 10:35:45 +01:00
$"SELECT languageISOCode FROM {Constants.DatabaseSchema.Tables.Language} WHERE id = @langId" ,
new { langId = entity . LanguageId } ) ;
2017-07-20 11:21:28 +02:00
}
2015-01-21 17:03:56 +11:00
2022-06-02 08:18:31 +02:00
entity . ResetDirtyProperties ( ) ;
}
2017-07-20 11:21:28 +02:00
2023-02-14 10:35:45 +01:00
protected int GetNewSortOrder ( int? rootContentId , bool isWildcard )
= > isWildcard
? - 1
: Database . ExecuteScalar < int > (
$"SELECT COALESCE(MAX(sortOrder), -1) + 1 FROM {Constants.DatabaseSchema.Tables.Domain} WHERE domainRootStructureID = @rootContentId AND NOT (domainName = '' OR domainName LIKE '*%')" ,
new { rootContentId } ) ;
2017-07-20 11:21:28 +02:00
}