2017-07-20 11:21:28 +02:00
using System ;
2015-01-21 17:03:56 +11:00
using System.Collections.Generic ;
2015-01-21 18:35:08 +11:00
using System.Data ;
2015-01-21 17:03:56 +11:00
using System.Linq ;
2020-09-17 09:42:55 +02:00
using Microsoft.Extensions.Logging ;
2016-04-12 15:11:07 +02:00
using NPoco ;
2015-01-21 17:03:56 +11:00
using Umbraco.Core.Cache ;
using Umbraco.Core.Models ;
2019-06-28 09:19:11 +02:00
using Umbraco.Core.Models.Entities ;
2017-12-28 09:06:33 +01:00
using Umbraco.Core.Persistence.Dtos ;
2015-01-21 17:03:56 +11:00
using Umbraco.Core.Persistence.Querying ;
2017-12-12 15:04:13 +01:00
using Umbraco.Core.Scoping ;
2015-01-21 17:03:56 +11:00
2017-12-07 16:45:25 +01:00
namespace Umbraco.Core.Persistence.Repositories.Implement
2015-01-21 17:03:56 +11:00
{
2019-01-27 01:17:32 -05:00
// TODO: We need to get a readonly ISO code for the domain assigned
2015-08-04 15:42:44 +02:00
2020-12-22 10:30:16 +11:00
internal class DomainRepository : EntityRepositoryBase < int , IDomain > , IDomainRepository
2015-01-21 17:03:56 +11:00
{
2020-09-17 09:42:55 +02:00
public DomainRepository ( IScopeAccessor scopeAccessor , AppCaches cache , ILogger < DomainRepository > logger )
2017-12-14 17:04:44 +01:00
: base ( scopeAccessor , cache , logger )
2017-05-12 14:49:44 +02:00
{ }
2015-01-21 17:03:56 +11:00
2017-12-15 16:29:14 +01:00
protected override IRepositoryCachePolicy < IDomain , int > CreateCachePolicy ( )
2015-01-21 17:03:56 +11:00
{
2017-12-15 16:29:14 +01:00
return new FullDataSetRepositoryCachePolicy < IDomain , int > ( GlobalIsolatedCache , ScopeAccessor , GetEntityId , /*expires:*/ false ) ;
2015-01-21 17:03:56 +11:00
}
protected override IDomain PerformGet ( int id )
{
2015-07-27 12:53:09 +02:00
//use the underlying GetAll which will force cache all domains
2017-12-07 16:45:25 +01:00
return GetMany ( ) . FirstOrDefault ( x = > x . Id = = id ) ;
2015-01-21 17:03:56 +11:00
}
protected override IEnumerable < IDomain > PerformGetAll ( params int [ ] ids )
{
2019-02-05 19:48:13 +01:00
var sql = GetBaseQuery ( false ) . Where ( "umbracoDomain.id > 0" ) ;
2015-07-27 12:53:09 +02:00
if ( ids . Any ( ) )
2015-01-21 17:03:56 +11:00
{
2019-02-05 19:48:13 +01:00
sql . Where ( "umbracoDomain.id in (@ids)" , new { ids = ids } ) ;
2015-01-21 17:03:56 +11:00
}
2015-07-27 12:53:09 +02:00
return Database . Fetch < DomainDto > ( sql ) . Select ( ConvertFromDto ) ;
2015-01-21 17:03:56 +11:00
}
protected override IEnumerable < IDomain > PerformGetByQuery ( IQuery < IDomain > query )
{
throw new NotSupportedException ( "This repository does not support this method" ) ;
}
2017-09-22 18:48:58 +02:00
protected override Sql < ISqlContext > GetBaseQuery ( bool isCount )
2015-01-21 17:03:56 +11:00
{
2016-04-12 15:11:07 +02:00
var sql = Sql ( ) ;
2015-08-04 15:42:44 +02:00
if ( isCount )
{
2016-04-12 15:11:07 +02:00
sql . SelectCount ( ) . From < DomainDto > ( ) ;
2015-08-04 15:42:44 +02:00
}
else
{
2019-02-05 19:48:13 +01:00
sql . Select ( "umbracoDomain.*, umbracoLanguage.languageISOCode" )
2016-04-12 15:11:07 +02:00
. From < DomainDto > ( )
. LeftJoin < LanguageDto > ( )
. On < DomainDto , LanguageDto > ( dto = > dto . DefaultLanguage , dto = > dto . Id ) ;
2015-08-04 15:42:44 +02:00
}
2017-07-20 11:21:28 +02:00
2015-01-21 17:03:56 +11:00
return sql ;
}
protected override string GetBaseWhereClause ( )
{
2019-02-05 19:48:13 +01:00
return "umbracoDomain.id = @id" ;
2015-01-21 17:03:56 +11:00
}
protected override IEnumerable < string > GetDeleteClauses ( )
{
2015-07-27 12:53:09 +02:00
var list = new List < string >
{
2019-02-05 19:48:13 +01:00
"DELETE FROM umbracoDomain WHERE id = @id"
2015-07-27 12:53:09 +02:00
} ;
return list ;
2015-01-21 17:03:56 +11:00
}
protected override Guid NodeObjectTypeId
{
get { throw new NotImplementedException ( ) ; }
}
protected override void PersistNewItem ( IDomain entity )
{
2019-02-05 19:48:13 +01:00
var exists = Database . ExecuteScalar < int > ( "SELECT COUNT(*) FROM umbracoDomain WHERE domainName = @domainName" , new { domainName = entity . DomainName } ) ;
2015-07-27 12:53:09 +02:00
if ( exists > 0 ) throw new DuplicateNameException ( string . Format ( "The domain name {0} is already assigned" , entity . DomainName ) ) ;
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
if ( entity . RootContentId . HasValue )
2015-01-21 17:03:56 +11:00
{
2018-03-22 17:17:01 +11:00
var contentExists = Database . ExecuteScalar < int > ( $"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Content} WHERE nodeId = @id" , new { id = entity . RootContentId . Value } ) ;
2015-07-27 12:53:09 +02:00
if ( contentExists = = 0 ) throw new NullReferenceException ( "No content exists with id " + entity . RootContentId . Value ) ;
2015-01-21 17:03:56 +11:00
}
2015-07-27 12:53:09 +02:00
if ( entity . LanguageId . HasValue )
2015-05-13 16:45:08 +10:00
{
2015-07-27 12:53:09 +02:00
var languageExists = Database . ExecuteScalar < int > ( "SELECT COUNT(*) FROM umbracoLanguage WHERE id = @id" , new { id = entity . LanguageId . Value } ) ;
if ( languageExists = = 0 ) throw new NullReferenceException ( "No language exists with id " + entity . LanguageId . Value ) ;
2015-05-13 16:45:08 +10:00
}
2019-06-28 09:19:11 +02:00
entity . AddingEntity ( ) ;
2015-01-21 18:35:08 +11:00
2015-07-27 12:53:09 +02:00
var factory = new DomainModelFactory ( ) ;
var dto = factory . BuildDto ( entity ) ;
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
var id = Convert . ToInt32 ( Database . Insert ( dto ) ) ;
entity . Id = id ;
2015-01-21 17:03:56 +11:00
2015-08-04 15:42:44 +02:00
//if the language changed, we need to resolve the ISO code!
if ( entity . LanguageId . HasValue )
{
( ( UmbracoDomain ) entity ) . LanguageIsoCode = Database . ExecuteScalar < string > ( "SELECT languageISOCode FROM umbracoLanguage WHERE id=@langId" , new { langId = entity . LanguageId } ) ;
}
2015-07-27 12:53:09 +02:00
entity . ResetDirtyProperties ( ) ;
2015-01-21 17:03:56 +11:00
}
2015-07-27 12:53:09 +02:00
protected override void PersistUpdatedItem ( IDomain entity )
2015-01-21 17:03:56 +11:00
{
2019-06-28 09:19:11 +02:00
entity . UpdatingEntity ( ) ;
2015-01-21 17:03:56 +11:00
2019-02-05 19:48:13 +01:00
var exists = Database . ExecuteScalar < int > ( "SELECT COUNT(*) FROM umbracoDomain WHERE domainName = @domainName AND umbracoDomain.id <> @id" ,
2015-07-27 12:53:09 +02:00
new { domainName = entity . DomainName , id = entity . Id } ) ;
//ensure there is no other domain with the same name on another entity
if ( exists > 0 ) throw new DuplicateNameException ( string . Format ( "The domain name {0} is already assigned" , entity . DomainName ) ) ;
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
if ( entity . RootContentId . HasValue )
2015-01-21 17:03:56 +11:00
{
2018-03-22 17:17:01 +11:00
var contentExists = Database . ExecuteScalar < int > ( $"SELECT COUNT(*) FROM {Constants.DatabaseSchema.Tables.Content} WHERE nodeId = @id" , new { id = entity . RootContentId . Value } ) ;
2015-07-27 12:53:09 +02:00
if ( contentExists = = 0 ) throw new NullReferenceException ( "No content exists with id " + entity . RootContentId . Value ) ;
2015-07-16 18:09:56 +02:00
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
if ( entity . LanguageId . HasValue )
2015-07-16 18:09:56 +02:00
{
2015-07-27 12:53:09 +02:00
var languageExists = Database . ExecuteScalar < int > ( "SELECT COUNT(*) FROM umbracoLanguage WHERE id = @id" , new { id = entity . LanguageId . Value } ) ;
if ( languageExists = = 0 ) throw new NullReferenceException ( "No language exists with id " + entity . LanguageId . Value ) ;
2015-01-21 17:03:56 +11:00
}
2015-07-27 12:53:09 +02:00
var factory = new DomainModelFactory ( ) ;
var dto = factory . BuildDto ( entity ) ;
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
Database . Update ( dto ) ;
2015-01-21 17:03:56 +11:00
2015-08-04 15:42:44 +02:00
//if the language changed, we need to resolve the ISO code!
if ( entity . WasPropertyDirty ( "LanguageId" ) )
{
( ( UmbracoDomain ) entity ) . LanguageIsoCode = Database . ExecuteScalar < string > ( "SELECT languageISOCode FROM umbracoLanguage WHERE id=@langId" , new { langId = entity . LanguageId } ) ;
}
2015-07-27 12:53:09 +02:00
entity . ResetDirtyProperties ( ) ;
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
public IDomain GetByName ( string domainName )
{
2017-12-07 16:45:25 +01:00
return GetMany ( ) . FirstOrDefault ( x = > x . DomainName . InvariantEquals ( domainName ) ) ;
2015-01-21 17:03:56 +11:00
}
2015-07-27 12:53:09 +02:00
public bool Exists ( string domainName )
2015-01-21 17:03:56 +11:00
{
2017-12-07 16:45:25 +01:00
return GetMany ( ) . Any ( x = > x . DomainName . InvariantEquals ( domainName ) ) ;
2015-07-27 12:53:09 +02:00
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
public IEnumerable < IDomain > GetAll ( bool includeWildcards )
{
2017-12-07 16:45:25 +01:00
return GetMany ( ) . Where ( x = > includeWildcards | | x . IsWildcard = = false ) ;
2015-07-27 12:53:09 +02:00
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
public IEnumerable < IDomain > GetAssignedDomains ( int contentId , bool includeWildcards )
{
2017-12-07 16:45:25 +01:00
return GetMany ( )
2015-07-27 12:53:09 +02:00
. Where ( x = > x . RootContentId = = contentId )
. Where ( x = > includeWildcards | | x . IsWildcard = = false ) ;
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
private IDomain ConvertFromDto ( DomainDto dto )
{
var factory = new DomainModelFactory ( ) ;
var entity = factory . BuildEntity ( dto ) ;
return entity ;
2017-07-20 11:21:28 +02:00
}
2015-01-21 17:03:56 +11:00
2015-07-27 12:53:09 +02:00
internal class DomainModelFactory
{
2017-07-20 11:21:28 +02:00
2015-07-27 12:53:09 +02:00
public IDomain BuildEntity ( DomainDto dto )
2015-01-21 17:03:56 +11:00
{
2015-08-04 15:42:44 +02:00
var domain = new UmbracoDomain ( dto . DomainName , dto . IsoCode )
{
Id = dto . Id ,
LanguageId = dto . DefaultLanguage ,
RootContentId = dto . RootStructureId
} ;
2017-11-10 11:27:12 +01:00
// reset dirty initial properties (U4-1946)
2015-01-21 17:03:56 +11:00
domain . ResetDirtyProperties ( false ) ;
return domain ;
}
2015-07-27 12:53:09 +02:00
public DomainDto BuildDto ( IDomain entity )
2015-01-21 17:03:56 +11:00
{
2015-07-27 12:53:09 +02:00
var dto = new DomainDto { DefaultLanguage = entity . LanguageId , DomainName = entity . DomainName , Id = entity . Id , RootStructureId = entity . RootContentId } ;
2015-01-21 17:03:56 +11:00
return dto ;
}
}
}
2017-07-20 11:21:28 +02:00
}