Merge remote-tracking branch 'origin/7.3.6' into dev-v7

Conflicts:
	build/UmbracoVersion.txt
	src/SolutionInfo.cs
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/UmbracoContext.cs
This commit is contained in:
Shannon
2016-01-27 15:42:06 +01:00
11 changed files with 81 additions and 88 deletions

View File

@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
/// <remarks>
/// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
/// default policy with no expiry.
/// </remarks>
internal class DefaultRepositoryCachePolicy<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
@@ -54,7 +58,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity);
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
@@ -225,7 +231,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(cacheKey, () => entity);
Cache.InsertCacheItem(cacheKey, () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
});
}
@@ -244,6 +252,7 @@ namespace Umbraco.Core.Cache
{
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
// to signify that there is a zero count cache
//NOTE: Don't set expiry/sliding for a zero count
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
}
else
@@ -256,7 +265,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (localCopy.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy);
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
}
}

View File

@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
/// <remarks>
/// This caching policy has no sliding expiration but uses the default ObjectCache.InfiniteAbsoluteExpiration as it's timeout, so it
/// should not leave the cache unless the cache memory is exceeded and it gets thrown out.
/// </remarks>
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{

View File

@@ -98,45 +98,10 @@ namespace Umbraco.Core.Models.PublishedContent
#endregion
#region Cache
// these methods are called by ContentTypeCacheRefresher and DataTypeCacheRefresher
internal static void ClearAll()
{
Logging.LogHelper.Debug<PublishedContentType>("Clear all.");
// ok and faster to do it by types, assuming noone else caches PublishedContentType instances
//ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_");
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>();
}
internal static void ClearContentType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
// requires a predicate because the key does not contain the ID
// faster than key strings comparisons anyway
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => value.Id == id);
}
internal static void ClearDataType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear data type w/id {0}.", () => id);
// there is no recursion to handle here because a PublishedContentType contains *all* its
// properties ie both its own properties and those that were inherited (it's based upon an
// IContentTypeComposition) and so every PublishedContentType having a property based upon
// the cleared data type, be it local or inherited, will be cleared.
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => value.PropertyTypes.Any(x => x.DataTypeId == id));
}
public static PublishedContentType Get(PublishedItemType itemType, string alias)
{
var key = string.Format("PublishedContentType_{0}_{1}",
itemType.ToString().ToLowerInvariant(), alias.ToLowerInvariant());
var type = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItem<PublishedContentType>(key,
() => CreatePublishedContentType(itemType, alias));
var type = CreatePublishedContentType(itemType, alias);
return type;
}
@@ -169,21 +134,8 @@ namespace Umbraco.Core.Models.PublishedContent
return new PublishedContentType(contentType);
}
// for unit tests - changing the callback must reset the cache obviously
private static Func<string, PublishedContentType> _getPublishedContentTypeCallBack;
internal static Func<string, PublishedContentType> GetPublishedContentTypeCallback
{
get { return _getPublishedContentTypeCallBack; }
set
{
// see note above
//ClearAll();
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheByKeySearch("PublishedContentType_");
// for unit tests
internal static Func<string, PublishedContentType> GetPublishedContentTypeCallback { get; set; }
_getPublishedContentTypeCallBack = value;
}
}
#endregion
}
}

View File

@@ -17,9 +17,12 @@ namespace Umbraco.Core.Persistence.Relators
// Is this the same DictionaryItem as the current one we're processing
if (Current != null && Current.Id == a.Id)
{
if (p.AppAlias.IsNullOrWhiteSpace() == false)
{
// Yes, just add this User2AppDto to the current item's collection
Current.User2AppDtos.Add(p);
}
// Return null to indicate we're not done with this User yet
return null;
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Persistence.Relators
Current = a;
Current.User2AppDtos = new List<User2AppDto>();
//this can be null since we are doing a left join
if (p.AppAlias != null)
if (p.AppAlias.IsNullOrWhiteSpace() == false)
{
Current.User2AppDtos.Add(p);
}

View File

@@ -85,7 +85,6 @@ namespace Umbraco.Core.Persistence.Repositories
return moveInfo;
}
/// <summary>
/// Returns the content type ids that match the query
/// </summary>

View File

