Compare commits

..

3 Commits

3362 changed files with 109598 additions and 95017 deletions
-10
View File
@@ -1,10 +0,0 @@
root=true
[*]
end_of_line = lf
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.{cs,cshtml,csx,vb,vbx,vbhtml,fs,fsx,txt,ps1,sql}]
indent_size = 4
-4
View File
@@ -142,7 +142,3 @@ build/ui-docs.zip
build/csharp-docs.zip
build/msbuild.log
.vs/
src/packages/
src/PrecompiledWeb/*
build/tools/
src/PrecompiledWeb/*
-2
View File
@@ -1,5 +1,3 @@
[![Build status](https://ci.appveyor.com/api/projects/status/ikpgqxiw9v8opltv/branch/dev-v7?svg=true)](https://ci.appveyor.com/project/Umbraco/umbraco-cms-hs8dx/branch/dev-v7)
Umbraco CMS
===========
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
+14 -15
View File
@@ -2,23 +2,21 @@ version: '{build}'
shallow_clone: true
build_script:
- cmd: >-
SET SLN=%CD%
SET SRC=%SLN%\src
SET PACKAGES=%SRC%\packages
CD build
cd build
SET "release="
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
ECHO "Restoring NuGet into %PACKAGES%"
%SRC%\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
%SRC%\.nuget\NuGet.exe restore %SRC%\umbraco.sln -Verbosity Quiet -NonInteractive -PackagesDirectory %PACKAGES%
SET nuGetFolder=C:\Users\appveyor\.nuget\packages
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
IF EXIST ..\src\umbraco.businesslogic\packages.config ..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Core\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER%
@@ -26,12 +24,13 @@ build_script:
SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe"
XCOPY "%SRC%\Umbraco.Tests\unit-test-log4net.CI.config" "%SRC%\Umbraco.Tests\unit-test-log4net.config" /Y
XCOPY "..\src\Umbraco.Tests\unit-test-log4net.CI.config" "..\src\Umbraco.Tests\unit-test-log4net.config" /Y
%MSBUILD% "%SLN%/src/Umbraco.Tests/Umbraco.Tests.csproj" /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /p:NugetPackagesDirectory=%PACKAGES%
%MSBUILD% "..\src\Umbraco.Tests\Umbraco.Tests.csproj" /consoleloggerparameters:Summary;ErrorsOnly
build.bat -integration -release:%release% -comment:build%APPVEYOR_BUILD_NUMBER% -nugetfolder:%PACKAGES%
build.bat nopause %release% build%APPVEYOR_BUILD_NUMBER%
ECHO %PATH%
test:
assemblies: src\Umbraco.Tests\bin\Debug\Umbraco.Tests.dll
artifacts:
+30 -142
View File
@@ -1,95 +1,31 @@
@ECHO OFF
:: UMBRACO BUILD FILE
:: ensure we have UmbracoVersion.txt
IF NOT EXIST UmbracoVersion.txt (
ECHO UmbracoVersion.txt is missing!
GOTO error
ECHO UmbracoVersion.txt missing!
GOTO :showerror
)
REM Get the version and comment from UmbracoVersion.txt lines 2 and 3
SET RELEASE=
SET COMMENT=
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED RELEASE SET RELEASE=%%i
FOR /F "skip=2 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED COMMENT SET COMMENT=%%i
SET "release="
SET "comment="
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
FOR /F "skip=2 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED comment SET "comment=%%i"
REM process args
REM If there's arguments on the command line overrule UmbracoVersion.txt and use that as the version
IF [%2] NEQ [] (SET release=%2)
IF [%3] NEQ [] (SET comment=%3) ELSE (IF [%2] NEQ [] (SET "comment="))
SET INTEGRATION=0
SET nuGetFolder=%CD%\..\src\packages
SET SKIPNUGET=0
REM Get the "is continuous integration" from the parameters
SET "isci=0"
IF [%1] NEQ [] (SET isci=1)
:processArgs
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
:: grab the first parameter as a whole eg "/action:start"
:: end if no more parameter
SET SWITCHPARSE=%1
IF [%SWITCHPARSE%] == [] goto endProcessArgs
ECHO.
ECHO Building Umbraco %version%
ECHO.
:: get switch and value
SET SWITCH=
SET VALUE=
FOR /F "tokens=1,* delims=: " %%a IN ("%SWITCHPARSE%") DO SET SWITCH=%%a& SET VALUE=%%b
:: route arg
IF '%SWITCH%'=='/release' GOTO argRelease
IF '%SWITCH%'=='-release' GOTO argRelease
IF '%SWITCH%'=='/comment' GOTO argComment
IF '%SWITCH%'=='-comment' GOTO argComment
IF '%SWITCH%'=='/integration' GOTO argIntegration
IF '%SWITCH%'=='-integration' GOTO argIntegration
IF '%SWITCH%'=='/nugetfolder' GOTO argNugetFolder
IF '%SWITCH%'=='-nugetfolder' GOTO argNugetFolder
IF '%SWITCH%'=='/skipnuget' GOTO argSkipNuget
IF '%SWITCH%'=='-skipnuget' GOTO argSkipNuget
ECHO "Invalid switch %SWITCH%"
GOTO error
:: handle each arg
:argRelease
set RELEASE=%VALUE%
SHIFT
goto processArgs
:argComment
SET COMMENT=%VALUE%
SHIFT
GOTO processArgs
:argIntegration
SET INTEGRATION=1
SHIFT
GOTO processArgs
:argNugetFolder
SET nuGetFolder=%VALUE%
SHIFT
GOTO processArgs
:argSkipNuget
SET SKIPNUGET=1
SHIFT
GOTO processArgs
:endProcessArgs
REM run
SET VERSION=%RELEASE%
IF [%COMMENT%] EQU [] (SET VERSION=%RELEASE%) ELSE (SET VERSION=%RELEASE%-%COMMENT%)
ECHO ################################################################
ECHO Building Umbraco %VERSION%
ECHO ################################################################
SET MSBUILDPATH=C:\Program Files (x86)\MSBuild\14.0\Bin
SET MSBUILD="%MSBUILDPATH%\MsBuild.exe"
SET PATH="%MSBUILDPATH%";%PATH%
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %RELEASE%
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
ECHO.
ECHO Removing the belle build folder and bower_components folder to make sure everything is clean as a whistle
@@ -99,10 +35,10 @@ RD ..\src\Umbraco.Web.UI.Client\bower_components /Q /S
ECHO.
ECHO Removing existing built files to make sure everything is clean as a whistle
RMDIR /Q /S _BuildOutput
DEL /F /Q UmbracoCms.*.zip 2>NUL
DEL /F /Q UmbracoExamine.*.zip 2>NUL
DEL /F /Q UmbracoCms.*.nupkg 2>NUL
DEL /F /Q webpihash.txt 2>NUL
DEL /F /Q UmbracoCms.*.zip
DEL /F /Q UmbracoExamine.*.zip
DEL /F /Q UmbracoCms.*.nupkg
DEL /F /Q webpihash.txt
ECHO.
ECHO Making sure Git is in the path so that the build can succeed
@@ -111,54 +47,11 @@ CALL InstallGit.cmd
REM Adding the default Git path so that if it's installed it can actually be found
REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might find Git,
REM but the path setting is lost due to SETLOCAL
SET PATH="C:\Program Files (x86)\Git\cmd";"C:\Program Files\Git\cmd";%PATH%
SET toolsFolder=%CD%\tools\
IF NOT EXIST "%toolsFolder%" (
MD tools
)
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Getting NuGet so we can fetch some tools
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
:: We need vswhere.exe for VS2017+
IF NOT EXIST "%toolsFolder%vswhere.exe" (
ECHO vswhere not found - fetching now
"%nuGetExecutable%" install vswhere -OutputDirectory tools -Verbosity quiet
)
FOR /f "delims=" %%A in ('dir "%toolsFolder%vswhere.*" /b') DO SET "vswhereExePath=%toolsFolder%%%A\"
MOVE "%vswhereExePath%tools\vswhere.exe" "%toolsFolder%vswhere.exe"
path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
ECHO.
ECHO Making sure we have a web.config
IF NOT EXIST "%CD%\..\src\Umbraco.Web.UI\web.config" COPY "%CD%\..\src\Umbraco.Web.UI\web.Template.config" "%CD%\..\src\Umbraco.Web.UI\web.config"
for /f "usebackq tokens=1* delims=: " %%i in (`"%CD%\tools\vswhere.exe" -latest -requires Microsoft.Component.MSBuild`) do (
if /i "%%i"=="installationPath" set InstallDir=%%j
)
SET VSWherePath="%InstallDir%\MSBuild"
ECHO.
ECHO Visual Studio is installed in: %InstallDir%
SET MSBUILDPATH=C:\Program Files (x86)\MSBuild\14.0\Bin
SET MSBUILD="%MSBUILDPATH%\MsBuild.exe"
ECHO.
ECHO Reporting NuGet version
"%nuGetExecutable%" help | findstr "^NuGet Version:"
ECHO.
ECHO Restoring NuGet packages
ECHO Into %nuGetFolder%
"%nuGetExecutable%" restore "%CD%\..\src\umbraco.sln" -Verbosity Quiet -NonInteractive -PackagesDirectory "%nuGetFolder%"
IF ERRORLEVEL 1 GOTO :error
IF NOT EXIST %CD%\..\src\Umbraco.Web.UI\web.config COPY %CD%\..\src\Umbraco.Web.UI\web.Template.config %CD%\..\src\Umbraco.Web.UI\web.config
ECHO.
ECHO.
@@ -167,15 +60,13 @@ ECHO This takes a few minutes and logging is set to report warnings
ECHO and errors only so it might seems like nothing is happening for a while.
ECHO You can check the msbuild.log file for progress.
ECHO.
%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%RELEASE% /p:BUILD_COMMENT=%COMMENT% /p:NugetPackagesDirectory="%nuGetFolder%" /p:VSWherePath=%VSWherePath% /consoleloggerparameters:Summary;ErrorsOnly /fileLogger
IF ERRORLEVEL 1 GOTO error
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /fileLogger
IF ERRORLEVEL 1 GOTO :error
ECHO.
ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it while loading the websites project
attrib +h ..\src\Umbraco.Web.UI.Client\node_modules
IF %SKIPNUGET% EQU 1 GOTO success
ECHO.
ECHO Adding Web.config transform files to the NuGet package
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
@@ -183,25 +74,22 @@ REN .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
ECHO.
ECHO Packing the NuGet release files
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %VERSION% -Symbols -Verbosity quiet
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %VERSION% -Verbosity quiet
IF ERRORLEVEL 1 GOTO error
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version% -Symbols -Verbosity quiet
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %version% -Verbosity quiet
IF ERRORLEVEL 1 GOTO :error
:success
ECHO.
ECHO No errors were detected!
ECHO There may still be some in the output, which you would need to investigate.
ECHO Warnings are usually normal.
ECHO.
ECHO.
GOTO :EOF
:error
ECHO.
ECHO Errors were detected!
ECHO.
REM don't pause if continuous integration else the build server waits forever
REM before cancelling the build (and, there is noone to read the output anyways)
IF %INTEGRATION% NEQ 1 PAUSE
IF isci NEQ 1 PAUSE
+20 -18
View File
@@ -1,8 +1,8 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
<!--
****************************************************
INCLUDES
INCLUDES
*****************************************************
-->
@@ -35,9 +35,9 @@
{
using (var cryptoProvider = new SHA1CryptoServiceProvider())
{
var fileHash = cryptoProvider.ComputeHash(stream);
using (TextWriter w = new StreamWriter(OutputFile, false))
{
w.WriteLine(string.Join("", fileHash.Select(b => b.ToString("x2"))));
@@ -52,9 +52,9 @@
</UsingTask>
<!--
<!--
****************************************************
VARIABLES
VARIABLES
*****************************************************
-->
@@ -102,9 +102,9 @@
<SystemFolders Include="$(WebAppFolder)Views" />
</ItemGroup>
<!--
<!--
****************************************************
TARGETS
TARGETS
*****************************************************
-->
@@ -155,7 +155,7 @@
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
</Target>
<Target Name="CreateSystemFolders" DependsOnTargets="CopyBelleBuild" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
<MakeDir Directories="@(SystemFolders)" />
</Target>
@@ -231,7 +231,7 @@
DestinationFiles="@(CustomLanguageFiles->'$(ConfigsFolder)Lang\%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy SourceFiles="@(WebConfigTransformFile)"
DestinationFiles="$(ConfigsFolder)Web.config.transform"
OverwriteReadOnlyFiles="true"
@@ -264,12 +264,14 @@
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
<!-- Build the Umbraco.Web.UI project -->
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath);Verbosity=minimal" Targets="Clean;Rebuild;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False" />
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath);Verbosity=minimal" Targets="Clean;Rebuild;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
</MSBuild>
<!-- DONE -->
<Message Text="Finished compiling projects" Importance="high" />
</Target>
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
<PropertyGroup>
<NewVersion>$(BUILD_RELEASE)</NewVersion>
@@ -305,34 +307,34 @@
ReplacementText="AssemblyFileVersion(&quot;$(BUILD_RELEASE)&quot;)"/>
<!--This updates the AssemblyInformationalVersion for the solution to the umbraco version and comment-->
<FileUpdate
<FileUpdate
Condition="'$(BUILD_COMMENT)'!=''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)-$(BUILD_COMMENT)&quot;)"/>
<FileUpdate
<FileUpdate
Condition="'$(BUILD_COMMENT)'==''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)&quot;)"/>
<FileUpdate
<FileUpdate
Condition="'$(BUILD_NIGHTLY)'!=''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)-$(BUILD_NIGHTLY)&quot;)"/>
<FileUpdate
<FileUpdate
Condition="'$(BUILD_COMMENT)'!='' AND '$(BUILD_NIGHTLY)'!=''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)-$(BUILD_COMMENT)-$(BUILD_NIGHTLY)&quot;)"/>
<FileUpdate
<FileUpdate
Condition="'$(BUILD_COMMENT)'=='' AND '$(BUILD_NIGHTLY)'==''"
Files="..\src\SolutionInfo.cs"
Regex="AssemblyInformationalVersion\(&quot;(.+)?&quot;\)"
ReplacementText="AssemblyInformationalVersion(&quot;$(BUILD_RELEASE)&quot;)"/>
<!--This updates the copyright year-->
<FileUpdate
<FileUpdate
Files="..\src\SolutionInfo.cs"
Regex="AssemblyCopyright\(&quot;Copyright © Umbraco (\d{4})&quot;\)"
ReplacementText="AssemblyCopyright(&quot;Copyright © Umbraco $([System.DateTime]::Now.ToString(`yyyy`))&quot;)"/>
+22 -57
View File
@@ -1,68 +1,33 @@
@ECHO OFF
SETLOCAL
:: SETLOCAL is on, so changes to the path not persist to the actual user's path
SET toolsFolder=%CD%\tools\
SET release=%1
ECHO Installing Npm NuGet Package
SET nuGetFolder=%CD%\..\src\packages\
ECHO Configured packages folder: %nuGetFolder%
ECHO Current folder: %CD%
SET nodeFileName=node-v6.9.1-win-x86.7z
SET nodeExtractFolder=%toolsFolder%node.js.691
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
:: We need 7za.exe for BuildBelle.bat
IF NOT EXIST "%toolsFolder%7za.exe" (
ECHO 7zip not found - fetching now
"%nuGetExecutable%" install 7-Zip.CommandLine -OutputDirectory tools -Verbosity quiet
)
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH=%npmPath%;%nodePath%;%PATH%
:: Put 7za.exe and vswhere.exe in a predictable path (not version specific)
FOR /f "delims=" %%A in ('dir "%toolsFolder%7-Zip.CommandLine.*" /b') DO SET "sevenZipExePath=%toolsFolder%%%A\"
MOVE "%sevenZipExePath%tools\7za.exe" "%toolsFolder%7za.exe"
SET buildFolder=%CD%
IF NOT EXIST "%nodeExtractFolder%" (
ECHO Downloading http://nodejs.org/dist/v6.9.1/%nodeFileName% to %toolsFolder%%nodeFileName%
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://nodejs.org/dist/v6.9.1/%nodeFileName%', '%toolsFolder%%nodeFileName%')"
ECHO Extracting %nodeFileName% to %nodeExtractFolder%
"%toolsFolder%\7za.exe" x "%toolsFolder%\%nodeFileName%" -o"%nodeExtractFolder%" -aos > nul
)
FOR /f "delims=" %%A in ('dir "%nodeExtractFolder%\node*" /b') DO SET "nodePath=%nodeExtractFolder%\%%A"
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
SET drive=%CD:~0,2%
SET nuGetFolder=%drive%\packages\
FOR /f "delims=" %%A in ('dir "%nuGetFolder%npm.*" /b') DO SET "npmPath=%nuGetFolder%%%A\"
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
IF [%npmPath%] == [] GOTO :installnpm
IF NOT [%npmPath%] == [] GOTO :build
:installnpm
ECHO Downloading npm
ECHO Configured packages folder: %nuGetFolder%
ECHO Installing Npm NuGet Package
"%nuGetExecutable%" install Npm -OutputDirectory %nuGetFolder% -Verbosity detailed
REM Ensures that we look for the just downloaded NPM, not whatever the user has installed on their machine
FOR /f "delims=" %%A in ('dir %nuGetFolder%npm.* /b') DO SET "npmPath=%nuGetFolder%%%A\"
GOTO :build
:build
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH="%npmPath%";"%nodePath%";%PATH%
SET buildFolder=%CD%
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
ECHO Move back to the build folder
CD "%buildFolder%"
ECHO Move back to the build folder
CD %buildFolder%
-14
View File
@@ -57,20 +57,6 @@ $IndexPath = "../src/umbraco.web.ui.client/docs/api/index.html"
# Build the solution in debug mode
$SolutionPath = Join-Path -Path $SolutionRoot -ChildPath "umbraco.sln"
# Go get nuget.exe if we don't hae it
$NuGet = "$ToolsRoot\nuget.exe"
$FileExists = Test-Path $NuGet
If ($FileExists -eq $False) {
Write-Host "Retrieving nuget.exe..."
$SourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
Invoke-WebRequest $SourceNugetExe -OutFile $NuGet
}
#restore nuget packages
Write-Host "Restoring nuget packages..."
& $NuGet restore $SolutionPath
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount /t:Clean
if (-not $?)
{
+3 -3
View File
@@ -1,18 +1,18 @@
@ECHO OFF
SETLOCAL
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
:: SETLOCAL is on, so changes to the path not persist to the actual user's path
git.exe --version
IF %ERRORLEVEL%==9009 GOTO :trydefaultpath
REM OK, DONE
GOTO :EOF
:: Git is installed, no need to to anything else
:trydefaultpath
PATH=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
git.exe --version
IF %ERRORLEVEL%==9009 GOTO :showerror
REM OK, DONE
GOTO :EOF
:: Git is installed, no need to to anything else
:showerror
ECHO Git is not in your path and could not be found in C:\Program Files (x86)\Git\cmd nor in C:\Program Files\Git\cmd
+48 -50
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata minClientVersion="3.4.4">
<metadata>
<id>UmbracoCms.Core</id>
<version>7.0.0</version>
<title>Umbraco Cms Core Binaries</title>
@@ -14,67 +14,65 @@
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="log4net" version="[2.0.8,3.0.0)" />
<dependency id="Log4Net.Async" version="[2.0.4,3.0.0)" />
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.1, 3.0.0)" />
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.1, 3.0.0)" />
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.1.0, 4.0.0)" />
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.1.0, 4.0.0)" />
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.1.0, 4.0.0)" />
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.9.5, 2.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.9, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.9.9, 7.0.0)" />
<dependency id="MySql.Data" version="[6.9.8, 7.0.0)" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.9.2, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0.0, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0, 2.0.0)" />
<!-- AutoMapper can not be updated due to: https://github.com/AutoMapper/AutoMapper/issues/373#issuecomment-127644405 -->
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
<dependency id="Examine" version="[0.1.83, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.3, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.3, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="System.Threading.Tasks.Dataflow" version="[4.7.0, 5.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Examine" version="[0.1.70, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.1, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.7.2, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="Markdown" version="[1.14.4, 2.0.0)" />
</dependencies>
</metadata>
<files>
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\net45\businesslogic.dll" />
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\net45\businesslogic.xml" />
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\net45\cms.dll" />
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\net45\cms.xml" />
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\net45\controls.dll" />
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\net45\controls.xml" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\net45\interfaces.dll" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\net45\interfaces.xml" />
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\net45\log4net.dll" />
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\net45\Microsoft.ApplicationBlocks.Data.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\net45\SQLCE4Umbraco.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.xml" target="lib\net45\SQLCE4Umbraco.xml" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\net45\System.Data.SqlServerCe.dll" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\net45\System.Data.SqlServerCe.Entity.dll" />
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\net45\TidyNet.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\net45\Umbraco.Core.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\net45\Umbraco.Core.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\net45\umbraco.DataLayer.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\net45\umbraco.DataLayer.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\net45\umbraco.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\net45\umbraco.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\net45\umbraco.editorControls.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\net45\umbraco.editorControls.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\net45\umbraco.MacroEngines.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\net45\umbraco.MacroEngines.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\net45\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\net45\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\net45\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\net45\Umbraco.Web.UI.xml" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\net45\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\net45\UmbracoExamine.xml" />
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.xml" target="lib\SQLCE4Umbraco.xml" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
<!-- Added to be able to produce a symbols package -->
+4 -6
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata minClientVersion="3.4.4">
<metadata minClientVersion="2.8">
<id>UmbracoCms</id>
<version>7.0.0</version>
<title>Umbraco Cms</title>
@@ -16,10 +16,9 @@
<tags>umbraco</tags>
<dependencies>
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.7, 4.0.0)" />
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.1, 3.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.5, 4.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
</dependencies>
</metadata>
<files>
@@ -46,7 +45,6 @@
<file src="tools\umbracoSettings.config.install.xdt" target="Content\config\umbracoSettings.config.install.xdt" />
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" />
<file src="tools\processing.config.install.xdt" target="Content\Config\imageprocessor\processing.config.install.xdt" />
<file src="tools\cache.config.install.xdt" target="Content\Config\imageprocessor\cache.config.install.xdt" />
<file src="build\**" target="build" />
</files>
</package>
@@ -41,6 +41,16 @@
views/dashboard/developer/examinemanagement.html
</control>
</tab>
<tab caption="Health Check" xdt:Transform="InsertIfMissing" xdt:Locator="Match(caption)">
<control>
views/dashboard/developer/healthcheck.html
</control>
</tab>
<tab caption="Redirect URL Management" xdt:Transform="InsertIfMissing" xdt:Locator="Match(caption)">
<control>
views/dashboard/developer/redirecturls.html
</control>
</tab>
</section>
<section alias="StartupMediaDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
@@ -70,26 +80,4 @@
<tab caption="Change Password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Last Edits" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
</section>
<section alias="RedirectUrlManagement" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas>
<area>content</area>
</areas>
<tab caption="Redirect URL Management">
<control>
views/dashboard/developer/redirecturls.html
</control>
</tab>
</section>
<section alias="UmbracoHealthCheck" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<areas>
<area>developer</area>
</areas>
<tab caption="Health Check">
<control>
views/dashboard/developer/healthcheck.html
</control>
</tab>
</section>
</dashBoard>
+1 -9
View File
@@ -8,17 +8,9 @@
----------------------------------------------------
*** IMPORTANT NOTICE FOR 7.6 UPGRADES ***
Be sure to read the version specific upgrade information before proceeding:
https://our.umbraco.org/documentation/Getting-Started/Setup/Upgrading/version-specific#version-7-6-0
You will most likely need to make some changes to your web.config and you will need to be
aware of the breaking changes listed there to see if these affect your installation.
Don't forget to build!
We've done our best to transform your configuration files but in case something is not quite right: remember we
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
+7 -20
View File
@@ -15,7 +15,6 @@
<section name="BaseRestExtensions" type="Umbraco.Core.Configuration.BaseRest.BaseRestSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="dashBoard" type="Umbraco.Core.Configuration.Dashboard.DashboardSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
<section name="HealthChecks" type="Umbraco.Core.Configuration.HealthChecks.HealthChecksSection, Umbraco.Core" requirePermission="false" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
</sectionGroup>
</configSections>
@@ -31,7 +30,6 @@
<BaseRestExtensions configSource="config\BaseRestExtensions.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<FileSystemProviders configSource="config\FileSystemProviders.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<dashBoard configSource="config\Dashboard.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
<HealthChecks configSource="config\HealthChecks.config" xdt:Locator="Match(configSource)" xdt:Transform="InsertIfMissing" />
</umbracoConfiguration>
<FileSystemProviders xdt:Transform="Remove" />
@@ -60,7 +58,7 @@
<httpRuntime xdt:Transform="InsertIfMissing" />
<httpRuntime maxRequestLength="51200" fcnMode="Single" xdt:Transform="SetAttributes(fcnMode,maxRequestLength)" />
<httpRuntime targetFramework="4.5" xdt:Locator="Condition(count(@targetFramework) != 1)" xdt:Transform="SetAttributes(targetFramework)" />
<membership defaultProvider="DefaultMembershipProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove" />
<roleManager defaultProvider="DefaultRoleProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>
<profile defaultProvider="DefaultProfileProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>>
@@ -332,9 +330,6 @@
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security.Cookies')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.CodeAnalysis.CSharp')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='log4net')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Data.SqlServerCe')" xdt:Transform="Remove" />
</assemblyBinding>
</runtime>
@@ -342,7 +337,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.9.5" newVersion="1.4.9.5" />
<bindingRedirect oldVersion="0.0.0.0-1.4.9.0" newVersion="1.4.9.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
@@ -354,7 +349,7 @@
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -370,32 +365,24 @@
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -1,6 +0,0 @@
<?xml version="1.0"?>
<caching xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<caches>
<cache name="DiskCache" trimCache="false" xdt:Transform="SetAttributes(trimCache)" xdt:Locator="Match(name)" />
</caches>
</caching>
+1
View File
@@ -53,6 +53,7 @@ if ($project) {
if(Test-Path $umbracoBinFolder\umbraco.providers.dll) { Remove-Item $umbracoBinFolder\umbraco.providers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UmbracoExamine.dll) { Remove-Item $umbracoBinFolder\UmbracoExamine.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll) { Remove-Item $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll -Force -Confirm:$false }
# Delete files Umbraco depends upon
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
+14 -25
View File
@@ -34,15 +34,10 @@
xdt:Transform="SetAttributes()" />
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" type="Umbraco.Web.Trees.PartialViewsTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTreeController, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
xdt:Transform="SetAttributes()" />
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
@@ -89,29 +84,23 @@
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco"
xdt:Locator="Match(application,alias,type)"
xdt:Transform="Remove()" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTreeController, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="InsertIfMissing" />
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="developer" alias="python"
xdt:Locator="Match(application,alias)"
xdt:Transform="Remove" />
<!--Users-->
<add initialize="true" sortOrder="0" alias="users" application="users" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.UserTreeController, umbraco"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<add application="users" alias="userTypes"
<add application="users" alias="users" title="Users" type="umbraco.loadUsers, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="0"
xdt:Locator="Match(application,alias)"
xdt:Transform="Remove" />
<add application="users" alias="userPermissions"
xdt:Transform="SetAttributes()" />
<add application="users" alias="userTypes" title="User Types" type="umbraco.cms.presentation.Trees.UserTypes, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="1"
xdt:Locator="Match(application,alias)"
xdt:Transform="Remove" />
xdt:Transform="SetAttributes()" />
<add application="users" alias="userPermissions" title="User Permissions" type="umbraco.cms.presentation.Trees.UserPermissions, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="2"
xdt:Locator="Match(application,alias)"
xdt:Transform="SetAttributes()" />
<!--Members-->
<add initialize="true" sortOrder="0" alias="member" application="member" title="Members" iconClosed="icon-folder" iconOpen="icon-folder-open" type="Umbraco.Web.Trees.MemberTreeController, umbraco"
+1 -2
View File
@@ -1,3 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.7.0
beta
7.5.7
Binary file not shown.
+1 -3
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -49,11 +49,9 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+11 -24
View File
@@ -180,16 +180,12 @@ namespace SqlCE4Umbraco
/// <returns>The return value of the command.</returns>
protected override object ExecuteScalar(string commandText, SqlCeParameter[] parameters)
{
#if DEBUG && DebugDataLayer
#if DEBUG && DebugDataLayer
// Log Query Execution
Trace.TraceInformation(GetType().Name + " SQL ExecuteScalar: " + commandText);
#endif
using (var cc = UseCurrentConnection)
{
return SqlCeApplicationBlock.ExecuteScalar(
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
CommandType.Text, commandText, parameters);
}
#endif
return SqlCeApplicationBlock.ExecuteScalar(ConnectionString, CommandType.Text, commandText, parameters);
}
/// <summary>
@@ -202,17 +198,12 @@ namespace SqlCE4Umbraco
/// </returns>
protected override int ExecuteNonQuery(string commandText, SqlCeParameter[] parameters)
{
#if DEBUG && DebugDataLayer
#if DEBUG && DebugDataLayer
// Log Query Execution
Trace.TraceInformation(GetType().Name + " SQL ExecuteNonQuery: " + commandText);
#endif
#endif
using (var cc = UseCurrentConnection)
{
return SqlCeApplicationBlock.ExecuteNonQuery(
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
CommandType.Text, commandText, parameters);
}
return SqlCeApplicationBlock.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText, parameters);
}
/// <summary>
@@ -225,17 +216,13 @@ namespace SqlCE4Umbraco
/// </returns>
protected override IRecordsReader ExecuteReader(string commandText, SqlCeParameter[] parameters)
{
#if DEBUG && DebugDataLayer
#if DEBUG && DebugDataLayer
// Log Query Execution
Trace.TraceInformation(GetType().Name + " SQL ExecuteReader: " + commandText);
#endif
#endif
using (var cc = UseCurrentConnection)
{
return new SqlCeDataReaderHelper(SqlCeApplicationBlock.ExecuteReader(
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
CommandType.Text, commandText, parameters));
}
return new SqlCeDataReaderHelper(SqlCeApplicationBlock.ExecuteReader(ConnectionString, CommandType.Text,
commandText, parameters));
}
+93 -175
View File
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;
using System.Data;
using System.Diagnostics;
@@ -23,60 +25,29 @@ namespace SqlCE4Umbraco
string commandText,
params SqlCeParameter[] commandParameters
)
{
try
{
using (var conn = SqlCeContextGuardian.Open(connectionString))
{
return ExecuteScalarTry(conn, null, commandText, commandParameters);
}
}
catch (Exception ee)
{
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee);
}
}
public static object ExecuteScalar(
SqlCeConnection conn, SqlCeTransaction trx,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters)
{
try
{
return ExecuteScalarTry(conn, trx, commandText, commandParameters);
}
catch (Exception ee)
{
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee);
}
}
public static object ExecuteScalar(
SqlCeConnection conn,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters)
{
return ExecuteScalar(conn, null, commandType, commandText, commandParameters);
}
private static object ExecuteScalarTry(
SqlCeConnection conn, SqlCeTransaction trx,
string commandText,
params SqlCeParameter[] commandParameters)
{
object retVal;
using (var cmd = trx == null ? new SqlCeCommand(commandText, conn) : new SqlCeCommand(commandText, conn, trx))
try
{
AttachParameters(cmd, commandParameters);
Debug.WriteLine("---------------------------------SCALAR-------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
retVal = cmd.ExecuteScalar();
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
{
using (SqlCeCommand cmd = new SqlCeCommand(commandText, conn))
{
AttachParameters(cmd, commandParameters);
Debug.WriteLine("---------------------------------SCALAR-------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
retVal = cmd.ExecuteScalar();
}
}
return retVal;
}
catch (Exception ee)
{
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
}
return retVal;
}
/// <summary>
@@ -95,10 +66,49 @@ namespace SqlCE4Umbraco
{
try
{
using (var conn = SqlCeContextGuardian.Open(connectionString))
int rowsAffected;
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
{
return ExecuteNonQueryTry(conn, null, commandText, commandParameters);
// this is for multiple queries in the installer
if (commandText.Trim().StartsWith("!!!"))
{
commandText = commandText.Trim().Trim('!');
string[] commands = commandText.Split('|');
string currentCmd = String.Empty;
foreach (string cmd in commands)
{
try
{
currentCmd = cmd;
if (!String.IsNullOrWhiteSpace(cmd))
{
SqlCeCommand c = new SqlCeCommand(cmd, conn);
c.ExecuteNonQuery();
}
}
catch (Exception e)
{
Debug.WriteLine("*******************************************************************");
Debug.WriteLine(currentCmd);
Debug.WriteLine(e);
Debug.WriteLine("*******************************************************************");
}
}
return 1;
}
else
{
Debug.WriteLine("----------------------------------------------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
SqlCeCommand cmd = new SqlCeCommand(commandText, conn);
AttachParameters(cmd, commandParameters);
rowsAffected = cmd.ExecuteNonQuery();
}
}
return rowsAffected;
}
catch (Exception ee)
{
@@ -106,74 +116,6 @@ namespace SqlCE4Umbraco
}
}
public static int ExecuteNonQuery(
SqlCeConnection conn,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters
)
{
return ExecuteNonQuery(conn, null, commandType, commandText, commandParameters);
}
public static int ExecuteNonQuery(
SqlCeConnection conn, SqlCeTransaction trx,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters
)
{
try
{
return ExecuteNonQueryTry(conn, trx, commandText, commandParameters);
}
catch (Exception ee)
{
throw new SqlCeProviderException("Error running NonQuery: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
}
}
private static int ExecuteNonQueryTry(
SqlCeConnection conn, SqlCeTransaction trx,
string commandText,
params SqlCeParameter[] commandParameters)
{
// this is for multiple queries in the installer
if (commandText.Trim().StartsWith("!!!"))
{
commandText = commandText.Trim().Trim('!');
var commands = commandText.Split('|');
var currentCmd = string.Empty;
foreach (var command in commands)
{
try
{
currentCmd = command;
if (string.IsNullOrWhiteSpace(command)) continue;
var c = trx == null ? new SqlCeCommand(command, conn) : new SqlCeCommand(command, conn, trx);
c.ExecuteNonQuery();
}
catch (Exception e)
{
Debug.WriteLine("*******************************************************************");
Debug.WriteLine(currentCmd);
Debug.WriteLine(e);
Debug.WriteLine("*******************************************************************");
}
}
return 1;
}
Debug.WriteLine("----------------------------------------------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
var cmd = new SqlCeCommand(commandText, conn);
AttachParameters(cmd, commandParameters);
var rowsAffected = cmd.ExecuteNonQuery();
return rowsAffected;
}
/// <summary>
///
/// </summary>
@@ -191,8 +133,25 @@ namespace SqlCE4Umbraco
{
try
{
var conn = SqlCeContextGuardian.Open(connectionString);
return ExecuteReaderTry(conn, null, commandText, commandParameters);
Debug.WriteLine("---------------------------------READER-------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
SqlCeDataReader reader;
SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString);
try
{
SqlCeCommand cmd = new SqlCeCommand(commandText, conn);
AttachParameters(cmd, commandParameters);
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
conn.Close();
throw;
}
return reader;
}
catch (Exception ee)
{
@@ -200,71 +159,30 @@ namespace SqlCE4Umbraco
}
}
public static SqlCeDataReader ExecuteReader(
SqlCeConnection conn,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters
)
{
return ExecuteReader(conn, commandType, commandText, commandParameters);
}
public static SqlCeDataReader ExecuteReader(
SqlCeConnection conn, SqlCeTransaction trx,
CommandType commandType,
string commandText,
params SqlCeParameter[] commandParameters
)
{
try
{
return ExecuteReaderTry(conn, trx, commandText, commandParameters);
}
catch (Exception ee)
{
throw new SqlCeProviderException("Error running Reader: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
}
}
private static SqlCeDataReader ExecuteReaderTry(
SqlCeConnection conn, SqlCeTransaction trx,
string commandText,
params SqlCeParameter[] commandParameters)
{
Debug.WriteLine("---------------------------------READER-------------------------------------");
Debug.WriteLine(commandText);
Debug.WriteLine("----------------------------------------------------------------------------");
try
{
var cmd = trx == null ? new SqlCeCommand(commandText, conn) : new SqlCeCommand(commandText, conn, trx);
AttachParameters(cmd, commandParameters);
return cmd.ExecuteReader();
}
catch
{
conn.Close();
throw;
}
}
public static bool VerifyConnection(string connectionString)
{
using (var conn = SqlCeContextGuardian.Open(connectionString))
bool isConnected = false;
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
{
return conn.State == ConnectionState.Open;
isConnected = conn.State == ConnectionState.Open;
}
return isConnected;
}
private static void AttachParameters(SqlCeCommand command, IEnumerable<SqlCeParameter> commandParameters)
private static void AttachParameters(SqlCeCommand command, SqlCeParameter[] commandParameters)
{
foreach (var parameter in commandParameters)
foreach (SqlCeParameter parameter in commandParameters)
{
if ((parameter.Direction == ParameterDirection.InputOutput) && (parameter.Value == null))
{
parameter.Value = DBNull.Value;
}
command.Parameters.Add(parameter);
}
}
}
}
+6 -10
View File
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -16,24 +16,20 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>
</configuration>
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.7.0")]
[assembly: AssemblyInformationalVersion("7.7.0-beta")]
[assembly: AssemblyFileVersion("7.5.7")]
[assembly: AssemblyInformationalVersion("7.5.7")]
+6 -6
View File
@@ -23,12 +23,12 @@ namespace Umbraco.Core
: base(serviceProvider, logger, packageActions)
{
}
/// <summary>
/// Gets the <see cref="IAction"/> implementations.
/// </summary>
public IEnumerable<IAction> Actions
}
/// <summary>
/// Gets the <see cref="IPackageAction"/> implementations.
/// </summary>
public IEnumerable<IAction> Actions
{
get
{
+24 -35
View File
@@ -1,11 +1,12 @@
using System;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Profiling;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
@@ -48,7 +49,7 @@ namespace Umbraco.Core
/// <param name="cache"></param>
[Obsolete("Use the other constructor specifying a ProfilingLogger instead")]
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
: this(dbContext, serviceContext, cache,
: this(dbContext, serviceContext, cache,
new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
{
}
@@ -89,7 +90,7 @@ namespace Umbraco.Core
/// <param name="replaceContext">If set to true and the singleton is already set, it will be replaced</param>
/// <returns></returns>
/// <remarks>
/// This is NOT thread safe
/// This is NOT thread safe
/// </remarks>
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
{
@@ -107,14 +108,14 @@ namespace Umbraco.Core
/// </summary>
/// <param name="cache"></param>
/// <param name="replaceContext">
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
/// startup if for some reason the boot manager is not the umbraco boot manager.
/// </param>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
/// <returns></returns>
/// <remarks>
/// This is NOT thread safe
/// This is NOT thread safe
/// </remarks>
[Obsolete("Use the other method specifying an ProfilingLogger instead")]
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
@@ -135,14 +136,14 @@ namespace Umbraco.Core
/// <param name="cache"></param>
/// <param name="logger"></param>
/// <param name="replaceContext">
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
/// startup if for some reason the boot manager is not the umbraco boot manager.
/// </param>
/// <param name="dbContext"></param>
/// <param name="serviceContext"></param>
/// <returns></returns>
/// <remarks>
/// This is NOT thread safe
/// This is NOT thread safe
/// </remarks>
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext)
{
@@ -161,11 +162,6 @@ namespace Umbraco.Core
/// </summary>
public static ApplicationContext Current { get; internal set; }
/// <summary>
/// Gets the scope provider.
/// </summary>
internal IScopeProvider ScopeProvider { get { return _databaseContext == null ? null : _databaseContext.ScopeProvider; } }
/// <summary>
/// Returns the application wide cache accessor
/// </summary>
@@ -175,7 +171,7 @@ namespace Umbraco.Core
public CacheHelper ApplicationCache { get; private set; }
/// <summary>
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
/// on most base classes or injected with IoC
/// </summary>
public ProfilingLogger ProfilingLogger { get; private set; }
@@ -213,7 +209,7 @@ namespace Umbraco.Core
// GlobalSettings.CurrentVersion returns the hard-coded "current version"
// the system is configured if they match
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
public bool IsConfigured
{
get { return _configured.Value; }
@@ -226,8 +222,8 @@ namespace Umbraco.Core
{
get
{
if (IsConfigured == false
&& DatabaseContext != null
if (IsConfigured == false
&& DatabaseContext != null
&& DatabaseContext.IsDatabaseConfigured)
{
var schemaresult = DatabaseContext.ValidateDatabaseSchema();
@@ -274,12 +270,12 @@ namespace Umbraco.Core
private Lazy<bool> _configured;
internal MainDom MainDom { get; private set; }
private void Init()
{
MainDom = new MainDom(ProfilingLogger.Logger);
MainDom.Acquire();
//Create the lazy value to resolve whether or not the application is 'configured'
_configured = new Lazy<bool>(() =>
{
@@ -289,7 +285,7 @@ namespace Umbraco.Core
var currentVersion = UmbracoVersion.GetSemanticVersion();
var ok =
//we are not configured if this is null
//we are not configured if this is null
string.IsNullOrWhiteSpace(configStatus) == false
//they must match
&& configStatus == currentVersion;
@@ -300,10 +296,10 @@ namespace Umbraco.Core
// if we have a db context available, if we don't then we are not installed anyways
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.CanConnect)
{
var found = Services.MigrationEntryService.FindEntry(Constants.System.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
var found = Services.MigrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
if (found == null)
{
//we haven't executed this migration in this environment, so even though the config versions match,
//we haven't executed this migration in this environment, so even though the config versions match,
// this db has not been updated.
ProfilingLogger.Logger.Debug<ApplicationContext>(string.Format("The migration for version: '{0} has not been executed, there is no record in the database", currentVersion.ToSemanticString()));
ok = false;
@@ -323,7 +319,7 @@ namespace Umbraco.Core
return false;
}
});
});
}
private string ConfigurationStatus
@@ -338,7 +334,7 @@ namespace Umbraco.Core
{
return String.Empty;
}
}
}
}
private void AssertIsNotReady()
@@ -363,7 +359,7 @@ namespace Umbraco.Core
}
internal set { _databaseContext = value; }
}
/// <summary>
/// Gets the current ServiceContext
/// </summary>
@@ -417,27 +413,20 @@ namespace Umbraco.Core
ResolverCollection.ResetAll();
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
Resolution.Reset();
//reset the instance objects
this.ApplicationCache = null;
if (_databaseContext != null) //need to check the internal field here
{
if (_databaseContext.ScopeProvider.AmbientScope != null)
{
var scope = _databaseContext.ScopeProvider.AmbientScope;
scope.Dispose();
}
/*
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
{
DatabaseContext.Database.Dispose();
}
*/
DatabaseContext.Database.Dispose();
}
}
this.DatabaseContext = null;
this.Services = null;
this._isReady = false; //set the internal field
// Indicate that the instance has been disposed.
_disposed = true;
}
-49
View File
@@ -1,49 +0,0 @@
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web;
using Umbraco.Core;
[assembly: PreApplicationStartMethod(typeof(BindingRedirects), "Initialize")]
namespace Umbraco.Core
{
/// <summary>
/// Manages any assembly binding redirects that cannot be done via config (i.e. unsigned --> signed assemblies)
/// </summary>
public sealed class BindingRedirects
{
public static void Initialize()
{
// this only gets called when an assembly can't be resolved
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private static readonly Regex Log4NetAssemblyPattern = new Regex("log4net, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=\\w+$", RegexOptions.Compiled);
private const string Log4NetReplacement = "log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a";
/// <summary>
/// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <returns></returns>
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//log4net:
if (Log4NetAssemblyPattern.IsMatch(args.Name) && args.Name != Log4NetReplacement)
{
return Assembly.Load(Log4NetAssemblyPattern.Replace(args.Name, Log4NetReplacement));
}
//AutoMapper:
// ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow
if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null"))
return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005"));
return null;
}
}
}
-39
View File
@@ -1,39 +0,0 @@
namespace Umbraco.Core
{
public static class ByteArrayExtensions
{
private static readonly char[] BytesToHexStringLookup = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
public static string ToHexString(this byte[] bytes)
{
int i = 0, p = 0, bytesLength = bytes.Length;
var chars = new char[bytesLength * 2];
while (i < bytesLength)
{
var b = bytes[i++];
chars[p++] = BytesToHexStringLookup[b / 0x10];
chars[p++] = BytesToHexStringLookup[b % 0x10];
}
return new string(chars, 0, chars.Length);
}
public static string ToHexString(this byte[] bytes, char separator, int blockSize, int blockCount)
{
int p = 0, bytesLength = bytes.Length, count = 0, size = 0;
var chars = new char[bytesLength * 2 + blockCount];
for (var i = 0; i < bytesLength; i++)
{
var b = bytes[i++];
chars[p++] = BytesToHexStringLookup[b / 0x10];
chars[p++] = BytesToHexStringLookup[b % 0x10];
if (count == blockCount) continue;
if (++size < blockSize) continue;
chars[p++] = '/';
size = 0;
count++;
}
return new string(chars, 0, chars.Length);
}
}
}
+5 -8
View File
@@ -55,10 +55,8 @@ namespace Umbraco.Core.Cache
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string UserCacheKey = "UmbracoUser";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
[EditorBrowsable(EditorBrowsableState.Never)]
public const string UserGroupPermissionsCacheKey = "UmbracoUserGroupPermissions";
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string ContentTypeCacheKey = "UmbracoContentType";
@@ -66,8 +64,7 @@ namespace Umbraco.Core.Cache
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
[Obsolete("No longer used and will be removed in v8")]
[EditorBrowsable(EditorBrowsableState.Never)]
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
@@ -91,7 +88,7 @@ namespace Umbraco.Core.Cache
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
public const string IdToKeyCacheKey = "UI2K__";
public const string KeyToIdCacheKey = "UK2I__";
public const string IdToKeyCacheKey = "UI2K";
public const string KeyToIdCacheKey = "UK2I";
}
}
@@ -26,9 +26,6 @@ namespace Umbraco.Core.Cache
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
{
if (innerProvider.GetType() == typeof(DeepCloneRuntimeCacheProvider))
throw new InvalidOperationException("A " + typeof(DeepCloneRuntimeCacheProvider) + " cannot wrap another instance of " + typeof(DeepCloneRuntimeCacheProvider));
InnerProvider = innerProvider;
}
@@ -108,11 +105,9 @@ namespace Umbraco.Core.Cache
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
if (value == null) return null; // do not store null values (backward compat)
//Clone/reset to go into the cache
return CheckCloneableAndTracksChanges(value);
}, timeout, isSliding, priority, removedCallback, dependentFiles);
//Clone/reset to go out of the cache
return CheckCloneableAndTracksChanges(cached);
}
@@ -1,250 +1,268 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Represents the default cache policy.
/// The default cache policy for retrieving a single entity
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <typeparam name="TId">The type of the identifier.</typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
/// <remarks>
/// <para>The default cache policy caches entities with a 5 minutes sliding expiration.</para>
/// <para>Each entity is cached individually.</para>
/// <para>If options.GetAllCacheAllowZeroCount then a 'zero-count' array is cached when GetAll finds nothing.</para>
/// <para>If options.GetAllCacheValidateCount then we check against the db when getting many entities.</para>
/// 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> : RepositoryCachePolicyBase<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private static readonly TEntity[] EmptyEntities = new TEntity[0]; // const
private readonly RepositoryCachePolicyOptions _options;
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
: base(cache)
{
{
if (options == null) throw new ArgumentNullException("options");
_options = options;
_options = options;
}
public override IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
{
return new ScopedRepositoryCachePolicy<TEntity, TId>(this, runtimeCache, scope);
}
protected string GetEntityCacheKey(object id)
protected string GetCacheIdKey(object id)
{
if (id == null) throw new ArgumentNullException("id");
return GetEntityTypeCacheKey() + id;
return string.Format("{0}{1}", GetCacheTypeKey(), id);
}
protected string GetEntityTypeCacheKey()
protected string GetCacheTypeKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
protected virtual void InsertEntity(string cacheKey, TEntity entity)
{
Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
}
protected virtual void InsertEntities(TId[] ids, TEntity[] entities)
{
if (ids.Length == 0 && entities.Length == 0 && _options.GetAllCacheAllowZeroCount)
{
// getting all of them, and finding nothing.
// if we can cache a zero count, cache an empty array,
// for as long as the cache is not cleared (no expiration)
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => EmptyEntities);
}
else
{
// individually cache each item
foreach (var entity in entities)
{
var capture = entity;
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
}
}
}
/// <inheritdoc />
public override void Create(TEntity entity, Action<TEntity> persistNew)
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistNew(entity);
persistMethod(entity);
// just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
//set the disposal action
SetCacheAction(() =>
{
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
}
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetEntityTypeCacheKey());
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
catch
{
// if an exception is thrown we need to remove the entry from cache,
// this is ONLY a work around because of the way
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetEntityTypeCacheKey());
//set the disposal action
SetCacheAction(() =>
{
//if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
Cache.ClearCacheItem(GetCacheIdKey(entity.Id));
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetCacheTypeKey());
});
throw;
}
}
/// <inheritdoc />
public override void Update(TEntity entity, Action<TEntity> persistUpdated)
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistUpdated(entity);
// just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
}
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetEntityTypeCacheKey());
}
catch
{
// if an exception is thrown we need to remove the entry from cache,
// this is ONLY a work around because of the way
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetEntityTypeCacheKey());
throw;
}
}
/// <inheritdoc />
public override void Delete(TEntity entity, Action<TEntity> persistDeleted)
{
if (entity == null) throw new ArgumentNullException("entity");
try
{
persistDeleted(entity);
persistMethod(entity);
}
finally
{
// whatever happens, clear the cache
var cacheKey = GetEntityCacheKey(entity.Id);
Cache.ClearCacheItem(cacheKey);
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetEntityTypeCacheKey());
//set the disposal action
var cacheKey = GetCacheIdKey(entity.Id);
SetCacheAction(() =>
{
Cache.ClearCacheItem(cacheKey);
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
}
/// <inheritdoc />
public override TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
{
var cacheKey = GetEntityCacheKey(id);
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
// if found in cache then return else fetch and cache
var cacheKey = GetCacheIdKey(id);
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
if (fromCache != null)
return fromCache;
var entity = performGet(id);
var entity = getFromRepo(id);
if (entity != null && entity.HasIdentity)
InsertEntity(cacheKey, entity);
//set the disposal action
SetCacheAction(cacheKey, entity);
return entity;
}
/// <inheritdoc />
public override TEntity GetCached(TId id)
public override TEntity Get(TId id)
{
var cacheKey = GetEntityCacheKey(id);
var cacheKey = GetCacheIdKey(id);
return Cache.GetCacheItem<TEntity>(cacheKey);
}
/// <inheritdoc />
public override bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
{
// if found in cache the return else check
var cacheKey = GetEntityCacheKey(id);
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
var cacheKey = GetCacheIdKey(id);
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
return fromCache != null || performExists(id);
return fromCache != null || getFromRepo(id);
}
/// <inheritdoc />
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
if (ids.Length > 0)
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
if (ids.Any())
{
// try to get each entity from the cache
// if we can find all of them, return
var entities = ids.Select(GetCached).WhereNotNull().ToArray();
if (ids.Length.Equals(entities.Length))
return entities; // no need for null checks, we are not caching nulls
var entities = ids.Select(Get).ToArray();
if (ids.Length.Equals(entities.Length) && entities.Any(x => x == null) == false)
return entities;
}
else
{
// get everything we have
var entities = Cache.GetCacheItemsByKeySearch<TEntity>(GetEntityTypeCacheKey())
.ToArray(); // no need for null checks, we are not caching nulls
if (entities.Length > 0)
var allEntities = GetAllFromCache();
if (allEntities.Any())
{
// if some of them were in the cache...
if (_options.GetAllCacheValidateCount)
{
// need to validate the count, get the actual count and return if ok
//Get count of all entities of current type (TEntity) to ensure cached result is correct
var totalCount = _options.PerformCount();
if (entities.Length == totalCount)
return entities;
if (allEntities.Length == totalCount)
return allEntities;
}
else
{
// no need to validate, just return what we have and assume it's all there is
return entities;
return allEntities;
}
}
else if (_options.GetAllCacheAllowZeroCount)
{
// if none of them were in the cache
// and we allow zero count - check for the special (empty) entry
var empty = Cache.GetCacheItem<TEntity[]>(GetEntityTypeCacheKey());
if (empty != null) return empty;
//if the repository allows caching a zero count, then check the zero count cache
if (HasZeroCountCache())
{
//there is a zero count cache so return an empty list
return new TEntity[] {};
}
}
}
// cache failed, get from repo and cache
var repoEntities = performGetAll(ids)
.WhereNotNull() // exclude nulls!
.Where(x => x.HasIdentity) // be safe, though would be weird...
//we need to do the lookup from the repo
var entityCollection = getFromRepo(ids)
//ensure we don't include any null refs in the returned collection!
.WhereNotNull()
.ToArray();
// note: if empty & allow zero count, will cache a special (empty) entry
InsertEntities(ids, repoEntities);
//set the disposal action
SetCacheAction(ids, entityCollection);
return repoEntities;
return entityCollection;
}
/// <inheritdoc />
public override void ClearAll()
/// <summary>
/// Looks up the zero count cache, must return null if it doesn't exist
/// </summary>
/// <returns></returns>
protected bool HasZeroCountCache()
{
Cache.ClearAllCache();
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
return (zeroCount != null && zeroCount.Any() == false);
}
/// <summary>
/// Performs the lookup for all entities of this type from the cache
/// </summary>
/// <returns></returns>
protected TEntity[] GetAllFromCache()
{
var allEntities = Cache.GetCacheItemsByKeySearch<TEntity>(GetCacheTypeKey())
.WhereNotNull()
.ToArray();
return allEntities.Any() ? allEntities : new TEntity[] {};
}
/// <summary>
/// Sets the action to execute on disposal for a single entity
/// </summary>
/// <param name="cacheKey"></param>
/// <param name="entity"></param>
protected virtual void SetCacheAction(string cacheKey, TEntity entity)
{
if (entity == null) return;
SetCacheAction(() =>
{
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
Cache.InsertCacheItem(cacheKey, () => entity,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
});
}
/// <summary>
/// Sets the action to execute on disposal for an entity collection
/// </summary>
/// <param name="ids"></param>
/// <param name="entityCollection"></param>
protected virtual void SetCacheAction(TId[] ids, TEntity[] entityCollection)
{
SetCacheAction(() =>
{
//This option cannot execute if we are looking up specific Ids
if (ids.Any() == false && entityCollection.Length == 0 && _options.GetAllCacheAllowZeroCount)
{
//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
{
//This is the default behavior, we'll individually cache each item so that if/when these items are resolved
// by id, they are returned from the already existing cache.
foreach (var entity in entityCollection.WhereNotNull())
{
var localCopy = entity;
//just to be safe, we cannot cache an item without an identity
if (localCopy.HasIdentity)
{
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
}
}
});
}
}
}
@@ -0,0 +1,27 @@
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Creates cache policies
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class DefaultRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly RepositoryCachePolicyOptions _options;
public DefaultRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
{
_runtimeCache = runtimeCache;
_options = options;
}
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
{
return new DefaultRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _options);
}
}
}
@@ -3,178 +3,227 @@ using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Collections;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Represents a caching policy that caches the entire entities set as a single collection.
/// A caching policy that caches an entire dataset as a single collection
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <typeparam name="TId">The type of the identifier.</typeparam>
/// <remarks>
/// <para>Caches the entire set of entities as a single collection.</para>
/// <para>Used by Content-, Media- and MemberTypeRepository, DataTypeRepository, DomainRepository,
/// LanguageRepository, PublicAccessRepository, TemplateRepository... things that make sense to
/// keep as a whole in memory.</para>
/// </remarks>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly Func<TEntity, TId> _entityGetId;
private readonly Func<TEntity, TId> _getEntityId;
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
private readonly bool _expires;
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> entityGetId, bool expires)
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
: base(cache)
{
_entityGetId = entityGetId;
_getEntityId = getEntityId;
_getAllFromRepo = getAllFromRepo;
_expires = expires;
}
public override IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
{
return new ScopedRepositoryCachePolicy<TEntity, TId>(this, runtimeCache, scope);
}
private bool? _hasZeroCountCache;
protected static readonly TId[] EmptyIds = new TId[0]; // const
protected string GetEntityTypeCacheKey()
protected string GetCacheTypeKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
protected void InsertEntities(TEntity[] entities)
{
// cache is expected to be a deep-cloning cache ie it deep-clones whatever is
// IDeepCloneable when it goes in, and out. it also resets dirty properties,
// making sure that no 'dirty' entity is cached.
//
// this policy is caching the entire list of entities. to ensure that entities
// are properly deep-clones when cached, it uses a DeepCloneableList. however,
// we don't want to deep-clone *each* entity in the list when fetching it from
// cache as that would not be efficient for Get(id). so the DeepCloneableList is
// set to ListCloneBehavior.CloneOnce ie it will clone *once* when inserting,
// and then will *not* clone when retrieving.
if (_expires)
{
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList<TEntity>(entities), TimeSpan.FromMinutes(5), true);
}
else
{
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList<TEntity>(entities));
}
}
/// <inheritdoc />
public override void Create(TEntity entity, Action<TEntity> persistNew)
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistNew(entity);
persistMethod(entity);
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
finally
catch
{
ClearAll();
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
throw;
}
}
/// <inheritdoc />
public override void Update(TEntity entity, Action<TEntity> persistUpdated)
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
{
if (entity == null) throw new ArgumentNullException("entity");
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
persistUpdated(entity);
persistMethod(entity);
}
finally
{
ClearAll();
//set the disposal action
SetCacheAction(() =>
{
//Clear all
Cache.ClearCacheItem(GetCacheTypeKey());
});
}
}
/// <inheritdoc />
public override void Delete(TEntity entity, Action<TEntity> persistDeleted)
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
{
if (entity == null) throw new ArgumentNullException("entity");
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
try
//we don't have anything in cache (this should never happen), just return from the repo
if (found == null) return getFromRepo(id);
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
if (entity == null) return null;
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
return (TEntity)entity.DeepClone();
}
public override TEntity Get(TId id)
{
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
//we don't have anything in cache (this should never happen), just return null
if (found == null) return null;
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
if (entity == null) return null;
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
return (TEntity)entity.DeepClone();
}
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
{
//Force get all with cache
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
//we don't have anything in cache (this should never happen), just return from the repo
return found == null
? getFromRepo(id)
: found.Any(x => _getEntityId(x).Equals(id));
}
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
//process getting all including setting the cache callback
var result = PerformGetAll(getFromRepo);
//now that the base result has been calculated, they will all be cached.
// Now we can just filter by ids if they have been supplied
return (ids.Any()
? result.Where(x => ids.Contains(_getEntityId(x))).ToArray()
: result)
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
.Select(x => (TEntity)x.DeepClone())
.ToArray();
}
private TEntity[] PerformGetAll(Func<TId[], IEnumerable<TEntity>> getFromRepo)
{
var allEntities = GetAllFromCache();
if (allEntities.Any())
{
persistDeleted(entity);
return allEntities;
}
finally
//check the zero count cache
if (HasZeroCountCache())
{
ClearAll();
//there is a zero count cache so return an empty list
return new TEntity[] { };
}
//we need to do the lookup from the repo
var entityCollection = getFromRepo(new TId[] { })
//ensure we don't include any null refs in the returned collection!
.WhereNotNull()
.ToArray();
//set the disposal action
SetCacheAction(entityCollection);
return entityCollection;
}
/// <inheritdoc />
public override TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
/// <summary>
/// For this type of caching policy, we don't cache individual items
/// </summary>
/// <param name="cacheKey"></param>
/// <param name="entity"></param>
protected void SetCacheAction(string cacheKey, TEntity entity)
{
// get all from the cache, then look for the entity
var all = GetAllCached(performGetAll);
var entity = all.FirstOrDefault(x => _entityGetId(x).Equals(id));
// see note in InsertEntities - what we get here is the original
// cached entity, not a clone, so we need to manually ensure it is deep-cloned.
return entity == null ? null : (TEntity) entity.DeepClone();
//No-op
}
/// <inheritdoc />
public override TEntity GetCached(TId id)
/// <summary>
/// Sets the action to execute on disposal for an entity collection
/// </summary>
/// <param name="entityCollection"></param>
protected void SetCacheAction(TEntity[] entityCollection)
{
// get all from the cache -- and only the cache, then look for the entity
var all = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetEntityTypeCacheKey());
var entity = all == null ? null : all.FirstOrDefault(x => _entityGetId(x).Equals(id));
//set the disposal action
SetCacheAction(() =>
{
//We want to cache the result as a single collection
// see note in InsertEntities - what we get here is the original
// cached entity, not a clone, so we need to manually ensure it is deep-cloned.
return entity == null ? null : (TEntity)entity.DeepClone();
if (_expires)
{
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection),
timeout: TimeSpan.FromMinutes(5),
isSliding: true);
}
else
{
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
}
});
}
/// <inheritdoc />
public override bool Exists(TId id, Func<TId, bool> performExits, Func<TId[], IEnumerable<TEntity>> performGetAll)
/// <summary>
/// Looks up the zero count cache, must return null if it doesn't exist
/// </summary>
/// <returns></returns>
protected bool HasZeroCountCache()
{
// get all as one set, then look for the entity
var all = GetAllCached(performGetAll);
return all.Any(x => _entityGetId(x).Equals(id));
if (_hasZeroCountCache.HasValue)
return _hasZeroCountCache.Value;
_hasZeroCountCache = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey()) != null;
return _hasZeroCountCache.Value;
}
/// <inheritdoc />
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
/// <summary>
/// This policy will cache the full data set as a single collection
/// </summary>
/// <returns></returns>
protected TEntity[] GetAllFromCache()
{
// get all as one set, from cache if possible, else repo
var all = GetAllCached(performGetAll);
var found = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey());
// if ids have been specified, filter
if (ids.Length > 0) all = all.Where(x => ids.Contains(_entityGetId(x)));
//This method will get called before checking for zero count cache, so we'll just set the flag here
_hasZeroCountCache = found != null;
// and return
// see note in SetCacheActionToInsertEntities - what we get here is the original
// cached entities, not clones, so we need to manually ensure they are deep-cloned.
return all.Select(x => (TEntity) x.DeepClone()).ToArray();
return found == null ? new TEntity[] { } : found.WhereNotNull().ToArray();
}
// does NOT clone anything, so be nice with the returned values
private IEnumerable<TEntity> GetAllCached(Func<TId[], IEnumerable<TEntity>> performGetAll)
{
// try the cache first
var all = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetEntityTypeCacheKey());
if (all != null) return all.ToArray();
// else get from repo and cache
var entities = performGetAll(EmptyIds).WhereNotNull().ToArray();
InsertEntities(entities); // may be an empty array...
return entities;
}
/// <inheritdoc />
public override void ClearAll()
{
Cache.ClearCacheItem(GetEntityTypeCacheKey());
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Creates cache policies
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class FullDataSetRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly Func<TEntity, TId> _getEntityId;
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
private readonly bool _expires;
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
{
_runtimeCache = runtimeCache;
_getEntityId = getEntityId;
_getAllFromRepo = getAllFromRepo;
_expires = expires;
}
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
{
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _getEntityId, _getAllFromRepo, _expires);
}
}
}
@@ -154,7 +154,7 @@ namespace Umbraco.Core.Cache
value = result.Value; // will not throw (safe lazy)
var eh = value as ExceptionHolder;
if (eh != null) throw new Exception("Exception while creating a value.", eh.Exception); // throw once!
if (eh != null) throw eh.Exception; // throw once!
return value;
}
@@ -1,97 +1,18 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
internal interface IRepositoryCachePolicy<TEntity, TId>
internal interface IRepositoryCachePolicy<TEntity, TId> : IDisposable
where TEntity : class, IAggregateRoot
{
// note:
// at the moment each repository instance creates its corresponding cache policy instance
// we could reduce allocations by using static cache policy instances but then we would need
// to modify all methods here to pass the repository and cache eg:
//
// TEntity Get(TRepository repository, IRuntimeCacheProvider cache, TId id);
//
// it is not *that* complicated but then RepositoryBase needs to have a TRepository generic
// type parameter and it all becomes convoluted - keeping it simple for the time being.
/// <summary>
/// Creates a scoped version of this cache policy.
/// </summary>
/// <param name="runtimeCache">The global isolated runtime cache for this policy.</param>
/// <param name="scope">The scope.</param>
/// <remarks>When a policy is scoped, it means that it has been created with a scoped
/// isolated runtime cache, and now it needs to be wrapped into something that can apply
/// changes to the global isolated runtime cache.</remarks>
IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope);
/// <summary>
/// Gets an entity from the cache, else from the repository.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="performGet">The repository PerformGet method.</param>
/// <param name="performGetAll">The repository PerformGetAll method.</param>
/// <returns>The entity with the specified identifier, if it exits, else null.</returns>
/// <remarks>First considers the cache then the repository.</remarks>
TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <summary>
/// Gets an entity from the cache.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>The entity with the specified identifier, if it is in the cache already, else null.</returns>
/// <remarks>Does not consider the repository at all.</remarks>
TEntity GetCached(TId id);
/// <summary>
/// Gets a value indicating whether an entity with a specified identifier exists.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="performExists">The repository PerformExists method.</param>
/// <param name="performGetAll">The repository PerformGetAll method.</param>
/// <returns>A value indicating whether an entity with the specified identifier exists.</returns>
/// <remarks>First considers the cache then the repository.</remarks>
bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <summary>
/// Creates an entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <param name="persistNew">The repository PersistNewItem method.</param>
/// <remarks>Creates the entity in the repository, and updates the cache accordingly.</remarks>
void Create(TEntity entity, Action<TEntity> persistNew);
/// <summary>
/// Updates an entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <param name="persistUpdated">The reopsitory PersistUpdatedItem method.</param>
/// <remarks>Updates the entity in the repository, and updates the cache accordingly.</remarks>
void Update(TEntity entity, Action<TEntity> persistUpdated);
/// <summary>
/// Removes an entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <param name="persistDeleted">The repository PersistDeletedItem method.</param>
/// <remarks>Removes the entity from the repository and clears the cache.</remarks>
void Delete(TEntity entity, Action<TEntity> persistDeleted);
/// <summary>
/// Gets entities.
/// </summary>
/// <param name="ids">The identifiers.</param>
/// <param name="performGetAll">The repository PerformGetAll method.</param>
/// <returns>If <paramref name="ids"/> is empty, all entities, else the entities with the specified identifiers.</returns>
/// <remarks>Get all the entities. Either from the cache or the repository depending on the implementation.</remarks>
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <summary>
/// Clears the entire cache.
/// </summary>
void ClearAll();
TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
TEntity Get(TId id);
bool Exists(TId id, Func<TId, bool> getFromRepo);
void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
void Remove(TEntity entity, Action<TEntity> persistMethod);
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
}
}
@@ -0,0 +1,9 @@
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
internal interface IRepositoryCachePolicyFactory<TEntity, TId> where TEntity : class, IAggregateRoot
{
IRepositoryCachePolicy<TEntity, TId> CreatePolicy();
}
}
@@ -1,62 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
internal class NoRepositoryCachePolicy<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private static readonly NoRepositoryCachePolicy<TEntity, TId> StaticInstance = new NoRepositoryCachePolicy<TEntity, TId>();
private NoRepositoryCachePolicy()
{ }
public static NoRepositoryCachePolicy<TEntity, TId> Instance { get { return StaticInstance; } }
public IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
{
throw new NotImplementedException();
}
public TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
return performGet(id);
}
public TEntity GetCached(TId id)
{
return null;
}
public bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
return performExists(id);
}
public void Create(TEntity entity, Action<TEntity> persistNew)
{
persistNew(entity);
}
public void Update(TEntity entity, Action<TEntity> persistUpdated)
{
persistUpdated(entity);
}
public void Delete(TEntity entity, Action<TEntity> persistDeleted)
{
persistDeleted(entity);
}
public TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
return performGetAll(ids).ToArray();
}
public void ClearAll()
{ }
}
}
@@ -0,0 +1,27 @@
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Creates cache policies
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class OnlySingleItemsRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly RepositoryCachePolicyOptions _options;
public OnlySingleItemsRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
{
_runtimeCache = runtimeCache;
_options = options;
}
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
{
return new SingleItemsOnlyRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _options);
}
}
}
@@ -1,51 +1,48 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A base class for repository cache policies.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <typeparam name="TId">The type of the identifier.</typeparam>
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private Action _action;
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
{
if (cache == null) throw new ArgumentNullException("cache");
if (cache == null) throw new ArgumentNullException("cache");
Cache = cache;
}
public abstract IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope);
protected IRuntimeCacheProvider Cache { get; private set; }
/// <inheritdoc />
public abstract TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <summary>
/// The disposal performs the caching
/// </summary>
protected override void DisposeResources()
{
if (_action != null)
{
_action();
}
}
/// <inheritdoc />
public abstract TEntity GetCached(TId id);
/// <inheritdoc />
public abstract bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <inheritdoc />
public abstract void Create(TEntity entity, Action<TEntity> persistNew);
/// <inheritdoc />
public abstract void Update(TEntity entity, Action<TEntity> persistUpdated);
/// <inheritdoc />
public abstract void Delete(TEntity entity, Action<TEntity> persistDeleted);
/// <inheritdoc />
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll);
/// <inheritdoc />
public abstract void ClearAll();
/// <summary>
/// Sets the action to execute on disposal
/// </summary>
/// <param name="action"></param>
protected void SetCacheAction(Action action)
{
_action = action;
}
public abstract TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
public abstract TEntity Get(TId id);
public abstract bool Exists(TId id, Func<TId, bool> getFromRepo);
public abstract void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
public abstract void Remove(TEntity entity, Action<TEntity> persistMethod);
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
}
}
@@ -2,9 +2,6 @@ using System;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Specifies how a repository cache policy should cache entities.
/// </summary>
internal class RepositoryCachePolicyOptions
{
/// <summary>
@@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Cache
{
internal class ScopedRepositoryCachePolicy<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
private readonly IRepositoryCachePolicy<TEntity, TId> _cachePolicy;
private readonly IRuntimeCacheProvider _globalIsolatedCache;
private readonly IScope _scope;
public ScopedRepositoryCachePolicy(IRepositoryCachePolicy<TEntity, TId> cachePolicy, IRuntimeCacheProvider globalIsolatedCache, IScope scope)
{
_cachePolicy = cachePolicy;
_globalIsolatedCache = globalIsolatedCache;
_scope = scope;
}
public IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
{
throw new InvalidOperationException(); // obviously
}
public TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
// loads into the local cache only, ok for now
return _cachePolicy.Get(id, performGet, performGetAll);
}
public TEntity GetCached(TId id)
{
// loads into the local cache only, ok for now
return _cachePolicy.GetCached(id);
}
public bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
// loads into the local cache only, ok for now
return _cachePolicy.Exists(id, performExists, performGetAll);
}
public void Create(TEntity entity, Action<TEntity> persistNew)
{
// writes into the local cache
_cachePolicy.Create(entity, persistNew);
}
public void Update(TEntity entity, Action<TEntity> persistUpdated)
{
// writes into the local cache
_cachePolicy.Update(entity, persistUpdated);
}
public void Delete(TEntity entity, Action<TEntity> persistDeleted)
{
// deletes the local cache
_cachePolicy.Delete(entity, persistDeleted);
}
public TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
{
// loads into the local cache only, ok for now
return _cachePolicy.GetAll(ids, performGetAll);
}
public void ClearAll()
{
// clears the local cache
_cachePolicy.ClearAll();
}
}
}
@@ -1,27 +1,24 @@
using System.Linq;
using Umbraco.Core.Collections;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Represents a special policy that does not cache the result of GetAll.
/// A caching policy that ignores all caches for GetAll - it will only cache calls for individual items
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <typeparam name="TId">The type of the identifier.</typeparam>
/// <remarks>
/// <para>Overrides the default repository cache policy and does not writes the result of GetAll
/// to cache, but only the result of individual Gets. It does read the cache for GetAll, though.</para>
/// <para>Used by DictionaryRepository.</para>
/// </remarks>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TId"></typeparam>
internal class SingleItemsOnlyRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
where TEntity : class, IAggregateRoot
{
public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
: base(cache, options)
{ }
protected override void InsertEntities(TId[] ids, TEntity[] entities)
public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options) : base(cache, options)
{
// nop
}
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
{
//no-op
}
}
}
+1 -8
View File
@@ -21,10 +21,6 @@ namespace Umbraco.Core
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider();
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider();
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider();
private static readonly IsolatedRuntimeCache NullIsolatedCache = new IsolatedRuntimeCache(_ => NullRuntimeCache);
private static readonly CacheHelper NullCache = new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, NullIsolatedCache);
public static CacheHelper NoCache { get { return NullCache; } }
/// <summary>
/// Creates a cache helper with disabled caches
@@ -35,10 +31,7 @@ namespace Umbraco.Core
/// </remarks>
public static CacheHelper CreateDisabledCacheHelper()
{
// do *not* return NoCache
// NoCache is a special instance that is detected by RepositoryBase and disables all cache policies
// CreateDisabledCacheHelper is used in tests to use no cache, *but* keep all cache policies
return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, NullIsolatedCache);
return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, new IsolatedRuntimeCache(t => NullRuntimeCache));
}
/// <summary>
@@ -1,34 +0,0 @@
using System;
namespace Umbraco.Core.CodeAnnotations
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal class ActionMetadataAttribute : Attribute
{
public string Category { get; private set; }
public string Name { get; private set; }
/// <summary>
/// Constructor used to assign a Category, since no name is assigned it will try to be translated from the language files based on the action's alias
/// </summary>
/// <param name="category"></param>
public ActionMetadataAttribute(string category)
{
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentException("Value cannot be null or whitespace.", "category");
Category = category;
}
/// <summary>
/// Constructor used to assign an explicit name and category
/// </summary>
/// <param name="category"></param>
/// <param name="name"></param>
public ActionMetadataAttribute(string category, string name)
{
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentException("Value cannot be null or whitespace.", "category");
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Value cannot be null or whitespace.", "name");
Category = category;
Name = name;
}
}
}
@@ -1,15 +0,0 @@
using System;
namespace Umbraco.Core.CodeAnnotations
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal class UmbracoUdiTypeAttribute : Attribute
{
public string UdiType { get; private set; }
public UmbracoUdiTypeAttribute(string udiType)
{
UdiType = udiType;
}
}
}
@@ -1,9 +0,0 @@
namespace Umbraco.Core.Configuration
{
internal enum ContentXmlStorage
{
Default,
AspNetTemp,
EnvironmentTemp
}
}
@@ -1,31 +0,0 @@
using System;
namespace Umbraco.Core.Configuration
{
internal static class CoreDebugExtensions
{
private static CoreDebug _coreDebug;
public static CoreDebug CoreDebug(this UmbracoConfig config)
{
return _coreDebug ?? (_coreDebug = new CoreDebug());
}
}
internal class CoreDebug
{
public CoreDebug()
{
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
}
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
// this helps troubleshooting rogue scopes that we forget to complete
public bool LogUncompletedScopes { get; private set; }
// when true, the Logger creates a minidump of w3wp in ~/App_Data/MiniDump whenever it logs
// an error due to a ThreadAbortException that is due to a timeout.
public bool DumpOnTimeoutThreadAbort { get; private set; }
}
}
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Configuration;
using System.Web;
using System.Web.Configuration;
using System.Web.Hosting;
@@ -43,6 +42,7 @@ namespace Umbraco.Core.Configuration
//ensure the built on (non-changeable) reserved paths are there at all times
private const string StaticReservedPaths = "~/app_plugins/,~/install/,";
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
#endregion
/// <summary>
@@ -53,7 +53,6 @@ namespace Umbraco.Core.Configuration
_reservedUrlsCache = null;
_reservedPaths = null;
_reservedUrls = null;
HasSmtpServer = null;
}
/// <summary>
@@ -65,26 +64,7 @@ namespace Umbraco.Core.Configuration
ResetInternal();
}
public static bool HasSmtpServerConfigured(string appPath)
{
if (HasSmtpServer.HasValue) return HasSmtpServer.Value;
var config = WebConfigurationManager.OpenWebConfiguration(appPath);
var settings = (MailSettingsSectionGroup)config.GetSectionGroup("system.net/mailSettings");
if (settings == null || settings.Smtp == null) return false;
if (settings.Smtp.SpecifiedPickupDirectory != null && string.IsNullOrEmpty(settings.Smtp.SpecifiedPickupDirectory.PickupDirectoryLocation) == false)
return true;
if (settings.Smtp.Network != null && string.IsNullOrEmpty(settings.Smtp.Network.Host) == false)
return true;
return false;
}
/// <summary>
/// For testing only
/// </summary>
internal static bool? HasSmtpServer { get; set; }
/// <summary>
/// <summary>
/// Gets the reserved urls from web.config.
/// </summary>
/// <value>The reserved urls.</value>
@@ -232,7 +212,7 @@ namespace Umbraco.Core.Configuration
{
get
{
var settings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];
var settings = ConfigurationManager.ConnectionStrings[UmbracoConnectionName];
var connectionString = string.Empty;
if (settings != null)
@@ -261,7 +241,10 @@ namespace Umbraco.Core.Configuration
}
}
}
//TODO: Move these to constants!
public const string UmbracoConnectionName = "umbracoDbDSN";
public const string UmbracoMigrationName = "Umbraco";
/// <summary>
/// Gets or sets the configuration status. This will return the version number of the currently installed umbraco instance.
@@ -537,25 +520,12 @@ namespace Umbraco.Core.Configuration
}
internal static bool ContentCacheXmlStoredInCodeGen
{
get { return ContentCacheXmlStorageLocation == ContentXmlStorage.AspNetTemp; }
}
internal static ContentXmlStorage ContentCacheXmlStorageLocation
{
get
{
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLStorage"))
{
return Enum<ContentXmlStorage>.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]);
}
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp"))
{
return bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"])
? ContentXmlStorage.AspNetTemp
: ContentXmlStorage.Default;
}
return ContentXmlStorage.Default;
//defaults to false
return ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp")
&& bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"]); //default to false
}
}
@@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Configuration.HealthChecks
{
public class DisabledHealthCheckElement : ConfigurationElement, IDisabledHealthCheck
{
private const string IdKey = "id";
private const string DisabledOnKey = "disabledOn";
private const string DisabledByKey = "disabledBy";
[ConfigurationProperty(IdKey, IsKey = true, IsRequired = true)]
public Guid Id
{
get
{
return ((Guid)(base[IdKey]));
}
}
[ConfigurationProperty(DisabledOnKey, IsKey = false, IsRequired = false)]
public DateTime DisabledOn
{
get
{
return ((DateTime)(base[DisabledOnKey]));
}
}
[ConfigurationProperty(DisabledByKey, IsKey = false, IsRequired = false)]
public int DisabledBy
{
get
{
return ((int)(base[DisabledByKey]));
}
}
}
}
@@ -1,40 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.HealthChecks
{
[ConfigurationCollection(typeof(DisabledHealthCheckElement), AddItemName = "check")]
public class DisabledHealthChecksElementCollection : ConfigurationElementCollection, IEnumerable<IDisabledHealthCheck>
{
protected override ConfigurationElement CreateNewElement()
{
return new DisabledHealthCheckElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((DisabledHealthCheckElement)(element)).Id;
}
public new DisabledHealthCheckElement this[string key]
{
get
{
return (DisabledHealthCheckElement)BaseGet(key);
}
}
IEnumerator<IDisabledHealthCheck> IEnumerable<IDisabledHealthCheck>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as DisabledHealthCheckElement;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.HealthChecks
{
public class HealthCheckNotificationSettingsElement : ConfigurationElement, IHealthCheckNotificationSettings
{
private const string EnabledKey = "enabled";
private const string FirstRunTimeKey = "firstRunTime";
private const string PeriodKey = "periodInHours";
private const string NotificationMethodsKey = "notificationMethods";
private const string DisabledChecksKey = "disabledChecks";
[ConfigurationProperty(EnabledKey, IsRequired = true)]
public bool Enabled
{
get
{
return (bool)base[EnabledKey];
}
}
[ConfigurationProperty(FirstRunTimeKey, IsRequired = false)]
public string FirstRunTime
{
get
{
return (string)base[FirstRunTimeKey];
}
}
[ConfigurationProperty(PeriodKey, IsRequired = true)]
public int PeriodInHours
{
get
{
return (int)base[PeriodKey];
}
}
[ConfigurationProperty(NotificationMethodsKey, IsDefaultCollection = true, IsRequired = false)]
public NotificationMethodsElementCollection NotificationMethods
{
get
{
return (NotificationMethodsElementCollection)base[NotificationMethodsKey];
}
}
[ConfigurationProperty(DisabledChecksKey, IsDefaultCollection = false, IsRequired = false)]
public DisabledHealthChecksElementCollection DisabledChecks
{
get
{
return (DisabledHealthChecksElementCollection)base[DisabledChecksKey];
}
}
bool IHealthCheckNotificationSettings.Enabled
{
get { return Enabled; }
}
string IHealthCheckNotificationSettings.FirstRunTime
{
get { return FirstRunTime; }
}
int IHealthCheckNotificationSettings.PeriodInHours
{
get { return PeriodInHours; }
}
IReadOnlyDictionary<string, INotificationMethod> IHealthCheckNotificationSettings.NotificationMethods
{
get { return NotificationMethods; }
}
IEnumerable<IDisabledHealthCheck> IHealthCheckNotificationSettings.DisabledChecks
{
get { return DisabledChecks; }
}
}
}
@@ -1,8 +0,0 @@
namespace Umbraco.Core.Configuration.HealthChecks
{
public enum HealthCheckNotificationVerbosity
{
Summary,
Detailed
}
}
@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.HealthChecks
{
public class HealthChecksSection : ConfigurationSection, IHealthChecks
{
private const string DisabledChecksKey = "disabledChecks";
private const string NotificationSettingsKey = "notificationSettings";
[ConfigurationProperty(DisabledChecksKey)]
public DisabledHealthChecksElementCollection DisabledChecks
{
get { return ((DisabledHealthChecksElementCollection)(base[DisabledChecksKey])); }
}
[ConfigurationProperty(NotificationSettingsKey, IsRequired = true)]
public HealthCheckNotificationSettingsElement NotificationSettings
{
get { return ((HealthCheckNotificationSettingsElement)(base[NotificationSettingsKey])); }
}
IEnumerable<IDisabledHealthCheck> IHealthChecks.DisabledChecks
{
get { return DisabledChecks; }
}
IHealthCheckNotificationSettings IHealthChecks.NotificationSettings
{
get { return NotificationSettings; }
}
}
}
@@ -1,11 +0,0 @@
using System;
namespace Umbraco.Core.Configuration.HealthChecks
{
public interface IDisabledHealthCheck
{
Guid Id { get; }
DateTime DisabledOn { get; }
int DisabledBy { get; }
}
}
@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.HealthChecks
{
public interface IHealthCheckNotificationSettings
{
bool Enabled { get; }
string FirstRunTime { get; }
int PeriodInHours { get; }
IReadOnlyDictionary<string, INotificationMethod> NotificationMethods { get; }
IEnumerable<IDisabledHealthCheck> DisabledChecks { get; }
}
}
@@ -1,10 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.HealthChecks
{
public interface IHealthChecks
{
IEnumerable<IDisabledHealthCheck> DisabledChecks { get; }
IHealthCheckNotificationSettings NotificationSettings { get; }
}
}
@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.HealthChecks
{
public interface INotificationMethod
{
string Alias { get; }
bool Enabled { get; }
HealthCheckNotificationVerbosity Verbosity { get; }
bool FailureOnly { get; }
IReadOnlyDictionary<string, INotificationMethodSettings> Settings { get; }
}
}
@@ -1,8 +0,0 @@
namespace Umbraco.Core.Configuration.HealthChecks
{
public interface INotificationMethodSettings
{
string Key { get; }
string Value { get; }
}
}
@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.HealthChecks
{
public class NotificationMethodElement : ConfigurationElement, INotificationMethod
{
private const string AliasKey = "alias";
private const string EnabledKey = "enabled";
private const string VerbosityKey = "verbosity";
private const string FailureonlyKey = "failureOnly";
private const string SettingsKey = "settings";
[ConfigurationProperty(AliasKey, IsKey = true, IsRequired = true)]
public string Alias
{
get
{
return (string)base[AliasKey];
}
}
[ConfigurationProperty(EnabledKey, IsKey = true, IsRequired = true)]
public bool Enabled
{
get
{
return (bool)base[EnabledKey];
}
}
[ConfigurationProperty(VerbosityKey, IsRequired = true)]
public HealthCheckNotificationVerbosity Verbosity
{
get
{
return (HealthCheckNotificationVerbosity)base[VerbosityKey];
}
}
[ConfigurationProperty(FailureonlyKey, IsRequired = false)]
public bool FailureOnly
{
get
{
return (bool)base[FailureonlyKey];
}
}
[ConfigurationProperty(SettingsKey, IsDefaultCollection = true, IsRequired = false)]
public NotificationMethodSettingsElementCollection Settings
{
get
{
return (NotificationMethodSettingsElementCollection)base[SettingsKey];
}
}
string INotificationMethod.Alias
{
get { return Alias; }
}
bool INotificationMethod.Enabled
{
get { return Enabled; }
}
HealthCheckNotificationVerbosity INotificationMethod.Verbosity
{
get { return Verbosity; }
}
bool INotificationMethod.FailureOnly
{
get { return FailureOnly; }
}
IReadOnlyDictionary<string, INotificationMethodSettings> INotificationMethod.Settings
{
get { return Settings; }
}
}
}
@@ -1,28 +0,0 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.HealthChecks
{
public class NotificationMethodSettingsElement : ConfigurationElement, INotificationMethodSettings
{
private const string KeyKey = "key";
private const string ValueKey = "value";
[ConfigurationProperty(KeyKey, IsKey = true, IsRequired = true)]
public string Key
{
get
{
return (string)base[KeyKey];
}
}
[ConfigurationProperty(ValueKey, IsRequired = true)]
public string Value
{
get
{
return (string)base[ValueKey];
}
}
}
}
@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
namespace Umbraco.Core.Configuration.HealthChecks
{
[ConfigurationCollection(typeof(NotificationMethodSettingsElement), AddItemName = "add")]
public class NotificationMethodSettingsElementCollection : ConfigurationElementCollection, IEnumerable<INotificationMethodSettings>, IReadOnlyDictionary<string, INotificationMethodSettings>
{
protected override ConfigurationElement CreateNewElement()
{
return new NotificationMethodSettingsElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((NotificationMethodSettingsElement)(element)).Key;
}
IEnumerator<KeyValuePair<string, INotificationMethodSettings>> IEnumerable<KeyValuePair<string, INotificationMethodSettings>>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
var val = (NotificationMethodSettingsElement)BaseGet(i);
var key = (string)BaseGetKey(i);
yield return new KeyValuePair<string, INotificationMethodSettings>(key, val);
}
}
IEnumerator<INotificationMethodSettings> IEnumerable<INotificationMethodSettings>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return (NotificationMethodSettingsElement)BaseGet(i);
}
}
bool IReadOnlyDictionary<string, INotificationMethodSettings>.ContainsKey(string key)
{
return ((IReadOnlyDictionary<string, INotificationMethodSettings>)this).Keys.Any(x => x == key);
}
bool IReadOnlyDictionary<string, INotificationMethodSettings>.TryGetValue(string key, out INotificationMethodSettings value)
{
try
{
var val = (NotificationMethodSettingsElement)BaseGet(key);
value = val;
return true;
}
catch (Exception)
{
value = null;
return false;
}
}
INotificationMethodSettings IReadOnlyDictionary<string, INotificationMethodSettings>.this[string key]
{
get { return (NotificationMethodSettingsElement)BaseGet(key); }
}
IEnumerable<string> IReadOnlyDictionary<string, INotificationMethodSettings>.Keys
{
get { return BaseGetAllKeys().Cast<string>(); }
}
IEnumerable<INotificationMethodSettings> IReadOnlyDictionary<string, INotificationMethodSettings>.Values
{
get
{
for (var i = 0; i < Count; i++)
{
yield return (NotificationMethodSettingsElement)BaseGet(i);
}
}
}
}
}
@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
namespace Umbraco.Core.Configuration.HealthChecks
{
[ConfigurationCollection(typeof(NotificationMethodElement), AddItemName = "notificationMethod")]
public class NotificationMethodsElementCollection : ConfigurationElementCollection, IEnumerable<INotificationMethod>, IReadOnlyDictionary<string, INotificationMethod>
{
protected override ConfigurationElement CreateNewElement()
{
return new NotificationMethodElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((NotificationMethodElement)(element)).Alias;
}
IEnumerator<KeyValuePair<string, INotificationMethod>> IEnumerable<KeyValuePair<string, INotificationMethod>>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
var val = (NotificationMethodElement)BaseGet(i);
var key = (string)BaseGetKey(i);
yield return new KeyValuePair<string, INotificationMethod>(key, val);
}
}
IEnumerator<INotificationMethod> IEnumerable<INotificationMethod>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return (NotificationMethodElement)BaseGet(i);
}
}
bool IReadOnlyDictionary<string, INotificationMethod>.ContainsKey(string key)
{
return ((IReadOnlyDictionary<string, INotificationMethod>) this).Keys.Any(x => x == key);
}
bool IReadOnlyDictionary<string, INotificationMethod>.TryGetValue(string key, out INotificationMethod value)
{
try
{
var val = (NotificationMethodElement)BaseGet(key);
value = val;
return true;
}
catch (Exception)
{
value = null;
return false;
}
}
INotificationMethod IReadOnlyDictionary<string, INotificationMethod>.this[string key]
{
get { return (NotificationMethodElement)BaseGet(key); }
}
IEnumerable<string> IReadOnlyDictionary<string, INotificationMethod>.Keys
{
get { return BaseGetAllKeys().Cast<string>(); }
}
IEnumerable<INotificationMethod> IReadOnlyDictionary<string, INotificationMethod>.Values
{
get
{
for (var i = 0; i < Count; i++)
{
yield return (NotificationMethodElement)BaseGet(i);
}
}
}
}
}
@@ -9,7 +9,6 @@ using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.BaseRest;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Configuration.Grid;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
@@ -53,12 +52,6 @@ namespace Umbraco.Core.Configuration
var dashboardConfig = ConfigurationManager.GetSection("umbracoConfiguration/dashBoard") as IDashboardSection;
SetDashboardSettings(dashboardConfig);
}
if (_healthChecks == null)
{
var healthCheckConfig = ConfigurationManager.GetSection("umbracoConfiguration/HealthChecks") as IHealthChecks;
SetHealthCheckSettings(healthCheckConfig);
}
}
/// <summary>
@@ -67,36 +60,18 @@ namespace Umbraco.Core.Configuration
/// <param name="umbracoSettings"></param>
/// <param name="baseRestSettings"></param>
/// <param name="dashboardSettings"></param>
/// <param name="healthChecks"></param>
public UmbracoConfig(IUmbracoSettingsSection umbracoSettings, IBaseRestSection baseRestSettings, IDashboardSection dashboardSettings, IHealthChecks healthChecks)
public UmbracoConfig(IUmbracoSettingsSection umbracoSettings, IBaseRestSection baseRestSettings, IDashboardSection dashboardSettings)
{
SetHealthCheckSettings(healthChecks);
SetUmbracoSettings(umbracoSettings);
SetBaseRestExtensions(baseRestSettings);
SetDashboardSettings(dashboardSettings);
}
private IHealthChecks _healthChecks;
private IDashboardSection _dashboardSection;
private IUmbracoSettingsSection _umbracoSettings;
private IBaseRestSection _baseRestExtensions;
private IGridConfig _gridConfig;
/// <summary>
/// Gets the IHealthCheck config
/// </summary>
public IHealthChecks HealthCheck()
{
if (_healthChecks == null)
{
var ex = new ConfigurationErrorsException("Could not load the " + typeof(IHealthChecks) + " from config file, ensure the web.config and healthchecks.config files are formatted correctly");
LogHelper.Error<UmbracoConfig>("Config error", ex);
throw ex;
}
return _healthChecks;
}
/// <summary>
/// Gets the IDashboardSection
/// </summary>
@@ -111,23 +86,14 @@ namespace Umbraco.Core.Configuration
return _dashboardSection;
}
/// <summary>
/// Only for testing
/// </summary>
/// <param name="value"></param>
public void SetDashboardSettings(IDashboardSection value)
{
_dashboardSection = value;
}
/// <summary>
/// Only for testing
/// </summary>
/// <param name="value"></param>
public void SetHealthCheckSettings(IHealthChecks value)
internal void SetDashboardSettings(IDashboardSection value)
{
_healthChecks = value;
_dashboardSection = value;
}
/// <summary>
@@ -139,12 +139,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
internal CommaDelimitedConfigurationElement DisallowedUploadFiles
{
get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); }
}
[ConfigurationProperty("allowedUploadFiles")]
internal CommaDelimitedConfigurationElement AllowedUploadFiles
{
get { return GetOptionalDelimitedElement("allowedUploadFiles", new string[0]); }
}
[ConfigurationProperty("cloneXmlContent")]
@@ -165,12 +159,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return GetOptionalTextElement("defaultDocumentTypeProperty", "Textstring"); }
}
[ConfigurationProperty("showDeprecatedPropertyEditors")]
internal InnerTextConfigurationElement<bool> ShowDeprecatedPropertyEditors
{
get { return GetOptionalTextElement("showDeprecatedPropertyEditors", false); }
}
[ConfigurationProperty("EnableInheritedDocumentTypes")]
internal InnerTextConfigurationElement<bool> EnableInheritedDocumentTypes
{
@@ -183,18 +171,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
}
[ConfigurationProperty("EnablePropertyValueConverters")]
internal InnerTextConfigurationElement<bool> EnablePropertyValueConverters
{
get { return GetOptionalTextElement("EnablePropertyValueConverters", false); }
}
[ConfigurationProperty("loginBackgroundImage")]
internal InnerTextConfigurationElement<string> LoginBackgroundImage
{
get { return GetOptionalTextElement("loginBackgroundImage", string.Empty); }
}
string IContentSection.NotificationEmailAddress
{
get { return Notifications.NotificationEmailAddress; }
@@ -313,11 +289,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
IEnumerable<string> IContentSection.DisallowedUploadFiles
{
get { return DisallowedUploadFiles; }
}
IEnumerable<string> IContentSection.AllowedUploadFiles
{
get { return AllowedUploadFiles; }
}
bool IContentSection.CloneXmlContent
@@ -335,11 +306,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return DefaultDocumentTypeProperty; }
}
bool IContentSection.ShowDeprecatedPropertyEditors
{
get { return ShowDeprecatedPropertyEditors; }
}
bool IContentSection.EnableInheritedDocumentTypes
{
get { return EnableInheritedDocumentTypes; }
@@ -349,14 +315,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return EnableInheritedMediaTypes; }
}
bool IContentSection.EnablePropertyValueConverters
{
get { return EnablePropertyValueConverters; }
}
string IContentSection.LoginBackgroundImage
{
get { return LoginBackgroundImage; }
}
}
}
@@ -1,19 +0,0 @@
using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public static class ContentSectionExtensions
{
/// <summary>
/// Determines if file extension is allowed for upload based on (optional) white list and black list
/// held in settings.
/// Allow upload if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted.
/// </summary>
public static bool IsFileAllowedForUpload(this IContentSection contentSection, string extension)
{
return contentSection.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) ||
(contentSection.AllowedUploadFiles.Any() == false &&
contentSection.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false);
}
}
}
@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
internal class HelpElement : ConfigurationElement, IHelpSection
{
[ConfigurationProperty("defaultUrl", DefaultValue = "http://our.umbraco.org/wiki/umbraco-help/{0}/{1}")]
@@ -52,9 +52,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
MacroErrorBehaviour MacroErrorBehaviour { get; }
IEnumerable<string> DisallowedUploadFiles { get; }
IEnumerable<string> AllowedUploadFiles { get; }
IEnumerable<string> DisallowedUploadFiles { get; }
bool CloneXmlContent { get; }
@@ -62,18 +60,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
string DefaultDocumentTypeProperty { get; }
/// <summary>
/// The default for this is false but if you would like deprecated property editors displayed
/// in the data type editor you can enable this
/// </summary>
bool ShowDeprecatedPropertyEditors { get; }
bool EnableInheritedDocumentTypes { get; }
bool EnableInheritedMediaTypes { get; }
bool EnablePropertyValueConverters { get; }
string LoginBackgroundImage { get; }
}
}
@@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
{
public interface IHelpSection : IUmbracoConfigurationSection
{
string DefaultUrl { get; }
@@ -1,10 +1,5 @@
using System;
using System.ComponentModel;
namespace Umbraco.Core.Configuration.UmbracoSettings
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
public interface ILink
{
string Application { get; }
@@ -8,7 +8,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
Guid Id { get; }
string RepositoryUrl { get; }
string WebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
string RestApiUrl { get; }
bool HasCustomWebServiceUrl { get; }
}
}
@@ -12,8 +12,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool ConvertUrlsToAscii { get; }
bool TryConvertUrlsToAscii { get; }
IEnumerable<IChar> CharCollection { get; }
}
}
@@ -1,7 +1,4 @@
using System;
using System.ComponentModel;
namespace Umbraco.Core.Configuration.UmbracoSettings
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IUmbracoSettingsSection : IUmbracoConfigurationSection
{
@@ -27,8 +24,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
IProvidersSection Providers { get; }
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
IHelpSection Help { get; }
IWebRoutingSection WebRouting { get; }
@@ -1,11 +1,7 @@
using System;
using System.ComponentModel;
using System.Configuration;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
internal class LinkElement : ConfigurationElement, ILink
{
[ConfigurationProperty("application")]
@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
internal class LinksCollection : ConfigurationElementCollection, IEnumerable<ILink>
{
protected override ConfigurationElement CreateNewElement()
@@ -1,19 +0,0 @@
using System;
using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public static class RepositoryConfigExtensions
{
//Our package repo
private static readonly Guid RepoGuid = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66");
public static IRepository GetDefault(this IRepositoriesSection repos)
{
var found = repos.Repositories.FirstOrDefault(x => x.Id == RepoGuid);
if (found == null)
throw new InvalidOperationException("No default package repository found with id " + RepoGuid);
return found;
}
}
}
@@ -38,16 +38,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get
{
var prop = Properties["webserviceurl"];
return (string) prop.DefaultValue != (string) this[prop];
var repoUrl = this[prop] as ConfigurationElement;
return (repoUrl != null && repoUrl.ElementInformation.IsPresent);
}
}
[ConfigurationProperty("restapiurl", DefaultValue = "https://our.umbraco.org/webapi/packages/v1")]
public string RestApiUrl
{
get { return (string)base["restapiurl"]; }
set { base["restapiurl"] = value; }
}
}
}
@@ -111,12 +111,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool IRequestHandlerSection.ConvertUrlsToAscii
{
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("true"); }
}
bool IRequestHandlerSection.TryConvertUrlsToAscii
{
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("try"); }
get { return UrlReplacing.ConvertUrlsToAscii; }
}
IEnumerable<IChar> IRequestHandlerSection.CharCollection
@@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
@@ -184,8 +183,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return Providers; }
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is no longer used and will be removed in future versions")]
IHelpSection IUmbracoSettingsSection.Help
{
get { return Help; }
@@ -11,10 +11,10 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return (bool) base["removeDoubleDashes"]; }
}
[ConfigurationProperty("toAscii", DefaultValue = "false")]
internal string ConvertUrlsToAscii
[ConfigurationProperty("toAscii", DefaultValue = false)]
internal bool ConvertUrlsToAscii
{
get { return (string) base["toAscii"]; }
get { return (bool)base["toAscii"]; }
}
[ConfigurationCollection(typeof(CharCollection), AddItemName = "char")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.7.0");
private static readonly Version Version = new Version("7.5.7");
/// <summary>
/// Gets the current version of Umbraco.
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "beta"; } }
public static string CurrentComment { get { return ""; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
@@ -33,9 +33,9 @@ namespace Umbraco.Core.Configuration
public static SemVersion GetSemanticVersion()
{
return new SemVersion(
Current.Major,
Current.Major,
Current.Minor,
Current.Build,
Current.Build,
CurrentComment.IsNullOrWhiteSpace() ? null : CurrentComment,
Current.Revision > 0 ? Current.Revision.ToInvariantString() : null);
}
+2 -15
View File
@@ -56,12 +56,7 @@
/// <summary>
/// alias for the content tree.
/// </summary>
public const string Content = "content";
/// <summary>
/// alias for the content blueprint tree.
/// </summary>
public const string ContentBlueprints = "contentBlueprints";
public const string Content = "content";
/// <summary>
/// alias for the member tree.
@@ -117,17 +112,9 @@
public const string Languages = "languages";
public const string PartialViews = "partialViews";
public const string PartialViewMacros = "partialViewMacros";
public const string Scripts = "scripts";
public const string Users = "users";
//TODO: Fill in the rest!
}
}
}
}
+1 -10
View File
@@ -4,22 +4,13 @@ using Umbraco.Core.Models;
namespace Umbraco.Core
{
public static partial class Constants
public static partial class Constants
{
/// <summary>
/// Defines the identifiers for property-type alias conventions that are used within the Umbraco core.
/// </summary>
public static class Conventions
{
internal static class PermissionCategories
{
public const string ContentCategory = "content";
public const string AdministrationCategory = "administration";
public const string StructureCategory = "structure";
public const string OtherCategory = "other";
}
public static class PublicAccess
{
public const string MemberUsernameRuleType = "MemberUsername";
@@ -1,12 +0,0 @@
namespace Umbraco.Core
{
public static partial class Constants
{
public static class DatabaseProviders
{
public const string SqlCe = "System.Data.SqlServerCe.4.0";
public const string SqlServer = "System.Data.SqlClient";
public const string MySql = "MySql.Data.MySqlClient";
}
}
}
@@ -1,17 +0,0 @@
namespace Umbraco.Core
{
public static partial class Constants
{
/// <summary>
/// Contains the valid selector values.
/// </summary>
public static class DeploySelector
{
public const string This = "this";
public const string ThisAndChildren = "this-and-children";
public const string ThisAndDescendants = "this-and-descendants";
public const string ChildrenOfThis = "children";
public const string DescendantsOfThis = "descendants";
}
}
}
+1 -81
View File
@@ -68,22 +68,12 @@ namespace Umbraco.Core
/// Guid for a Document object.
/// </summary>
public const string Document = "C66BA18E-EAF3-4CFF-8A22-41B16D66A972";
/// <summary>
/// Guid for a Document object.
/// </summary>
public static readonly Guid DocumentGuid = new Guid(Document);
/// <summary>
/// Guid for a Document Blueprint object.
/// </summary>
public const string DocumentBlueprint = "6EBEF410-03AA-48CF-A792-E1C1CB087ACA";
/// <summary>
/// Guid for a Document object.
/// </summary>
public static readonly Guid DocumentBlueprintGuid = new Guid(DocumentBlueprint);
/// <summary>
/// Guid for a Document Type object.
/// </summary>
@@ -99,11 +89,6 @@ namespace Umbraco.Core
/// </summary>
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
/// <summary>
/// Guid for a Document object.
/// </summary>
public static readonly Guid MediaGuid = new Guid(Media);
/// <summary>
/// Guid for the Media Recycle Bin.
/// </summary>
@@ -124,21 +109,11 @@ namespace Umbraco.Core
/// </summary>
public const string Member = "39EB0F98-B348-42A1-8662-E7EB18487560";
/// <summary>
/// Guid for a Media Type object.
/// </summary>
public static readonly Guid MemberGuid = new Guid(Member);
/// <summary>
/// Guid for a Member Group object.
/// </summary>
public const string MemberGroup = "366E63B9-880F-4E13-A61C-98069B029728";
/// <summary>
/// Guid for a Member Group object.
/// </summary>
public static readonly Guid MemberGroupGuid = new Guid(MemberGroup);
/// <summary>
/// Guid for a Member Type object.
/// </summary>
@@ -168,11 +143,6 @@ namespace Umbraco.Core
/// </summary>
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
/// <summary>
/// Guid for a Template object.
/// </summary>
public static readonly Guid TemplateTypeGuid = new Guid(Template);
/// <summary>
/// Guid for a Lock object.
/// </summary>
@@ -182,56 +152,6 @@ namespace Umbraco.Core
/// Guid for a Lock object.
/// </summary>
public static readonly Guid LockObjectGuid = new Guid(LockObject);
/// <summary>
/// Guid for a relation type.
/// </summary>
public const string RelationType = "B1988FAD-8675-4F47-915A-B3A602BC5D8D";
/// <summary>
/// Guid for a relation type.
/// </summary>
public static readonly Guid RelationTypeGuid = new Guid(RelationType);
/// <summary>
/// Guid for a Forms Form.
/// </summary>
public const string FormsForm = "F5A9F787-6593-46F0-B8FF-BFD9BCA9F6BB";
/// <summary>
/// Guid for a Forms Form.
/// </summary>
public static readonly Guid FormsFormGuid = new Guid(FormsForm);
/// <summary>
/// Guid for a Forms PreValue Source.
/// </summary>
public const string FormsPreValue = "42D7BF9B-A362-4FEE-B45A-674D5C064B70";
/// <summary>
/// Guid for a Forms PreValue Source.
/// </summary>
public static readonly Guid FormsPreValueGuid = new Guid(FormsPreValue);
/// <summary>
/// Guid for a Forms DataSource.
/// </summary>
public const string FormsDataSource = "CFED6CE4-9359-443E-9977-9956FEB1D867";
/// <summary>
/// Guid for a Forms DataSource.
/// </summary>
public static readonly Guid FormsDataSourceGuid = new Guid(FormsDataSource);
/// <summary>
/// Guid for a Language.
/// </summary>
public const string Language = "6B05D05B-EC78-49BE-A4E4-79E274F07A77";
/// <summary>
/// Guid for a Forms DataSource.
/// </summary>
public static readonly Guid LanguageGuid = new Guid(Language);
}
}
}
+7 -29
View File
@@ -42,14 +42,10 @@ namespace Umbraco.Core
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string ContentPicker = "158AA029-24ED-4948-939E-C3DA209E5FBA";
[Obsolete("This is an obsoleted content picker, use ContentPicker2Alias instead")]
public const string ContentPickerAlias = "Umbraco.ContentPickerAlias";
/// <summary>
/// Alias for the Content Picker datatype.
/// </summary>
public const string ContentPicker2Alias = "Umbraco.ContentPicker2";
public const string ContentPickerAlias = "Umbraco.ContentPickerAlias";
/// <summary>
/// Guid for the Date datatype.
@@ -196,15 +192,11 @@ namespace Umbraco.Core
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string MediaPicker = "EAD69342-F06D-4253-83AC-28000225583B";
[Obsolete("This is an obsoleted picker, use MediaPicker2Alias instead")]
public const string MediaPickerAlias = "Umbraco.MediaPicker";
/// <summary>
/// Alias for the Media Picker datatype.
/// </summary>
public const string MediaPicker2Alias = "Umbraco.MediaPicker2";
public const string MediaPickerAlias = "Umbraco.MediaPicker";
[Obsolete("This is an obsoleted picker, use MediaPicker2Alias instead")]
public const string MultipleMediaPickerAlias = "Umbraco.MultipleMediaPicker";
/// <summary>
@@ -213,32 +205,26 @@ namespace Umbraco.Core
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string MemberPicker = "39F533E4-0551-4505-A64B-E0425C5CE775";
[Obsolete("This is an obsoleted picker, use MemberPicker2Alias instead")]
public const string MemberPickerAlias = "Umbraco.MemberPicker";
/// <summary>
/// Alias for the Member Picker datatype.
/// </summary>
public const string MemberPicker2Alias = "Umbraco.MemberPicker2";
public const string MemberPickerAlias = "Umbraco.MemberPicker";
/// <summary>
/// Alias for the Member Group Picker datatype.
/// </summary>
public const string MemberGroupPickerAlias = "Umbraco.MemberGroupPicker";
/// <summary>
/// Guid for the Multi-Node Tree Picker datatype
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string MultiNodeTreePicker = "7E062C13-7C41-4AD9-B389-41D88AEEF87C";
[Obsolete("This is an obsoleted picker, use MultiNodeTreePicker2Alias instead")]
public const string MultiNodeTreePickerAlias = "Umbraco.MultiNodeTreePicker";
/// <summary>
/// Alias for the Multi-Node Tree Picker datatype
/// </summary>
public const string MultiNodeTreePicker2Alias = "Umbraco.MultiNodeTreePicker2";
public const string MultiNodeTreePickerAlias = "Umbraco.MultiNodeTreePicker";
/// <summary>
/// Guid for the Multiple Textstring datatype.
@@ -289,14 +275,11 @@ namespace Umbraco.Core
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string RelatedLinks = "71B8AD1A-8DC2-425C-B6B8-FAA158075E63";
[Obsolete("This is an obsoleted picker, use RelatedLinks2Alias instead")]
public const string RelatedLinksAlias = "Umbraco.RelatedLinks";
/// <summary>
/// Alias for the Related Links property editor.
/// Alias for the Related Links datatype.
/// </summary>
public const string RelatedLinks2Alias = "Umbraco.RelatedLinks2";
public const string RelatedLinksAlias = "Umbraco.RelatedLinks";
/// <summary>
/// Guid for the Slider datatype.
@@ -437,11 +420,6 @@ namespace Umbraco.Core
/// </summary>
public const string EmailAddressAlias = "Umbraco.EmailAddress";
/// <summary>
/// Alias for the nested content property editor.
/// </summary>
public const string NestedContentAlias = "Umbraco.NestedContent";
public static class PreValueKeys
{
/// <summary>
-38
View File
@@ -1,38 +0,0 @@
using System;
using System.ComponentModel;
namespace Umbraco.Core
{
public static partial class Constants
{
public static class Security
{
public const string AdminGroupAlias = "admin";
public const string BackOfficeAuthenticationType = "UmbracoBackOffice";
public const string BackOfficeExternalAuthenticationType = "UmbracoExternalCookie";
public const string BackOfficeExternalCookieName = "UMB_EXTLOGIN";
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
public const string BackOfficeTwoFactorAuthenticationType = "UmbracoTwoFactorCookie";
internal const string EmptyPasswordPrefix = "___UIDEMPTYPWORD__";
internal const string ForceReAuthFlag = "umbraco-force-auth";
/// <summary>
/// The prefix used for external identity providers for their authentication type
/// </summary>
/// <remarks>
/// By default we don't want to interfere with front-end external providers and their default setup, for back office the
/// providers need to be setup differently and each auth type for the back office will be prefixed with this value
/// </remarks>
public const string BackOfficeExternalAuthenticationTypePrefix = "Umbraco.";
public const string StartContentNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startcontentnode";
public const string StartMediaNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startmedianode";
public const string AllowedApplicationsClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/allowedapp";
public const string SessionIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/sessionid";
}
}
}
+9 -3
View File
@@ -26,9 +26,15 @@
public const int DefaultMediaListViewDataTypeId = -96;
public const int DefaultMembersListViewDataTypeId = -97;
public const string UmbracoConnectionName = "umbracoDbDSN";
public const string UmbracoMigrationName = "Umbraco";
// identifiers for lock objects
public const int ServersLock = -331;
}
public static class DatabaseProviders
{
public const string SqlCe = "System.Data.SqlServerCe.4.0";
public const string SqlServer = "System.Data.SqlClient";
public const string MySql = "MySql.Data.MySqlClient";
}
}
}
+25 -1
View File
@@ -29,6 +29,30 @@ namespace Umbraco.Core
public const string AuthCookieName = "UMB_UCONTEXT";
}
public static class Security
{
public const string BackOfficeAuthenticationType = "UmbracoBackOffice";
public const string BackOfficeExternalAuthenticationType = "UmbracoExternalCookie";
public const string BackOfficeExternalCookieName = "UMB_EXTLOGIN";
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
public const string BackOfficeTwoFactorAuthenticationType = "UmbracoTwoFactorCookie";
/// <summary>
/// The prefix used for external identity providers for their authentication type
/// </summary>
/// <remarks>
/// By default we don't want to interfere with front-end external providers and their default setup, for back office the
/// providers need to be setup differently and each auth type for the back office will be prefixed with this value
/// </remarks>
public const string BackOfficeExternalAuthenticationTypePrefix = "Umbraco.";
public const string StartContentNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startcontentnode";
public const string StartMediaNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startmedianode";
public const string AllowedApplicationsClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/allowedapp";
public const string SessionIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/sessionid";
}
}
}
+9 -11
View File
@@ -28,7 +28,6 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Publishing;
using Umbraco.Core.Macros;
using Umbraco.Core.Manifest;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
using Umbraco.Core.Strings;
@@ -106,14 +105,11 @@ namespace Umbraco.Core
LegacyParameterEditorAliasConverter.CreateMappingsForCoreEditors();
//create database and service contexts for the app context
var dbFactory = new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, ProfilingLogger.Logger);
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, ProfilingLogger.Logger);
Database.Mapper = new PetaPocoMapper();
var scopeProvider = new ScopeProvider(dbFactory);
dbFactory.ScopeProvider = scopeProvider;
var dbContext = new DatabaseContext(
scopeProvider,
dbFactory,
ProfilingLogger.Logger,
SqlSyntaxProviders.CreateDefault(ProfilingLogger.Logger));
@@ -121,7 +117,7 @@ namespace Umbraco.Core
dbContext.Initialize();
//get the service context
var serviceContext = CreateServiceContext(dbContext, scopeProvider);
var serviceContext = CreateServiceContext(dbContext, dbFactory);
//set property and singleton from response
ApplicationContext.Current = ApplicationContext = CreateApplicationContext(dbContext, serviceContext);
@@ -164,15 +160,17 @@ namespace Umbraco.Core
/// Creates and returns the service context for the app
/// </summary>
/// <param name="dbContext"></param>
/// <param name="scopeProvider"></param>
/// <param name="dbFactory"></param>
/// <returns></returns>
protected virtual ServiceContext CreateServiceContext(DatabaseContext dbContext, IScopeProvider scopeProvider)
protected virtual ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
{
//default transient factory
var msgFactory = new TransientMessagesFactory();
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(scopeProvider),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(msgFactory, ProfilingLogger.Logger),
ApplicationCache,
ProfilingLogger.Logger,
msgFactory);
@@ -417,7 +415,7 @@ namespace Umbraco.Core
if (currentTry == 5)
{
throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but Umbraco cannot connect to the database.");
throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but the Umbraco cannot connect to the database.");
}
}
+72 -194
View File
@@ -4,6 +4,7 @@ using System.Data.SqlServerCe;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using System.Xml.Linq;
using Semver;
using Umbraco.Core.Configuration;
@@ -13,7 +14,6 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.Migrations.Initial;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
namespace Umbraco.Core
@@ -26,42 +26,31 @@ namespace Umbraco.Core
/// </remarks>
public class DatabaseContext
{
internal readonly IScopeProviderInternal ScopeProvider;
private readonly IDatabaseFactory _factory;
private readonly ILogger _logger;
private readonly SqlSyntaxProviders _syntaxProviders;
private bool _configured;
private readonly object _locker = new object();
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
private DateTime? _connectionLastChecked;
private DateTime? _connectionLastChecked = null;
/// <summary>
/// The number of minutes to throttle the checks to CanConnect
/// </summary>
private const int ConnectionCheckMinutes = 1;
#region Compatibility with 7.5
// note: the ctors accepting IDatabaseFactory are here only for backward compatibility purpose
//
// problem: IDatabaseFactory2 adds the CreateNewDatabase() method which creates a new database
// 'cos IDatabaseFactory CreateDatabase() is supposed to also manage the ambient thing. We
// want to keep these ctors for backward compatibility reasons (in case ppl use them in tests)
// so we need to create a scope provider (else nothing would work) and so we need a IDatabaseFactory2,
// so...?
// solution: wrap IDatabaseFactory and pretend we have a IDatabaseFactory2, it *should* work in most
// cases but really, it depends on what ppl are doing in their tests... yet, cannot really see any
// other way to do it?
[Obsolete("Use the constructor specifying all dependencies instead")]
public DatabaseContext(IDatabaseFactory factory)
: this(factory, LoggerResolver.Current.Logger, new SqlSyntaxProviders(new ISqlSyntaxProvider[]
{
new MySqlSyntaxProvider(LoggerResolver.Current.Logger),
new SqlCeSyntaxProvider(),
new SqlCeSyntaxProvider(),
new SqlServerSyntaxProvider()
}))
{ }
{
}
/// <summary>
/// Default constructor
@@ -75,11 +64,7 @@ namespace Umbraco.Core
if (logger == null) throw new ArgumentNullException("logger");
if (syntaxProviders == null) throw new ArgumentNullException("syntaxProviders");
var asDbFactory2 = factory as IDatabaseFactory2;
ScopeProvider = asDbFactory2 == null
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
: new ScopeProvider(asDbFactory2);
_factory = factory;
_logger = logger;
_syntaxProviders = syntaxProviders;
}
@@ -96,83 +81,7 @@ namespace Umbraco.Core
_providerName = providerName;
SqlSyntax = sqlSyntax;
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
var asDbFactory2 = factory as IDatabaseFactory2;
ScopeProvider = asDbFactory2 == null
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
: new ScopeProvider(asDbFactory2);
_logger = logger;
_configured = true;
}
private class DatabaseFactoryWrapper : IDatabaseFactory2
{
private readonly IDatabaseFactory _factory;
public DatabaseFactoryWrapper(IDatabaseFactory factory)
{
_factory = factory;
}
public UmbracoDatabase CreateDatabase()
{
return _factory.CreateDatabase();
}
public UmbracoDatabase CreateNewDatabase()
{
return CreateDatabase();
}
public void Dispose()
{
_factory.Dispose();
}
}
#endregion
[Obsolete("Use the constructor specifying all dependencies instead")]
internal DatabaseContext(IScopeProviderInternal scopeProvider)
: this(scopeProvider, LoggerResolver.Current.Logger, new SqlSyntaxProviders(new ISqlSyntaxProvider[]
{
new MySqlSyntaxProvider(LoggerResolver.Current.Logger),
new SqlCeSyntaxProvider(),
new SqlServerSyntaxProvider()
}))
{ }
/// <summary>
/// Default constructor
/// </summary>
/// <param name="scopeProvider"></param>
/// <param name="logger"></param>
/// <param name="syntaxProviders"></param>
internal DatabaseContext(IScopeProviderInternal scopeProvider, ILogger logger, SqlSyntaxProviders syntaxProviders)
{
if (scopeProvider == null) throw new ArgumentNullException("scopeProvider");
if (logger == null) throw new ArgumentNullException("logger");
if (syntaxProviders == null) throw new ArgumentNullException("syntaxProviders");
ScopeProvider = scopeProvider;
_logger = logger;
_syntaxProviders = syntaxProviders;
}
/// <summary>
/// Create a configured DatabaseContext
/// </summary>
/// <param name="scopeProvider"></param>
/// <param name="logger"></param>
/// <param name="sqlSyntax"></param>
/// <param name="providerName"></param>
internal DatabaseContext(IScopeProviderInternal scopeProvider, ILogger logger, ISqlSyntaxProvider sqlSyntax, string providerName)
{
_providerName = providerName;
SqlSyntax = sqlSyntax;
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
ScopeProvider = scopeProvider;
_factory = factory;
_logger = logger;
_configured = true;
}
@@ -180,27 +89,16 @@ namespace Umbraco.Core
public ISqlSyntaxProvider SqlSyntax { get; private set; }
/// <summary>
/// Gets an "ambient" database for doing CRUD operations against custom tables that resides in the Umbraco database.
/// Gets the <see cref="Database"/> object for doing CRUD operations
/// against custom tables that resides in the Umbraco database.
/// </summary>
/// <remarks>
/// <para>Should not be used for operation against standard Umbraco tables; as services should be used instead.</para>
/// <para>Gets or creates an "ambient" database that is either stored in http context + available for the whole
/// request + auto-disposed at the end of the request, or stored in call context if there is no http context - in which
/// case it *must* be explicitely disposed (which will remove it from call context).</para>
/// This should not be used for CRUD operations or queries against the
/// standard Umbraco tables! Use the Public services for that.
/// </remarks>
public virtual UmbracoDatabase Database
{
get
{
if (IsDatabaseConfigured == false)
{
throw new InvalidOperationException("Cannot create a database instance, there is no available connection string");
}
return ScopeProvider.GetAmbientOrNoScope().Database;
//var scope = ScopeProvider.AmbientScope;
//return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
}
get { return _factory.CreateDatabase(); }
}
/// <summary>
@@ -223,7 +121,7 @@ namespace Umbraco.Core
//Don't check again if the timeout period hasn't elapsed
//this ensures we don't keep checking the connection too many times in a row like during startup.
//Do check if the _connectionLastChecked is null which means we're just initializing or it could
//Do check if the _connectionLastChecked is null which means we're just initializing or it could
//not connect last time it was checked.
if ((_connectionLastChecked.HasValue && (DateTime.Now - _connectionLastChecked.Value).TotalMinutes > ConnectionCheckMinutes)
|| _connectionLastChecked.HasValue == false)
@@ -259,14 +157,14 @@ namespace Umbraco.Core
return _providerName;
_providerName = Constants.DatabaseProviders.SqlServer;
if (ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName] != null)
if (ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName] != null)
{
if (string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName) == false)
_providerName = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName;
if (string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName) == false)
_providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
}
else
{
throw new NullReferenceException("Can't find a connection string with the name '" + Constants.System.UmbracoConnectionName + "'");
throw new InvalidOperationException("Can't find a connection string with the name '" + GlobalSettings.UmbracoConnectionName + "'");
}
return _providerName;
}
@@ -305,10 +203,15 @@ namespace Umbraco.Core
var path = Path.Combine(GlobalSettings.FullpathToRoot, "App_Data", "Umbraco.sdf");
if (File.Exists(path) == false)
{
using (var engine = new SqlCeEngine(connectionString))
{
engine.CreateDatabase();
}
var engine = new SqlCeEngine(connectionString);
engine.CreateDatabase();
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
// since it's been like this for quite some time
//using (var engine = new SqlCeEngine(connectionString))
//{
// engine.CreateDatabase();
//}
}
Initialize(providerName);
@@ -348,14 +251,14 @@ namespace Umbraco.Core
/// <param name="password">Database Password</param>
/// <param name="databaseProvider">Type of the provider to be used (Sql, Sql Azure, Sql Ce, MySql)</param>
public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider)
{
{
string providerName;
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out providerName);
SaveConnectionString(connectionString, providerName);
Initialize(providerName);
}
public string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName)
{
providerName = Constants.DatabaseProviders.SqlServer;
@@ -386,18 +289,18 @@ namespace Umbraco.Core
public string GetIntegratedSecurityDatabaseConnectionString(string server, string databaseName)
{
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
}
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
{
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
server = string.Format("tcp:{0}", server);
if (server.Contains(".") == false && ServerStartsWithTcp(server))
{
string serverName = server.Contains(",")
? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal))
string serverName = server.Contains(",")
? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal))
: server;
var portAddition = string.Empty;
@@ -407,10 +310,10 @@ namespace Umbraco.Core
server = string.Format("{0}.database.windows.net{1}", serverName, portAddition);
}
if (ServerStartsWithTcp(server) == false)
server = string.Format("tcp:{0}.database.windows.net", server);
if (server.Contains(",") == false)
server = string.Format("{0},1433", server);
@@ -447,23 +350,23 @@ namespace Umbraco.Core
{
//Set the connection string for the new datalayer
var connectionStringSettings = string.IsNullOrEmpty(providerName)
? new ConnectionStringSettings(Constants.System.UmbracoConnectionName,
? new ConnectionStringSettings(GlobalSettings.UmbracoConnectionName,
connectionString)
: new ConnectionStringSettings(Constants.System.UmbracoConnectionName,
: new ConnectionStringSettings(GlobalSettings.UmbracoConnectionName,
connectionString, providerName);
_connectionString = connectionString;
_providerName = providerName;
var fileName = IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root));
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
var connectionstrings = xml.Root.DescendantsAndSelf("connectionStrings").Single();
// Update connectionString if it exists, or else create a new appSetting for the given key and value
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == Constants.System.UmbracoConnectionName);
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == GlobalSettings.UmbracoConnectionName);
if (setting == null)
connectionstrings.Add(new XElement("add",
new XAttribute("name", Constants.System.UmbracoConnectionName),
new XAttribute("name", GlobalSettings.UmbracoConnectionName),
new XAttribute("connectionString", connectionStringSettings),
new XAttribute("providerName", providerName)));
else
@@ -488,23 +391,23 @@ namespace Umbraco.Core
/// </remarks>
internal void Initialize()
{
var databaseSettings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];
var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName];
if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false)
{
var providerName = Constants.DatabaseProviders.SqlServer;
string connString = null;
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName))
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName))
{
providerName = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName;
connString = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ConnectionString;
providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
connString = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
}
Initialize(providerName, connString);
}
else if (ConfigurationManager.AppSettings.ContainsKey(Constants.System.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[Constants.System.UmbracoConnectionName]) == false)
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
{
//A valid connectionstring does not exist, but the legacy appSettings key was found, so we'll reconfigure the conn.string.
var legacyConnString = ConfigurationManager.AppSettings[Constants.System.UmbracoConnectionName];
var legacyConnString = ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName];
if (legacyConnString.ToLowerInvariant().Contains("sqlce4umbraco"))
{
ConfigureEmbeddedDatabaseConnection();
@@ -535,8 +438,8 @@ namespace Umbraco.Core
}
//Remove the legacy connection string, so we don't end up in a loop if something goes wrong.
GlobalSettings.RemoveSetting(Constants.System.UmbracoConnectionName);
GlobalSettings.RemoveSetting(GlobalSettings.UmbracoConnectionName);
}
else
{
@@ -555,15 +458,15 @@ namespace Umbraco.Core
{
if (_syntaxProviders != null)
{
SqlSyntax = _syntaxProviders.GetByProviderNameOrDefault(providerName);
SqlSyntax = _syntaxProviders.GetByProviderNameOrDefault(providerName);
}
else if (SqlSyntax == null)
{
throw new InvalidOperationException("No " + typeof(ISqlSyntaxProvider) + " specified or no " + typeof(SqlSyntaxProviders) + " instance specified");
}
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
_configured = true;
}
catch (Exception e)
@@ -603,7 +506,7 @@ namespace Umbraco.Core
}
internal Result CreateDatabaseSchemaAndData(ApplicationContext applicationContext)
{
{
try
{
var readyForInstall = CheckReadyForInstall();
@@ -621,7 +524,7 @@ namespace Umbraco.Core
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
/*
/*
var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
if (supportsCaseInsensitiveQueries == false)
{
@@ -639,9 +542,9 @@ namespace Umbraco.Core
message = GetResultMessageForMySql();
var schemaResult = ValidateDatabaseSchema();
var installedSchemaVersion = schemaResult.DetermineInstalledVersion();
//If Configuration Status is empty and the determined version is "empty" its a new install - otherwise upgrade the existing
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) && installedSchemaVersion.Equals(new Version(0, 0, 0)))
{
@@ -660,9 +563,9 @@ namespace Umbraco.Core
message = "<p>Upgrading database, this may take some time...</p>";
return new Result
{
RequiresUpgrade = true,
Message = message,
Success = true,
RequiresUpgrade = true,
Message = message,
Success = true,
Percentage = "30"
};
}
@@ -690,7 +593,7 @@ namespace Umbraco.Core
_logger.Info<DatabaseContext>("Database upgrade started");
var database = new UmbracoDatabase(_connectionString, ProviderName, _logger);
//var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
//var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
var message = GetResultMessageForMySql();
@@ -698,32 +601,32 @@ namespace Umbraco.Core
var installedSchemaVersion = new SemVersion(schemaResult.DetermineInstalledVersion());
var installedMigrationVersion = schemaResult.DetermineInstalledVersionByMigrations(migrationEntryService);
var installedMigrationVersion = schemaResult.DetermineInstalledVersionByMigrations(migrationEntryService);
var targetVersion = UmbracoVersion.Current;
//In some cases - like upgrading from 7.2.6 -> 7.3, there will be no migration information in the database and therefore it will
// return a version of 0.0.0 and we don't necessarily want to run all migrations from 0 -> 7.3, so we'll just ensure that the
// return a version of 0.0.0 and we don't necessarily want to run all migrations from 0 -> 7.3, so we'll just ensure that the
// migrations are run for the target version
if (installedMigrationVersion == new SemVersion(new Version(0, 0, 0)) && installedSchemaVersion > new SemVersion(new Version(0, 0, 0)))
{
//set the installedMigrationVersion to be one less than the target so the latest migrations are guaranteed to execute
installedMigrationVersion = new SemVersion(targetVersion.SubtractRevision());
}
//Figure out what our current installed version is. If the web.config doesn't have a version listed, then we'll use the minimum
// version detected between the schema installed and the migrations listed in the migration table.
// version detected between the schema installed and the migrations listed in the migration table.
// If there is a version in the web.config, we'll take the minimum between the listed migration in the db and what
// is declared in the web.config.
var currentInstalledVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
//Take the minimum version between the detected schema version and the installed migration version
? new[] {installedSchemaVersion, installedMigrationVersion}.Min()
//Take the minimum version between the installed migration version and the version specified in the config
: new[] { SemVersion.Parse(GlobalSettings.ConfigurationStatus), installedMigrationVersion }.Min();
//Ok, another edge case here. If the current version is a pre-release,
// then we want to ensure all migrations for the current release are executed.
//Ok, another edge case here. If the current version is a pre-release,
// then we want to ensure all migrations for the current release are executed.
if (currentInstalledVersion.Prerelease.IsNullOrWhiteSpace() == false)
{
currentInstalledVersion = new SemVersion(currentInstalledVersion.GetVersion().SubtractRevision());
@@ -731,7 +634,7 @@ namespace Umbraco.Core
//DO the upgrade!
var runner = new MigrationRunner(migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), Constants.System.UmbracoMigrationName);
var runner = new MigrationRunner(migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), GlobalSettings.UmbracoMigrationName);
var upgraded = runner.Execute(database, true);
@@ -858,7 +761,7 @@ namespace Umbraco.Core
{
var datasource = dataSourcePart.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString());
var filePath = datasource.Replace("Data Source=", string.Empty);
sqlCeDatabaseExists = File.Exists(filePath);
sqlCeDatabaseExists = File.Exists(filePath);
}
}
@@ -872,30 +775,5 @@ namespace Umbraco.Core
return true;
}
/*
private class UsingDatabase : IDisposable
{
private readonly UmbracoDatabase _orig;
private readonly UmbracoDatabase _temp;
public UsingDatabase(UmbracoDatabase orig, UmbracoDatabase temp)
{
_orig = orig;
_temp = temp;
}
public void Dispose()
{
if (_temp != null)
{
_temp.Dispose();
if (_orig != null)
DefaultDatabaseFactory.AttachAmbientDatabase(_orig);
}
GC.SuppressFinalize(this);
}
}
*/
}
}
+1 -37
View File
@@ -41,43 +41,7 @@ namespace Umbraco.Core
Hour,
Minute,
Second
}
/// <summary>
/// Calculates the number of minutes from a date time, on a rolling daily basis (so if
/// date time is before the time, calculate onto next day)
/// </summary>
/// <param name="fromDateTime">Date to start from</param>
/// <param name="scheduledTime">Time to compare against (in Hmm form, e.g. 330, 2200)</param>
/// <returns></returns>
public static int PeriodicMinutesFrom(this DateTime fromDateTime, string scheduledTime)
{
// Ensure time provided is 4 digits long
if (scheduledTime.Length == 3)
{
scheduledTime = "0" + scheduledTime;
}
var scheduledHour = int.Parse(scheduledTime.Substring(0, 2));
var scheduledMinute = int.Parse(scheduledTime.Substring(2));
DateTime scheduledDateTime;
if (IsScheduledInRemainingDay(fromDateTime, scheduledHour, scheduledMinute))
{
scheduledDateTime = new DateTime(fromDateTime.Year, fromDateTime.Month, fromDateTime.Day, scheduledHour, scheduledMinute, 0);
}
else
{
var nextDay = fromDateTime.AddDays(1);
scheduledDateTime = new DateTime(nextDay.Year, nextDay.Month, nextDay.Day, scheduledHour, scheduledMinute, 0);
}
return (int)(scheduledDateTime - fromDateTime).TotalMinutes;
}
private static bool IsScheduledInRemainingDay(DateTime fromDateTime, int scheduledHour, int scheduledMinute)
{
return scheduledHour > fromDateTime.Hour || (scheduledHour == fromDateTime.Hour && scheduledMinute >= fromDateTime.Minute);
}
}
}
-56
View File
@@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Provides a base class to all artifacts.
/// </summary>
public abstract class ArtifactBase<TUdi> : IArtifact
where TUdi : Udi
{
protected ArtifactBase(TUdi udi, IEnumerable<ArtifactDependency> dependencies = null)
{
if (udi == null)
throw new ArgumentNullException("udi");
Udi = udi;
Name = Udi.ToString();
Dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
_checksum = new Lazy<string>(GetChecksum);
}
private readonly Lazy<string> _checksum;
private IEnumerable<ArtifactDependency> _dependencies;
protected abstract string GetChecksum();
#region Abstract implementation of IArtifactSignature
Udi IArtifactSignature.Udi
{
get { return Udi; }
}
public TUdi Udi { get; set; }
[JsonIgnore]
public string Checksum
{
get { return _checksum.Value; }
}
public IEnumerable<ArtifactDependency> Dependencies
{
get { return _dependencies; }
set { _dependencies = value.OrderBy(x => x.Udi); }
}
#endregion
public string Name { get; set; }
public string Alias { get; set; }
}
}
@@ -1,40 +0,0 @@
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Represents an artifact dependency.
/// </summary>
/// <remarks>
/// <para>Dependencies have an order property which indicates whether it must be respected when ordering artifacts.</para>
/// <para>Dependencies have a mode which can be <c>Match</c> or <c>Exist</c> depending on whether the checksum should match.</para>
/// </remarks>
public class ArtifactDependency
{
/// <summary>
/// Initializes a new instance of the ArtifactDependency class with an entity identifier and a mode.
/// </summary>
/// <param name="udi">The entity identifier of the artifact that is a dependency.</param>
/// <param name="ordering">A value indicating whether the dependency is ordering.</param>
/// <param name="mode">The dependency mode.</param>
public ArtifactDependency(Udi udi, bool ordering, ArtifactDependencyMode mode)
{
Udi = udi;
Ordering = ordering;
Mode = mode;
}
/// <summary>
/// Gets the entity id of the artifact that is a dependency.
/// </summary>
public Udi Udi { get; private set; }
/// <summary>
/// Gets a value indicating whether the dependency is ordering.
/// </summary>
public bool Ordering { get; private set; }
/// <summary>
/// Gets the dependency mode.
/// </summary>
public ArtifactDependencyMode Mode { get; private set; }
}
}
@@ -1,69 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Represents a collection of distinct <see cref="ArtifactDependency"/>.
/// </summary>
/// <remarks>The collection cannot contain duplicates and modes are properly managed.</remarks>
public class ArtifactDependencyCollection : ICollection<ArtifactDependency>
{
private readonly Dictionary<Udi, ArtifactDependency> _dependencies
= new Dictionary<Udi, ArtifactDependency>();
public IEnumerator<ArtifactDependency> GetEnumerator()
{
return _dependencies.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(ArtifactDependency item)
{
if (_dependencies.ContainsKey(item.Udi))
{
var exist = _dependencies[item.Udi];
if (item.Mode == ArtifactDependencyMode.Exist || item.Mode == exist.Mode)
return;
}
_dependencies[item.Udi] = item;
}
public void Clear()
{
_dependencies.Clear();
}
public bool Contains(ArtifactDependency item)
{
return _dependencies.ContainsKey(item.Udi) &&
(_dependencies[item.Udi].Mode == item.Mode || _dependencies[item.Udi].Mode == ArtifactDependencyMode.Match);
}
public void CopyTo(ArtifactDependency[] array, int arrayIndex)
{
_dependencies.Values.CopyTo(array, arrayIndex);
}
public bool Remove(ArtifactDependency item)
{
throw new NotSupportedException();
}
public int Count
{
get { return _dependencies.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
}
}
@@ -1,18 +0,0 @@
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Indicates the mode of the dependency.
/// </summary>
public enum ArtifactDependencyMode
{
/// <summary>
/// The dependency must match exactly.
/// </summary>
Match,
/// <summary>
/// The dependency must exist.
/// </summary>
Exist
}
}
@@ -1,50 +0,0 @@
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Represent the state of an artifact being deployed.
/// </summary>
public abstract class ArtifactDeployState
{
/// <summary>
/// Creates a new instance of the <see cref="ArtifactDeployState"/> class from an artifact and an entity.
/// </summary>
/// <typeparam name="TArtifact">The type of the artifact.</typeparam>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="art">The artifact.</param>
/// <param name="entity">The entity.</param>
/// <param name="connector">The service connector deploying the artifact.</param>
/// <param name="nextPass">The next pass number.</param>
/// <returns>A deploying artifact.</returns>
public static ArtifactDeployState<TArtifact, TEntity> Create<TArtifact, TEntity>(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass)
where TArtifact : IArtifact
{
return new ArtifactDeployState<TArtifact, TEntity>(art, entity, connector, nextPass);
}
/// <summary>
/// Gets the artifact.
/// </summary>
public IArtifact Artifact
{
get { return GetArtifactAsIArtifact(); }
}
/// <summary>
/// Gets the artifact as an <see cref="IArtifact"/>.
/// </summary>
/// <returns>The artifact, as an <see cref="IArtifact"/>.</returns>
/// <remarks>This is because classes that inherit from this class cannot override the Artifact property
/// with a property that specializes the return type, and so they need to 'new' the property.</remarks>
protected abstract IArtifact GetArtifactAsIArtifact();
/// <summary>
/// Gets or sets the service connector in charge of deploying the artifact.
/// </summary>
public IServiceConnector Connector { get; set; }
/// <summary>
/// Gets or sets the next pass number.
/// </summary>
public int NextPass { get; set; }
}
}
@@ -1,48 +0,0 @@
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Represent the state of an artifact being deployed.
/// </summary>
/// <typeparam name="TArtifact">The type of the artifact.</typeparam>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
public class ArtifactDeployState<TArtifact, TEntity> : ArtifactDeployState
where TArtifact : IArtifact
{
/// <summary>
/// Initializes a new instance of the <see cref="ArtifactDeployState{TArtifact,TEntity}"/> class.
/// </summary>
public ArtifactDeployState()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ArtifactDeployState{TArtifact,TEntity}"/> class.
/// </summary>
/// <param name="art">The artifact.</param>
/// <param name="entity">The entity.</param>
/// <param name="connector">The service connector deploying the artifact.</param>
/// <param name="nextPass">The next pass number.</param>
public ArtifactDeployState(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass)
{
Artifact = art;
Entity = entity;
Connector = connector;
NextPass = nextPass;
}
/// <summary>
/// Gets or sets the artifact.
/// </summary>
public new TArtifact Artifact { get; set; }
/// <summary>
/// Gets or sets the entity.
/// </summary>
public TEntity Entity { get; set; }
/// <inheritdoc/>
protected sealed override IArtifact GetArtifactAsIArtifact()
{
return Artifact;
}
}
}
@@ -1,21 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Deploy
{
public sealed class ArtifactSignature : IArtifactSignature
{
public ArtifactSignature(Udi udi, string checksum, IEnumerable<ArtifactDependency> dependencies = null)
{
Udi = udi;
Checksum = checksum;
Dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
}
public Udi Udi { get; private set; }
public string Checksum { get; private set; }
public IEnumerable<ArtifactDependency> Dependencies { get; private set; }
}
}

Some files were not shown because too many files have changed in this diff Show More