@@ -475,7 +475,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (aliases.Any() == false) return base.GetAll();
//return from base.GetAll, this is all cached
return base.GetAll().Where(x => aliases.Contains(x.Alias));
return base.GetAll().Where(x => aliases.InvariantContains(x.Alias));
}
public IEnumerable<ITemplate> GetChildren(int masterTemplateId)

View File

@@ -142,8 +142,6 @@ namespace Umbraco.Web.Cache
//clear static object cache
global::umbraco.cms.businesslogic.ContentType.RemoveAllDataTypeCache();
PublishedContentType.ClearAll();
base.RefreshAll();
}
@@ -281,8 +279,6 @@ namespace Umbraco.Web.Cache
//clears the dictionary object cache of the legacy ContentType
global::umbraco.cms.businesslogic.ContentType.RemoveFromDataTypeCache(payload.Alias);
PublishedContentType.ClearContentType(payload.Id);
//need to recursively clear the cache for each child content type
foreach (var descendant in payload.DescendantPayloads)
{

View File

@@ -108,7 +108,6 @@ namespace Umbraco.Web.Cache
if (dataTypeCache)
dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id));
PublishedContentType.ClearDataType(payload.Id);
});
base.Refresh(jsonPayload);

View File

@@ -40,8 +40,13 @@ namespace Umbraco.Web.Install.InstallSteps
var clientDependencyConfig = new ClientDependencyConfiguration(_applicationContext.ProfilingLogger.Logger);
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
//During a new install we'll log the default user in (which is id = 0).
// During an upgrade, the user will already need to be logged in in order to run the installer.
if (InstallTypeTarget == InstallationType.NewInstall)
{
var security = new WebSecurity(_httpContext, _applicationContext);
security.PerformLogin(0);
}
//reports the ended install
var ih = new InstallHelper(UmbracoContext.Current);

View File

@@ -125,6 +125,7 @@ namespace Umbraco.Web
if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
if (urlProviders == null) throw new ArgumentNullException("urlProviders");
//if there's already a singleton, and we're not replacing then there's no need to ensure anything
if (UmbracoContext.Current != null)
{
if (replaceContext == false)
@@ -132,6 +133,39 @@ namespace Umbraco.Web
UmbracoContext.Current._replacing = true;
}
var umbracoContext = CreateContext(httpContext, applicationContext, webSecurity, umbracoSettings, urlProviders, preview ?? false);
//assign the singleton
UmbracoContext.Current = umbracoContext;
return UmbracoContext.Current;
}
/// <summary>
/// Creates a standalone UmbracoContext instance
/// </summary>
/// <param name="httpContext"></param>
/// <param name="applicationContext"></param>
/// <param name="webSecurity"></param>
/// <param name="umbracoSettings"></param>
/// <param name="urlProviders"></param>
/// <param name="preview"></param>
/// <returns>
/// A new instance of UmbracoContext
/// </returns>
public static UmbracoContext CreateContext(
HttpContextBase httpContext,
ApplicationContext applicationContext,
WebSecurity webSecurity,
IUmbracoSettingsSection umbracoSettings,
IEnumerable<IUrlProvider> urlProviders,
bool preview)
{
if (httpContext == null) throw new ArgumentNullException("httpContext");
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
if (webSecurity == null) throw new ArgumentNullException("webSecurity");
if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
if (urlProviders == null) throw new ArgumentNullException("urlProviders");
var umbracoContext = new UmbracoContext(
httpContext,
applicationContext,
@@ -159,9 +193,7 @@ namespace Umbraco.Web
//assign the routing context back
umbracoContext.RoutingContext = routingContext;
//assign the singleton
UmbracoContext.Current = umbracoContext;
return UmbracoContext.Current;
return umbracoContext;
}
/// <summary>
@@ -460,17 +492,9 @@ namespace Umbraco.Web
protected override void DisposeResources()
{
Security.DisposeIfDisposable();
Security = null;
_umbracoContext = null;
//Before we set these to null but in fact these are application lifespan singletons so
//there's no reason we need to set them to null and this also caused a problem with packages
//trying to access the cache properties on RequestEnd.
//http://issues.umbraco.org/issue/U4-2734
//http://our.umbraco.org/projects/developer-tools/301-url-tracker/version-2/44327-Issues-with-URL-Tracker-in-614
//ContentCache = null;
//MediaCache = null;
//Application = null;
//If not running in a web ctx, ensure the thread based instance is nulled
_umbracoContext = null;
}
}
}