diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2df1da5b5077d597142e85e19812ba900a4e81c --- /dev/null +++ b/.gitignore @@ -0,0 +1,270 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Database connection for t4 class generation from database +**/*.generated.cs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user +Resharper + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +#cake +tools/* +!tools/packages.config +dist/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..b339a45c43a1dcb4b80ab99e6224bc7232abd723 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,55 @@ +stages: + - test + - release + - releasetrigger + +cake:Test: + stage: test + script: + - PowerShell .\build.ps1 -Target Test -Configuration Debug + variables: + GIT_STRATEGY: clone + artifacts: + reports: + junit: "./Artifacts/TestResults.xml" + paths: + - "./Artifacts/*" + except: + - master + - tags + +cake:Release: + stage: release + script: + - PowerShell .\build.ps1 -Target Release -Configuration Release --nugetApiKey="${NUGET_API_KEY}" + variables: + GIT_STRATEGY: clone + dependencies: + - cake:Test + artifacts: + paths: + - "./Artifacts/*" + only: + - tags + +cake:Prerelease: + stage: release + script: + - PowerShell .\build.ps1 -Target Prerelease -Configuration Release + variables: + GIT_STRATEGY: clone + dependencies: + - cake:Test + artifacts: + paths: + - "./Artifacts/*" + except: + - tags + - master + +cake:GitlabRelease: + stage: releasetrigger + script: + - PowerShell .\build.ps1 -Target GitlabRelease --GitlabProjectPath="${CI_PROJECT_PATH}" --gitlabProjectId="${CI_PROJECT_ID}" --gitlabToken="${GITLAB_TOKEN}" + only: + - master \ No newline at end of file diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000000000000000000000000000000000000..1bdc0fe219f5f35d8a024a66d9fd715f44539640 --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,7 @@ +mode: ContinuousDeployment +next-version: 1.0.0 +major-version-bump-message: 'Breaking:' +minor-version-bump-message: '(Update|New):' +patch-version-bump-message: 'Fix:' +no-bump-message: '.*' +commit-message-incrementing: Enabled \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..028e1445d83a05b6d68027507edb53033ca40ac3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 RWTH Aachen University + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/build.cake b/build.cake new file mode 100644 index 0000000000000000000000000000000000000000..81648ff61bbee492e1bc7b4390eb8e0cc33d3056 --- /dev/null +++ b/build.cake @@ -0,0 +1,351 @@ +#tool nuget:?package=NUnit.ConsoleRunner&version=3.10.0 +#tool nuget:?package=vswhere&version=2.8.4 +#tool nuget:?package=GitVersion.CommandLine&version=5.1.3 + +#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Json&version=4.0.0 +#addin nuget:https://api.nuget.org/v3/index.json?package=Newtonsoft.Json&version=11.0.2 +#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=3.2.1 + +using System.Net; +using System.Net.Http; + +// Commandline arguments +var target = Argument("target", "Default"); +var configuration = Argument("configuration", "Release"); +var nugetApiKey = Argument<string>("nugetApiKey", null); +var version = Argument("nugetVersion", ""); +var gitlabProjectPath = Argument("gitlabProjectPath", ""); +var gitlabProjectId = Argument("gitlabProjectId", ""); +var gitlabToken = Argument("gitlabToken", ""); + +// Define directories +var projects = GetFiles("./**/*.csproj"); +var artifactsDir = Directory("./Artifacts"); +string nupkgDir; +var solutionFile = GetFiles("./**/*.sln").First(); +var projectName = solutionFile.GetFilenameWithoutExtension().ToString(); +var nugetSource = "https://api.nuget.org/v3/index.json"; +var assemblyInfoSubPath = "Properties/AssemblyInfo.cs"; +var semanticVersion = ""; +string localNugetFeed; + +// get latest MSBuild version +var vsLatest = VSWhereLatest(); +var msBuildPathX64 = (vsLatest == null) ? null : vsLatest.CombineWithFilePath("./MSBuild/Current/Bin/MSBuild.exe"); + +Setup(context =>{ + nupkgDir = $"{artifactsDir.ToString()}/nupkg"; + var branch = GitVersion(new GitVersionSettings { + UpdateAssemblyInfo = false + }).BranchName.Replace("/", "-"); + + localNugetFeed = $"C:\\coscine\\LocalNugetFeeds\\{branch}"; + Information("{0}", branch); + Information("Started at {0}", DateTime.Now); +}); + +Teardown(context =>{ + Information("Finished at {0}", DateTime.Now); +}); + +Task("Clean") +.Description("Cleans all build and artifacts directories") +.Does(() =>{ + var settings = new DeleteDirectorySettings { + Recursive = true, + Force = true + }; + + var directoriesToClean = new List<DirectoryPath>(); + + foreach(var project in projects) { + directoriesToClean.Add(Directory($"{project.GetDirectory()}/obj")); + directoriesToClean.Add(Directory($"{project.GetDirectory()}/bin")); + } + + directoriesToClean.Add(artifactsDir); + + foreach(var dir in directoriesToClean) { + Information("Cleaning {0}", dir.ToString()); + if (DirectoryExists(dir)) { + DeleteDirectory(dir, settings); + CreateDirectory(dir); + } else { + CreateDirectory(dir); + } + } +}); + +Task("Restore") +.Does(() =>{ + NuGetRestore(solutionFile, new NuGetRestoreSettings { + NoCache = true, + FallbackSource = new List<string>{ localNugetFeed }, + }); +}); + +Task("Test") +.IsDependentOn("Build") +.Does(() =>{ + NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings { + // generate the xml file + NoResults = false, + Results = new NUnit3Result[] { + new NUnit3Result() { + FileName = $"{artifactsDir}/TestResults.xml", + Transform = $"{Context.Environment.WorkingDirectory}/nunit3-junit.xslt" + } + } + }); +}); + +Task("GitVersion") +.Does(() => { + if(string.IsNullOrWhiteSpace(version)) { + version = GitVersion(new GitVersionSettings { + UpdateAssemblyInfo = false + }).NuGetVersionV2; + } + var index = version.IndexOf("-"); + semanticVersion = index > 0 ? version.Substring(0, index) : version; + Information("Version: {0}, SemanticVersion: {1}", version, semanticVersion); +}); + +Task("UpdateAssemblyInfo") +.Does(() =>{ + var index = version.IndexOf("-"); + var semanticVersion = index > 0 ? version.Substring(0, index) : version; + + foreach(var project in projects) { + CreateAssemblyInfo($"{project.GetDirectory()}/{assemblyInfoSubPath}", new AssemblyInfoSettings { + Product = project.GetFilenameWithoutExtension().ToString(), + Title = project.GetFilenameWithoutExtension().ToString(), + Company = "IT Center, RWTH Aachen University", + Version = semanticVersion, + FileVersion = semanticVersion, + InformationalVersion = version, + Copyright = $"{DateTime.Now.Year} IT Center, RWTH Aachen University", + Description = $"{project.GetFilenameWithoutExtension().ToString()} is a part of the CoScInE group." + }); + } +}); + +Task("GitlabRelease") +.IsDependentOn("GitVersion") +.Does(() => { + var client = new HttpClient(); + client.DefaultRequestHeaders.Add("PRIVATE-TOKEN", gitlabToken); + + // get the latest tag + var result = client.GetAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/repository/tags").Result; + if(!result.IsSuccessStatusCode) { + throw new Exception("Tag query failed."); + } + + var tagList = result.Content.ReadAsStringAsync().Result; + var jArray = JArray.Parse(tagList); + // null if not tags exists yet + var lastTag = jArray.Select(x => x["name"]).FirstOrDefault(); + + var url = $"https://git.rwth-aachen.de/{gitlabProjectPath}"; + + if(url.EndsWith(".git")) { + url = url.Substring(0, url.Length - ".git".Length); + } + + if(url.EndsWith("/")) { + url = url.Substring(0, url.Length - 1); + } + + var description = ""; + // First line of description + // Gitlab compare url, if something can be compared + if(lastTag == null) { + description = $"# {semanticVersion} ({DateTime.Now.Year}-{DateTime.Now.Month}-{DateTime.Now.Day})\n\n\n"; + } else { + description = $"# [{semanticVersion}]({url}/compare/{lastTag}...v{semanticVersion}) ({DateTime.Now.Year}-{DateTime.Now.Month}-{DateTime.Now.Day})\n\n\n"; + } + + // From when will messages be parsed, null results in all messages + var logParam = ""; + if(lastTag != null) { + logParam = $"{lastTag}..Head"; + } + + Information(lastTag); + + IEnumerable<string> redirectedStandardOutput; + var exitCodeWithArgument = + StartProcess( + "git", + new ProcessSettings { + Arguments = $"log {logParam} --pretty=format:HASH%h:%B", + RedirectStandardOutput = true + }, + out redirectedStandardOutput + ); + + var prefixList = new Dictionary<string, List<string>>{ + {"Fix", new List<string>()}, + {"Update", new List<string>()}, + {"New", new List<string>()}, + {"Breaking", new List<string>()}, + {"Docs", new List<string>()}, + {"Build", new List<string>()}, + {"Upgrade", new List<string>()}, + {"Chore", new List<string>()}, + }; + + var currentHash = ""; + // Output last line of process output. + foreach(var line in redirectedStandardOutput) { + var commitMessage = ""; + if(line.StartsWith("HASH")) { + currentHash = line.Substring("HASH".Length); + currentHash = currentHash.Substring(0, currentHash.IndexOf(":")); + commitMessage = line.Substring(currentHash.Length + line.IndexOf(currentHash) + 1); + } else { + commitMessage = line; + } + + foreach(var kv in prefixList) { + if(commitMessage.StartsWith($"{kv.Key}:")) { + kv.Value.Add($"* {commitMessage.Substring(kv.Key.Length + 1).Trim()} {currentHash}"); + break; + } + }; + } + + foreach(var kv in prefixList) { + if(kv.Value.Any()) { + description += $" ### {kv.Key}\n\n"; + foreach(var line in kv.Value) { + description += $"{line}\n"; + } + description += "\n"; + } + } + // correctly escape the json newlines + description = description.Replace("\n", "\\n"); + Information("Description: {0}", description); + + // create tag + result = client.PostAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/repository/tags?tag_name=v{semanticVersion}&ref=master", null).Result; + Information("Create tag: {0}", result.Content.ReadAsStringAsync().Result); + if(!result.IsSuccessStatusCode) { + throw new Exception("Tag creation failed."); + } + + // create release + var json = $"{{\"name\": \"v{semanticVersion}\", \"tag_name\": \"v{semanticVersion}\", \"description\": \"{description}\"}}"; + var content = new StringContent(json, Encoding.UTF8, "application/json"); + result = client.PostAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/releases", content).Result; + Information("Create release: {0}", result.Content.ReadAsStringAsync().Result); + if(!result.IsSuccessStatusCode) { + throw new Exception("Release creation failed."); + } +}); + +Task("Build") +.IsDependentOn("Clean") +.IsDependentOn("GitVersion") +.IsDependentOn("UpdateAssemblyInfo") +.IsDependentOn("Restore") +.Does(() =>{ + var frameworkSettingsWindows = new MSBuildSettings { + Configuration = configuration + }; + + frameworkSettingsWindows.ToolPath = msBuildPathX64; + frameworkSettingsWindows.WorkingDirectory = Context.Environment.WorkingDirectory; + + if (configuration.Equals("Release")) { + frameworkSettingsWindows.WithProperty("DebugSymbols", "false"); + frameworkSettingsWindows.WithProperty("DebugType", "None"); + } + + // Use MSBuild + Information("Building {0}", solutionFile); + MSBuild(solutionFile, frameworkSettingsWindows); +}); + +Task("NugetPack") +.IsDependentOn("Build") +.Does(() =>{ + foreach(var project in projects) { + var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec"; + if(!project.ToString().EndsWith(".Tests") && FileExists(nuspec)) + { + var settings = new NuGetPackSettings + { + OutputDirectory = nupkgDir, + Version = version, + Properties = new Dictionary<string, string> + { + { "Configuration", configuration} + } + }; + NuGetPack(project.ToString(), settings); + } + } +}); + +Task("NugetPush") +.IsDependentOn("NugetPack") +.Does(() =>{ + var nupkgs = GetFiles($"{nupkgDir}/*.nupkg"); + Information("Need to push {0} packages", nupkgs.Count); + if(!String.IsNullOrWhiteSpace(nugetApiKey)) { + foreach(var nupkg in nupkgs) { + Information("Pushing {0}", nupkg); + NuGetPush(nupkg, new NuGetPushSettings { + Source = nugetSource, + ApiKey = nugetApiKey + }); + } + } else { + Information("NugetApiKey is not set. Can't push."); + throw new Exception("NugetApiKey is not set. Can't push."); + } +}); + +Task("CopyToArtifacts") +.Does(() =>{ + foreach(var project in projects) { + if(!project.GetDirectory().ToString().EndsWith(".Tests") + && !FileExists($"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec") + && DirectoryExists(project.GetDirectory())) + { + Information("Copying {0}/* to {1}", $"{project.GetDirectory()}/bin/{configuration}", artifactsDir); + CopyDirectory($"{project.GetDirectory()}/bin/{configuration}/", artifactsDir); + } + } +}); + +Task("NugetPushLocal") +.IsDependentOn("NugetPack") +.Does(() =>{ + var nupkgs = GetFiles($"{nupkgDir}/*.nupkg"); + foreach(var nupkg in nupkgs) { + if(!DirectoryExists(localNugetFeed)) { + CreateDirectory(localNugetFeed); + } + CopyFile(nupkg.ToString(), $"{localNugetFeed}\\{nupkg.GetFilename()}"); + } +}); + +Task("Prerelease") +.IsDependentOn("Build") +.IsDependentOn("CopyToArtifacts") +.IsDependentOn("NugetPushLocal"); + +Task("Release") +.IsDependentOn("NugetPack") +.IsDependentOn("CopyToArtifacts") +.IsDependentOn("NugetPushLocal") +.IsDependentOn("NugetPush"); + +Task("Default") +.IsDependentOn("Test"); + +RunTarget(target); diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..f83382e8e4092ba6cf32a47f9dfa4e211c878430 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,255 @@ +#The MIT License (MIT) +# +#Copyright (c) 2014 - 2016 Patrik Svensson, Mattias Karlsson, Gary Ewan Park and contributors +# +#Permission is hereby granted, free of charge, to any person obtaining a copy of +#this software and associated documentation files (the "Software"), to deal in +#the Software without restriction, including without limitation the rights to +#use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +#the Software, and to permit persons to whom the Software is furnished to do so, +#subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +#FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +#COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +#IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +#CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER ShowDescription +Shows description about tasks. +.PARAMETER DryRun +Performs a dry run. +.PARAMETER Experimental +Uses the nightly builds of the Roslyn script engine. +.PARAMETER Mono +Uses the Mono Compiler rather than the Roslyn script engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +https://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "build.cake", + [string]$Target, + [string]$Configuration, + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity, + [switch]$ShowDescription, + [Alias("WhatIf", "Noop")] + [switch]$DryRun, + [switch]$Experimental, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null +function MD5HashFile([string] $filePath) +{ + if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) + { + return $null + } + + [System.IO.Stream] $file = $null; + [System.Security.Cryptography.MD5] $md5 = $null; + try + { + $md5 = [System.Security.Cryptography.MD5]::Create() + $file = [System.IO.File]::OpenRead($filePath) + return [System.BitConverter]::ToString($md5.ComputeHash($file)) + } + finally + { + if ($file -ne $null) + { + $file.Dispose() + } + } +} + +function GetProxyEnabledWebClient +{ + $wc = New-Object System.Net.WebClient + $proxy = [System.Net.WebRequest]::GetSystemWebProxy() + $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials + $wc.Proxy = $proxy + return $wc +} + +Write-Host "Preparing to run build script..." + +if(!$PSScriptRoot){ + $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent +} + +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" +$MODULES_DIR = Join-Path $TOOLS_DIR "Modules" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" +$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" +$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" +$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + + # Check for changes in packages.config and remove installed tools if true. + [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) + if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or + ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { + Write-Verbose -Message "Missing or changed package.config hash..." + Remove-Item * -Recurse -Exclude packages.config,nuget.exe + } + + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet tools." + } + else + { + $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" + } + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore addins from NuGet +if (Test-Path $ADDINS_PACKAGES_CONFIG) { + Push-Location + Set-Location $ADDINS_DIR + + Write-Verbose -Message "Restoring addins from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet addins." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore modules from NuGet +if (Test-Path $MODULES_PACKAGES_CONFIG) { + Push-Location + Set-Location $MODULES_DIR + + Write-Verbose -Message "Restoring modules from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet modules." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + + + +# Build Cake arguments +$cakeArguments = @("$Script"); +if ($Target) { $cakeArguments += "-target=$Target" } +if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } +if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } +if ($ShowDescription) { $cakeArguments += "-showdescription" } +if ($DryRun) { $cakeArguments += "-dryrun" } +if ($Experimental) { $cakeArguments += "-experimental" } +if ($Mono) { $cakeArguments += "-mono" } +$cakeArguments += $ScriptArgs + +# Start Cake +Write-Host "Running build script..." +&$CAKE_EXE $cakeArguments +exit $LASTEXITCODE diff --git a/build.sh b/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..d088917ed78538ff57cf654cf71aad6bf045d655 --- /dev/null +++ b/build.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +#The MIT License (MIT) +# +#Copyright (c) 2014 - 2016 Patrik Svensson, Mattias Karlsson, Gary Ewan Park and contributors +# +#Permission is hereby granted, free of charge, to any person obtaining a copy of +#this software and associated documentation files (the "Software"), to deal in +#the Software without restriction, including without limitation the rights to +#use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +#the Software, and to permit persons to whom the Software is furnished to do so, +#subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +#FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +#COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +#IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +#CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +########################################################################## +# This is the Cake bootstrapper script for Linux and OS X. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +# Define directories. +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +TOOLS_DIR=$SCRIPT_DIR/tools +NUGET_EXE=$TOOLS_DIR/nuget.exe +CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe +PACKAGES_CONFIG=$TOOLS_DIR/packages.config +PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum + +# Define md5sum or md5 depending on Linux/OSX +MD5_EXE= +if [[ "$(uname -s)" == "Darwin" ]]; then + MD5_EXE="md5 -r" +else + MD5_EXE="md5sum" +fi + +# Define default arguments. +SCRIPT="build.cake" +TARGET="Default" +CONFIGURATION="Release" +VERBOSITY="verbose" +DRYRUN= +SHOW_VERSION=false +SCRIPT_ARGUMENTS=() + +# Parse arguments. +for i in "$@"; do + case $1 in + -s|--script) SCRIPT="$2"; shift ;; + -t|--target) TARGET="$2"; shift ;; + -c|--configuration) CONFIGURATION="$2"; shift ;; + -v|--verbosity) VERBOSITY="$2"; shift ;; + -d|--dryrun) DRYRUN="-dryrun" ;; + --version) SHOW_VERSION=true ;; + --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; + *) SCRIPT_ARGUMENTS+=("$1") ;; + esac + shift +done + +# Make sure the tools folder exist. +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" +fi + +# Make sure that packages.config exist. +if [ ! -f "$TOOLS_DIR/packages.config" ]; then + echo "Downloading packages.config..." + curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages + if [ $? -ne 0 ]; then + echo "An error occurred while downloading packages.config." + exit 1 + fi +fi + +# Download NuGet if it does not exist. +if [ ! -f "$NUGET_EXE" ]; then + echo "Downloading NuGet..." + curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + if [ $? -ne 0 ]; then + echo "An error occurred while downloading nuget.exe." + exit 1 + fi +fi + +# Restore tools from NuGet. +pushd "$TOOLS_DIR" >/dev/null +if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then + find . -type d ! -name . | xargs rm -rf +fi + +mono "$NUGET_EXE" install -ExcludeVersion +if [ $? -ne 0 ]; then + echo "Could not restore NuGet packages." + exit 1 +fi + +$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 + +popd >/dev/null + +# Make sure that Cake has been installed. +if [ ! -f "$CAKE_EXE" ]; then + echo "Could not find Cake.exe at '$CAKE_EXE'." + exit 1 +fi + +# Start Cake +if $SHOW_VERSION; then + exec mono "$CAKE_EXE" -version +else + exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" +fi \ No newline at end of file diff --git a/nunit3-junit.xslt b/nunit3-junit.xslt new file mode 100644 index 0000000000000000000000000000000000000000..bf69bdb1d2cd6fc2fdbeb915b4eb6732f720848e --- /dev/null +++ b/nunit3-junit.xslt @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Taken from: https://github.com/nunit/nunit-transforms/tree/master/nunit3-junit +--> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:output method="xml" indent="yes"/> + + <xsl:template match="/test-run"> + <testsuites tests="{@testcasecount}" failures="{@failed}" disabled="{@skipped}" time="{@duration}"> + <xsl:apply-templates/> + </testsuites> + </xsl:template> + + <xsl:template match="test-suite"> + <xsl:if test="test-case"> + <testsuite tests="{@testcasecount}" time="{@duration}" errors="{@testcasecount - @passed - @skipped - @failed}" failures="{@failed}" skipped="{@skipped}" timestamp="{@start-time}"> + <xsl:attribute name="name"> + <xsl:for-each select="ancestor-or-self::test-suite/@name"> + <xsl:value-of select="concat(., '.')"/> + </xsl:for-each> + </xsl:attribute> + <xsl:apply-templates select="test-case"/> + </testsuite> + <xsl:apply-templates select="test-suite"/> + </xsl:if> + <xsl:if test="not(test-case)"> + <xsl:apply-templates/> + </xsl:if> + </xsl:template> + + <xsl:template match="test-case"> + <testcase name="{@name}" assertions="{@asserts}" time="{@duration}" status="{@result}" classname="{@classname}"> + <xsl:if test="@runstate = 'Skipped' or @runstate = 'Ignored'"> + <skipped/> + </xsl:if> + + <xsl:apply-templates/> + </testcase> + </xsl:template> + + <xsl:template match="command-line"/> + <xsl:template match="settings"/> + + <xsl:template match="output"> + <system-out> + <xsl:value-of select="."/> + </system-out> + </xsl:template> + + <xsl:template match="stack-trace"> + </xsl:template> + + <xsl:template match="test-case/failure"> + <failure message="{./message}"> + <xsl:value-of select="./stack-trace"/> + </failure> + </xsl:template> + + <xsl:template match="test-suite/failure"/> + + <xsl:template match="test-case/reason"> + <skipped message="{./message}"/> + </xsl:template> + + <xsl:template match="test-case/assertions"> + </xsl:template> + + <xsl:template match="test-suite/reason"/> + + <xsl:template match="properties"/> +</xsl:stylesheet> \ No newline at end of file diff --git a/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll b/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll new file mode 100644 index 0000000000000000000000000000000000000000..dd8e0105289d37e4be97c1419fd12a2cbc6e00c4 Binary files /dev/null and b/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll differ diff --git a/src/.tools/linq2db.t4models/Init.ps1 b/src/.tools/linq2db.t4models/Init.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..d7e710d55907097cf93d3d3e546801028e12d906 --- /dev/null +++ b/src/.tools/linq2db.t4models/Init.ps1 @@ -0,0 +1,9 @@ +param($installPath, $toolsPath, $package, $project) + +# get the active solution +$solution = Get-Interface $dte.Solution ([EnvDTE80.Solution2]) +$solutionPath = [System.IO.Path]::GetDirectoryName($solution.FullName) +$linq2dbToolsPath = [System.IO.Path]::Combine($solutionPath, ".tools", "linq2db.t4models") + +# tools copy +xcopy $("$toolsPath\*.*") $("$linq2dbToolsPath\") /y /e diff --git a/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll b/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll new file mode 100644 index 0000000000000000000000000000000000000000..d4dd789939d82c83eb2720bf5868234ffafca86d Binary files /dev/null and b/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll differ diff --git a/src/.tools/linq2db.t4models/MySql.Data.dll b/src/.tools/linq2db.t4models/MySql.Data.dll new file mode 100644 index 0000000000000000000000000000000000000000..d97ad46b903f211ecb4e3e09bc44e7128ec887e2 Binary files /dev/null and b/src/.tools/linq2db.t4models/MySql.Data.dll differ diff --git a/src/.tools/linq2db.t4models/Npgsql.dll b/src/.tools/linq2db.t4models/Npgsql.dll new file mode 100644 index 0000000000000000000000000000000000000000..c814b2681c107eac00cbb32812954bc9d163ba73 Binary files /dev/null and b/src/.tools/linq2db.t4models/Npgsql.dll differ diff --git a/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll b/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll new file mode 100644 index 0000000000000000000000000000000000000000..c228b7093fb73194e9bf9689d99b1154a963cf15 Binary files /dev/null and b/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll differ diff --git a/src/.tools/linq2db.t4models/SQLite.Interop.dll b/src/.tools/linq2db.t4models/SQLite.Interop.dll new file mode 100644 index 0000000000000000000000000000000000000000..5b872055f5a4b1b759bfa0811901675d4c01346b Binary files /dev/null and b/src/.tools/linq2db.t4models/SQLite.Interop.dll differ diff --git a/src/.tools/linq2db.t4models/System.Data.SQLite.dll b/src/.tools/linq2db.t4models/System.Data.SQLite.dll new file mode 100644 index 0000000000000000000000000000000000000000..59f3dcc375988dbd291f100bd06f259b88a887e0 Binary files /dev/null and b/src/.tools/linq2db.t4models/System.Data.SQLite.dll differ diff --git a/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll b/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000000000000000000000000000000000000..6807cbd9ba040b9f721a03d7fbe6bc0ec088d50b Binary files /dev/null and b/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll differ diff --git a/src/.tools/linq2db.t4models/linq2db.dll b/src/.tools/linq2db.t4models/linq2db.dll new file mode 100644 index 0000000000000000000000000000000000000000..bcbdac1d0742aad9fe3866797e3036961812b53d Binary files /dev/null and b/src/.tools/linq2db.t4models/linq2db.dll differ diff --git a/src/Version.sln b/src/Version.sln new file mode 100644 index 0000000000000000000000000000000000000000..df813aa1ad58934516a0840df2b8f7b8e618f62f --- /dev/null +++ b/src/Version.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30523.141 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Version", "Version\Version.csproj", "{D942046B-88D3-44AA-856B-6A7B5A7DCBB0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D942046B-88D3-44AA-856B-6A7B5A7DCBB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D942046B-88D3-44AA-856B-6A7B5A7DCBB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D942046B-88D3-44AA-856B-6A7B5A7DCBB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D942046B-88D3-44AA-856B-6A7B5A7DCBB0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {08320DB2-75D1-493F-997C-03CD85808E87} + EndGlobalSection +EndGlobal diff --git a/src/Version/App.config b/src/Version/App.config new file mode 100644 index 0000000000000000000000000000000000000000..9a78cf9f40f376983adf6b40c385c1e5f2bfecd6 --- /dev/null +++ b/src/Version/App.config @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <configSections> + <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> + <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> + </configSections> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> + </startup> + <entityFramework> + <providers> + <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> + </providers> + </entityFramework> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="linq2db" publicKeyToken="e41013125f9e410a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.FileProviders.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.1.1" newVersion="4.1.1.1" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Http" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.2.0" newVersion="2.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Http.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Http.Features" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Routing.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Routing" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.2.0" newVersion="2.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Mvc.Core" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.2.0" newVersion="2.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.CodeAnalysis.CSharp" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.3.0" newVersion="1.4.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Authorization" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Mvc.ApiExplorer" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Mvc.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Mvc.Formatters.Json" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.StaticFiles" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Cryptography.Cng" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" publicKeyToken="adb9793829ddae60" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> \ No newline at end of file diff --git a/src/Version/Controllers/VersionController.cs b/src/Version/Controllers/VersionController.cs new file mode 100644 index 0000000000000000000000000000000000000000..e301c1e7b2e20dd007e1ae64961bcae4d955e49a --- /dev/null +++ b/src/Version/Controllers/VersionController.cs @@ -0,0 +1,65 @@ +using Coscine.Configuration; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Coscine.Api.Version.Controllers +{ + public class VersionController : Controller + { + + private readonly IConfiguration _configuration; + + + public VersionController(ILogger<VersionController> logger) + { + _configuration = Program.Configuration; + + } + [HttpGet("[controller]/versions")] + public IActionResult Versions() + { + JObject Versions = new JObject(); + Versions.Add("api", GetEntries("apis")); + Versions.Add("app", GetEntries("apps")); + Versions.Add("dlls", GetEntries("dlls")); + Versions.Add("scripts", GetEntries("scripts")); + Versions.Add("sharepoint", GetEntries("sharepoint")); + Versions.Add("cron", GetEntries("cron")); + return Json(Versions); + } + + public JArray GetEntries(string name) + { + var Infos = new JArray(); + try { + var stringlist = _configuration.Keys("coscine/" + name + "/"); + var array = stringlist.Select((entry) => entry.Substring(0, entry.LastIndexOf("/") + 1)) + .Distinct().ToArray(); + + foreach (var entry in array) + { + var Version = _configuration.GetString(entry + "version"); + var Name = _configuration.GetString(entry + "name"); + var Port = _configuration.GetString(entry + "port"); + + var Info = new JObject + { + ["name"] = Name, + ["version"] = Version, + ["port"] = Port + }; + Infos.Add(Info); + } + + } + catch + { + } + return Infos; + } + } +} diff --git a/src/Version/LinqToDB.Templates/CopyMe.Access.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.Access.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..01f9aed963515d8a1ae1cf6e091b0253dae602ae --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.Access.tt.txt @@ -0,0 +1,46 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4AccessTemplatesDirectory)LinqToDB.Access.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4AccessTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.Access.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" providerName="Access" + connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MyDatabase.mdb;Locale Identifier=1033;Jet OLEDB:Engine Type=5;Persist Security Info=True" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadAccessMetadata(@"C:\Data", "MyDatabase.mdb"); +// LoadAccessMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.DB2.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.DB2.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..611011da4fed824c029df80fdab44e53a60b8f49 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.DB2.tt.txt @@ -0,0 +1,50 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4DB2TemplatesDirectory)LinqToDB.DB2.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4DB2TemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.DB2.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Download and install IBM Data Server Provider for .NET. + + 2. Add a reference to IBM.Data.DB2.dll. + + 3. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 4. Modify the connection settings below to connect to your database. + + 5. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" providerName="DB2" + connectionString="Server=MyServer:50000;Database=MyDatabase;UID=MyUser;PWD=TestPassword;" /> + </connectionStrings> + + 6. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 7. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadDB2Metadata("MyServer", "50000", "MyDatabase", "MyUser", "TestPassword"); +// LoadDB2Metadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.Firebird.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.Firebird.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..f3d2559e053ba0ba0340d4e1dcf86f99f610598a --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.Firebird.tt.txt @@ -0,0 +1,46 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4FirebirdTemplatesDirectory)LinqToDB.Firebird.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4FirebirdTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.Firebird.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="DataSource=MyServer;Database=C:\Data\MyDatabase.fdb;User Id=SYSDBA;Password=masterkey" providerName="Firebird" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadFirebirdMetadata("MyServer", @"C:\Data\MyDatabase.fdb"); +// LoadFirebirdMetadata(string server, string database, string uid, string password); +// LoadFirebirdMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.Informix.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.Informix.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..17acc1fc73fd405e8fc72106fb3859d9f4dc9ce6 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.Informix.tt.txt @@ -0,0 +1,51 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4InformixTemplatesDirectory)LinqToDB.Informix.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4InformixTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.Informix.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Download and install IBM Data Server Provider for .NET. + + 2. Add a reference to IBM.Data.Informix.dll. + + 3. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 4. Modify the connection settings below to connect to your database. + + 5. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" + connectionString="Host=MyServer;Service=9088;Server=ol_informix1170;Protocol=onsoctcp;Database=MyDatabase;UID=informix;PWD=TestPassword;" + providerName="IBM.Data.Informix"/> + </connectionStrings> + + 6. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 7. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadInformixMetadata("MyServer", "9088", "ol_informix1170", "MyDatabase", "informix", "TestPassword"); +// LoadInformixMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.MySql.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.MySql.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..173d74fa74253225d96a9fe552999988d1247b1d --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.MySql.tt.txt @@ -0,0 +1,45 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4MySqlTemplatesDirectory)LinqToDB.MySql.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4MySqlTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.MySql.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Server=MyServer;Port=3306;Database=MyDatabase;Uid=root;Pwd=TestPassword;charset=utf8;" providerName="MySql.Data.MySqlClient" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadMySqlMetadata("MyServer", "MyDatabase", "root", "TestPassword"); +// LoadMySqlMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.Oracle.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.Oracle.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..16b17cab5f4bd5b3468af299008663b363e19ea8 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.Oracle.tt.txt @@ -0,0 +1,45 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4OracleTemplatesDirectory)LinqToDB.Oracle.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4OracleTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.Oracle.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MyServer)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MyDatabase)));User Id=MyUser;Password=MyPassword;" providerName="Oracle" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadOracleMetadata("MyServer", "1521", "MyDatabase", "MyUser", "MyPassword"); +// LoadOracleMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.PostgreSQL.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.PostgreSQL.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..801611a896edbc93cd6541eaa45ae2e60cfbf936 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.PostgreSQL.tt.txt @@ -0,0 +1,45 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4PostgreSQLTemplatesDirectory)LinqToDB.PostgreSQL.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4PostgreSQLTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.PostgreSQL.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Server=MyServer;Port=5432;Database=MyDatabase;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;Protocol=3;" providerName="PostgreSQL" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadPostgreSQLMetadata("MyServer", "5432", "MyDatabase", "postgres", "TestPassword"); +// LoadPostgreSQLMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.SQLite.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.SQLite.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..d0d8f08812059acae99cf83bc735018f97f2de3a --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.SQLite.tt.txt @@ -0,0 +1,45 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4SQLiteTemplatesDirectory)LinqToDB.SQLite.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4SQLiteTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.SQLite.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Data Source=MyDatabase.sqlite" providerName="SQLite" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadSQLiteMetadata(@"C:\Data", "MyDatabase.sqlite"); +// LoadSQLiteMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.SapHana.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.SapHana.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..7c79bf9e504ab5f80552069e9f34c8cf343f7a78 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.SapHana.tt.txt @@ -0,0 +1,49 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4SapHanaTemplatesDirectory)LinqToDB.SapHana.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4SapHanaTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.SapHana.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Download and install SapHana data provider for .NET. + + 2. Add a reference to Sap.Data.Hana.dll. + + 3. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 4. Modify the connection settings below to connect to your database. + + 5. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Server=hanahost:port;Current Schema=TEST;UserID=Test;Password=TestPassword;" providerName="Sap.Data.Hana" /> + </connectionStrings> + + 6. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 7. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadSapHanaMetadata("MyServer", "MyDatabase", "TestUser", "TestPassword"); +// LoadSapHanaMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.SqlCe.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.SqlCe.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..386b3a0b29c496403ff67f1dc7b99ca14b2293bc --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.SqlCe.tt.txt @@ -0,0 +1,45 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4SqlCeTemplatesDirectory)LinqToDB.SqlCe.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4SqlCeTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.SqlCe.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Data Source=MyDatabase.sdf" providerName="System.Data.SqlServerCe" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadSqlCeMetadata(@"C:\Data", "MyDatabase.sdf"); +// LoadSqlCeMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.SqlServer.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.SqlServer.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..891b6b7b8f425a77475c43995b6d0d807b198483 --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.SqlServer.tt.txt @@ -0,0 +1,56 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4SqlServerTemplatesDirectory)LinqToDB.SqlServer.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4SqlServerTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.SqlServer.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 2. Modify the connection settings below to connect to your database. + + 3. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" providerName="System.Data.SqlClient" + connectionString="Data Source=.;Database=MyDatabase;User Id=User;Password=TestPassword;" /> + </connectionStrings> + + 4. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 5. See more at https://github.com/linq2db/t4models + + If you need to use the Microsoft.SqlServer.Types namespace, install the Microsoft.SqlServer.Types nuget, + and replace the following include at the top of this file: + + "$(ProjectDir)LinqToDB.Templates\LinqToDB.SqlServer.Tools.ttinclude" + + with + + "$(ProjectDir)LinqToDB.Templates\LinqToDB.SqlServer.SqlTypes.Tools.ttinclude" + */ + + NamespaceName = "DataModels"; + + LoadSqlServerMetadata("MyServer", "MyDatabase", "User", "Password"); +// LoadSqlServerMetadata(".", "MyDatabase"); // Integrated Security +// LoadSqlServerMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/CopyMe.Sybase.tt.txt b/src/Version/LinqToDB.Templates/CopyMe.Sybase.tt.txt new file mode 100644 index 0000000000000000000000000000000000000000..edbad0dc74d407c83fee3c18a0d08fc5ead3f29f --- /dev/null +++ b/src/Version/LinqToDB.Templates/CopyMe.Sybase.tt.txt @@ -0,0 +1,49 @@ +<#@ template language="C#" debug="True" hostSpecific="True" #> +<#@ output extension=".generated.cs" #> +<#@ include file="$(LinqToDBT4SybaseTemplatesDirectory)LinqToDB.Sybase.Tools.ttinclude" #> +<#@ include file="$(LinqToDBT4SybaseTemplatesDirectory)PluralizationService.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.Sybase.Tools.ttinclude" #> +<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude" #> +<# + /* + 1. Download and install Sybase data provider for .NET. + + 2. Add a reference to Sybase.AdoNet2(4).AseClient.dll. + + 3. Create new *.tt file (e.g. MyDatabase.tt) in a folder where you would like to generate your data model + and copy content from this file to it. For example: + + MyProject + DataModels + MyDatabase.tt + + 4. Modify the connection settings below to connect to your database. + + 5. Add connection string to the web/app.config file: + + <connectionStrings> + <add name="MyDatabase" connectionString="Data Source=MyServer;Port=5000;Database=MyDatabase;Uid=sa;Password=TestPassword;Charset=utf8;" providerName="Sybase" /> + </connectionStrings> + + 6. To access your database use the following code: + + using (var db = new MyDatabaseDB()) + { + var q = + from c in db.Customers + select c; + + foreach (var c in q) + Console.WriteLine(c.ContactName); + } + + 7. See more at https://github.com/linq2db/t4models + */ + + NamespaceName = "DataModels"; + + LoadSybaseMetadata("MyServer", "5000", "MyDatabase", "sa", "TestPassword"); +// LoadSybaseMetadata(string connectionString); + + GenerateModel(); +#> diff --git a/src/Version/LinqToDB.Templates/DataAnnotations.ttinclude b/src/Version/LinqToDB.Templates/DataAnnotations.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..a98aea24cf313345913d948297bba0784055801a --- /dev/null +++ b/src/Version/LinqToDB.Templates/DataAnnotations.ttinclude @@ -0,0 +1,65 @@ +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + beforeGenerateModel(); + DataAnnotationsImpl(); + }; + } +#> +<#+ +void DataAnnotationsImpl() +{ + foreach (Class cl in GetTreeNodes(Model).OfType<Class>()) + { + foreach (var p in GetTreeNodes(cl).OfType<Property>()) + { + if (p.DisplayName != null) + { + p.Attributes.Add(new Attribute("Display", "Name=" + ToStringLiteral(p.DisplayName)) { IsSeparated = true }); + } + + if (p.IsRequired) + { + var attr = new Attribute("Required") { IsSeparated = true }; + + if (p.IsRequiredMessage != null) + attr.Parameters.Add(string.Format("ErrorMessage=" + ToStringLiteral(p.IsRequiredMessage), p.DisplayName ?? p.Name)); + + p.Attributes.Add(attr); + } + + if (p.StringLength > 0) + { + var attr = new Attribute("StringLength", p.StringLength.ToString()) { IsSeparated = true }; + + if (p.StringLengthMessage != null) + attr.Parameters.Add(string.Format("ErrorMessage=" + ToStringLiteral(p.StringLengthMessage), p.DisplayName ?? p.Name)); + + p.Attributes.Add(attr); + +// p.Attributes.Add( +// new Attribute("StringLength", +// p.StringLength.ToString(), +// "ErrorMessage=" + ToStringLiteral(string.Format( +// "The {0} must be a string with a maximum length of {1}.", +// p.DisplayName ?? "field", +// p.StringLength))) +// { +// IsSeparated = true +// }); + } + } + } +} + +partial class Property +{ + public string DisplayName; + public bool IsRequired; + public string IsRequiredMessage; + public int StringLength; + public string StringLengthMessage; +} +#> diff --git a/src/Version/LinqToDB.Templates/DataModel.ttinclude b/src/Version/LinqToDB.Templates/DataModel.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..b28013d9c981ef4b05570f9207d23fbb95cd44fd --- /dev/null +++ b/src/Version/LinqToDB.Templates/DataModel.ttinclude @@ -0,0 +1,871 @@ +<#@ assembly name="System.Data" #> +<#@ import namespace="System.Data" #> +<#@ import namespace="LinqToDB.SchemaProvider" #> +<#@ import namespace="LinqToDB.Data" #> +<#@ include file="T4Model.ttinclude" #> +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + GenerateTypesFromMetadata(); + beforeGenerateModel(); + }; + } +#><#+ + +string NamespaceName +{ + get { return Model.Namespace.Name; } + set { Model.Namespace.Name = value; } +} + +string DatabaseName = null; +string DataContextName = null; +string BaseDataContextClass = null; +string BaseEntityClass = null; +string OneToManyAssociationType = "IEnumerable<{0}>"; + +bool GenerateDatabaseName = false; +bool GenerateConstructors = true; +string DefaultConfiguration = null; +bool GenerateAssociations = true; +bool GenerateBackReferences = true; +bool GenerateAssociationExtensions = false; +bool ReplaceSimilarTables = true; +bool IncludeDefaultSchema = true; + +Class DataContextObject; + +bool PluralizeClassNames = false; +bool SingularizeClassNames = true; +bool PluralizeDataContextPropertyNames = true; +bool SingularizeDataContextPropertyNames = false; + +bool NormalizeNames = true; + +private Func<string, bool, string> _toValidName; +Func<string, bool, string> ToValidName +{ + get { return _toValidName ?? ToValidNameDefault; } + set { _toValidName = value; } +} + +private Func<string, bool, string> _convertToCompilabl; +Func<string, bool, string> ConvertToCompilable +{ + get { return _convertToCompilabl ?? ConvertToCompilableDefault; } + set { _convertToCompilabl = value; } +} + +private Func<ForeignKey, string> _getAssociationExtensionPluralName; +Func<ForeignKey, string> GetAssociationExtensionPluralName +{ + get { return _getAssociationExtensionPluralName ?? GetAssociationExtensionPluralNameDefault; } + set { _getAssociationExtensionPluralName = value; } +} + +private Func<ForeignKey, string> _getAssociationExtensionSingularName; +Func<ForeignKey, string> GetAssociationExtensionSinglularName +{ + get { return _getAssociationExtensionSingularName ?? GetAssociationExtensionSinglularNameDefault; } + set { _getAssociationExtensionSingularName = value; } +} + +LinqToDB.SchemaProvider.GetSchemaOptions GetSchemaOptions = + new LinqToDB.SchemaProvider.GetSchemaOptions(); + +LinqToDB.SqlProvider.ISqlBuilder SqlBuilder; + +Func<TableSchema,Table> LoadProviderSpecificTable = tableSchema => null; + +static Func<ColumnSchema,string> ConvertColumnMemberType = (c) => c.MemberType; +static Func<TableSchema,ColumnSchema,string> ConvertTableColumnMemberType = (t,c) => ConvertColumnMemberType(c); +static Func<ProcedureSchema,ColumnSchema,string> ConvertProcedureColumnMemberType = (t,c) => ConvertColumnMemberType(c); + +HashSet<string> KeyWords = new HashSet<string> +{ + "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", + "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", + "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", + "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "new", + "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", + "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "struct", "switch", + "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", + "using", "virtual", "volatile", "void", "while", "namespace", "string" +}; + +void LoadServerMetadata(DataConnection dataConnection) +{ + SqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(); + + var sp = dataConnection.DataProvider.GetSchemaProvider(); + var db = sp.GetSchema(dataConnection, GetSchemaOptions); + + if (DatabaseName == null && GenerateDatabaseName) + DatabaseName = db.Database; + + if (DataContextName == null) + DataContextObject.Name = DataContextName = ToValidName(db.Database, true) + "DB"; + + DataContextObject.Comment.Add("/ <summary>"); + DataContextObject.Comment.Add("/ Database : " + db.Database); + DataContextObject.Comment.Add("/ Data Source : " + db.DataSource); + DataContextObject.Comment.Add("/ Server Version : " + db.ServerVersion); + DataContextObject.Comment.Add("/ </summary>"); + + var tables = db.Tables + .Where(t => !t.IsProviderSpecific) + .Select(t => new + { + t, + key = t.IsDefaultSchema ? t.TableName : t.SchemaName + "." + t.TableName, + table = new Table + { + TableSchema = t, + IsDefaultSchema = t.IsDefaultSchema, + Schema = t.IsDefaultSchema && !IncludeDefaultSchema || string.IsNullOrEmpty(t.SchemaName)? null : t.SchemaName, + BaseClass = BaseEntityClass, + TableName = t.TableName, + TypeName = t.TypeName, + DataContextPropertyName = t.TypeName, + IsView = t.IsView, + IsProviderSpecific = false, + Description = t.Description, + Columns = t.Columns.ToDictionary( + c => c.ColumnName, + c => new Column + { + ColumnName = c.ColumnName, + ColumnType = c.ColumnType, + DataType = "DataType." + c.DataType, + Length = c.Length, + Precision = c.Precision, + Scale = c.Scale, + IsNullable = c.IsNullable, + IsIdentity = c.IsIdentity, + IsPrimaryKey = c.IsPrimaryKey, + PrimaryKeyOrder = c.PrimaryKeyOrder, + MemberName = CheckType(c.SystemType, c.MemberName), + TypeBuilder = () => ConvertTableColumnMemberType(t, c), + SkipOnInsert = c.SkipOnInsert, + SkipOnUpdate = c.SkipOnUpdate, + Description = c.Description, + }) + } + }) + .ToList(); + + if (PluralizeClassNames || SingularizeClassNames) + { + var foundNames = new HashSet<string>(tables.Select(t => t.table.Schema + '.' + t.table.TypeName)); + + foreach (var t in tables) + { + var newName = t.table.TypeName; + newName = + PluralizeClassNames ? ToPlural (newName) : + SingularizeClassNames ? ToSingular(newName) : newName; + + if (newName != t.table.TypeName) + { + if (!foundNames.Contains(t.table.Schema + '.' + newName)) + { + t.table.TypeName = newName; + foundNames.Add(t.table.Schema + '.' + newName); + } + } + } + } + + if (PluralizeDataContextPropertyNames || SingularizeDataContextPropertyNames) + { + var foundNames = new HashSet<string>(tables.Select(t => t.table.Schema + '.' + t.table.DataContextPropertyName)); + + foreach (var t in tables) + { + var newName = t.table.DataContextPropertyName; + newName = + PluralizeDataContextPropertyNames ? ToPlural (newName) : + SingularizeDataContextPropertyNames ? ToSingular(newName) : newName; + + if (newName != t.table.TypeName) + { + if (!foundNames.Contains(t.table.Schema + '.' + newName)) + { + t.table.DataContextPropertyName = newName; + foundNames.Add(t.table.Schema + '.' + newName); + } + } + } + } + + tables.AddRange(db.Tables + .Where(t => t.IsProviderSpecific) + .Select(t => new + { + t, + key = t.IsDefaultSchema ? t.TableName : t.SchemaName + "." + t.TableName, + table = LoadProviderSpecificTable(t) + }) + .Where(t => t.table != null)); + + foreach (var t in tables) + Tables.Add(t.key, t.table); + + var keys = + ( + from t in tables + from k in t.t.ForeignKeys + let otherTable = tables.Where(tbl => tbl.t == k.OtherTable).Select(tbl => tbl.table).Single() + select new + { + k, + k.KeyName, + t, + key = new ForeignKey + { + KeyName = k.KeyName, + OtherTable = otherTable, + OtherColumns = k.OtherColumns.Select(c => otherTable.Columns[c.ColumnName]).ToList(), + ThisColumns = k.ThisColumns. Select(c => t.table. Columns[c.ColumnName]).ToList(), + CanBeNull = k.CanBeNull, + MemberName = k.MemberName, + AssociationType = (AssociationType)(int)k.AssociationType, + } + } + ).ToList(); + + foreach (var key in keys) + { + key.t.table.ForeignKeys.Add( + key.k.OtherTable.IsDefaultSchema ? key.KeyName : key.k.OtherTable.SchemaName + "." + key.KeyName, + key.key); + + if (key.k.BackReference != null) + key.key.BackReference = keys.First(k => k.k == key.k.BackReference).key; + + key.key.MemberName = key.key.MemberName.Replace(".", string.Empty); + + key.key.MemberName = key.key.AssociationType == AssociationType.OneToMany ? + ToPlural(key.key.MemberName) : ToSingular(key.key.MemberName); + } + + var procedures = db.Procedures + .Select(p => new + { + p, + key = p.IsDefaultSchema ? p.ProcedureName : p.SchemaName + "." + p.ProcedureName, + proc = new Procedure + { + Schema = (p.IsDefaultSchema && !IncludeDefaultSchema) || string.IsNullOrEmpty(p.SchemaName)? null : p.SchemaName, + ProcedureName = p.ProcedureName, + Name = ToValidName(p.MemberName, true), + IsFunction = p.IsFunction, + IsTableFunction = p.IsTableFunction, + IsAggregateFunction = p.IsAggregateFunction, + IsDefaultSchema = p.IsDefaultSchema, + IsLoaded = p.IsLoaded, + ResultTable = p.ResultTable == null ? null : + new Table + { + TypeName = ToValidName( + PluralizeClassNames ? ToPlural (p.ResultTable.TypeName) : + SingularizeClassNames ? ToSingular(p.ResultTable.TypeName) : p.ResultTable.TypeName, true), + Columns = ToDictionary( + p.ResultTable.Columns, + c => c.ColumnName, + c => new Column + { + ColumnName = c.ColumnName, + ColumnType = c.ColumnType, + IsNullable = c.IsNullable, + IsIdentity = c.IsIdentity, + IsPrimaryKey = c.IsPrimaryKey, + PrimaryKeyOrder = c.PrimaryKeyOrder, + MemberName = CheckColumnName(CheckType(c.SystemType, c.MemberName)), + TypeBuilder = () => ConvertProcedureColumnMemberType(p, c), + SkipOnInsert = c.SkipOnInsert, + SkipOnUpdate = c.SkipOnUpdate, + Description = c.Description, + }, + (c,n) => + { + c.IsDuplicateOrEmpty = true; + return "$" + (c.MemberName = "Column" + n); + }) + }, + ResultException = p.ResultException, + SimilarTables = p.SimilarTables == null ? new List<Table>() : + p.SimilarTables + .Select(t => tables.Single(tbl => tbl.t == t).table) + .ToList(), + ProcParameters = p.Parameters + .Select(pr => new Parameter + { + SchemaName = pr.SchemaName, + SchemaType = pr.SchemaType, + IsIn = pr.IsIn, + IsOut = pr.IsOut, + IsResult = pr.IsResult, + Size = pr.Size, + ParameterName = CheckParameterName(CheckType(pr.SystemType, pr.ParameterName)), + ParameterType = pr.ParameterType, + SystemType = pr.SystemType, + DataType = pr.DataType.ToString(), + }) + .ToList(), + } + }) + .ToList(); + + foreach (var p in procedures) + { + if (ReplaceSimilarTables) + if (p.proc.SimilarTables.Count() == 1 || p.proc.SimilarTables.Count(t => !t.IsView) == 1) + p.proc.ResultTable = p.proc.SimilarTables.Count() == 1 ? + p.proc.SimilarTables[0] : + p.proc.SimilarTables.First(t => !t.IsView); + + Procedures[p.key] = p.proc; + } +} + +Dictionary<string,TR> ToDictionary<T,TR>(IEnumerable<T> source, Func<T,string> keyGetter, Func<T,TR> objGetter, Func<TR,int,string> getKeyName) +{ + var dic = new Dictionary<string,TR>(); + var current = 1; + + foreach (var item in source) + { + var key = keyGetter(item); + var obj = objGetter(item); + + if (string.IsNullOrEmpty(key) || dic.ContainsKey(key)) + key = getKeyName(obj, current); + + dic.Add(key, obj); + + current++; + } + + return dic; +} + +string CheckType(Type type, string typeName) +{ + if (!Model.Usings.Contains(type.Namespace)) + Model.Usings.Add(type.Namespace); + return typeName; +} + +string CheckColumnName(string memberName) +{ + if (string.IsNullOrEmpty(memberName)) + memberName = "Empty"; + else + { + memberName = memberName + .Replace("%", "Percent") + .Replace(">", "Greater") + .Replace("<", "Lower") + .Replace("+", "Plus") + .Replace('(', '_') + .Replace(')', '_') + .Replace('-', '_') + .Replace('|', '_') + .Replace(',', '_') + .Replace('"', '_') + .Replace("'", "_") + .Replace(".", "_") + .Replace("\u00A3", "Pound"); + + if (KeyWords.Contains(memberName)) + memberName = "@" + memberName; + } + return memberName; +} + +string CheckParameterName(string parameterName) +{ + var invalidParameterNames = new List<string> + { + "@DataType" + }; + + var result = parameterName; + while (invalidParameterNames.Contains(result)) + { + result = result + "_"; + } + return result; +} + +Action AfterLoadMetadata = () => {}; + +void LoadMetadata(DataConnection dataConnection) +{ + if (DataContextObject == null) + { + DataContextObject = new Class(DataContextName) { BaseClass = BaseDataContextClass, }; + + Model.Types.Add(DataContextObject); + } + + LoadServerMetadata(dataConnection); + + if (Tables.Values.SelectMany(_ => _.ForeignKeys.Values).Any(_ => _.AssociationType == AssociationType.OneToMany)) + Model.Usings.Add("System.Collections.Generic"); + + foreach (var t in Tables.Values) + { + if (KeyWords.Contains(t.TypeName)) + t.TypeName = "@" + t.TypeName; + + if (KeyWords.Contains(t.DataContextPropertyName)) + t.DataContextPropertyName = "@" + t.DataContextPropertyName; + + t.TypeName = ConvertToCompilable(t.TypeName, true); + t.DataContextPropertyName = ConvertToCompilable(t.DataContextPropertyName, true); + + foreach (var col in t.Columns.Values) + { + if (KeyWords.Contains(col.MemberName)) + col.MemberName = "@" + col.MemberName; + + col.MemberName = ConvertToCompilable(col.MemberName, true); + + if (col.MemberName == t.TypeName) + col.MemberName += "_Column"; + } + + foreach (var fk in t.ForeignKeys.Values) + { + if (KeyWords.Contains(fk.MemberName)) + fk.MemberName = "@" + fk.MemberName; + + fk.MemberName = ConvertToCompilable(fk.MemberName, true); + + if (fk.MemberName == t.TypeName) + fk.MemberName += "_FK"; + } + } + + foreach (var t in Tables.Values) + { + var hasDuplicates = t.Columns.Values + .Select(c => c.MemberName) + .Concat(t.ForeignKeys.Values.Select(f => f.MemberName)) + .ToLookup(n => n) + .Any(g => g.Count() > 1); + + if (hasDuplicates) + { + foreach (var fk in t.ForeignKeys.Values) + { + var mayDuplicate = t.Columns.Values + .Select(c => c.MemberName) + .Concat(t.ForeignKeys.Values.Where(f => f != fk).Select(f => f.MemberName)); + + fk.MemberName = SuggestNoDuplicate(mayDuplicate, fk.MemberName, "FK"); + } + + foreach (var col in t.Columns.Values) + { + var mayDuplicate = t.Columns.Values + .Where(c => c != col) + .Select(c => c.MemberName) + .Concat(t.ForeignKeys.Values.Select(fk => fk.MemberName)); + + col.MemberName = SuggestNoDuplicate(mayDuplicate, col.MemberName, null); + } + } + } + + foreach (var proc in Procedures.Values) + { + proc.Name = ConvertToCompilable(proc.Name, false); + + if (KeyWords.Contains(proc.Name)) + proc.Name = "@" + proc.Name; + + foreach (var param in proc.ProcParameters) + { + if (KeyWords.Contains(param.ParameterName)) + param.ParameterName = ConvertToCompilable("@" + param.ParameterName, true); + } + } + + AfterLoadMetadata(); +} + +string SuggestNoDuplicate(IEnumerable<string> currentNames, string newName, string prefix) +{ + var names = new HashSet<string>(currentNames); + var result = newName; + if (names.Contains(result)) + { + if (!string.IsNullOrEmpty(prefix)) + result = prefix + result; + if (names.Contains(result)) + { + var counter = 0; + var number = string.Concat(result.Reverse().Take(6).TakeWhile(c => Char.IsDigit(c)).Reverse()); + if (!string.IsNullOrEmpty(number)) + { + if (int.TryParse(number, out counter)) + { + result = result.Remove(result.Length - number.Length); + } + } + + do + { + ++counter; + if (!names.Contains(result + counter)) + { + result = result + counter; + break; + } + } + while(true); + } + } + + return result; +} + +string ConvertToCompilableDefault(string name, bool mayRemoveUnderscore) +{ + var query = + from c in name + select char.IsLetterOrDigit(c) || c == '@' ? c : '_'; + + return ToValidName(new string(query.ToArray()), mayRemoveUnderscore); +} + +Table GetTable(string name) +{ + Table tbl; + + if (Tables.TryGetValue(name, out tbl)) + return tbl; + + WriteLine("#error Table '" + name + "' not found."); + WriteLine("/*"); + WriteLine("\tExisting tables:"); + WriteLine(""); + + foreach (var key in Tables.Keys) + WriteLine("\t" + key); + + WriteLine(" */"); + + throw new ArgumentException("Table '" + name + "' not found."); +} + +Procedure GetProcedure(string name) +{ + Procedure proc; + + if (Procedures.TryGetValue(name, out proc)) + return proc; + + WriteLine("#error Procedure '" + name + "' not found."); + WriteLine(""); + WriteLine("/*"); + WriteLine("\tExisting procedures:"); + WriteLine(""); + + foreach (var key in Procedures.Keys) + WriteLine("\t" + key); + + WriteLine(" */"); + + throw new ArgumentException("Procedure '" + name + "' not found."); +} + +Column GetColumn(string tableName, string columnName) +{ + var tbl = GetTable(tableName); + + Column col; + + if (tbl.Columns.TryGetValue(columnName, out col)) + return col; + + WriteLine("#error Column '" + tableName + "'.'" + columnName + "' not found."); + WriteLine(""); + WriteLine("/*"); + WriteLine("\tExisting '" + tableName + "'columns:"); + WriteLine(""); + + foreach (var key in tbl.Columns.Keys) + WriteLine("\t" + key); + + WriteLine(" */"); + + throw new ArgumentException("Column '" + tableName + "'.'" + columnName + "' not found."); +} + +ForeignKey GetFK(string tableName, string fkName) +{ + return GetForeignKey(tableName, fkName); +} + +ForeignKey GetForeignKey(string tableName, string fkName) +{ + var tbl = GetTable(tableName); + + ForeignKey col; + + if (tbl.ForeignKeys.TryGetValue(fkName, out col)) + return col; + + WriteLine("#error FK '" + tableName + "'.'" + fkName + "' not found."); + WriteLine(""); + WriteLine("/*"); + WriteLine("\tExisting '" + tableName + "'FKs:"); + WriteLine(""); + + foreach (var key in tbl.ForeignKeys.Keys) + WriteLine("\t" + key); + + WriteLine(" */"); + + throw new ArgumentException("FK '" + tableName + "'.'" + fkName + "' not found."); +} + + +public TableContext SetTable(string tableName, + string TypeName = null, + string DataContextPropertyName = null) +{ + var ctx = new TableContext { Transformation = this, TableName = tableName }; + + if (TypeName != null || DataContextPropertyName != null) + { + var t = GetTable(tableName); + + if (TypeName != null) t.TypeName = TypeName; + if (DataContextPropertyName != null) t.DataContextPropertyName = DataContextPropertyName; + } + + return ctx; +} + +public class TableContext +{ + public GeneratedTextTransformation Transformation; + public string TableName; + + public TableContext Column(string columnName, + string MemberName = null, + string Type = null, + bool? IsNullable = null, + string Conditional = null) + { + var c = Transformation.GetColumn(TableName, columnName); + + if (MemberName != null) c.MemberName = MemberName; + if (Type != null) c.TypeBuilder = () => Type; + if (IsNullable != null) c.IsNullable = IsNullable.Value; + if (Conditional != null) c.Conditional = Conditional; + + return this; + } + + public TableContext FK(string fkName, + string MemberName = null, + AssociationType? AssociationType = null, + bool? CanBeNull = null) + { + var c = Transformation.GetFK(TableName, fkName); + + if (MemberName != null) c.MemberName = MemberName; + if (AssociationType != null) c.AssociationType = AssociationType.Value; + if (CanBeNull != null) c.CanBeNull = CanBeNull.Value; + + return this; + } +} + + +Dictionary<string,Table> Tables = new Dictionary<string,Table> (); +Dictionary<string,Procedure> Procedures = new Dictionary<string,Procedure>(); + +public partial class Table : Class +{ + public TableSchema TableSchema { get; set; } + public string Schema { get; set; } + public string TableName { get; set; } + public string DataContextPropertyName { get; set; } + public MemberBase DataContextProperty { get; set; } + public bool IsView { get; set; } + public bool IsProviderSpecific { get; set; } + public bool IsDefaultSchema { get; set; } + public string Description { get; set; } + public string AliasPropertyName { get; set; } + public string AliasTypeName { get; set; } + public string TypePrefix { get; set; } + + public string TypeName + { + get { return Name; } + set { Name = value; } + } + + public Dictionary<string,Column> Columns; + public Dictionary<string,ForeignKey> ForeignKeys = new Dictionary<string,ForeignKey>(); +} + +public partial class Column : Property +{ + public string ColumnName; // Column name in database + public bool IsNullable; + public bool IsIdentity; + public string ColumnType; // Type of the column in database + public string DataType; + public long? Length; + public int? Precision; + public int? Scale; + public DbType DbType; + public string Description; + public bool IsPrimaryKey; + public int PrimaryKeyOrder; + public bool SkipOnUpdate; + public bool SkipOnInsert; + public bool IsDuplicateOrEmpty; + public bool IsDiscriminator; + public string AliasName; + + public string MemberName + { + get { return Name; } + set { Name = value; } + } +} + +public enum AssociationType +{ + Auto, + OneToOne, + OneToMany, + ManyToOne, +} + +public partial class ForeignKey : Property +{ + public string KeyName; + public Table OtherTable; + public List<Column> ThisColumns; + public List<Column> OtherColumns; + public bool CanBeNull; + public ForeignKey BackReference; + + public string MemberName + { + get { return Name; } + set { Name = value; } + } + + private AssociationType _associationType = AssociationType.Auto; + public AssociationType AssociationType + { + get { return _associationType; } + set + { + _associationType = value; + + if (BackReference != null) + { + switch (value) + { + case AssociationType.Auto : BackReference.AssociationType = AssociationType.Auto; break; + case AssociationType.OneToOne : BackReference.AssociationType = AssociationType.OneToOne; break; + case AssociationType.OneToMany : BackReference.AssociationType = AssociationType.ManyToOne; break; + case AssociationType.ManyToOne : BackReference.AssociationType = AssociationType.OneToMany; break; + } + } + } + } +} + +public partial class Procedure : Method +{ + public string Schema { get; set; } + public string ProcedureName { get; set; } + public bool IsFunction { get; set; } + public bool IsTableFunction { get; set; } + public bool IsAggregateFunction { get; set; } + public bool IsDefaultSchema { get; set; } + public bool IsLoaded { get; set; } + + public Table ResultTable { get; set; } + public Exception ResultException { get; set; } + public List<Table> SimilarTables { get; set; } + public List<Parameter> ProcParameters { get; set; } +} + +public class Parameter +{ + public string SchemaName { get; set; } + public string SchemaType { get; set; } + public bool IsIn { get; set; } + public bool IsOut { get; set; } + public bool IsResult { get; set; } + public long? Size { get; set; } + + public string ParameterName { get; set; } + public string ParameterType { get; set; } + public Type SystemType { get; set; } + public string DataType { get; set; } +} + +private int _counter = 0; + +string ToValidNameDefault(string name, bool mayRemoveUnderscore) +{ + if (NormalizeNames && mayRemoveUnderscore && name.Contains("_")) + { + name = SplitAndJoin(name, "", '_'); + } + + if (name.Contains(".")) + { + name = SplitAndJoin(name, "", '.'); + } + + if (name.Length > 0 && char.IsDigit(name[0])) + name = "_" + name; + + if (string.IsNullOrEmpty(name)) + name = "_" + _counter++; + + if (NormalizeNames) + { + name = char.ToUpper(name[0]) + name.Substring(1); + } + + return name; +} + +static string SplitAndJoin(string value, string join, params char[] split) +{ + var ss = value.Split(split, StringSplitOptions.RemoveEmptyEntries) + .Select(s => char.ToUpper(s[0]) + (s.Substring(1).All(char.IsUpper) ? s.Substring(1).ToLower() : s.Substring(1))); + + return string.Join(join, ss.ToArray()); +} + +private string GetAssociationExtensionSinglularNameDefault(ForeignKey key) +{ + return ToSingular(key.Name); +} + +private string GetAssociationExtensionPluralNameDefault(ForeignKey key) +{ + return ToPlural(ToSingular(key.Name)); +} + +#> diff --git a/src/Version/LinqToDB.Templates/EditableObject.ttinclude b/src/Version/LinqToDB.Templates/EditableObject.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..e9506c2a27020962e7fe38b07be4972479478707 --- /dev/null +++ b/src/Version/LinqToDB.Templates/EditableObject.ttinclude @@ -0,0 +1,250 @@ +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + EditableObjectImpl(); + beforeGenerateModel(); + }; + + SetPropertyValueAction += (obj,prop,val) => + { + if (prop == "IsEditable") + obj.IsEditable = (bool)val; + }; + } +#> +<#+ +void EditableObjectImpl() +{ + foreach (Property prop in GetTreeNodes(Model).OfType<Property>().Where(p => p.IsEditable).ToList()) + { + SetPropertyValue(prop, "IsNotifying", true); + + List<IClassMember> parentMembers; + + MemberGroup gr = null; + + if (prop.Parent is Class) + { + var parent = (Class)prop.Parent; + parentMembers = parent.Members; + } + else + { + var parent = (MemberGroup)prop.Parent; + parentMembers = parent.Members; + + parent.IsCompact = false; + } + + var name = prop.Name.Trim(); + var type = prop.BuildType().Trim(); + + if (gr == null) + { + gr = new MemberGroup + { + Region = name + " : " + type, + Members = { prop }, + IsPropertyGroup = true, + }; + + var index = parentMembers.IndexOf(prop); + + parentMembers.RemoveAt(index); + parentMembers.Insert (index, gr); + } + + var originalField = new Field(() => type, "_original" + name) + { + AccessModifier = AccessModifier.Private, + InsertBlankLineAfter = false, + }; + + gr.Members.Insert(0, originalField); + + var currentField = new Field(() => type, " _current" + name) + { + AccessModifier = AccessModifier.Private, + InsertBlankLineAfter = false, + }; + + if (prop.InitValue != null) + currentField.InitValue = prop.InitValue; + + gr.Members.Insert(0, currentField); + + prop.Name = " " + name; + prop.TypeBuilder = () => " " + type; + prop.IsAuto = false; + + if (prop.HasGetter) prop.GetBodyBuilders.Add(() => new [] { "return " + currentField.Name.Trim() + ";" }); + if (prop.HasSetter) prop.SetBodyBuilders.Add(() => new [] { currentField.Name.Trim() + " = value;" }); + + var ac = new Method (() => "void", "Accept" + name + "Changes", null, () => new[] { string.Format("_original{0} = _current{0};", name) }); + var rc = new Method (() => "void", "Reject" + name + "Changes", null, () => new[] { string.Format("{0} = _original{0};", name) }); + var id = new Property(() => "bool", "Is" + name + "Dirty") + .InitGetter(() => new [] { string.Format(prop.IsDirtyText, "_current" + name, "_original" + name) }); + + gr.Members.Add(new MemberGroup + { + Region = "EditableObject support", + Members = { ac, rc, id }, + }); + + prop.Parent.SetTree(); + } + + foreach (Class cl in GetTreeNodes(Model).OfType<Class>()) + { + var props = GetTreeNodes(cl).OfType<Property>().Where(p => p.IsEditable).ToList(); + + if (props.Count > 0) + { + if (props.Any(p => p.IsEditable)) + { + var ctor = GetTreeNodes(cl) + .OfType<Method>() + .FirstOrDefault(m => m.Name == cl.Name && m.ParameterBuilders.Count == 0); + + if (ctor == null) + { + ctor = new Method(null, cl.Name); + cl.Members.Insert(0, ctor); + } + + ctor.BodyBuilders.Add(() => new [] { "AcceptChanges();" }); + } + + var maxLen = props.Max(p => p.Name.Trim().Length); + + var ac = new Method(() => "void", "AcceptChanges") { IsVirtual = true }; + var rc = new Method(() => "void", "RejectChanges") { IsVirtual = true }; + var id = new Property(() => "bool", "IsDirty") { IsAuto = false, HasSetter = false, IsVirtual = true }; + + ac.BodyBuilders.Add(() => new [] + { + "BeforeAcceptChanges();", + "" + }); + rc.BodyBuilders.Add(() => new [] + { + "BeforeRejectChanges();", + "" + }); + id.GetBodyBuilders.Add(() => new [] { "return" }); + + foreach (var p in props) + { + var name = p.Name.Trim(); + + ac.BodyBuilders.Add(() => new [] { string.Format("Accept{0}Changes();", name) }); + rc.BodyBuilders.Add(() => new [] { string.Format("Reject{0}Changes();", name) }); + id.GetBodyBuilders.Add(() => new [] { string.Format("\tIs{0}Dirty{1} ||", name, LenDiff(maxLen, name)) }); + } + + ac.BodyBuilders.Add(() => new[] + { + "", + "AfterAcceptChanges();" + }); + rc.BodyBuilders.Add(() => new[] + { + "", + "AfterRejectChanges();" + }); + var getBody = id.BuildGetBody().ToArray(); + getBody[getBody.Length - 1] = getBody[getBody.Length - 1].Trim(' ' , '|') + ";"; + id.GetBodyBuilders.Clear(); + id.GetBodyBuilders.Add(() => getBody); + + cl.Members.Add(new MemberGroup + { + Region = "EditableObject support", + Members = + { + new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "BeforeAcceptChanges") { AccessModifier = AccessModifier.Partial }, + new Method(() => "void", "AfterAcceptChanges") { AccessModifier = AccessModifier.Partial }, + } + }, + ac, + new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "BeforeRejectChanges") { AccessModifier = AccessModifier.Partial }, + new Method(() => "void", "AfterRejectChanges") { AccessModifier = AccessModifier.Partial }, + } + }, + rc, + id + }, + }); + + if (!cl.Interfaces.Contains("IEditableObject")) + { + if (!Model.Usings.Contains("System.ComponentModel")) + Model.Usings.Add("System.ComponentModel"); + + cl.Interfaces.Add("IEditableObject"); + + cl.Members.Add(new MemberGroup + { + Region = "IEditableObject support", + Members = + { + new MemberGroup + { + IsCompact = true, + Members = + { + new Field (() => "bool", "_isEditing") { AccessModifier = AccessModifier.Private }, + new Property(() => "bool", " IsEditing").InitGetter(() => new [] { "_isEditing" }), + } + }, + new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "BeginEdit", null, () => new[] { "AcceptChanges();", "_isEditing = true;" }) { IsVirtual = true }, + new Method(() => "void", "CancelEdit", null, () => new[] { "_isEditing = false;", "RejectChanges();", }) { IsVirtual = true }, + new Method(() => "void", "EndEdit", null, () => new[] { "_isEditing = false;", "AcceptChanges();", }) { IsVirtual = true }, + } + }, + } + }); + } + } + + cl.SetTree(); + } +} + +partial class Property +{ + public bool IsEditable; + public string IsDirtyText = "{0} != {1}"; +} + +class EditableProperty : Property +{ + public EditableProperty() + { + IsEditable = true; + } + + public EditableProperty(string type, string name) + : base(() => type, name, null, null) + { + IsEditable = true; + } +} +#> diff --git a/src/Version/LinqToDB.Templates/Humanizer.ttinclude b/src/Version/LinqToDB.Templates/Humanizer.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..17be0916cc74e01a29558a7cd6013fe567aa1409 --- /dev/null +++ b/src/Version/LinqToDB.Templates/Humanizer.ttinclude @@ -0,0 +1,15 @@ +<# +/* +To use this extension you should: +1) Reference Humanizer NuGet package into your project +2) Include Humanizer.ttinclude +3) Reference assembly like <_#@ assembly name="$(SolutionDir)\packages\Humanizer.Core.2.2.0\lib\netstandard1.0\Humanizer.dll" #_> +*/ +#> +<#@ import namespace="Humanizer" #> +<# + NormalizeNames = true; + ToPlural = s => s.Pluralize (inputIsKnownToBeSingular: false); + ToSingular = s => s.Singularize(inputIsKnownToBePlural: false); + ToValidName = (s, r) => s.Pascalize(); +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Access.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Access.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..ebabf0fb9054ec5336c069f94297ed81ea95e1f4 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Access.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Access.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Access.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Access.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..806e50298187b6c2bccde49d7a3ee4f52673b8d1 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Access.ttinclude @@ -0,0 +1,26 @@ +<#@ include file="LinqToDB.ttinclude" #> +<#+ +LinqToDB.Data.DataConnection GetAccessConnection(string connectionString) +{ + return LinqToDB.DataProvider.Access.AccessTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetAccessConnection(string path, string database) +{ + return GetAccessConnection(string.Format( + "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Locale Identifier=1033;Jet OLEDB:Engine Type=5;Persist Security Info=True", + System.IO.Path.Combine(path, database))); +} + +void LoadAccessMetadata(string connectionString) +{ + using (var dataConnection = GetAccessConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadAccessMetadata(string path, string database) +{ + using(var dataConnection = GetAccessConnection(path, database)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.DB2.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.DB2.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..c9aba99f74df410d0f2677bffa35d976f6d0c045 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.DB2.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.DB2.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.DB2.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.DB2.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..12a174244be63278b41ce4f1e58fa8a4c0df8220 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.DB2.ttinclude @@ -0,0 +1,24 @@ +<#@ include file="LinqToDB.ttinclude" #> +<#+ +LinqToDB.Data.DataConnection GetDB2Connection(string connectionString, LinqToDB.DataProvider.DB2.DB2Version version = LinqToDB.DataProvider.DB2.DB2Version.LUW) +{ + return LinqToDB.DataProvider.DB2.DB2Tools.CreateDataConnection(connectionString, version); +} + +LinqToDB.Data.DataConnection GetDB2Connection(string server, string port, string database, string uid, string password) +{ + return GetDB2Connection(string.Format("Server={0}:{1};Database={2};UID={3};PWD={4};", server, port, database, uid, password)); +} + +void LoadDB2Metadata(string connectionString) +{ + using (var dataConnection = GetDB2Connection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadDB2Metadata(string server, string port, string database, string uid, string password) +{ + using (var dataConnection = GetDB2Connection(server, port, database, uid, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Firebird.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Firebird.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..8c5568ddef69c280d079bd03b0a4a0643d0f0947 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Firebird.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4FirebirdToolsDirectory)FirebirdSql.Data.FirebirdClient.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Firebird.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Firebird.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Firebird.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..533dbdf01c0bf77e4373bffceea3e978322630ff --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Firebird.ttinclude @@ -0,0 +1,71 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + LinqToDB.DataProvider.Firebird.FirebirdTools.ResolveFirebird( + typeof(FirebirdSql.Data.FirebirdClient.FbConnection).Assembly); + + { + var afterLoadMetadata = AfterLoadMetadata; + AfterLoadMetadata = () => + { + afterLoadMetadata(); + CheckNameCasing(); + }; + } +#> +<#+ +void CheckNameCasing() +{ + foreach (var t in Tables.Values) + { + var name = t.TableName; + + if (!name.StartsWith("\"")) + if (name.StartsWith("_") || name.Any(c => char.IsLower(c) || char.IsWhiteSpace(c))) + t.TableName = "\"" + name + "\""; + + foreach (var col in t.Columns.Values) + { + name = col.ColumnName; + + if (!name.StartsWith("\"")) + if (name.StartsWith("_") || name.Any(c => char.IsLower(c) || char.IsWhiteSpace(c))) + col.ColumnName = "\"" + name + "\""; + } + } +} + +LinqToDB.Data.DataConnection GetFirebirdConnection(string connectionString) +{ + return LinqToDB.DataProvider.Firebird.FirebirdTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetFirebirdConnection(string server, string database) +{ + return GetFirebirdConnection(server, database, "SYSDBA", "masterkey"); +} + +LinqToDB.Data.DataConnection GetFirebirdConnection(string server, string database, string uid, string password) +{ + return GetFirebirdConnection(string.Format( + "DataSource={0};Database={1};User Id={2};Password={3}", + server, database, uid, password)); +} + +void LoadFirebirdMetadata(string connectionString) +{ + using (var dataConnection = GetFirebirdConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadFirebirdMetadata(string server, string database, string uid, string password) +{ + using (var dataConnection = GetFirebirdConnection(server, database, uid, password)) + LoadMetadata(dataConnection); +} + +void LoadFirebirdMetadata(string server, string database) +{ + using (var dataConnection = GetFirebirdConnection(server, database)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Informix.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Informix.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..ffe6b4aaecbd4307757ded267dc29884ea397da6 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Informix.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Informix.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Informix.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Informix.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..ce007c248db35929125d254f5e511bd3698664a5 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Informix.ttinclude @@ -0,0 +1,24 @@ +<#@ include file="LinqToDB.ttinclude" #> +<#+ +LinqToDB.Data.DataConnection GetInformixConnection(string connectionString) +{ + return new LinqToDB.Data.DataConnection(new LinqToDB.DataProvider.Informix.InformixDataProvider(), connectionString); +} + +LinqToDB.Data.DataConnection GetInformixConnection(string host, string port, string server, string database, string uid, string password) +{ + return GetInformixConnection(string.Format("Host={0};Service={1};Server={2};Protocol=onsoctcp;Database={3};UID={4};PWD={5}", host, port, server, database, uid, password)); +} + +void LoadInformixMetadata(string connectionString) +{ + using (var dataConnection = GetInformixConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadInformixMetadata(string host, string port, string server, string database, string uid, string password) +{ + using (var dataConnection = GetInformixConnection(host, port, server, database, uid, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.MySql.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.MySql.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..023871292b7d43e2e12da1981d227ac7bdb2af7e --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.MySql.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4MySqlToolsDirectory)MySql.Data.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.MySql.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.MySql.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.MySql.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..fd93d3e9c686f3b52e7d2064a25c1aefd6a6dac5 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.MySql.ttinclude @@ -0,0 +1,30 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + LinqToDB.DataProvider.MySql.MySqlTools.ResolveMySql( + typeof(MySql.Data.MySqlClient.MySqlConnection).Assembly); +#> +<#+ +LinqToDB.Data.DataConnection GetMySqlConnection(string connectionString) +{ + return LinqToDB.DataProvider.MySql.MySqlTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetMySqlConnection(string server, string database, string uid, string password, int port=3306) +{ + return GetMySqlConnection(string.Format( + "Server={0};Port={4};Database={1};Uid={2};Pwd={3};charset=utf8;", + server, database, uid, password,port)); +} + +void LoadMySqlMetadata(string connectionString) +{ + using (var dataConnection = GetMySqlConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadMySqlMetadata(string server, string database, string uid, string password,int port=3306) +{ + using (var dataConnection = GetMySqlConnection(server, database, uid, password,port)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Managed.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Managed.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..4b4be38b605c7e394bbcea45db70e8d5ee78e2da --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Managed.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4OracleToolsDirectory)Oracle.ManagedDataAccess.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Oracle.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..4b4be38b605c7e394bbcea45db70e8d5ee78e2da --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4OracleToolsDirectory)Oracle.ManagedDataAccess.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Oracle.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Oracle.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..ff6f6725137777d95a6bbb3c76d8d47672439a35 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.ttinclude @@ -0,0 +1,29 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + LinqToDB.DataProvider.Oracle.OracleTools.AssemblyName = "Oracle.ManagedDataAccess"; + LinqToDB.DataProvider.Oracle.OracleTools.ResolveOracle( + typeof(Oracle.ManagedDataAccess.Client.OracleConnection).Assembly); +#><#+ +LinqToDB.Data.DataConnection GetOracleConnection(string connectionString) +{ + //return LinqToDB.DataProvider.Oracle.OracleTools.CreateDataConnection(connectionString); + return new LinqToDB.Data.DataConnection(new LinqToDB.DataProvider.Oracle.OracleDataProvider("OracleManaged"), connectionString); +} + +LinqToDB.Data.DataConnection GetOracleConnection(string server, string port, string database, string uid, string password) +{ + return GetOracleConnection(string.Format("Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1}))(CONNECT_DATA=(SERVICE_NAME={2})));User Id={3};Password={4};", server, port, database, uid, password)); +} + +void LoadOracleMetadata(string connectionString) +{ + using (var dataConnection = GetOracleConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadOracleMetadata(string server, string port, string database, string uid, string password) +{ + using (var dataConnection = GetOracleConnection(server, port, database, uid, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x64.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x64.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..4b4be38b605c7e394bbcea45db70e8d5ee78e2da --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x64.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4OracleToolsDirectory)Oracle.ManagedDataAccess.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Oracle.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x86.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x86.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..4b4be38b605c7e394bbcea45db70e8d5ee78e2da --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Oracle.x86.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4OracleToolsDirectory)Oracle.ManagedDataAccess.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Oracle.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..d23123133419d046323c415e8806e8e880714ed4 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.Tools.ttinclude @@ -0,0 +1,4 @@ +<#@ assembly name="$(LinqToDBT4PostgreSQLToolsDirectory)Npgsql.dll" #> +<#@ assembly name="$(LinqToDBT4PostgreSQLToolsDirectory)System.Threading.Tasks.Extensions.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.PostgreSQL.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..7fae75f29bb430e61978db6845a9be11c3b612b6 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude @@ -0,0 +1,144 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + LinqToDB.DataProvider.PostgreSQL.PostgreSQLTools.ResolvePostgreSQL( + typeof(Npgsql.NpgsqlConnection).Assembly); + + { + var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; + BeforeGenerateLinqToDBModel = () => + { + beforeGenerateLinqToDBModel(); + SetCaseSensitiveNames(); + + FixTableFunctions(); + FixRecordResultFunctions(); + FixVoidFunctions(); + FixFunctionNames(); + }; + } +#> +<#+ +bool GenerateCaseSensitiveNames = false; // Defines whether to generate case sensitive or insensitive names + +// functions with multiple out parameters implemented by pgsql as functions with input parameters that return record with +// value for each output parameter so we need to move out parameters to result value class field and map +// record, returned by npgsql provider as object[], to this class +// exception: functions with only one out parameter treat it as return parameter +void FixRecordResultFunctions() +{ + var initMappingSchema = new Method(() => "void", "InitMappingSchema") { AccessModifier = AccessModifier.Partial }; + DataContextObject.Members.Add(initMappingSchema); + foreach (var proc in Procedures.Values + .Where(p => p.IsFunction && !p.IsAggregateFunction && !p.IsTableFunction && p.ProcParameters.Any(pr => pr.IsOut))) + { + if (proc.ProcParameters.Count(pr => pr.IsOut) > 1) + { + var result = new Class(SchemaProviderBase.ToValidName(proc.ProcedureName + "Result")); + Model.Types.Add(result); + + proc.ProcParameters.Add(new Parameter() + { + IsResult = true, + ParameterType = result.Name + }); + + var mappings = new List<string>(); + foreach (var outParam in proc.ProcParameters.Where(_ => _.IsOut)) + { + result.Members.Add(new Property(() => outParam.ParameterType, outParam.ParameterName, null, null)); + mappings.Add($"{outParam.ParameterName} = ({outParam.ParameterType})tuple[{mappings.Count}]"); + + if (outParam.IsIn) + outParam.IsOut = false; + } + + proc.ProcParameters = proc.ProcParameters.Where(_ => !_.IsOut).ToList(); + + initMappingSchema.BodyBuilders.Add(() => new [] { $"MappingSchema.SetConvertExpression<object[], {result.Name}>(tuple => new {result.Name}() {{ {string.Join(", ", mappings)} }});" }); + } + else // one parameter + { + var param = proc.ProcParameters.Single(_ => _.IsOut); + proc.ProcParameters.Remove(param); + proc.ProcParameters.Add(new Parameter() + { + IsResult = true, + ParameterType = param.ParameterType + }); + } + } +} + +void FixFunctionNames() +{ + foreach (var proc in Procedures.Values) + { + if (proc.ProcedureName.Any(char.IsUpper)) + proc.ProcedureName = "\"" + proc.ProcedureName + "\""; + } +} + +void FixTableFunctions() +{ + foreach (var proc in Procedures.Values + .Where(p => p.IsTableFunction && p.ProcParameters.Any(pr => pr.IsOut))) + { + proc.ProcParameters = proc.ProcParameters.Where(pr => !pr.IsOut).ToList(); + } +} + +void FixVoidFunctions() +{ + // generated functions should return object for void-typed functions + foreach (var proc in Procedures.Values + .Where(p => p.IsFunction/* && !p.IsAggregateFunction*/ && !p.IsTableFunction && !p.ProcParameters.Any(pr => pr.IsResult))) + { + proc.ProcParameters.Add(new Parameter() + { + IsResult = true, + ParameterType = "object", + SystemType = typeof(object) + }); + } +} + +void SetCaseSensitiveNames() +{ + if (GenerateCaseSensitiveNames) + { + foreach (var t in Tables.Values) + { + if (t.TableName.Any(char.IsUpper)) + t.TableName = "\"" + t.TableName + "\""; + + foreach (var c in t.Columns.Values) + { + if (c.ColumnName.Any(char.IsUpper)) + c.ColumnName = "\"" + c.ColumnName + "\""; + } + } + } +} + +LinqToDB.Data.DataConnection GetPostgreSQLConnection(string connectionString) +{ + return LinqToDB.DataProvider.PostgreSQL.PostgreSQLTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetPostgreSQLConnection(string server, string port, string database, string uid, string password) +{ + return GetPostgreSQLConnection(string.Format(@"Server={0};Port={1};Database={2};User Id={3};Password={4};Pooling=true;MinPoolSize=10;MaxPoolSize=100;", server, port, database, uid, password)); +} + +void LoadPostgreSQLMetadata(string connectionString) +{ + using (var dataConnection = GetPostgreSQLConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadPostgreSQLMetadata(string server, string port, string database, string uid, string password) +{ + using (var dataConnection = GetPostgreSQLConnection(server, port, database, uid, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SQLite.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SQLite.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..71eb281790ae04b858c71883c55bbd90241a2d3b --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SQLite.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4SQLiteToolsDirectory)System.Data.SQLite.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.SQLite.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SQLite.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SQLite.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..1b7e65c09fbd04492d059f4e1081da50fb5ce787 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SQLite.ttinclude @@ -0,0 +1,44 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + LinqToDB.DataProvider.SQLite.SQLiteTools.ResolveSQLite(typeof(System.Data.SQLite.SQLiteConnection).Assembly); + + { + var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; + BeforeGenerateLinqToDBModel = () => + { + ConvertSQLiteMetadata(); + beforeGenerateLinqToDBModel(); + }; + } +#> +<#+ +void ConvertSQLiteMetadata() +{ + foreach (var t in Tables.Values) + foreach (var fk in t.ForeignKeys.Values) + if (fk.MemberName.Length == 0 || char.IsDigit(fk.MemberName[0])) + fk.MemberName = "FK_" + fk.MemberName; +} + +LinqToDB.Data.DataConnection GetSQLiteConnection(string connectionString) +{ + return LinqToDB.DataProvider.SQLite.SQLiteTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetSQLiteConnection(string path, string database) +{ + return GetSQLiteConnection(string.Format("Data Source={0}", System.IO.Path.Combine(path, database))); +} + +void LoadSQLiteMetadata(string connectionString) +{ + using (var dataConnection = GetSQLiteConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadSQLiteMetadata(string path, string database) +{ + using (var dataConnection = GetSQLiteConnection(path, database)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SapHana.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SapHana.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..9d7fb847f993fc7058c09a1b629d089de1f309f8 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SapHana.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.SapHana.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SapHana.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SapHana.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..28ce34ddfabd8c59e6e5886063e742d75bcaab52 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SapHana.ttinclude @@ -0,0 +1,106 @@ +<#@ include file="LinqToDB.ttinclude" #> +<#@ import namespace="LinqToDB.DataProvider.SapHana" #> +<# + Model.Usings.Add("LinqToDB.DataProvider.SapHana"); + Model.Usings.Add("System.Reflection"); + + GenerateProviderSpecificTable = t => + { + var method = new Method( + () => string.Format("ITable<{0}>", t.TypeName), + t.DataContextPropertyName, + t.Parameters.Select(p => (Func<string>)(() => p.ParameterType + " " + p.ParameterName)), + () => new [] + { + String.Concat("return GetTable<",t.TypeName,">(this, (MethodInfo) MethodBase.GetCurrentMethod(),"), + String.Join(",", t.Parameters.Select(p => p.ParameterName)), + ");" + }); + + method.Attributes.Add(new Attribute("CalculationViewInputParametersExpression", new string[] {})); + return method; + }; + + LoadProviderSpecificTable = t => + { + var v = t as ViewWithParametersTableSchema; + return new Table + { + Schema = (t.IsDefaultSchema && !IncludeDefaultSchema) || string.IsNullOrEmpty(t.SchemaName)? null : t.SchemaName, + BaseClass = BaseEntityClass, + TableName = t.TableName, + TypeName = + PluralizeClassNames ? ToPlural (t.TypeName) : + SingularizeClassNames ? ToSingular(t.TypeName) : t.TypeName, + DataContextPropertyName = + PluralizeDataContextPropertyNames ? ToPlural (t.TypeName) : + SingularizeDataContextPropertyNames ? ToSingular(t.TypeName) : t.TypeName, + IsView = t.IsView, + IsProviderSpecific = true, + Description = t.Description, + Columns = t.Columns.ToDictionary( + c => c.ColumnName, + c => new Column + { + ColumnName = c.ColumnName, + ColumnType = c.ColumnType, + IsNullable = c.IsNullable, + IsIdentity = c.IsIdentity, + IsPrimaryKey = c.IsPrimaryKey, + PrimaryKeyOrder = c.PrimaryKeyOrder, + MemberName = CheckType(c.SystemType, c.MemberName), + TypeBuilder = () => c.MemberType, + SkipOnInsert = c.SkipOnInsert, + SkipOnUpdate = c.SkipOnUpdate, + Description = c.Description, + }), + Parameters = v.Parameters.Select(pr => new Parameter + { + SchemaName = pr.SchemaName, + SchemaType = pr.SchemaType, + IsIn = pr.IsIn, + IsOut = pr.IsOut, + IsResult = pr.IsResult, + Size = pr.Size, + ParameterName = pr.ParameterName, + ParameterType = pr.ParameterType, + SystemType = pr.SystemType, + DataType = pr.DataType.ToString(), + }) + .ToList() + }; + }; +#> +<#+ + public partial class Table + { + public List<Parameter> Parameters; + } + + LinqToDB.Data.DataConnection GetSapHanaConnection(string connectionString) + { + return LinqToDB.DataProvider.SapHana.SapHanaTools.CreateDataConnection(connectionString); + } + + LinqToDB.Data.DataConnection GetSapHanaConnection(string server, string schema, string uid, string password) + { + return GetSapHanaConnection(string.Format("Server={0};Current Schema={1};UserID={2};Password={3};", server, schema, uid, password)); + } + + void LoadSapHanaMetadata(DataConnection dataConnection) + { + LoadMetadata(dataConnection); + } + + void LoadSapHanaMetadata(string connectionString) + { + using (var dataConnection = GetSapHanaConnection(connectionString)) + LoadMetadata(dataConnection); + } + + void LoadSapHanaMetadata(string server, string schema, string uid, string password) + { + using (var dataConnection = GetSapHanaConnection(server, schema, uid, password)) + LoadMetadata(dataConnection); + } +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..208440acd9184e941519a7235267659aeea40c00 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.SqlCe.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..7f4a3ebe52ec0062b5300de028011fa6f06726ca --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude @@ -0,0 +1,24 @@ +<#@ include file="LinqToDB.ttinclude" #> +<#+ +LinqToDB.Data.DataConnection GetSqlCeConnection(string connectionString) +{ + return LinqToDB.DataProvider.SqlCe.SqlCeTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetSqlCeConnection(string path, string database) +{ + return GetSqlCeConnection(string.Format("Data Source={0}", System.IO.Path.Combine(path, database))); +} + +void LoadSqlCeMetadata(string connectionString) +{ + using (var dataConnection = GetSqlCeConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadSqlCeMetadata(string path, string database) +{ + using (var dataConnection = GetSqlCeConnection(path, database)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..05a8e66ec1169fb6519f94ac9ddb65e45e26cb44 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.Tools.ttinclude @@ -0,0 +1,3 @@ +<#@ assembly name="$(LinqToDBT4SqlServerToolsDirectory)Microsoft.SqlServer.Types.dll" #> +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.SqlServer.SqlTypes.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..cd971c366743fde5382c8f8ffaa09ec91e7d57b8 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude @@ -0,0 +1,5 @@ +<#@ include file="LinqToDB.SqlServer.ttinclude" #> +<# + LinqToDB.DataProvider.SqlServer.SqlServerTools.ResolveSqlTypes( + typeof(Microsoft.SqlServer.Types.SqlGeography).Assembly); +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..fc678e10b2c02405a263e5e11578a0cb1bbb9b62 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.SqlServer.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..29047c285da6f08bb7cb85973e1f3a364e3c1c15 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude @@ -0,0 +1,144 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + { + GenerateProcedureDbType = p => p.DataType == "Structured" && p.SchemaType != null; + + var afterGenerateLinqToDBModel = AfterGenerateLinqToDBModel; + AfterGenerateLinqToDBModel = () => + { + afterGenerateLinqToDBModel(); + DoGenerateSqlServerFreeText(); + }; + + var buildColumnComparison = BuildColumnComparison; + BuildColumnComparison = (c, padding1, padding2, last) => + { + if (c.BuildType() == "SqlHierarchyId") + return string.Format("\t(bool)(t.{0}{1} == {0}{3}){2}", c.MemberName, padding1, last ? ");" : " &&", last ? "" : padding2); + else + return buildColumnComparison(c, padding1, padding2, last); + }; + } +#> +<#+ +bool GenerateSqlServerFreeText = true; // Defines whether to generate extensions for Free Text search, or not + +void DoGenerateSqlServerFreeText() +{ + if (!GenerateSqlServerFreeText) + return; + + Model.Usings.Add("System.Collections.Generic"); + Model.Usings.Add("System.Linq.Expressions"); + Model.Usings.Add("System.Reflection"); + Model.Usings.Add("LinqToDB"); + Model.Usings.Add("LinqToDB.DataProvider.SqlServer"); + Model.Usings.Add("LinqToDB.Extensions"); + + DataContextObject.Members.Add( + new MemberGroup + { + Region = "FreeTextTable", + Members = + { + new Class("FreeTextKey", + new MemberGroup + { + IsCompact = true, + Members = + { + new Field(() => "T", "Key"), + new Field(() => "int", "Rank") + } + }) + { + GenericArguments = { "T" }, + IsPartial = false + }, + + new Field(() => "MethodInfo", "_freeTextTableMethod1") + { + AccessModifier = AccessModifier.Private, + IsStatic = true, + InitValue = "typeof(" + DataContextObject.Name + ").GetMethod(\"FreeTextTable\", new Type[] { typeof(string), typeof(string) })" + }, + + new Method(() => "ITable<FreeTextKey<TKey>>", "FreeTextTable", + new Func<string>[] { () => "string field", () => "string text" }, + () => new[] + { + "return this.GetTable<FreeTextKey<TKey>>(", + " this,", + " _freeTextTableMethod1,", + " field,", + " text);", + }) + { + GenericArguments = new List<string>() { "TTable", "TKey" }, + Attributes = { new Attribute("FreeTextTableExpression") } + }, + + new Field(() => "MethodInfo", "_freeTextTableMethod2") + { + AccessModifier = AccessModifier.Private, + IsStatic = true, + InitValue = Environment.NewLine + + " typeof(" + DataContextObject.Name + ").GetMethods()" + Environment.NewLine + + " .Where(m => m.Name == \"FreeTextTable\" && m.IsGenericMethod && m.GetParameters().Length == 2)" + Environment.NewLine + + " .Where(m => m.GetParameters()[0].ParameterType.IsGenericTypeEx() && m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>))" + Environment.NewLine + + " .Where(m => m.GetParameters()[1].ParameterType == typeof(string))" + Environment.NewLine + + " .Single()" + }, + + new Method(() => "ITable<FreeTextKey<TKey>>", "FreeTextTable", + new Func<string>[] { () => "Expression<Func<TTable,string>> fieldSelector", () => "string text" }, + () => new[] + { + "return this.GetTable<FreeTextKey<TKey>>(", + " this,", + " _freeTextTableMethod2,", + " fieldSelector,", + " text);", + }) + { + GenericArguments = { "TTable", "TKey" }, + Attributes = { new Attribute("FreeTextTableExpression") } + }, + } + } + ); +} + +LinqToDB.Data.DataConnection GetSqlServerConnection(string connectionString) +{ + return LinqToDB.DataProvider.SqlServer.SqlServerTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetSqlServerConnection(string server, string database) +{ + return GetSqlServerConnection(string.Format("Data Source={0};Database={1};Integrated Security=SSPI", server, database)); +} + +LinqToDB.Data.DataConnection GetSqlServerConnection(string server, string database, string user, string password) +{ + return GetSqlServerConnection(string.Format("Server={0};Database={1};User Id={2};Password={3};", server, database, user, password)); +} + +void LoadSqlServerMetadata(string connectionString) +{ + using (var dataConnection = GetSqlServerConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadSqlServerMetadata(string server, string database) +{ + using (var dataConnection = GetSqlServerConnection(server, database)) + LoadMetadata(dataConnection); +} + +void LoadSqlServerMetadata(string server, string database, string user, string password) +{ + using (var dataConnection = GetSqlServerConnection(server, database, user, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Sybase.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Sybase.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..bced686ff81440076443ed6565daca09a06c2927 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Sybase.Tools.ttinclude @@ -0,0 +1,2 @@ +<#@ include file="LinqToDB.Tools.ttinclude" #> +<#@ include file="LinqToDB.Sybase.ttinclude" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Sybase.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Sybase.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..52c6e6726e689db5b1b5d930a3b9f9753dcc86b9 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Sybase.ttinclude @@ -0,0 +1,79 @@ +<#@ include file="LinqToDB.ttinclude" #> +<# + { + var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; + BeforeGenerateLinqToDBModel = () => + { + beforeGenerateLinqToDBModel(); + GenerateSybaseTypes(); + }; + } +#><#+ +bool GenerateSybaseSystemTables = false; // Defines whether to generate Sybase sysobjects tables or not + +void GenerateSybaseTypes() +{ + if (GenerateSybaseSystemTables) + { + Tables.Add("sysobjects", new Table + { + Name = "sysobjects", + TableName = "sysobjects", + TypeName = "SysObject", + DataContextPropertyName = "SysObjects", + BaseClass = BaseEntityClass, + Columns = new Dictionary<string,Column>() + { + { "name", new Column { Name = "name", ColumnName = "name", ColumnType = "varchar", TypeBuilder = () => "string", DbType = DbType.AnsiString, /*Length = 255*/ }}, + { "id", new Column { Name = "id", ColumnName = "id", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "uid", new Column { Name = "uid", ColumnName = "uid", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "type", new Column { Name = "type", ColumnName = "type", ColumnType = "char", TypeBuilder = () => "string", DbType = DbType.AnsiStringFixedLength, /*Length = 2,*/ }}, + { "userstat", new Column { Name = "userstat", ColumnName = "userstat", ColumnType = "smallint", TypeBuilder = () => "short", DbType = DbType.Int16, }}, + { "sysstat", new Column { Name = "sysstat", ColumnName = "sysstat", ColumnType = "smallint", TypeBuilder = () => "short", DbType = DbType.Int16, }}, + { "indexdel", new Column { Name = "indexdel", ColumnName = "indexdel", ColumnType = "smallint", TypeBuilder = () => "short", DbType = DbType.Int16, }}, + { "schemacnt", new Column { Name = "schemacnt", ColumnName = "schemacnt", ColumnType = "smallint", TypeBuilder = () => "short", DbType = DbType.Int16, }}, + { "sysstat2", new Column { Name = "sysstat2", ColumnName = "sysstat2", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "crdate", new Column { Name = "crdate", ColumnName = "crdate", ColumnType = "datetime", TypeBuilder = () => "DateTime", DbType = DbType.DateTime }}, + { "expdate", new Column { Name = "expdate", ColumnName = "expdate", ColumnType = "datetime", TypeBuilder = () => "DateTime", DbType = DbType.DateTime }}, + { "deltrig", new Column { Name = "deltrig", ColumnName = "deltrig", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "instrig", new Column { Name = "instrig", ColumnName = "instrig", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "updtrig", new Column { Name = "updtrig", ColumnName = "updtrig", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "seltrig", new Column { Name = "seltrig", ColumnName = "seltrig", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "ckfirst", new Column { Name = "ckfirst", ColumnName = "ckfirst", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "cache", new Column { Name = "cache", ColumnName = "cache", ColumnType = "smallint", TypeBuilder = () => "short", DbType = DbType.Int16 }}, + { "audflags", new Column { Name = "audflags", ColumnName = "audflags", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, IsNullable = true }}, + { "objspare", new Column { Name = "objspare", ColumnName = "objspare", ColumnType = "int", TypeBuilder = () => "int", DbType = DbType.Int32, }}, + { "versionts", new Column { Name = "versionts", ColumnName = "versionts", ColumnType = "binary", TypeBuilder = () => "byte[]", DbType = DbType.Binary, IsNullable = true, /*Length = 6*/ }}, + { "loginame", new Column { Name = "loginame", ColumnName = "loginame", ColumnType = "varchar", TypeBuilder = () => "string", DbType = DbType.AnsiString, /*Length = 30*/ }}, + } + }); + } +} + +LinqToDB.Data.DataConnection GetSybaseConnection(string connectionString) +{ + return LinqToDB.DataProvider.Sybase.SybaseTools.CreateDataConnection(connectionString); +} + +LinqToDB.Data.DataConnection GetSybaseConnection(string server, string database) +{ + return GetSybaseConnection(string.Format("Data Source={0};Database={1};Integrated Security=SSPI", server, database)); +} + +LinqToDB.Data.DataConnection GetSybaseConnection(string server, string port, string database, string uid, string password) +{ + return GetSybaseConnection(string.Format("Data Source={0};Port={1};Database={2};Uid={3};Password={4};Charset=utf8;", server, port, database, uid, password)); +} + +void LoadSybaseMetadata(string connectionString) +{ + using (var dataConnection = GetSybaseConnection(connectionString)) + LoadMetadata(dataConnection); +} + +void LoadSybaseMetadata(string server, string port, string database, string uid, string password) +{ + using (var dataConnection = GetSybaseConnection(server, port, database, uid, password)) + LoadMetadata(dataConnection); +} +#> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.Tools.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.Tools.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..d804bb85f737d248fb336c5a61e116e54d8dea57 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.Tools.ttinclude @@ -0,0 +1 @@ +<#@ assembly name="$(LinqToDBT4ToolsDirectory)linq2db.dll" #> diff --git a/src/Version/LinqToDB.Templates/LinqToDB.ttinclude b/src/Version/LinqToDB.Templates/LinqToDB.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..0aa897a12f42602a506ee540d14effb295099263 --- /dev/null +++ b/src/Version/LinqToDB.Templates/LinqToDB.ttinclude @@ -0,0 +1,1044 @@ +<#@ assembly name="System.Data" #> +<#@ import namespace="System.Data" #> +<#@ import namespace="LinqToDB.Data" #> +<#@ import namespace="System.Text" #> +<#@ include file="DataModel.ttinclude" #> +<# + if (BaseDataContextClass == null) + BaseDataContextClass = "LinqToDB.Data.DataConnection"; +#> +<#+ +Action BeforeGenerateLinqToDBModel = () => {}; +Action AfterGenerateLinqToDBModel = () => {}; + +Func<Table,MemberBase> GenerateProviderSpecificTable = t => null; +Func<Parameter, bool> GenerateProcedureDbType = p => false; + +bool GenerateObsoleteAttributeForAliases = false; +bool GenerateFindExtensions = true; +bool IsCompactColumns = true; +bool IsCompactColumnAliases = true; +bool GenerateDataTypes = false; +bool? GenerateLengthProperty = null; +bool? GeneratePrecisionProperty = null; +bool? GenerateScaleProperty = null; +bool GenerateDbTypes = false; +bool GenerateSchemaAsType = false; +bool GenerateViews = true; +bool GenerateProcedureResultAsList = false; +bool PrefixTableMappingWithSchema = true; +string SchemaNameSuffix = "Schema"; +string SchemaDataContextTypeName = "DataContext"; + +Dictionary<string,string> SchemaNameMapping = new Dictionary<string,string>(); + +Func<string,string,IEnumerable<Method>> GetConstructors = (conf, name) => GetConstructorsImpl(conf, name); + +Func<Column, string, string, bool, string> BuildColumnComparison = (c, padding1, padding2, last) => +{ + return string.Format("\tt.{0}{1} == {0}{3}{2}", c.MemberName, padding1, last ? ");" : " &&", last ? "" : padding2); +}; + +static IEnumerable<Method> GetConstructorsImpl(string defaultConfiguration, string name) +{ + if (defaultConfiguration == null) + yield return new Method((Func<string>)null, name); + else + yield return new Method((Func<string>)null, name) { AfterSignature = { ": base(" + ToStringLiteral(defaultConfiguration) + ")" } }; + yield return new Method((Func<string>)null, name, new Func<string>[] { () => "string configuration" }) { AfterSignature = { ": base(configuration)" } }; +} + +void GenerateTypesFromMetadata() +{ + BeforeGenerateLinqToDBModel(); + + Model.Usings.Add("LinqToDB"); + Model.Usings.Add("LinqToDB.Mapping"); + + if (NamespaceName == null) + NamespaceName = "DataModel"; + + string schemaName; + + var schemas = + ( + from t in Tables.Values + where GenerateSchemaAsType && t.Schema != null && !t.TableSchema.IsDefaultSchema + group t by t.Schema into gr + orderby gr.Key + let typeName = SchemaNameMapping.TryGetValue(gr.Key, out schemaName) ? schemaName : gr.Key + select new + { + Name = gr.Key, + TypeName = typeName + SchemaNameSuffix, + PropertyName = typeName, + Props = new MemberGroup { IsCompact = true }, + Aliases = new MemberGroup { IsCompact = true, Region = "Alias members" }, + TableExtensions = new MemberGroup { Region = "Table Extensions" }, + Type = new Class(typeName + SchemaNameSuffix) { IsStatic = true }, + Tables = gr.ToList(), + DataContext = new Class(SchemaDataContextTypeName), + Procedures = new MemberGroup(), + Functions = new MemberGroup(), + TableFunctions = new MemberGroup { Region = "Table Functions" }, + } + ).ToDictionary(t => t.Name); + + var procSchemas = + ( + from p in Procedures.Values + where GenerateSchemaAsType && p.Schema != null && !p.IsDefaultSchema && !schemas.ContainsKey(p.Schema) + group p by p.Schema into gr + orderby gr.Key + let typeName = SchemaNameMapping.TryGetValue(gr.Key, out schemaName) ? schemaName : gr.Key + select new + { + Name = gr.Key, + TypeName = typeName + SchemaNameSuffix, + PropertyName = typeName, + Props = new MemberGroup { IsCompact = true }, + Aliases = new MemberGroup { IsCompact = true, Region = "Alias members" }, + TableExtensions = new MemberGroup { Region = "Table Extensions" }, + Type = new Class(typeName + SchemaNameSuffix) { IsStatic = true }, + Tables = new List<Table>(), + DataContext = new Class(SchemaDataContextTypeName), + Procedures = new MemberGroup(), + Functions = new MemberGroup(), + TableFunctions = new MemberGroup { Region = "Table Functions" }, + } + ).ToDictionary(s => s.Name); + + foreach(var schema in procSchemas) + schemas.Add(schema.Key, schema.Value); + + var defProps = new MemberGroup { IsCompact = true }; + var defAliases = new MemberGroup { IsCompact = true, Region = "Alias members" }; + var defTableExtensions = new MemberGroup { }; + + if (schemas.Count > 0) + { + var body = new List<Func<IEnumerable<string>>>(); + + var schemaGroup = new MemberGroup { Region = "Schemas" }; + var schemaMembers = new MemberGroup { IsCompact = true }; + + var maxLen1 = schemas.Values.Max(schema => schema.PropertyName.Trim().Length); + var maxLen2 = schemas.Values.Max(schema => schema.TypeName. Trim().Length); + + foreach (var schema in schemas.Values) + { + schemaMembers.Members.Add(new Property(() => schema.TypeName + "." + SchemaDataContextTypeName, schema.PropertyName)); + body.Add(() => new string[] { + schema.PropertyName + LenDiff(maxLen1, schema.PropertyName) + + " = new " + schema.TypeName + "." + LenDiff(maxLen2, schema.TypeName) + + SchemaDataContextTypeName + "(this);"}); + } + + schemaGroup.Members.Add(schemaMembers); + schemaGroup.Members.Add(new Method(() => "void", "InitSchemas", new Func<string>[0], body.ToArray())); + + DataContextObject.Members.Add(schemaGroup); + } + + if (GenerateConstructors) + { + foreach (var c in GetConstructors(DefaultConfiguration, DataContextObject.Name)) + { + if (c.BodyBuilders.Count > 0) + c.BodyBuilders.Add(() => new[] { "" }); + + if (schemas.Count > 0) + c.BodyBuilders.Add(() => new[] { "InitSchemas();" }); + + c.BodyBuilders.Add(() => new [] {"InitDataContext();", "InitMappingSchema();" }); + + DataContextObject.Members.Add(c); + } + } + + DataContextObject.Members.Add(new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "InitDataContext" ) { AccessModifier = AccessModifier.Partial }, + new Method(() => "void", "InitMappingSchema") { AccessModifier = AccessModifier.Partial } + } + }); + + if (Tables.Count > 0) + DataContextObject.Members.Insert(0, defProps); + + foreach (var schema in schemas.Values) + { + schema.Type.Members.Add(schema.DataContext); + schema.DataContext.Members.Insert(0, schema.Props); + + schema.DataContext.Members.Add(new Field (() => "IDataContext", "_dataContext") { AccessModifier = AccessModifier.Private, IsReadonly = true }); + schema.DataContext.Members.Add(new Method(() => null, schema.DataContext.Name, new Func<string>[] { () => "IDataContext dataContext" }, () => new[] { "_dataContext = dataContext;" })); + + foreach (var t in schema.Tables) + { + t.TypePrefix = schema.TypeName + "."; + } + } + + var associationExtensions = new MemberGroup() {Region = "Associations"}; + + foreach (var t in Tables.Values.OrderBy(tbl => tbl.IsProviderSpecific).ThenBy(tbl => tbl.TypeName)) + { + Action<Class> addType = tp => Model.Types.Add(tp); + var props = defProps; + var aliases = defAliases; + var tableExtensions = defTableExtensions; + + if (t.IsView && !GenerateViews) { + continue; + } + + var schema = t.Schema != null && schemas.ContainsKey(t.Schema) ? schemas[t.Schema] : null; + + if (schema != null) + { + var si = schemas[t.Schema]; + + addType = tp => si.Type.Members.Add(tp); + props = si.Props; + aliases = si.Aliases; + tableExtensions = si.TableExtensions; + } + + MemberBase dcProp = t.IsProviderSpecific ? + GenerateProviderSpecificTable(t) : + new Property( + () => string.Format("ITable<{0}>", t.TypeName), + t.DataContextPropertyName, + () => new[] { string.Format((schema == null ? "this" : "_dataContext") + ".GetTable<{0}>()", t.TypeName) }, + null); + + if (dcProp == null) continue; + + t.DataContextProperty = dcProp; + + props.Members.Add(dcProp); + + Property aProp = null; + + if (t.AliasPropertyName != null && t.AliasPropertyName != t.DataContextPropertyName) + { + aProp = new Property( + () => string.Format("ITable<{0}>", t.TypeName), + t.AliasPropertyName, + () => new[] { t.DataContextPropertyName }, + null); + + if (GenerateObsoleteAttributeForAliases) + aProp.Attributes.Add(new Attribute("Obsolete", ToStringLiteral("Use " + t.DataContextPropertyName + " instead."))); + + aliases.Members.Add(aProp); + } + + var tableAttrs = new List<string>(); + + if (DatabaseName != null) tableAttrs.Add("Database=" + ToStringLiteral(DatabaseName)); + if (t.Schema != null) tableAttrs.Add("Schema=" + ToStringLiteral(t.Schema)); + + tableAttrs.Add((tableAttrs.Count == 0 ? "" : "Name=") + ToStringLiteral(t.TableName)); + + if (t.IsView) + tableAttrs.Add("IsView=true"); + + t.Attributes.Add(new Attribute("Table", tableAttrs.ToArray()) { IsSeparated = true } ); + + var comments = new List<string>(); + + if (!string.IsNullOrWhiteSpace(t.Description)) + { + comments.Add("/ <summary>"); + foreach (var line in t.Description.Split('\n')) + comments.Add("/ " + line.TrimEnd()); + comments.Add("/ </summary>"); + } + + if (comments.Count > 0) + { + t. Comment.AddRange(comments); + dcProp.Comment.AddRange(comments); + + if (aProp != null) + aProp.Comment.AddRange(comments); + } + + var columns = new MemberGroup { IsCompact = IsCompactColumns }; + var columnAliases = new MemberGroup { IsCompact = IsCompactColumnAliases, Region = "Alias members" }; + var nPKs = t.Columns.Values.Count(c => c.IsPrimaryKey); + var allNullable = t.Columns.Values.All (c => c.IsNullable || c.IsIdentity); + var nameMaxLen = t.Columns.Values.Max (c => (int?)(c.MemberName == c.ColumnName + ? 0 + : ToStringLiteral(c.ColumnName).Length)) ?? 0; + var dbTypeMaxLen = t.Columns.Values.Max (c => (int?)(c.ColumnType.Length)) ?? 0; + var dataTypeMaxLen = t.Columns.Values.Where(c => c.DataType != null).Max (c => (int?)(c.DataType.Length)) ?? 0; + var dataTypePrefix = t.Columns.Values.Any (c => c.MemberName == "DataType") ? "LinqToDB." : ""; + + foreach (var c in t.Columns.Values) + { + // Column. + // + var ca = new Attribute("Column"); + var canBeReplaced = true; + + if (c.MemberName != c.ColumnName) + { + var columnNameInAttr = ToStringLiteral(c.ColumnName); + + var space = new string(' ', nameMaxLen - columnNameInAttr.Length); + + ca.Parameters.Add(columnNameInAttr + space); + canBeReplaced = false; + } + else if (nameMaxLen > 0) + { + ca.Parameters.Add(new string(' ', nameMaxLen)); + canBeReplaced = false; + } + + if (GenerateDbTypes) + { + var space = new string(' ', dbTypeMaxLen - c.ColumnType.Length); + + ca.Parameters.Add("DbType=" + ToStringLiteral(c.ColumnType) + space); + canBeReplaced = false; + } + + if (GenerateDataTypes) + { + var space = new string(' ', dataTypeMaxLen - c.DataType.Length); + ca.Parameters.Add("DataType=" + dataTypePrefix + c.DataType + space); + canBeReplaced = false; + } + + if (GenerateDataTypes && !GenerateLengthProperty.HasValue || GenerateLengthProperty == true) + { + if (c.Length != null) ca.Parameters.Add("Length=" + (c.Length == int.MaxValue ? "int.MaxValue" : c.Length.ToString())); + canBeReplaced = false; + } + + if (GenerateDataTypes && !GeneratePrecisionProperty.HasValue || GeneratePrecisionProperty == true) + { + if (c.Precision != null) ca.Parameters.Add("Precision=" + c.Precision); + canBeReplaced = false; + } + + if (GenerateDataTypes && !GenerateScaleProperty.HasValue || GenerateScaleProperty == true) + { + if (c.Scale != null) ca.Parameters.Add("Scale=" + c.Scale); + canBeReplaced = false; + } + + if (c.SkipOnInsert && !c.IsIdentity) + { + ca.Parameters.Add("SkipOnInsert=true"); + canBeReplaced = false; + } + + if (c.SkipOnUpdate && !c.IsIdentity) + { + ca.Parameters.Add("SkipOnUpdate=true"); + canBeReplaced = false; + } + + if (c.IsDiscriminator) + { + ca.Parameters.Add("IsDiscriminator=true"); + canBeReplaced = false; + } + + c.Attributes.Add(ca); + + // PK. + // + if (c.IsPrimaryKey) + { + var pka = new Attribute("PrimaryKey"); + + if (nPKs > 1) + pka.Parameters.Add(c.PrimaryKeyOrder.ToString()); + + if (canBeReplaced) + c.Attributes[0] = pka; + else + c.Attributes.Add(pka); + + canBeReplaced = false; + } + + // Identity. + // + if (c.IsIdentity) + { + var ida = new Attribute("Identity"); + + if (canBeReplaced) + c.Attributes[0] = ida; + else + c.Attributes.Add(ida); + + canBeReplaced = false; + } + + // Nullable. + // + if (c.IsNullable) + c.Attributes.Add(new Attribute((allNullable ? "" : " ") + "Nullable")); + else if (!c.IsIdentity) + c.Attributes.Add(new Attribute("NotNull")); + + var columnComments = new List<string>(); + + if (!string.IsNullOrWhiteSpace(c.Description)) + { + columnComments.Add("/ <summary>"); + foreach (var line in c.Description.Split('\n')) + columnComments.Add("/ " + line.TrimEnd()); + columnComments.Add("/ </summary>"); + } + + if (columnComments.Count > 0) + c.Comment.AddRange(columnComments); + + // End line comment. + // + c.EndLineComment = c.ColumnType; + + SetPropertyValue(c, "IsNotifying", true); + SetPropertyValue(c, "IsEditable", true); + + columns.Members.Add(c); + + // Alias. + // + if (c.AliasName != null && c.AliasName != c.MemberName) + { + var caProp = new Property( + c.TypeBuilder, + c.AliasName, + () => new[] { c.MemberName }, + () => new[] { c.MemberName + " = value;"}); + + caProp.Comment.AddRange(columnComments); + + if (GenerateObsoleteAttributeForAliases) + caProp.Attributes.Add(new Attribute("Obsolete", ToStringLiteral("Use " + c.MemberName + " instead."))); + + caProp.Attributes.Add(new Attribute("ColumnAlias" , ToStringLiteral(c.MemberName))); + + columnAliases.Members.Add(caProp); + } + } + + t.Members.Add(columns); + + if (columnAliases.Members.Count > 0) + t.Members.Add(columnAliases); + + if (GenerateAssociations || GenerateAssociationExtensions) + { + var keys = t.ForeignKeys.Values.ToList(); + + if (!GenerateBackReferences) + keys = keys.Where(k => k.BackReference != null).ToList(); + + if (keys.Count > 0) + { + var associations = new MemberGroup { Region = "Associations" }; + var extensionAssociations = new MemberGroup { Region = t.Name + " Associations"}; + + foreach (var key in keys.OrderBy(k => k.MemberName)) + { + key.Comment.Add("/ <summary>"); + key.Comment.Add("/ " + key.KeyName); + key.Comment.Add("/ </summary>"); + + if (key.AssociationType == AssociationType.OneToMany) + key.TypeBuilder = () => string.Format(OneToManyAssociationType, key.OtherTable.TypePrefix + key.OtherTable.TypeName); + else + key.TypeBuilder = () => key.OtherTable.TypePrefix + key.OtherTable.TypeName; + + var aa = new Attribute("Association"); + + aa.Parameters.Add("ThisKey=" + ToStringLiteral(string.Join(", ", (from c in key.ThisColumns select c.MemberName).ToArray()))); + aa.Parameters.Add("OtherKey=" + ToStringLiteral(string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray()))); + aa.Parameters.Add("CanBeNull=" + (key.CanBeNull ? "true" : "false")); + + switch (key.AssociationType) + { + case AssociationType.OneToOne : aa.Parameters.Add("Relationship=Relationship.OneToOne"); break; + case AssociationType.OneToMany : aa.Parameters.Add("Relationship=Relationship.OneToMany"); break; + case AssociationType.ManyToOne : aa.Parameters.Add("Relationship=Relationship.ManyToOne"); break; + } + + if (key.BackReference != null) + { + if (!string.IsNullOrEmpty(key.KeyName)) + aa.Parameters.Add("KeyName=" + ToStringLiteral(key.KeyName)); + if (GenerateBackReferences && !string.IsNullOrEmpty(key.BackReference.MemberName)) + aa.Parameters.Add("BackReferenceName=" + ToStringLiteral(key.BackReference.MemberName)); + } + else + { + aa.Parameters.Add("IsBackReference=true"); + } + + key.Attributes.Add(aa); + + SetPropertyValue(key, "IsNotifying", true); + SetPropertyValue(key, "IsEditable", true); + + associations.Members.Add(key); + + var extension = new Method(() => string.Format("IQueryable<{0}>", key.OtherTable.TypePrefix + key.OtherTable.TypeName), GetAssociationExtensionPluralName(key)); + extension.Name = GetAssociationExtensionPluralName(key); + + extension.ParameterBuilders.Add(() => string.Format("this {0}{1} obj", t.TypePrefix, t.TypeName)); + + extension.ParameterBuilders.Add(() => "IDataContext db"); + extension.Attributes.Add(aa); + extension.IsStatic = true; + + extension.Comment.Add("/ <summary>"); + extension.Comment.Add("/ " + key.KeyName); + extension.Comment.Add("/ </summary>"); + + Func<string> builder = () => + { + var sb = new StringBuilder(); + sb + .Append("return db.GetTable<") + .Append(key.OtherTable.TypePrefix + key.OtherTable.TypeName) + .Append(">().Where(c => "); + for (var i = 0; i < key.OtherColumns.Count; i++) + { + sb.Append("c.") + .Append(key.OtherColumns[i].MemberName) + .Append(" == obj.") + .Append(key.ThisColumns[i].MemberName) + .Append(" && "); + } + sb.Length -= 4; + sb.Append(");"); + + return sb.ToString(); + }; + + extension.BodyBuilders.Add(() => new[] { builder() }); + + extensionAssociations.Members.Add(extension); + + if (key.AssociationType != AssociationType.OneToMany) + { + var single = new Method(() => t.TypePrefix + t.TypeName, GetAssociationExtensionSinglularName(key)); + + single.ParameterBuilders.Add(() => string.Format("this {0}{1} obj", key.OtherTable.TypePrefix, key.OtherTable.TypeName)); + + single.ParameterBuilders.Add(() => "IDataContext db"); + single.Attributes.Add(aa); + single.IsStatic = true; + + single.Comment.Add("/ <summary>"); + single.Comment.Add("/ " + key.KeyName); + single.Comment.Add("/ </summary>"); + + Func<string> builderSingle = () => + { + var sb = new StringBuilder(); + sb + .Append("return db.GetTable<") + .Append(t.TypePrefix + t.TypeName) + .Append(">().Where(c => "); + for (var i = 0; i < key.OtherColumns.Count; i++) + { + sb.Append("c.") + .Append(key.ThisColumns[i].MemberName) + .Append(" == obj.") + .Append(key.OtherColumns[i].MemberName) + .Append(" && "); + } + sb.Length -= 4; + sb.Append(");"); + + return sb.ToString(); + }; + + single.BodyBuilders.Add(() => + { + var sb = new StringBuilder(builderSingle()); + sb.Length -= 1; + + if (key.CanBeNull) + sb.Append(".FirstOrDefault();"); + else + sb.Append(".First();"); + + return new [] { sb.ToString() }; + }); + + extensionAssociations.Members.Add(single); + } + } + + if (GenerateAssociations) + t.Members.Add(associations); + if (GenerateAssociationExtensions) + associationExtensions.Members.Add(extensionAssociations); + } + } + + if (GenerateFindExtensions && nPKs > 0) + { + var PKs = t.Columns.Values.Where(c => c.IsPrimaryKey).ToList(); + var maxNameLen1 = PKs.Max(c => (int?)c.MemberName.Length) ?? 0; + var maxNameLen2 = PKs.Take(nPKs - 1).Max(c => (int?)c.MemberName.Length) ?? 0; + + tableExtensions.Members.Add( + new Method( + () => t.TypeName, + "Find", + new Func<string>[] { () => (string.Format("this ITable<{0}> table", t.TypeName)) } + .Union(PKs.Select(c => (Func<string>)(() => c.BuildType() + " " + c.MemberName))), + () => new[] { "return table.FirstOrDefault(t =>" } + .Union(PKs.SelectMany((c,i) => + { + var ss = new List<string>(); + + if (c.Conditional != null) + ss.Add("#if " + c.Conditional); + + ss.Add(BuildColumnComparison(c, LenDiff(maxNameLen1, c.MemberName), LenDiff(maxNameLen2, c.MemberName), i == nPKs - 1)); + + if (c.Conditional != null) + { + if (ss[1].EndsWith(");")) + { + ss[1] = ss[1].Substring(0, ss[1].Length - 2); + ss.Add("#endif"); + ss.Add("\t\t);"); + } + else + { + ss.Add("#endif"); + } + } + + return ss; + }))) + { + IsStatic = true + }); + } + + addType(t); + + if (!string.IsNullOrWhiteSpace(t.AliasTypeName)) + { + var aClass = new Class(t.AliasTypeName) + { + BaseClass = t.TypeName + }; + + if (comments.Count > 0) + aClass.Comment.AddRange(comments); + + if (GenerateObsoleteAttributeForAliases) + aClass.Attributes.Add(new Attribute("Obsolete", ToStringLiteral("Use " + t.TypeName + " instead."))); + + Model.Types.Add(aClass); + } + } + + if (associationExtensions.Members.Count > 0) + defTableExtensions.Members.Add(associationExtensions); + + if (defAliases.Members.Count > 0) + DataContextObject.Members.Add(defAliases); + + foreach (var schema in schemas.Values) + if (schema.Aliases.Members.Count > 0) + schema.Type.Members.Add(defAliases); + + if (Procedures.Count > 0) + { + Model.Usings.Add("System.Collections.Generic"); + Model.Usings.Add("System.Data"); + Model.Usings.Add("LinqToDB.Data"); + Model.Usings.Add("LinqToDB.Common"); + + if (Procedures.Values.Any(p => p.IsTableFunction)) + Model.Usings.Add("System.Reflection"); + + if (Procedures.Values.Any(p => p.IsAggregateFunction)) + Model.Usings.Add("System.Linq.Expressions"); + + var procs = new MemberGroup(); + var funcs = new MemberGroup(); + var tabfs = new MemberGroup { Region = "Table Functions" }; + + foreach (var p in Procedures.Values.Where( + proc => proc.IsLoaded || proc.IsFunction && !proc.IsTableFunction || + proc.IsTableFunction && proc.ResultException != null + )) + { + Action<MemberGroup> addProcs = tp => procs.Members.Add(tp); + Action<MemberGroup> addFuncs = tp => funcs.Members.Add(tp); + Action<MemberGroup> addTabfs = tp => tabfs.Members.Add(tp); + + var thisDataContext = "this"; + + var schema = p.Schema != null && schemas.ContainsKey(p.Schema) ? schemas[p.Schema] : null; + + if (schema != null) + { + var si = schemas[p.Schema]; + + addProcs = tp => si.Procedures. Members.Add(tp); + addFuncs = tp => si.Functions. Members.Add(tp); + addTabfs = tp => si.TableFunctions.Members.Add(tp); + thisDataContext = "_dataContext"; + } + + var proc = new MemberGroup { Region = p.Name }; + + if (!p.IsFunction) addProcs(proc); + else if (p.IsTableFunction) addTabfs(proc); + else addFuncs(proc); + + if (p.ResultException != null) + { + proc.Errors.Add(p.ResultException.Message); + continue; + } + + proc.Members.Add(p); + + if (p.IsTableFunction) + { + var tableAttrs = new List<string>(); + + if (DatabaseName != null) tableAttrs.Add("Database=" + ToStringLiteral(DatabaseName)); + if (p.Schema != null) tableAttrs.Add("Schema=" + ToStringLiteral(p.Schema)); + + tableAttrs.Add("Name=" + ToStringLiteral(p.ProcedureName)); + + p.Attributes.Add(new Attribute("Sql.TableFunction", tableAttrs.ToArray())); + + p.TypeBuilder = () => "ITable<" + p.ResultTable.TypeName + ">"; + } + else if (p.IsAggregateFunction) + { + p.IsStatic = true; + p.TypeBuilder = () => p.ProcParameters.Single(pr => pr.IsResult).ParameterType; + var paramCount = p.ProcParameters.Count(pr => !pr.IsResult); + p.Attributes.Add(new Attribute("Sql.Function", "Name=" + ToStringLiteral((p.Schema != null ? p.Schema + "." : null) + p.ProcedureName), "ServerSideOnly=true, IsAggregate = true" + (paramCount > 0 ? (", ArgIndices = new[] { " + string.Join(", ", Enumerable.Range(0, p.ProcParameters.Count(pr => !pr.IsResult))) + " }") : null))); + + if (p.IsDefaultSchema || !GenerateSchemaAsType) + p.ParameterBuilders.Add(() => "this IEnumerable<TSource> src"); + else // otherwise function will be generated in nested class, which doesn't support extension methods + p.ParameterBuilders.Add(() => "IEnumerable<TSource> src"); + + foreach (var inp in p.ProcParameters.Where(pr => !pr.IsResult)) + p.ParameterBuilders.Add(() => $"Expression<Func<TSource, {inp.ParameterType}>> " + inp.ParameterName); + + p.Name += "<TSource>"; + } + else if (p.IsFunction) + { + p.IsStatic = true; + p.TypeBuilder = () => p.ProcParameters.Single(pr => pr.IsResult).ParameterType; + p.Attributes.Add(new Attribute("Sql.Function", "Name=" + ToStringLiteral((p.Schema != null ? p.Schema + "." : null) + p.ProcedureName), "ServerSideOnly=true")); + } + else + { + p.IsStatic = true; + p.TypeBuilder = () => p.ResultTable == null + ? "int" + : GenerateProcedureResultAsList + ? "List<" + p.ResultTable.TypeName + ">" + : "IEnumerable<" + p.ResultTable.TypeName + ">"; + + if (p.IsDefaultSchema || !GenerateSchemaAsType) + p.ParameterBuilders.Add(() => "this DataConnection dataConnection"); + else + p.ParameterBuilders.Add(() => "DataConnection dataConnection"); + } + + if (!p.IsAggregateFunction) + foreach (var pr in p.ProcParameters.Where(par => !par.IsResult)) + p.ParameterBuilders.Add(() => string.Format("{0}{1} {2}", + pr.IsOut ? pr.IsIn ? "ref " : "out " : "", pr.ParameterType, pr.ParameterName)); + + if (p.IsTableFunction) + { + p.BodyBuilders.Add(() => new[] + { + string.Format("return " + thisDataContext + ".GetTable<{0}>(this, (MethodInfo)MethodBase.GetCurrentMethod()", p.ResultTable.TypeName) + + (p.ProcParameters.Count == 0 ? ");" : ",") + }); + + for (var idx = 0; idx < p.ProcParameters.Count; idx++) + { + var i = idx; + p.BodyBuilders.Add(() => new []{ "\t" + p.ProcParameters[i].ParameterName + (i + 1 == p.ProcParameters.Count ? ");" : ",") }); + } + } + else if (p.IsFunction) + { + p.BodyBuilders.Add(() => new [] { "throw new InvalidOperationException();" }); + } + else + { + var spName = + SqlBuilder.BuildTableName( + new System.Text.StringBuilder(), + (string)SqlBuilder.Convert(DatabaseName, LinqToDB.SqlProvider.ConvertType.NameToDatabase), + (string)SqlBuilder.Convert(p.Schema, LinqToDB.SqlProvider.ConvertType.NameToSchema), + (string)SqlBuilder.Convert(p.ProcedureName, LinqToDB.SqlProvider.ConvertType.NameToQueryTable) + ).ToString(); + + spName = ToStringLiteral(spName); + + var inputParameters = p.ProcParameters.Where(pp => pp.IsIn). ToList(); + var outputParameters = p.ProcParameters.Where(pp => pp.IsOut). ToList(); + var inOrOutputParameters = p.ProcParameters.Where(pp => pp.IsIn || pp.IsOut).ToList(); + + spName += inOrOutputParameters.Count == 0 + ? (p.ResultTable == null || !GenerateProcedureResultAsList ? ");" : ").ToList();") + : ","; + + var retName = "ret"; + var retNo = 0; + + while (p.ProcParameters.Any(pp => pp.ParameterName == retName)) + retName = "ret" + ++retNo; + + var hasOut = outputParameters.Any(pr => pr.IsOut); + var prefix = hasOut ? "var " + retName + " = " : "return "; + + if (p.ResultTable == null) + p.BodyBuilders.Add(() => new [] { prefix + "dataConnection.ExecuteProc(" + spName }); + else + { + if (p.ResultTable.Columns.Values.Any(c => c.IsDuplicateOrEmpty)) + { + p.BodyBuilders.Add(() => new [] + { + "var ms = dataConnection.MappingSchema;", + "", + prefix + "dataConnection.QueryProc(dataReader =>", + "\tnew " + p.ResultTable.TypeName, + "\t{" + }); + + var n = 0; + var maxNameLen = p.ResultTable.Columns.Values.Max(c => (int?)c.MemberName .Length) ?? 0; + var maxTypeLen = p.ResultTable.Columns.Values.Max(c => (int?)c.BuildType().Length) ?? 0; + + foreach (var c in p.ResultTable.Columns.Values) + { + p.BodyBuilders.Add(() => new [] {string.Format("\t\t{0}{1} = Converter.ChangeTypeTo<{2}>{3}(dataReader.GetValue({4}), ms),", + c.MemberName, LenDiff(maxNameLen, c.MemberName), c.BuildType(), LenDiff(maxTypeLen, c.BuildType()), n++) }); + } + + p.BodyBuilders.Add(() => new [] {"\t},", "\t" + spName }); + } + else + { + p.BodyBuilders.Add(() => new [] { prefix + "dataConnection.QueryProc<" + p.ResultTable.TypeName + ">(" + spName }); + } + } + + var maxLenSchema = inputParameters.Max(pr => (int?)pr.SchemaName. Length) ?? 0; + var maxLenParam = inputParameters.Max(pr => (int?)pr.ParameterName.Length) ?? 0; + var maxLenType = inputParameters.Max(pr => (int?)("DataType." + pr.DataType).Length) ?? 0; + + for (var idx = 0; idx < inOrOutputParameters.Count; idx++) + { + var i = idx; + var pr = inOrOutputParameters[i]; + + p.BodyBuilders.Add(() => + { + var str = string.Format( + !pr.IsIn && pr.IsOut + ? "\tnew DataParameter({0}, null, {3}{4})" + : "\tnew DataParameter({0}, {1}{2}, {3}{4})" + (GenerateProcedureDbType(pr) ? "{{ DbType = {5} }}" : null), + ToStringLiteral(pr.SchemaName), + LenDiff(maxLenSchema, pr.SchemaName), + pr.ParameterName, + LenDiff(maxLenParam, pr.ParameterName), + "DataType." + pr.DataType, + ToStringLiteral(pr.SchemaType)); + + if (pr.IsOut) + { + str += LenDiff(maxLenType, "DataType." + pr.DataType); + str += " { Direction = " + (pr.IsIn ? "ParameterDirection.InputOutput" : "ParameterDirection.Output"); + + if (pr.Size != null && pr.Size.Value != 0) + str += ", Size = " + pr.Size.Value; + + str += " }"; + } + + // we need to call ToList(), because otherwise output parameters will not be updated + // with values. See https://msdn.microsoft.com/en-us/library/ms971497#gazoutas_topic6 + str += i + 1 == inOrOutputParameters.Count + ? ((GenerateProcedureResultAsList || outputParameters.Count > 0) && p.ResultTable != null ? ").ToList();" : ");") + : ","; + + return new [] { str }; + }); + } + + if (hasOut) + { + maxLenSchema = outputParameters.Max(pr => (int?)pr.SchemaName. Length) ?? 0; + maxLenParam = outputParameters.Max(pr => (int?)pr.ParameterName.Length) ?? 0; + maxLenType = outputParameters.Max(pr => (int?)pr.ParameterType.Length) ?? 0; + + p.BodyBuilders.Add(() => new [] { string.Empty }); + + foreach (var pr in p.ProcParameters.Where(_ => _.IsOut)) + { + p.BodyBuilders.Add(() => new [] { string.Format("{0} {1}= Converter.ChangeTypeTo<{2}>{3}(((IDbDataParameter)dataConnection.Command.Parameters[{4}]).{5}Value);", + pr.ParameterName, + LenDiff(maxLenParam, pr.ParameterName), + pr.ParameterType, + LenDiff(maxLenType, pr.ParameterType), + ToStringLiteral(pr.SchemaName), + LenDiff(maxLenSchema, pr.SchemaName)) }); + } + + p.BodyBuilders.Add(() => new [] {"", "return " + retName + ";" }); + } + } + + if (p.ResultTable != null && p.ResultTable.DataContextPropertyName == null) + { + var columns = new MemberGroup { IsCompact = true }; + + foreach (var c in p.ResultTable.Columns.Values) + { + if (c.MemberName != c.ColumnName) + c.Attributes.Add(new Attribute("Column") { Parameters = { ToStringLiteral(c.ColumnName) } }); + columns.Members.Add(c); + } + + p.ResultTable.Members.Add(columns); + proc.Members.Add(p.ResultTable); + } + } + + if (procs.Members.Count > 0) + Model.Types.Add(new Class(DataContextObject.Name + "StoredProcedures", procs) { IsStatic = true }); + + if (funcs.Members.Count > 0) + Model.Types.Add(new Class("SqlFunctions", funcs) { IsStatic = true }); + + if (tabfs.Members.Count > 0) + DataContextObject.Members.Add(tabfs); + + MakeTypeMembersNamesUnique(DataContextObject, "InitDataContext", "InitMappingSchema"); + MakeMembersNamesUnique(Model.Types, "Table"); + foreach (var type in Model.Types.OfType<Class>()) + MakeTypeMembersNamesUnique(type, exceptMethods: new [] { "Find", "InitDataContext", "InitMappingSchema" }); + + foreach (var schema in schemas.Values) + { + if (schema.Procedures.Members.Count > 0) + schema.Type.Members.Add(new Class(DataContextObject.Name + "StoredProcedures", schema.Procedures) { IsStatic = true }); + + if (schema.Functions.Members.Count > 0) + schema.Type.Members.Add(new Class("SqlFunctions", schema.Functions) { IsStatic = true }); + + if (schema.TableFunctions.Members.Count > 0) + schema.DataContext.Members.Add(schema.TableFunctions); + + MakeTypeMembersNamesUnique(schema.DataContext, "InitDataContext", "InitMappingSchema"); + foreach (var type in schema.Type.Members.OfType<Class>()) + MakeTypeMembersNamesUnique(type); + } + } + + if (defTableExtensions.Members.Count > 0) + { + Model.Usings.Add("System.Linq"); + var tableExtensions = new Class("TableExtensions", defTableExtensions) { IsStatic = true }; + Model.Types.Add(tableExtensions); + MakeTypeMembersNamesUnique(tableExtensions, exceptMethods: new [] { "Find" }); + } + + foreach (var schema in schemas.Values) + { + Model.Types.Add(schema.Type); + + if (schema.TableExtensions.Members.Count > 0) + { + Model.Usings.Add("System.Linq"); + schema.Type.Members.Add(schema.TableExtensions); + } + } + + Tables. Clear(); + Procedures.Clear(); + + Model.SetTree(); + + AfterGenerateLinqToDBModel(); +} + +void MakeTypeMembersNamesUnique(Class type, string defaultName = "Member", params string[] exceptMethods) +{ + var reservedNames = new [] { type.Name }; + if (exceptMethods != null && exceptMethods.Length > 0) + reservedNames = reservedNames.Concat(exceptMethods).ToArray(); + + MakeMembersNamesUnique(GetAllClassMembers(type.Members, exceptMethods), defaultName, reservedNames); +} + +void MakeMembersNamesUnique(IEnumerable<IClassMember> members, string defaultName, params string[] reservedNames) +{ + LinqToDB.Common.Utils.MakeUniqueNames( + members, + reservedNames, + m => m is Table tbl ? (tbl.Schema != null && !tbl.IsDefaultSchema && PrefixTableMappingWithSchema ? tbl.Schema + "_" : null) + tbl.Name : (m is TypeBase t ? t.Name : ((MemberBase)m).Name), + (m, newName) => + { + if (m is TypeBase t) + t.Name = newName; + else + ((MemberBase)m).Name = newName; + }, + defaultName); +} + +IEnumerable<IClassMember> GetAllClassMembers(IEnumerable<IClassMember> members, params string[] exceptMethods) +{ + foreach (var member in members) + { + if (member is MemberGroup mg) + foreach (var m in GetAllClassMembers(mg.Members, exceptMethods)) + yield return m; + // constructors don't have own type/flag + else if (member is Method method && (method.BuildType() == null || (exceptMethods != null && exceptMethods.Contains(method.Name)))) + continue; + else + yield return member; + } +} + +// left for backward compatibility +string NormalizeStringName(string name) +{ + return ToStringLiteral(name); +} + +#> diff --git a/src/Version/LinqToDB.Templates/MultipleFiles.ttinclude b/src/Version/LinqToDB.Templates/MultipleFiles.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..4b43ba0cb45ef6415572f3758f81c3cec9fc9c93 --- /dev/null +++ b/src/Version/LinqToDB.Templates/MultipleFiles.ttinclude @@ -0,0 +1,70 @@ +<#@ assembly name="System.Core" #> +<#@ assembly name="EnvDTE" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="EnvDTE" #> +<#+ +DTE _dte; +DTE DTE => _dte ?? (_dte = (DTE)((IServiceProvider)Host).GetService(typeof(DTE))); + +ProjectItem _templateProjectItem; +ProjectItem TemplateProjectItem => _templateProjectItem ?? (_templateProjectItem = DTE.Solution.FindProjectItem(Host.TemplateFile)); + +readonly Dictionary<string,int> _fileNames = new Dictionary<string,int>(); + +Func<string,string,bool> CompareContent = (s1,s2) => s1 == s2; + +void SaveOutput(string fileName, int fileType = 1) +{ + var dir = Path.GetDirectoryName(Host.TemplateFile); + var output = Path.Combine(dir, fileName); + var newContent = GenerationEnvironment.ToString(); + var oldContent = File.Exists(output) ? File.ReadAllText(output) : ""; + + if (!CompareContent(newContent, oldContent)) + { + if (DTE.SourceControl != null && DTE.SourceControl.IsItemUnderSCC(output) && !DTE.SourceControl.IsItemCheckedOut(output)) + DTE.SourceControl.CheckOutItem(output); + + File.WriteAllText(output, newContent); + } + + GenerationEnvironment.Length = 0; + + _fileNames.Add(output, fileType); +} + +void SyncProject() +{ + var keepFileNames = _fileNames.ToDictionary(f => f.Key); + var projectFiles = new Dictionary<string,ProjectItem>(); + var templateFileName = TemplateProjectItem.FileNames[0]; + var originalFilePrefix = Path.GetFileNameWithoutExtension(templateFileName) + "."; + + foreach (ProjectItem projectItem in TemplateProjectItem.ProjectItems) + { + projectFiles.Add(projectItem.FileNames[0], projectItem); + } + + foreach (var pair in projectFiles) + { + if (!keepFileNames.ContainsKey(pair.Key)) + if (!(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) + //if (pair.Key != templateFileName) + pair.Value.Delete(); + } + + // Add missing files to the project. + // + foreach (var fileName in keepFileNames) + { + if (!projectFiles.ContainsKey(fileName.Value.Key)) + if (File.Exists(fileName.Value.Key)) + { + var newItem = TemplateProjectItem.ProjectItems.AddFromFile(fileName.Value.Key); + newItem.Properties.Item("BuildAction").Value = fileName.Value.Value; + } + } +} +#> diff --git a/src/Version/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude b/src/Version/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..06e72afe36bacddb7945459593de4a5bf6e93a79 --- /dev/null +++ b/src/Version/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude @@ -0,0 +1,133 @@ +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + beforeGenerateModel(); + NotifyDataErrorInfoImpl(); + }; + } +#> +<#+ +void NotifyDataErrorInfoImpl() +{ + foreach (var prop in GetTreeNodes(Model).OfType<Property>().Where(p => p.CustomValidation).ToList()) + { + ITree p = prop.Parent; + + while (!(p is Class) && p != null) + p = p.Parent; + + if (p != null) + { + var cl = (Class)p; + + if (!cl.Interfaces.Contains("INotifyDataErrorInfo")) + { + if (!Model.Usings.Contains("System.ComponentModel")) Model.Usings.Add("System.ComponentModel"); + if (!Model.Usings.Contains("System.Collections")) Model.Usings.Add("System.Collections"); + if (!Model.Usings.Contains("System.Linq")) Model.Usings.Add("System.Linq"); + + cl.Interfaces.Add("INotifyDataErrorInfo"); + + cl.Members.Add(new MemberGroup + { + Region = "INotifyDataErrorInfo support", + Members = + { + new Event(() => "EventHandler<DataErrorsChangedEventArgs>", "ErrorsChanged") + { + IsVirtual = true, + Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } + }, + new Field(() => "Dictionary<string,List<string>>", "_validationErrors") + { + InitValue = "new Dictionary<string,List<string>>()", + AccessModifier = AccessModifier.Private, + IsReadonly = true, + Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } + }, + new Method(() => "void", "AddError", + new Func<string>[] + { + () => "string propertyName", + () => "string error" + }, + () => new[] + { + "List<string> errors;", + "", + "if (!_validationErrors.TryGetValue(propertyName, out errors))", + "{", + "\t_validationErrors[propertyName] = new List<string> { error };", + "}", + "else if (!errors.Contains(error))", + "{", + "\terrors.Add(error);", + "}", + "else", + "\treturn;", + "", + "OnErrorsChanged(propertyName);", + }) + { + AccessModifier = AccessModifier.Public + }, + new Method(() => "void", "RemoveError", + new Func<string>[] + { + () => "string propertyName", + }, + () => new[] + { + "List<string> errors;", + "", + "if (_validationErrors.TryGetValue(propertyName, out errors) && errors.Count > 0)", + "{", + "\t_validationErrors.Clear();", + "\tOnErrorsChanged(propertyName);", + "}", + }) + { + AccessModifier = AccessModifier.Public + }, + new Method(() => "void", "OnErrorsChanged", + new Func<string>[] + { + () => "string propertyName", + }, + () => new[] + { + "if (ErrorsChanged != null)", + "{", + "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", + "\t\tErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));", + "\telse", + "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", + "\t\t\t() => ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)));", + "}", + }) + { + AccessModifier = AccessModifier.Protected + }, + new Method(() => "IEnumerable", "GetErrors", + new Func<string>[] + { + () => "string propertyName", + }, + () => new[] + { + "List<string> errors;", + "return propertyName != null && _validationErrors.TryGetValue(propertyName, out errors) ? errors : null;", + }) + { + AccessModifier = AccessModifier.Public + }, + new Property(() => "bool", "HasErrors").InitGetter(() => new [] { "_validationErrors.Values.Any(e => e.Count > 0)" }) + } + }); + } + } + } +} +#> diff --git a/src/Version/LinqToDB.Templates/NotifyPropertyChanged.ttinclude b/src/Version/LinqToDB.Templates/NotifyPropertyChanged.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..49234e7df4ac27c2f5f6314587a7396bcac16a53 --- /dev/null +++ b/src/Version/LinqToDB.Templates/NotifyPropertyChanged.ttinclude @@ -0,0 +1,382 @@ +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + beforeGenerateModel(); + NotifyPropertyChangedImpl(); + }; + + SetPropertyValueAction += (obj,prop,val) => + { + if (prop == "IsNotifying") + obj.IsNotifying = (bool)val; + }; + } +#><#+ +public bool ImplementNotifyPropertyChanging; +public bool SkipNotifyPropertyChangedImplementation = false; + +void NotifyPropertyChangedImpl() +{ + foreach (Property prop in GetTreeNodes(Model).OfType<Property>().Where(p => p.IsNotifying).ToList()) + { + List<IClassMember> parentMembers; + + MemberGroup gr = null; + + if (prop.Parent is Class) + { + var parent = (Class)prop.Parent; + parentMembers = parent.Members; + } + else + { + var parent = (MemberGroup)prop.Parent; + + parent.IsCompact = false; + + parentMembers = parent.Members; + + if (parent.IsPropertyGroup) + gr = parent; + } + + var name = prop.Name.Trim(); + var type = prop.BuildType().Trim(); + + if (gr == null) + { + gr = new MemberGroup + { + Region = name + " : " + type, + Members = { prop }, + IsPropertyGroup = true, + }; + + var index = parentMembers.IndexOf(prop); + + parentMembers.RemoveAt(index); + parentMembers.Insert (index, gr); + } + + if (prop.IsAuto) + { + var field = new Field(() => type, "_" + ToCamelCase(name)) + { + AccessModifier = AccessModifier.Private, + InsertBlankLineAfter = false, + }; + + if (prop.InitValue != null) + field.InitValue = prop.InitValue; + + gr.Members.Insert(0, field); + + prop.Name = " " + name; + prop.TypeBuilder = () => " " + type; + prop.IsAuto = false; + + if (prop.HasGetter) prop.GetBodyBuilders.Add(() => new [] { "return " + field.Name + ";" }); + if (prop.HasSetter) prop.SetBodyBuilders.Add(() => new [] { field.Name + " = value;" }); + } + + var methods = new MemberGroup + { + Region = "INotifyPropertyChanged support", + Members = + { + new Field(() => "const string", "NameOf" + name) + { + InitValue = ToStringLiteral(name), + AccessModifier = AccessModifier.Public, + }, + new Field(() => "PropertyChangedEventArgs", "_" + ToCamelCase(name) + "ChangedEventArgs") + { + InitValue = "new PropertyChangedEventArgs(NameOf" + name + ")", + AccessModifier = AccessModifier.Private, + IsStatic = true, + IsReadonly = true, + }, + new Method(() => "void", "On" + name + "Changed", null, + () => new[] { "OnPropertyChanged(_" + ToCamelCase(name) + "ChangedEventArgs);" }) + { + AccessModifier = AccessModifier.Private + } + } + }; + + gr.Members.Add(methods); + + if (prop.Dependents.Count == 0) + prop.Dependents.Add(name); + + if (ImplementNotifyPropertyChanging) + { + gr.Members.Add(new MemberGroup + { + Region = "INotifyPropertyChanging support", + Members = + { + new Field(() => "PropertyChangingEventArgs", "_" + ToCamelCase(name) + "ChangingEventArgs") + { + InitValue = "new PropertyChangingEventArgs(NameOf" + name + ")", + AccessModifier = AccessModifier.Private, + IsStatic = true, + IsReadonly = true, + }, + new Method(() => "void", "On" + name + "Changing", null, + () => new[] { "OnPropertyChanging(_" + ToCamelCase(name) + "ChangingEventArgs);" }) + { + AccessModifier = AccessModifier.Private + } + } + }); + } + + if (prop.HasSetter) + { + var setBody = prop.BuildSetBody().Select(s => "\t" + s).ToArray(); + prop.SetBodyBuilders.Clear(); + prop.SetBodyBuilders.Add(() => setBody); + + string getValue; + + var getBody = prop.BuildGetBody().ToArray(); + if (getBody.Length == 1 && getBody[0].StartsWith("return")) + { + getValue = getBody[0].Substring("return".Length).Trim(' ', '\t', ';'); + } + else + { + getValue = name; + } + + var insSpaces = setBody.Length > 1; + var n = 0; + + prop.SetBodyBuilders.Insert(n++, () => new [] {"if (" + getValue + " != value)", "{" }); + + if (ImplementNotifyPropertyChanging) + { + foreach (var dp in prop.Dependents) + prop.SetBodyBuilders.Insert(n++, () => new [] { "\tOn" + dp + "Changing();" }); + prop.SetBodyBuilders.Insert(n++, () => new [] { "" }); + } + + prop.SetBodyBuilders.Insert(n++, () => new [] { "\tBefore" + name + "Changed(value);" }); + + if (insSpaces) + { + prop.SetBodyBuilders.Insert(3, () => new [] { "" }); + prop.SetBodyBuilders.Add(() => new [] { "" }); + } + + prop.SetBodyBuilders.Add(() => new [] { "\tAfter" + name + "Changed();" }); + prop.SetBodyBuilders.Add(() => new [] { "" }); + + foreach (var dp in prop.Dependents) + prop.SetBodyBuilders.Add(() => new [] { "\tOn" + dp + "Changed();" }); + + prop.SetBodyBuilders.Add(() => new [] { "}" }); + + methods.Members.Insert(0, new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "Before" + name + "Changed", new Func<string>[] { () => type + " newValue" }) { AccessModifier = AccessModifier.Partial }, + new Method(() => "void", "After" + name + "Changed") { AccessModifier = AccessModifier.Partial }, + } + }); + } + + prop.Parent.SetTree(); + + ITree p = prop.Parent; + + while (!(p is Class) && p != null) + p = p.Parent; + + if (p != null) + { + var cl = (Class)p; + + if (!SkipNotifyPropertyChangedImplementation && !cl.Interfaces.Contains("INotifyPropertyChanged")) + { + if (!Model.Usings.Contains("System.ComponentModel")) + Model.Usings.Add("System.ComponentModel"); + + cl.Interfaces.Add("INotifyPropertyChanged"); + + cl.Members.Add(new MemberGroup + { + Region = "INotifyPropertyChanged support", + Members = + { + new Event(() => "PropertyChangedEventHandler", "PropertyChanged") + { + IsVirtual = true, + Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } + }, + new Method(() => "void", "OnPropertyChanged", new Func<string>[] { () => "string propertyName" }, () => OnPropertyChangedBody) + { + AccessModifier = AccessModifier.Protected + }, + new Method(() => "void", "OnPropertyChanged", new Func<string>[] { () => "PropertyChangedEventArgs arg" }, () => OnPropertyChangedArgBody) + { + AccessModifier = AccessModifier.Protected + }, + } + }); + } + + if (ImplementNotifyPropertyChanging && !cl.Interfaces.Contains("INotifyPropertyChanging")) + { + if (!Model.Usings.Contains("System.ComponentModel")) + Model.Usings.Add("System.ComponentModel"); + + cl.Interfaces.Add("INotifyPropertyChanging"); + + cl.Members.Add(new MemberGroup + { + Region = "INotifyPropertyChanging support", + Members = + { + new Event(() => "PropertyChangingEventHandler", "PropertyChanging") + { + IsVirtual = true, + Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } + }, + new Method(() => "void", "OnPropertyChanging", new Func<string>[] { () => "string propertyName" }, () => OnPropertyChangingBody) + { + AccessModifier = AccessModifier.Protected + }, + new Method(() => "void", "OnPropertyChanging", new Func<string>[] { () => "PropertyChangingEventArgs arg" }, () => OnPropertyChangingArgBody) + { + AccessModifier = AccessModifier.Protected + }, + } + }); + } + } + } +} + +public string[] OnPropertyChangedBody = new[] +{ + "var propertyChanged = PropertyChanged;", + "", + "if (propertyChanged != null)", + "{", + "#if SILVERLIGHT", + "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", + "\t\tpropertyChanged(this, new PropertyChangedEventArgs(propertyName));", + "\telse", + "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", + "\t\t\t() =>", + "\t\t\t{", + "\t\t\t\tvar pc = PropertyChanged;", + "\t\t\t\tif (pc != null)", + "\t\t\t\t\tpc(this, new PropertyChangedEventArgs(propertyName));", + "\t\t\t});", + "#else", + "\tpropertyChanged(this, new PropertyChangedEventArgs(propertyName));", + "#endif", + "}", +}; + +public string[] OnPropertyChangedArgBody = new[] +{ + "var propertyChanged = PropertyChanged;", + "", + "if (propertyChanged != null)", + "{", + "#if SILVERLIGHT", + "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", + "\t\tpropertyChanged(this, arg);", + "\telse", + "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", + "\t\t\t() =>", + "\t\t\t{", + "\t\t\t\tvar pc = PropertyChanged;", + "\t\t\t\tif (pc != null)", + "\t\t\t\t\tpc(this, arg);", + "\t\t\t});", + "#else", + "\tpropertyChanged(this, arg);", + "#endif", + "}", +}; + +public string[] OnPropertyChangingBody = new[] +{ + "var propertyChanging = PropertyChanging;", + "", + "if (propertyChanging != null)", + "{", + "#if SILVERLIGHT", + "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", + "\t\tpropertyChanging(this, new PropertyChangingEventArgs(propertyName));", + "\telse", + "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", + "\t\t\t() =>", + "\t\t\t{", + "\t\t\t\tvar pc = PropertyChanging;", + "\t\t\t\tif (pc != null)", + "\t\t\t\t\tpc(this, new PropertyChangingEventArgs(propertyName));", + "\t\t\t});", + "#else", + "\tpropertyChanging(this, new PropertyChangingEventArgs(propertyName));", + "#endif", + "}", +}; + +public string[] OnPropertyChangingArgBody = new[] +{ + "var propertyChanging = PropertyChanging;", + "", + "if (propertyChanging != null)", + "{", + "#if SILVERLIGHT", + "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", + "\t\tpropertyChanging(this, arg);", + "\telse", + "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", + "\t\t\t() =>", + "\t\t\t{", + "\t\t\t\tvar pc = PropertyChanging;", + "\t\t\t\tif (pc != null)", + "\t\t\t\t\tpc(this, arg);", + "\t\t\t});", + "#else", + "\tpropertyChanging(this, arg);", + "#endif", + "}", +}; + +partial class Property +{ + public bool IsNotifying; + public List<string> Dependents = new List<string>(); +} + +class NotifyingProperty : Property +{ + public NotifyingProperty() + { + IsNotifying = true; + } + + public NotifyingProperty(string type, string name, params string[] dependents) + : base(() => type, name, null, null) + { + IsNotifying = true; + + if (dependents.Length == 0) + Dependents.Add(name); + else + Dependents.AddRange(dependents); + } +} +#> diff --git a/src/Version/LinqToDB.Templates/ObsoleteAttributes.ttinclude b/src/Version/LinqToDB.Templates/ObsoleteAttributes.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..b95b0d894120fb8d42eb07cf84319f9c2e92def8 --- /dev/null +++ b/src/Version/LinqToDB.Templates/ObsoleteAttributes.ttinclude @@ -0,0 +1,100 @@ +<# + { + var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; + var afterGenerateLinqToDBModel = AfterGenerateLinqToDBModel; + + var obsoleteTables = new List<Tuple<string,string,string>>(); + + BeforeGenerateLinqToDBModel = () => + { + beforeGenerateLinqToDBModel(); + + foreach (var table in Tables.Values) + { + var idx = table.Description.IndexOf("[Obsolete"); + + if (idx >= 0) + { + var idx2 = table.Description.IndexOf(']', idx); + + if (idx2 > idx) + { + var text = table.Description.Substring(idx + 1, idx2 - idx - 1); + var attr = new Attribute(text); + var info = Tuple.Create(table.Schema, table.Name, text); + + if (obsoleteTables.All(a => a != info)) + obsoleteTables.Add(info); + table.Attributes.Add(attr); + table.Description = table.Description.Substring(0, idx) + table.Description.Substring(idx2 + 1); + } + } + + foreach (var c in table.Columns.Values) + { + idx = c.Description.IndexOf("[Obsolete"); + + if (idx >= 0) + { + var idx2 = c.Description.IndexOf(']', idx); + + if (idx2 > idx) + { + var attr = new Attribute(c.Description.Substring(idx + 1, idx2 - idx - 1)); + + c.Attributes.Add(attr); + c.Description = c.Description.Substring(0, idx) + c.Description.Substring(idx2 + 1); + } + } + } + } + }; + + AfterGenerateLinqToDBModel = () => + { + foreach (var tableInfo in obsoleteTables) + { + var schema = tableInfo.Item1; + var name = tableInfo.Item2; + var text = tableInfo.Item3; + var obsoleteAttr = new Attribute(text); + + foreach (var cm in GetTreeNodes(Model) + .OfType<MemberBase>() + .Where(t => t.BuildType() != null) + .Where(t => t.BuildType() == name || t.BuildType().Contains("<" + name + ">"))) + { + // check schema + + if (cm.Parent != null && cm.Parent.Parent != null) + { + var parent = cm.Parent.Parent; + + if (parent is Table) + { + var table = (Table)parent; + + if (schema == table.Schema) + if (cm.Attributes.All(a => a.Name != text)) + cm.Attributes.Add(obsoleteAttr); + } + else if (parent is Class) + { + var cls = (Class)parent; + + bool parentClassIncludesSchemaName = cls.Name.Equals(schema + "Schema", StringComparison.InvariantCultureIgnoreCase); + bool classIsForDefaultSchema = cls.Name == DataContextName; + bool isExtensionMethod = cls.Parent is Namespace || cls.Name == "TableExtensions"; + + if (classIsForDefaultSchema || parentClassIncludesSchemaName || isExtensionMethod) + if (cm.Attributes.All(a => a.Name != text)) + cm.Attributes.Add(obsoleteAttr); + } + } + } + } + + afterGenerateLinqToDBModel(); + }; + } +#> diff --git a/src/Version/LinqToDB.Templates/PluralizationService.ttinclude b/src/Version/LinqToDB.Templates/PluralizationService.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..2bed1d6fe7c818c122b539e4f88a5acb1486186f --- /dev/null +++ b/src/Version/LinqToDB.Templates/PluralizationService.ttinclude @@ -0,0 +1,185 @@ +<#@ assembly name="System.Data.Entity.Design" #> +<#@ import namespace="System.Data.Entity.Design.PluralizationServices" #> +<# + { + ToPlural = Pluralization.ToPlural; + ToSingular = Pluralization.ToSingular; + } +#> +<#+ +static class Pluralization +{ + public static string CultureInfo = "en"; + + static PluralizationService _service; + + public static Dictionary<string,string> Dictionary = new Dictionary<string,string> + { + { "access", "accesses" }, { "afterlife", "afterlives" }, { "alga", "algae" }, + { "alumna", "alumnae" }, { "alumnus", "alumni" }, { "analysis", "analyses" }, + { "antenna", "antennae" }, { "appendix", "appendices" }, { "axis", "axes" }, + { "bacillus", "bacilli" }, { "basis", "bases" }, { "Bedouin", "Bedouin" }, + { "cactus", "cacti" }, { "calf", "calves" }, { "cherub", "cherubim" }, + { "child", "children" }, { "cod", "cod" }, { "cookie", "cookies" }, + { "criterion", "criteria" }, { "curriculum", "curricula" }, { "data", "data" }, + { "deer", "deer" }, { "diagnosis", "diagnoses" }, { "die", "dice" }, + { "dormouse", "dormice" }, { "elf", "elves" }, { "elk", "elk" }, + { "erratum", "errata" }, { "esophagus", "esophagi" }, { "fauna", "faunae" }, + { "fish", "fish" }, { "flora", "florae" }, { "focus", "foci" }, + { "foot", "feet" }, { "formula", "formulae" }, { "fundus", "fundi" }, + { "fungus", "fungi" }, { "genie", "genii" }, { "genus", "genera" }, + { "goose", "geese" }, { "grouse", "grouse" }, { "hake", "hake" }, + { "half", "halves" }, { "headquarters", "headquarters" }, { "hippo", "hippos" }, + { "hippopotamus", "hippopotami" }, { "hoof", "hooves" }, { "housewife", "housewives" }, + { "hypothesis", "hypotheses" }, { "index", "indices" }, { "info", "info" }, + { "jackknife", "jackknives" }, + { "knife", "knives" }, { "labium", "labia" }, { "larva", "larvae" }, + { "leaf", "leaves" }, { "life", "lives" }, { "loaf", "loaves" }, + { "louse", "lice" }, { "magus", "magi" }, { "man", "men" }, + { "memorandum", "memoranda" }, { "midwife", "midwives" }, { "millennium", "millennia" }, + { "moose", "moose" }, { "mouse", "mice" }, { "nebula", "nebulae" }, + { "neurosis", "neuroses" }, { "nova", "novas" }, { "nucleus", "nuclei" }, + { "oesophagus", "oesophagi" }, { "offspring", "offspring" }, { "ovum", "ova" }, + { "ox", "oxen" }, { "papyrus", "papyri" }, { "passerby", "passersby" }, + { "penknife", "penknives" }, { "person", "people" }, { "phenomenon", "phenomena" }, + { "placenta", "placentae" }, { "pocketknife", "pocketknives" }, { "process", "processes" }, + { "pupa", "pupae" }, { "radius", "radii" }, { "reindeer", "reindeer" }, + { "retina", "retinae" }, { "rhinoceros", "rhinoceros" }, { "roe", "roe" }, + { "salmon", "salmon" }, { "scarf", "scarves" }, { "self", "selves" }, + { "seraph", "seraphim" }, { "series", "series" }, { "sheaf", "sheaves" }, + { "sheep", "sheep" }, { "shelf", "shelves" }, { "species", "species" }, + { "spectrum", "spectra" }, { "status", "status" }, { "stimulus", "stimuli" }, + { "stratum", "strata" }, { "supernova", "supernovas" }, { "swine", "swine" }, + { "terminus", "termini" }, { "thesaurus", "thesauri" }, { "thesis", "theses" }, + { "thief", "thieves" }, { "trout", "trout" }, { "vulva", "vulvae" }, + { "wife", "wives" }, { "wildebeest", "wildebeest" }, { "wolf", "wolves" }, + { "woman", "women" }, { "yen", "yen" }, + }; + + static string GetLastWord(string str) + { + if (string.IsNullOrWhiteSpace(str)) + return string.Empty; + + var i = str.Length - 1; + var isLower = char.IsLower(str[i]); + + while (i > 0 && char.IsLetter(str[i - 1]) && char.IsLower(str[i - 1]) == isLower) + i--; + + return str.Substring(isLower && i > 0 && char.IsLetter(str[i - 1]) ? i - 1 : i); + } + + public static string ToPlural(string str) + { + if (_service == null) + _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); + + var word = GetLastWord(str); + + string newWord; + + if (!Dictionary.TryGetValue(word.ToLower(), out newWord)) + newWord = _service.IsPlural(word) ? word : _service.Pluralize(word); + + if (string.Compare(word, newWord, true) != 0) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1).ToLower(); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; + } + + public static string ToSingular(string str) + { + if (_service == null) + _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); + + var word = GetLastWord(str); + + var newWord = + Dictionary + .Where(dic => string.Compare(dic.Value, word, true) == 0) + .Select(dic => dic.Key) + .FirstOrDefault() + ?? + (_service.IsSingular(word) ? word : _service.Singularize(word)); + + if (string.Compare(word, newWord, true) != 0) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; + } + + static string GetLastWordVersion1(string str) + { + if (string.IsNullOrWhiteSpace(str)) + return string.Empty; + + var i = str.Length - 1; + var isLower = char.IsLower(str[i]); + + while (i > 0 && char.IsLower(str[i-1]) == isLower) + i--; + + return str.Substring(isLower && i > 0 ? i - 1 : i); + } + + public static string ToPluralVersion1(string str) + { + if (_service == null) + _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); + + var word = GetLastWordVersion1(str); + + string newWord; + + if (!Dictionary.TryGetValue(word.ToLower(), out newWord)) + newWord = _service.IsPlural(word) ? word : _service.Pluralize(word); + + if (string.Compare(word, newWord, true) != 0) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; + } + + public static string ToSingularVersion1(string str) + { + if (_service == null) + _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); + + var word = GetLastWordVersion1(str); + + var newWord = + Dictionary + .Where(dic => string.Compare(dic.Value, word, true) == 0) + .Select(dic => dic.Key) + .FirstOrDefault() + ?? + (_service.IsSingular(word) ? word : _service.Singularize(word)); + + if (string.Compare(word, newWord, true) != 0) + { + if (char.IsUpper(word[0])) + newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); + + return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; + } + + return str; + } +} +#> diff --git a/src/Version/LinqToDB.Templates/README.md b/src/Version/LinqToDB.Templates/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0c16bb299841c238e9838723a22350d31fb0800f --- /dev/null +++ b/src/Version/LinqToDB.Templates/README.md @@ -0,0 +1,383 @@ +# T4 Models + +T4 models are used to generate POCO's C# code using your database structure. + +## Installation + +Firstly you should install one of tools packages into your project: + +`Install-Package linq2db.XXX` + +Where XXX is one of supported databases, for example: + +`Install-Package linq2db.SqlServer` + +This also will install needed linq2db packages: + +* linq2db.t4models +* linq2db + +But **not** data provider packages (install them only if needed to compile your project, T4 models ships it's own data provider assemblies). + +### .Net Core specific + +Because of .Net Core projects do not support NuGet content files all stuff is not copied into project's folder, so to run T4 templates you'll need: + +* open `$(SolutionDir).tools\linq2db.t4models` in Explorer +* copy `CopyMe.XXX.Core.tt.txt` to your project's folder or subfolder, then you should use it instead of `CopyMe.XXX.tt.txt` + +## Running + +After package installing you will see new `LinqToDB.Templates` folder in your project, this folder contains all needed T4 stuff to generate your model. Also would be created new folder in tour solution: `$(SolutionDir).tools\linq2db.t4models`, it is used to store and link assemblies, needed for generation (linq2db.dll and data provider assemblies). + +To create a data model template take a look at one of the CopyMe.XXX.tt.txt file in your LinqToDB.Templates project folder. Copy this file to needed project location and rename it, like `MyModel.tt` + +There are few main steps in this file: + +1. Configuring generation process (read below) +1. Loading metadata - this is a call to `LoadMatadata()` function - it connects to your database and fetches all needed metadata (table structure, views, and so on) +1. Customizing generation process (read below) +1. Calling `GenerateModel()` - this will run model generation + +## Configuring schema load process + +Use the following initialization **before** you call the `LoadMetadata()` method. + +All schema load functionality configured using `GetSchemaOptions` property of [`LinqToDB.SchemaProvider.GetSchemaOptions`](https://github.com/linq2db/linq2db/blob/master/Source/LinqToDB/SchemaProvider/GetSchemaOptions.cs) type. Check this class for all available options. + +All loaded schema information is used for mappings generation, so if you want to limit generated mappings, it is the best place to do it. + +```cs +// Enables loading of tables and views information +GetSchemaOptions.GetTables = true; +// Enables loading of functions and procedures information +GetSchemaOptions.GetProcedures = true; +// Enables use of System.Char type in generated model for text types +// with length 1 instead of System.String +GetSchemaOptions.GenerateChar1AsString = false; + +// (string[]) List of schemas to select. +// Option applied only if is is not empty +GetSchemaOptions.IncludedSchemas = null; +// (string[]) List of schemas to exclude from select. +// Option applied only if is is not empty +GetSchemaOptions.ExcludedSchemas = null; + +// Option makes sense only for providers that return schema for several databases +// (string[]) List of databases/catalogs to select. +// Option applied only if is is not empty +GetSchemaOptions.IncludedCatalogs = null; +// Option makes sense only for providers that return schema for several databases +// (string[]) List of databases/catalogs to exclude from select. +// Option applied only if is is not empty +GetSchemaOptions.ExcludedCatalogs = null; + +// Comparer, used for IncludedSchemas/ExcludedSchemas/IncludedCatalogs/ExcludedCatalogs lookups +StringComparer = StringComparer.OrdinalIgnoreCase; + +// Custom filter for procedure/function result schema loader. +// Can be used to exclude schema load for functions, that generate error during schema load +// Also check GenerateProcedureErrors option below +// ProcedureSchema type: +// https://github.com/linq2db/linq2db/blob/master/Source/LinqToDB/SchemaProvider/ProcedureSchema.cs +GetSchemaOptions.LoadProcedure = (ProcedureSchema p) => true; + +// type: Func<ForeignKeySchema, string> +// Defines custom association naming logic +// https://github.com/linq2db/linq2db/blob/master/Source/LinqToDB/SchemaProvider/ForeignKeySchema.cs +GetSchemaOptions.GetAssociationMemberName = null; + +// Procedures load progress reporting callback +// Not applicable for T4 templates +GetSchemaOptions.ProcedureLoadingProgress = (int total, int current) => {}; +``` + +## Configuring generation process + +Use the following initialization **before** you call the `LoadMetadata()` method. + +```cs +/* Global/generic options */ +// Namespace to use for generated model +NamespaceName = "DataModels"; + +/* Data context configuration */ +// (string) Name of base class for generated data context class. +// Default: LinqToDB.Data.DataConnection. +BaseDataContextClass = null; +// (string) Name of data context class. +// Default: <DATABASE_NAME> + "DB" +DataContextName = null; +// Enables generation of constructors for data context class. +// Disabling could be usefull if you need to have custom implementation +// of constructors in partial class +GenerateConstructors = true; // Enforce generating DataContext constructors. +// (string) Defines name of default configuration to use with default data context constructor +DefaultConfiguration = null; + +/* Schemas configuration */ +// Enables generation of mappings for each schema in separate type +GenerateSchemaAsType = false; +// Contains mapping of schema name to corresponding schema class name +// By default is empty and class name generated from schema name +// Requires GenerateSchemaAsType=true set +SchemaNameMapping = Dictionary<string,string>(); +// Suffix, added to schema class name +// Requires GenerateSchemaAsType=true set +SchemaNameSuffix = "Schema" +// Name of data context class for schema. +// Requires GenerateSchemaAsType=true set +SchemaDataContextTypeName = "DataContext" + +/* Table mappings configuration */ +// (string) Specify base class (or comma-separated list of class and/or interfaces) for table mappings +BaseEntityClass = null; +// Enables generation of TableAttribute.Database property using database name, returned by schema loader +GenerateDatabaseName = false; +// Enables generation of TableAttribute.Database property with provided name value. +// (string) If set, overrides GenerateDatabaseName behavior +DatabaseName = null; +// Enables generation of TableAttribute.Schema property for default schema +IncludeDefaultSchema = true; +// Enables generation of mappings for views +GenerateViews = true; +// Enables prefixing mapping classes for tables in non-default schema with schema name +// E.g. MySchema.MyTable -> MySchema_MyTable +// Applicable only if GenerateSchemaAsType = false +PrefixTableMappingWithSchema = true; + +/* Columns comfiguration */ +// Enables compact generation of column properties +IsCompactColumns = true; +// Enables compact generation of aliased column properties +IsCompactColumnAliases = true; +// Enables generation of DataType, Length, Precision and Scale properties of ColumnAttribute. +// Could be overriden (except DataType) by options below +GenerateDataTypes = false; +// (boolean) Enables or disables generation of ColumnAttribute.Length property. +// If null, GenerateDataTypes value is used +GenerateLengthProperty = null; +// (boolean) Enables or disables generation of ColumnAttribute.Precision property. +// If null, GenerateDataTypes value is used +GeneratePrecisionProperty = null; +// (boolean) Enables or disables generation of ColumnAttribute.Scale property. +// If null, GenerateDataTypes value is used +GenerateScaleProperty = null; +// Enables generation of ColumnAttribute.DbType property. +GenerateDbTypes = false; +// Enables generation of ObsoleteAttribute for column aliases +GenerateObsoleteAttributeForAliases = false; + +/* Associations configuration */ +// Defines type template for one-to-many association, when it is generated as a member of table mapping. +// Some other options: "{0}[]", "List<{0}>". +OneToManyAssociationType = "IEnumerable<{0}>"; +// Enables generation of associations in table mappings +GenerateAssociations = true; +// Enables generation of back side of association. Applies to both table mapping members and extension +// associations +GenerateBackReferences = true; +// Enables generation of associations as extension methods for related table mapping classes +GenerateAssociationExtensions = false; +// Defines method to generate name for "one" side of association +Func<ForeignKey, string> GetAssociationExtensionSinglularName + = GetAssociationExtensionSinglularNameDefault; +// Defines method to generate name for "many" side of association +Func<ForeignKey, string> GetAssociationExtensionPluralName + = GetAssociationExtensionPluralNameDefault; + +/* Procedures and functions configuration */ +// Enables use of existing table mappings for procedures and functions that return same results as +// defined by mapping +ReplaceSimilarTables = true; +// If enabled, procedure schema load error will be generated as #error directive and fail build +// of output file. Useful for initial generation to highlight places, that require review or +// additional hints for schema loader +// Also check GetSchemaOptions.LoadProcedure option above +GenerateProcedureErrors = true; +// If enabled, methods for procedures that return table will be generated with List<T> return type and +// IMPORTANT: this will lead to load of all procedure results into list and could lead +// to performance issues on big results +GenerateProcedureResultAsList = false; + +/* Other generated functionality */ +// Enables generation of Find(pk fields) extension methods for record selection by primary key value +GenerateFindExtensions = true; + +/* Pluralization services */ +// Enables pluralization of table mapping classes +PluralizeClassNames = false; +// Enables singularization of table mapping classes +SingularizeClassNames = true; +// Enables pluralization of ITable<> properties in data context +PluralizeDataContextPropertyNames = true; +// Enables singularization of ITable<> properties in data context +SingularizeDataContextPropertyNames = false; + +/* Naming configuration */ +// Enables normalization of of type and member names. +// Default normalization removes underscores and capitalize first letter. +// Could be overriden using ToValidName option below. +NormalizeNames = false; +// Defines logic to convert type/member name, derived from database object name, to C# identifier. +Func<string, bool, string> ToValidName = ToValidNameDefault; +// Makes C# identifier valid by removing unsupported symbols and calling ToValidName +Func<string, bool, string> ConvertToCompilable = ConvertToCompilableDefault; +``` + +## Provider specific options + +### SQL Server + +```cs +// Enables generation of extensions for Free Text Search +bool GenerateSqlServerFreeText = true; +``` + +### PostgreSQL + +```cs +// Enables generation of case-sensitive names of database objects +bool GenerateCaseSensitiveNames = false; +``` + +### Sybase + +```cs +// Enables generation of Sybase sysobjects tables +bool GenerateSybaseSystemTables = false; +``` + +## Example of generation process customization + +Use the following code to modify your model **before** you call the `GenerateModel()` method. + +```c# +// Replaces table mapping class name +GetTable("Person").TypeName = "MyName"; +// Sets base class & interface for mapping class +GetTable("Person").BaseClass = "PersonBase, IId"; + +// Replaces property name for column PersonID of Person table with ID. +GetColumn("Person", "PersonID") .MemberName = "ID"; +// Sets [Column(SkipOnUpdate=true)]. +// Same logic can be used for other column options +GetColumn("Person", "PasswordHash").SkipOnUpdate = true; +// Change column property type +GetColumn("Person", "Gender") .Type = "global::Model.Gender"; + +// Replaces association property name +GetFK("Orders", "FK_Orders_Customers").MemberName = "Customers"; +// Changes association type +GetFK("Orders", "FK_Orders_Customers").AssociationType = AssociationType.OneToMany; + +SetTable(string tableName, + string TypeName = null, + string DataContextPropertyName = null) + + .Column(string columnName, string MemberName = null, string Type = null, bool? IsNullable = null) + .FK (string fkName, string MemberName = null, AssociationType? AssociationType = null) + ; + +// Adds extra namespace to usings +Model.Usings.Add("MyNamespace"); + +// Replaces all property names for columns where name is '<TableName>' + 'ID' with 'ID'. +foreach (var t in Tables.Values) + foreach (var c in t.Columns.Values) + if (c.IsPrimaryKey && c.MemberName == t.TypeName + "ID") + c.MemberName = "ID"; +``` + +## Useful members and data structures + +```c# +Dictionary<string,Table> Tables = new Dictionary<string,Table> (); +Dictionary<string,Procedure> Procedures = new Dictionary<string,Procedure>(); + +Table GetTable (string name); +Procedure GetProcedure (string name); +Column GetColumn (string tableName, string columnName); +ForeignKey GetFK (string tableName, string fkName); +ForeignKey GetForeignKey(string tableName, string fkName); + +public class Table +{ + public string Schema; + public string TableName; + public string DataContextPropertyName; + public bool IsView; + public string Description; + public string AliasPropertyName; + public string AliasTypeName; + public string TypeName; + + public Dictionary<string,Column> Columns; + public Dictionary<string,ForeignKey> ForeignKeys; +} + +public partial class Column : Property +{ + public string ColumnName; // Column name in database + public bool IsNullable; + public bool IsIdentity; + public string ColumnType; // Type of the column in database + public DbType DbType; + public string Description; + public bool IsPrimaryKey; + public int PrimaryKeyOrder; + public bool SkipOnUpdate; + public bool SkipOnInsert; + public bool IsDuplicateOrEmpty; + public string AliasName; + public string MemberName; +} + +public enum AssociationType +{ + Auto, + OneToOne, + OneToMany, + ManyToOne, +} + +public partial class ForeignKey : Property +{ + public string KeyName; + public Table OtherTable; + public List<Column> ThisColumns; + public List<Column> OtherColumns; + public bool CanBeNull; + public ForeignKey BackReference; + public string MemberName; + public AssociationType AssociationType; +} + +public partial class Procedure : Method +{ + public string Schema; + public string ProcedureName; + public bool IsFunction; + public bool IsTableFunction; + public bool IsDefaultSchema; + + public Table ResultTable; + public Exception ResultException; + public List<Table> SimilarTables; + public List<Parameter> ProcParameters; +} + +public class Parameter +{ + public string SchemaName; + public string SchemaType; + public bool IsIn; + public bool IsOut; + public bool IsResult; + public int? Size; + public string ParameterName; + public string ParameterType; + public Type SystemType; + public string DataType; +} +``` diff --git a/src/Version/LinqToDB.Templates/T4Model.ttinclude b/src/Version/LinqToDB.Templates/T4Model.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..d164aaef9a42fd1d4ad0d5e12b738f916af133c9 --- /dev/null +++ b/src/Version/LinqToDB.Templates/T4Model.ttinclude @@ -0,0 +1,1564 @@ +<#@ assembly name="System.Core" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#+ +static Action<GeneratedTextTransformation,string> WriteComment = (tt,s) => tt.WriteLine("//{0}", s); + +Action BeforeGenerateModel = () => {}; + +bool GenerateProcedureErrors = true; + +void GenerateModel() +{ + Model.SetTree(); + + if (GenerationEnvironment.Length > 0 && GenerationEnvironment.ToString().Trim().Length == 0) + GenerationEnvironment.Length = 0; + + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + WriteComment(this, " <auto-generated>"); + WriteComment(this, " This code was generated by T4Model template for T4 (https://github.com/linq2db/linq2db)."); + WriteComment(this, " Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."); + WriteComment(this, " </auto-generated>"); + WriteComment(this, "---------------------------------------------------------------------------------------------------"); + + WriteLine(""); + WriteLine("#pragma warning disable 1591"); + WriteLine(""); + + BeforeGenerateModel(); + + Model.Render(this); + + WriteLine(""); + WriteLine("#pragma warning restore 1591"); + +} + +void Trim() +{ + var arr = new[] { '\r', '\n', ' ' }; + while (GenerationEnvironment.Length > 0 && arr.Contains(GenerationEnvironment[GenerationEnvironment.Length - 1])) + GenerationEnvironment.Length--; + + WriteLine(""); +} + +static Action<GeneratedTextTransformation,string> WriteUsing = (tt,s) => tt.WriteLine("using {0};", s); + +void RenderUsings(List<string> usings) +{ + var q = + from ns in usings.Distinct() + group ns by ns.Split('.')[0]; + + var groups = + (from ns in q where ns.Key == "System" select ns).Concat + (from ns in q where ns.Key != "System" orderby ns.Key select ns); + + foreach (var gr in groups) + { + foreach (var ns in from s in gr orderby s select s) + WriteUsing(this, ns); + + WriteLine(""); + } + + Trim(); +} + +// Base data types. +// +public interface ITree +{ + ITree Parent { get; set; } + IEnumerable<ITree> GetNodes(); + void SetTree(); +} + +ModelSource Model = new ModelSource(); + +public partial class ModelSource : ITree +{ + public int CurrentNamespace = 0; + + public List<string> Usings = new List<String> { "System" }; + public List<Namespace> Namespaces = new List<Namespace> { new Namespace() }; + + public Namespace Namespace { get { return Namespaces[CurrentNamespace]; } } + public List<TypeBase> Types { get { return Namespaces[CurrentNamespace].Types; } } + + public virtual void Render(GeneratedTextTransformation tt) + { + tt.RenderUsings(Usings); + tt.WriteLine(""); + + foreach (var nm in Namespaces) + { + nm.Render(tt); + tt.WriteLine(""); + } + + tt.Trim(); + } + + public ITree Parent { get; set; } + public IEnumerable<ITree> GetNodes() { return Namespaces; } + + public void SetTree() + { + foreach (var ch in GetNodes()) + { + ch.Parent = this; + ch.SetTree(); + } + } +} + +static Action<GeneratedTextTransformation,string> WriteBeginNamespace = (tt,s) => { tt.WriteLine("namespace {0}", s); tt.WriteLine("{"); }; +static Action<GeneratedTextTransformation> WriteEndNamespace = tt => tt.WriteLine("}"); + +public partial class Namespace : ITree +{ + public string Name; + public List<TypeBase> Types = new List<TypeBase>(); + public List<string> Usings = new List<string>(); + + public virtual void Render(GeneratedTextTransformation tt) + { + if (!string.IsNullOrEmpty(Name)) + { + WriteBeginNamespace(tt, Name); + tt.PushIndent("\t"); + } + + tt.RenderUsings(Usings); + + foreach (var t in Types) + { + t.Render(tt); + tt.WriteLine(""); + } + + tt.Trim(); + + if (!string.IsNullOrEmpty(Name)) + { + tt.PopIndent(); + WriteEndNamespace(tt); + } + } + + public ITree Parent { get; set; } + public IEnumerable<ITree> GetNodes() { return Types; } + + public void SetTree() + { + foreach (var ch in GetNodes()) + { + ch.Parent = this; + ch.SetTree(); + } + } +} + +public interface IClassMember : ITree +{ +} + +public enum AccessModifier +{ + Public, + Protected, + Internal, + Private, + Partial +} + +public abstract partial class TypeBase : IClassMember +{ + public AccessModifier AccessModifier = AccessModifier.Public; + public string Name; + public bool IsPartial = true; + public List<string> Comment = new List<string>(); + public List<Attribute> Attributes = new List<Attribute>(); + public string Conditional; + + public abstract void Render(GeneratedTextTransformation tt); + + protected virtual void BeginConditional(GeneratedTextTransformation tt) + { + if (Conditional != null) + { + tt.RemoveSpace(); + tt.WriteLine("#if " + Conditional); + tt.WriteLine(""); + } + } + + protected virtual void EndConditional(GeneratedTextTransformation tt) + { + if (Conditional != null) + { + tt.RemoveSpace(); + tt.WriteLine(""); + tt.RemoveSpace(); + tt.WriteLine("#endif"); + } + } + + public ITree Parent { get; set; } + public abstract IEnumerable<ITree> GetNodes(); + public abstract void SetTree (); +} + +static Action<GeneratedTextTransformation,Class> WriteBeginClass = (tt,cl) => +{ + tt.Write(cl.AccessModifier.ToString().ToLower() + " "); + if (cl.IsStatic) tt.Write("static "); + if (cl.IsPartial) tt.Write("partial ", cl.Name); + tt.Write("class {0}{1}", cl.Name, cl.GenericArguments.Count > 0 ? $"<{string.Join(", ", cl.GenericArguments)}>" : string.Empty); + + if (!string.IsNullOrEmpty(cl.BaseClass) || cl.Interfaces.Count > 0) + { + var arr = new[] { cl.BaseClass }.Concat(cl.Interfaces) + .Where(n => n != null) + .ToArray(); + + tt.Write(" : "); + tt.Write(string.Join(", ", arr)); + } + + tt.WriteLine(""); + tt.WriteLine("{"); +}; + +static Action<GeneratedTextTransformation> WriteEndClass = tt => tt.WriteLine("}"); + +public partial class Class : TypeBase +{ + public string BaseClass; + public List<string> GenericArguments = new List<string>(); + public bool IsStatic = false; + public List<string> Interfaces = new List<string>(); + public List<IClassMember> Members = new List<IClassMember>(); + + public Class() + { + } + + public Class(string name, params IClassMember[] members) + { + Name = name; + Members.AddRange(members); + } + + public override void Render(GeneratedTextTransformation tt) + { + BeginConditional(tt); + + foreach (var c in Comment) + tt.WriteLine("//" + c); + + if (Attributes.Count > 0) + { + var aa = Attributes.Where(a => !a.IsSeparated).ToList(); + + if (aa.Count > 0) + { + tt.Write("["); + + for (var i = 0; i < aa.Count; i++) + { + if (i > 0) SkipSpacesAndInsert(tt, ", "); + aa[i].Render(tt); + } + + tt.WriteLine("]"); + } + + aa = Attributes.Where(a => a.IsSeparated).ToList(); + + foreach (var a in aa) + { + tt.Write("["); + a.Render(tt); + tt.WriteLine("]"); + } + } + + WriteBeginClass(tt, this); + tt.PushIndent("\t"); + + foreach (var cm in Members) + { + if (cm is MemberBase) + { + var m = (MemberBase)cm; + + if (!(m is MemberGroup)) + m.BeginConditional(tt, false); + + foreach (var c in m.Comment) + WriteComment(tt, c); + + if (m.Attributes.Count > 0) + { + var q = + from a in m.Attributes + group a by a.Conditional ?? ""; + + foreach (var g in q) + { + if (g.Key.Length > 0) + { + tt.RemoveSpace(); + tt.WriteLine("#if " + g.Key); + } + + var attrs = g.ToList(); + + tt.Write("["); + + for (var i = 0; i < attrs.Count; i++) + { + if (i > 0) SkipSpacesAndInsert(tt, ", "); + attrs[i].Render(tt); + } + + tt.WriteLine("]"); + + if (g.Key.Length > 0) + { + tt.RemoveSpace(); + tt.WriteLine("#endif"); + } + } + } + + m.Render(tt, false); + if (m.InsertBlankLineAfter) + tt.WriteLine(""); + + if (!(m is MemberGroup)) + m.EndConditional(tt, false); + } + else if (cm is TypeBase) + { + var t = (TypeBase)cm; + + t.Render(tt); + tt.WriteLine(""); + } + } + + tt.Trim(); + + tt.PopIndent(); + WriteEndClass(tt); + + EndConditional(tt); + } + + public override IEnumerable<ITree> GetNodes() + { + return Members; + } + + public override void SetTree() + { + foreach (var ch in GetNodes()) + { + ch.Parent = this; + ch.SetTree(); + } + } +} + +public abstract partial class MemberBase : IClassMember +{ + public string ID; + public AccessModifier AccessModifier = AccessModifier.Public; + public string Name; + public Func<string> TypeBuilder; + public List<string> Comment = new List<string>(); + public string EndLineComment; + public List<Attribute> Attributes = new List<Attribute>(); + public bool InsertBlankLineAfter = true; + public string Conditional; + + public int AccessModifierLen; + public int ModifierLen; + public int TypeLen; + public int NameLen; + public int ParamLen; + public int BodyLen; + + public string Type + { + get { return TypeBuilder?.Invoke(); } + set { TypeBuilder = () => value; } + } + + public string BuildType() { return TypeBuilder?.Invoke(); } + + public virtual int CalcModifierLen() { return 0; } + public abstract int CalcBodyLen (); + public virtual int CalcParamLen () { return 0; } + public abstract void Render (GeneratedTextTransformation tt, bool isCompact); + + public virtual void BeginConditional(GeneratedTextTransformation tt, bool isCompact) + { + if (Conditional != null) + { + tt.RemoveSpace(); + tt.WriteLine("#if " + Conditional); + if (!isCompact) + tt.WriteLine(""); + } + } + + public virtual void EndConditional(GeneratedTextTransformation tt, bool isCompact) + { + if (Conditional != null) + { + tt.RemoveSpace(); + tt.WriteLine("#endif"); + if (!isCompact) + tt.WriteLine(""); + } + } + + public ITree Parent { get; set; } + public virtual IEnumerable<ITree> GetNodes() { return Enumerable.Empty<ITree>(); } + public virtual void SetTree () {} +} + +static Action<GeneratedTextTransformation,string> BeginRegion = (tt,s) => { tt.WriteLine("#region {0}", s); }; +static Action<GeneratedTextTransformation> EndRegion = (tt) => { tt.WriteLine("#endregion"); }; + +public partial class MemberGroup : MemberBase +{ + public string Region; + public bool IsCompact; + public bool IsPropertyGroup; + public List<IClassMember> Members = new List<IClassMember>(); + public List<string> Errors = new List<string>(); + + public override int CalcBodyLen() { return 0; } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + if (!string.IsNullOrEmpty(Region)) + { + BeginRegion(tt, Region); + tt.WriteLine(""); + } + + BeginConditional(tt, isCompact); + + if (Errors.Count > 0 && tt.GenerateProcedureErrors) + { + tt.RemoveSpace(); + WriteComment(tt, " Use 'GenerateProcedureErrors=false' to disable errors."); + foreach (var error in Errors) + { + tt.Error(error); + + foreach (var e in error.Split('\n')) + { + tt.RemoveSpace(); + tt.WriteLine("#error " + e.Trim('\r')); + } + } + + tt.WriteLine(""); + } + + if (IsCompact) + { + var allMembers = GetTreeNodes(this).OfType<MemberBase>().Where(m => !(m is MemberGroup)).ToList(); + + if (allMembers.Count > 0) + { + int max = allMembers.Max(m => m.AccessModifier.ToString().Length); + foreach (var m in allMembers) + m.AccessModifierLen = max; + + max = allMembers.Max(m => m.CalcModifierLen()); + foreach (var m in allMembers) + m.ModifierLen = max; + + max = allMembers.Max(m => (m.BuildType() ?? "").Length); + foreach (var m in allMembers) + m.TypeLen = max; + + var notHasGetter = allMembers.OfType<Property>().Any(m => m.IsAuto && !m.HasGetter); + var notHasSetter = allMembers.OfType<Property>().Any(m => m.IsAuto && !m.HasSetter); + + foreach (var p in allMembers.OfType<Property>()) + { + if (notHasGetter) p.GetterLen = 13; + if (notHasSetter) p.SetterLen = 13; + } + + max = allMembers.Max(m => m.Name.Length); + foreach (var m in allMembers) + m.NameLen = max; + + max = allMembers.Max(m => m.CalcParamLen()); + foreach (var m in allMembers) + m.ParamLen = max; + + max = allMembers.Max(m => m.CalcBodyLen()); + foreach (var m in allMembers) + m.BodyLen = max; + + var members = + ( + from m in allMembers + select new + { + m, + attrs = + ( + from a in m.Attributes + group a by a.Name into gr + select gr.Select((a,i) => new { a, name = a.Name + "." + i }).ToList() into s + from a in s + select a + ).ToList() + } + ).ToList(); + + var attrWeight = + ( + from m in members + from a in m.attrs + group a by a.name into gr + select new { gr.Key, Count = gr.Count() } + ).ToDictionary(a => a.Key, a => a.Count); + + var q = + from m in members + where m.attrs.Count > 0 + select new { m, w = m.attrs.Sum(aa => attrWeight[aa.name]) } into m + orderby m.w descending + select m.m; + + var attrs = new List<string>(); + + foreach (var m in q) + { + var list = m.attrs.Select(a => a.name).ToList(); + + if (attrs.Count == 0) + attrs.AddRange(list); + else + { + for (var i = 0; i < list.Count; i++) + { + var nm = list[i]; + + if (!attrs.Contains(nm)) + { + for (var j = i + 1; j < list.Count; j++) + { + var idx = attrs.IndexOf(list[j]); + + if (idx >= 0) + { + attrs.Insert(idx, nm); + break; + } + } + } + + if (!attrs.Contains(nm)) + attrs.Add(nm); + } + } + } + + var mms = members.Select(m => + { + var arr = new Attribute[attrs.Count]; + + foreach (var a in m.attrs) + arr[attrs.IndexOf(a.name)] = a.a; + + return new { m.m, attrs = arr.ToList() }; + }).ToList(); + + var idxs = Enumerable.Range(0, attrs.Count).Select(_ => new List<int>()).ToList(); + + for (var i = 0; i < mms.Count; i++) + for (var j = 0; j < mms[i].attrs.Count; j++) + if (mms[i].attrs[j] != null) + idxs[j].Add(i); + + var toRemove = new List<int>(); + + for (int i = 1; i < idxs.Count; i++) + { + for (int j = 0; j < i; j++) + { + if (idxs[j] == null) + continue; + + if (idxs[i].Intersect(idxs[j]).Count() == 0) + { + foreach (var m in mms) + { + if (m.attrs[i] != null) + { + m.attrs[j] = m.attrs[i]; + m.attrs[i] = null; + } + } + + idxs[j].AddRange(idxs[i]); + idxs[i] = null; + toRemove.Add(i); + break; + } + } + + } + + foreach (var n in toRemove.OrderByDescending(i => i)) + foreach (var m in mms) + m.attrs.RemoveAt(n); + + var lens = new int[attrs.Count - toRemove.Count]; + + foreach (var m in mms) + { + for (var i = 0; i < m.attrs.Count; i++) + { + var a = m.attrs[i]; + + if (a != null) + { + var len = a.Name.Length; + + if (a.Parameters.Count >= 0) + len += a.Parameters.Sum(p => 2 + p.Length); + + lens[i] = Math.Max(lens[i], len); + } + } + } + + foreach (var m in allMembers) + { + if (!(m is MemberGroup)) + m.BeginConditional(tt, IsCompact); + + foreach (var c in m.Comment) + WriteComment(tt, c); + + if (attrs.Count > 0) + { + var ma = mms.First(mr => mr.m == m); + + if (m.Attributes.Count > 0) + { + tt.Write("["); + + for (var i = 0; i < ma.attrs.Count; i++) + { + var a = ma.attrs[i]; + + if (a == null) + { + tt.WriteSpaces(lens[i]); + if (i + 1 < ma.attrs.Count) + tt.Write(" "); + } + else + { + var len = tt.GenerationEnvironment.Length; + a.Render(tt); + len = (tt.GenerationEnvironment.Length - len); + + var commaAdded = false; + + for (var j = i + 1; j < ma.attrs.Count; j++) + { + if (ma.attrs[j] != null) + { + SkipSpacesAndInsert(tt, ", "); + commaAdded = true; + break; + } + } + + if (i + 1 < ma.attrs.Count && !commaAdded) + tt.Write(" "); + + tt.WriteSpaces(lens[i] - len); + } + } + + tt.Write("] "); + } + else + { + tt.WriteSpaces(lens.Sum() + ma.attrs.Count * 2 + 1); + } + } + + m.Render(tt, true); + + if (!IsCompact) + tt.WriteLine(""); + + if (!(m is MemberGroup)) + m.EndConditional(tt, IsCompact); + } + } + } + else + { + foreach (var cm in Members) + { + if (cm is MemberBase) + { + var m = (MemberBase)cm; + + if (!(m is MemberGroup)) + m.BeginConditional(tt, IsCompact); + + foreach (var c in m.Comment) + WriteComment(tt, c); + + if (m.Attributes.Count > 0) + { + var q = + from a in m.Attributes + group a by a.Conditional ?? ""; + + foreach (var g in q) + { + if (g.Key.Length > 0) + { + tt.RemoveSpace(); + tt.WriteLine("#if " + g.Key); + } + + var attrs = g.ToList(); + + var aa = attrs.Where(a => !a.IsSeparated).ToList(); + + if (aa.Count > 0) + { + tt.Write("["); + + for (var i = 0; i < aa.Count; i++) + { + if (i > 0) tt.Write(", "); + aa[i].Render(tt); + } + + tt.WriteLine("]"); + } + + aa = attrs.Where(a => a.IsSeparated).ToList(); + + foreach (var a in aa) + { + tt.Write("["); + a.Render(tt); + tt.WriteLine("]"); + } + + if (g.Key.Length > 0) + { + tt.RemoveSpace(); + tt.WriteLine("#endif"); + } + } + } + + m.Render(tt, false); + + if (m.InsertBlankLineAfter) + tt.WriteLine(""); + + if (!(m is MemberGroup)) + m.EndConditional(tt, IsCompact); + } + else if (cm is TypeBase) + { + var t = (TypeBase)cm; + + t.Render(tt); + tt.WriteLine(""); + } + } + } + + tt.Trim(); + + EndConditional(tt, isCompact); + + if (!string.IsNullOrEmpty(Region)) + { + tt.WriteLine(""); + EndRegion(tt); + } + } + + public override IEnumerable<ITree> GetNodes() { return Members; } + + public override void SetTree() + { + foreach (var ch in GetNodes()) + { + ch.Parent = this; + ch.SetTree(); + } + } +} + +static Action<GeneratedTextTransformation,Field> WriteField = (tt,f) => +{ + var am = f.AccessModifier.ToString().ToLower(); + var mdf = + (f.IsStatic ? " static" : "") + + (f.IsReadonly ? " readonly" : "") ; + + tt.Write("{0}{1}{2}{3} {4}{5} {6}", + am, LenDiff(f.AccessModifierLen, am), + mdf, LenDiff(f.ModifierLen, mdf), + f.BuildType(), LenDiff(f.TypeLen, f.BuildType()), + f.Name); + + if (f.InitValue != null) + { + tt.Write(" = {0}", f.InitValue); + } + + tt.Write(";"); + + if (!string.IsNullOrEmpty(f.EndLineComment)) + { + tt.WriteSpaces(f.NameLen - f.Name.Length + f.BodyLen + f.ParamLen - 1); + tt.Write(" "); + WriteComment(tt, " " + f.EndLineComment); + } + else + tt.WriteLine(""); +}; + +public partial class Field : MemberBase +{ + public bool IsStatic; + public bool IsReadonly; + public string InitValue; + + public Field() + { + } + + public Field(Func<string> typeBuilder, string name) + { + TypeBuilder = typeBuilder; + Name = name; + } + + public override int CalcModifierLen() + { + return + (IsStatic ? " static". Length : 0) + + (IsReadonly ? " readonly".Length : 0) ; + } + + public override int CalcBodyLen() { return InitValue == null ? 1 : 4 + InitValue.Length; } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + WriteField(tt, this); + } +} + +static Action<GeneratedTextTransformation,Event> WriteEvent = (tt,m) => +{ + var am = m.AccessModifier.ToString().ToLower(); + var mdf = + (m.IsStatic ? " static" : "") + + (m.IsVirtual ? " virtual" : "") + + " event"; + + tt.Write("{0}{1}{2}{3} {4}{5} {6};", + am, LenDiff(m.AccessModifierLen, am), + mdf, LenDiff(m.ModifierLen, mdf), + m.BuildType(), LenDiff(m.TypeLen, m.BuildType()), + m.Name); + + if (!string.IsNullOrEmpty(m.EndLineComment)) + { + tt.WriteSpaces(m.NameLen - m.Name.Length + m.BodyLen + m.ParamLen - 1); + tt.Write(" "); + WriteComment(tt, " " + m.EndLineComment); + } + else + tt.WriteLine(""); +}; + +public partial class Event : MemberBase +{ + public bool IsStatic; + public bool IsVirtual; + + public Event() + { + } + + public Event(Func<string> typeBuilder, string name) + { + TypeBuilder = typeBuilder; + Name = name; + } + + public override int CalcModifierLen() + { + return + (IsStatic ? " static". Length : 0) + + (IsVirtual ? " virtual".Length : 0) + + " event".Length; + } + + public override int CalcBodyLen() { return 1; } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + WriteEvent(tt, this); + } +} + +static Action<GeneratedTextTransformation,Property,bool> WriteProperty = (tt,p,compact) => +{ + var am = p.AccessModifier.ToString().ToLower(); +// var mdf = p.IsVirtual ? " virtual" : ""; + var mdf = p.IsAbstract ? " abstract" : p.IsVirtual ? " virtual" : p.IsOverride ? " override" : p.IsStatic ? " static" : ""; + + tt.Write("{0}{1}{2}{3} {4}{5} {6}", + am, LenDiff(p.AccessModifierLen, am), + mdf, LenDiff(p.ModifierLen, mdf), + p.BuildType(), LenDiff(p.TypeLen, p.BuildType()), + p.Name); + + Action writeComment = () => + { + if (!string.IsNullOrEmpty(p.EndLineComment)) + { + tt.Write(" "); + WriteComment(tt, " " + p.EndLineComment); + } + else + tt.WriteLine(""); + }; + + if (p.IsAuto) + { + tt.Write(LenDiff(p.NameLen + p.ParamLen, p.Name)); + + var len = tt.GenerationEnvironment.Length; + + tt.Write(" { "); + + if (!p.HasGetter) + tt.Write("private "); + else if (p.GetterLen == 13) + tt.Write(" "); + tt.Write("get; "); + + if (!p.HasSetter) + tt.Write("private "); + else if (p.SetterLen == 13) + tt.Write(" "); + tt.Write("set; "); + + tt.Write("}"); + + if (!string.IsNullOrEmpty(p.EndLineComment)) + tt.WriteSpaces(p.BodyLen - (tt.GenerationEnvironment.Length - len)); + writeComment(); + } + else + { + if (compact) + { + tt.Write(LenDiff(p.NameLen + p.ParamLen, p.Name)); + + var len = tt.GenerationEnvironment.Length; + + tt.Write(" { "); + + if (p.HasGetter) + { + tt.Write("get { "); + foreach (var t in p.BuildGetBody()) + tt.Write("{0} ", t); + tt.Write("} "); + } + + if (p.HasSetter) + { + tt.Write("set { "); + foreach (var t in p.BuildSetBody()) + tt.Write("{0} ", t); + tt.Write("} "); + } + + tt.Write("}"); + + if (!string.IsNullOrEmpty(p.EndLineComment)) + tt.WriteSpaces(p.BodyLen - (tt.GenerationEnvironment.Length - len)); + writeComment(); + } + else + { + writeComment(); + + tt.WriteLine("{"); + tt.PushIndent("\t"); + + if (p.HasGetter) + { + var getBody = p.BuildGetBody().ToArray(); + if (getBody.Length == 1) + { + tt.WriteLine("get {{ {0} }}", getBody[0]); + } + else + { + tt.WriteLine("get"); + tt.WriteLine("{"); + tt.PushIndent("\t"); + + foreach (var t in getBody) + tt.WriteLine(t); + + tt.PopIndent(); + tt.WriteLine("}"); + } + } + + if (p.HasSetter) + { + var setBody = p.BuildSetBody().ToArray(); + if (setBody.Length == 1) + { + tt.WriteLine("set {{ {0} }}", setBody[0]); + } + else + { + tt.WriteLine("set"); + tt.WriteLine("{"); + tt.PushIndent("\t"); + + foreach (var t in setBody) + tt.WriteLine(t); + + tt.PopIndent(); + tt.WriteLine("}"); + } + } + + tt.PopIndent(); + tt.WriteLine("}"); + } + } +}; + +public partial class Property : MemberBase +{ + public bool IsAuto = true; + public string InitValue; + public bool IsVirtual; + public bool IsOverride; + public bool IsAbstract; + public bool IsStatic; + public bool HasGetter = true; + public bool HasSetter = true; + public List<Func<IEnumerable<string>>> GetBodyBuilders = new List<Func<IEnumerable<string>>>(); + public List<Func<IEnumerable<string>>> SetBodyBuilders = new List<Func<IEnumerable<string>>>(); + + public int GetterLen = 5; + public int SetterLen = 5; + + public Property() + { + } + + public Property(Func<string> typeBuilder, string name, Func<IEnumerable<string>> getBodyBuilder = null, Func<IEnumerable<string>> setBodyBuilder = null) + { + TypeBuilder = typeBuilder; + Name = name; + + InitBody(getBodyBuilder, setBodyBuilder); + } + + public override int CalcModifierLen() + { + return IsVirtual ? " virtual".Length : 0; + } + + public override int CalcBodyLen() + { + if (IsAuto) + return 4 + GetterLen + SetterLen; // ' { get; set; }' + + var len = " {".Length; + + if (HasGetter) + { + len += " get {".Length; + foreach (var t in BuildGetBody()) + len += 1 + t.Length; + len += " }".Length; + } + + if (HasSetter) + { + len += " set {".Length; + foreach (var t in BuildSetBody()) + len += 1 + t.Length; + len += " }".Length; + } + + len += " }".Length; + + return len; + } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + if (!IsAuto && HasGetter) + { + var getBody = BuildGetBody().ToArray(); + if (getBody.Length == 1) + { + var t = getBody[0]; + + if (!t.StartsWith("return")) + { + t = "return " + t; + + if (!t.EndsWith(";")) + t += ";"; + + GetBodyBuilders.Clear(); + GetBodyBuilders.Add(() => new [] { t }); + } + } + } + + WriteProperty(tt, this, isCompact); + } + + public Property InitBody(Func<IEnumerable<string>> getBodyBuilder = null, Func<IEnumerable<string>> setBodyBuilder = null) + { + IsAuto = getBodyBuilder == null && setBodyBuilder == null; + + if (getBodyBuilder != null) GetBodyBuilders.Add(getBodyBuilder); + if (setBodyBuilder != null) SetBodyBuilders.Add(setBodyBuilder); + + if (!IsAuto) + { + HasGetter = getBodyBuilder != null; + HasSetter = setBodyBuilder != null; + } + + return this; + } + + public Property InitGetter(Func<IEnumerable<string>> getBodyBuilder) + { + return InitBody(getBodyBuilder, null); + } + + public IEnumerable<string> BuildGetBody() + { + return GetBodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty<string>()); + } + + public IEnumerable<string> BuildSetBody() + { + return SetBodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty<string>()); + } +} + +static Action<GeneratedTextTransformation,Method,bool> WriteMethod = (tt,m,compact) => +{ + var am1 = m.AccessModifier.ToString().ToLower(); + var len1 = m.AccessModifierLen; + var am2 = ""; + var len2 = 0; + var mdf = m.IsAbstract ? " abstract" : m.IsVirtual ? " virtual" : m.IsOverride ? " override" : m.IsStatic ? " static" : ""; + var mlen = m.ModifierLen; + + if (am1 == "partial" && mdf.Length > 0) + { + am2 = " " + am1; len2 = len1 + 1; + am1 = ""; len1 = 0; + mdf = mdf.Trim(); + mlen--; + } + + tt.Write("{0}{1}{2}{3}{4}{5}{6}{7}{8} {9}{10}", + am1, LenDiff(len1, am1), + mdf, LenDiff(mlen, mdf), + am2, LenDiff(len2, am2), + m.BuildType() == null ? "" : " ", + m.BuildType(), LenDiff(m.TypeLen, m.BuildType() ?? ""), + m.Name, + m.GenericArguments.Count > 0 ? $"<{string.Join(", ", m.GenericArguments)}>" : string.Empty); + + Action writeComment = () => + { + if (!string.IsNullOrEmpty(m.EndLineComment)) + { + tt.Write(" "); + WriteComment(tt, " " + m.EndLineComment); + } + else + tt.WriteLine(""); + }; + + Action writeParams = () => + { + tt.Write("("); + + for (int i = 0; i < m.ParameterBuilders.Count; i++) + { + if (i > 0) + tt.Write(", "); + tt.Write(m.ParameterBuilders[i]()); + } + + tt.Write(")"); + }; + + if (compact) + { + tt.Write(LenDiff(m.NameLen, m.Name)); + + var len = tt.GenerationEnvironment.Length; + + writeParams(); + + foreach (var s in m.AfterSignature) + { + tt.Write(" "); + tt.Write(s); + } + + len = tt.GenerationEnvironment.Length - len; + + if (m.IsAbstract || m.AccessModifier == AccessModifier.Partial) + { + tt.Write(";"); + len = 0; + } + else + { + tt.WriteSpaces(m.ParamLen - len); + + len = tt.GenerationEnvironment.Length; + + tt.Write(" {"); + + foreach (var t in m.BuildBody()) + tt.Write(" {0}", t); + + tt.Write(" }"); + } + + if (!string.IsNullOrEmpty(m.EndLineComment)) + tt.WriteSpaces(m.BodyLen - (tt.GenerationEnvironment.Length - len)); + writeComment(); + } + else + { + writeParams (); + writeComment(); + + tt.PushIndent("\t"); + foreach (var s in m.AfterSignature) + tt.WriteLine(s); + tt.PopIndent(); + + tt.WriteLine("{"); + tt.PushIndent("\t"); + + foreach (var t in m.BuildBody()) + { + if (t.Length > 1 && t[0] == '#') + { + tt.RemoveSpace(); + } + + tt.WriteLine(t); + } + + tt.PopIndent(); + tt.WriteLine("}"); + } +}; + +public partial class Method : MemberBase +{ + public bool IsAbstract; + public bool IsVirtual; + public bool IsOverride; + public bool IsStatic; + public List<string> GenericArguments = new List<string>(); + public List<string> AfterSignature = new List<string>(); + public List<Func<string>> ParameterBuilders = new List<Func<string>>(); + public List<Func<IEnumerable<string>>> BodyBuilders = new List<Func<IEnumerable<string>>>(); + + public Method() + { + } + + public Method(Func<string> typeBuilder, string name, IEnumerable<Func<string>> parameterBuilders = null, params Func<IEnumerable<string>>[] bodyBuilders) + { + TypeBuilder = typeBuilder; + Name = name; + + if (parameterBuilders != null) ParameterBuilders.AddRange(parameterBuilders); + if (bodyBuilders != null) BodyBuilders.AddRange(bodyBuilders); + } + + public static Method Create(string type, string name, IEnumerable<string> parameters = null, IEnumerable<string> body = null) + { + return new Method( + () => type, + name, + parameters?.Select<string,Func<string>>((string p) => () => p), + body?.Select<string,Func<IEnumerable<string>>>(p => () => new[] { p }).ToArray()); + } + + public IEnumerable<string> BuildBody() + { + return BodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty<string>()); + } + + public override int CalcModifierLen() + { + return + IsAbstract ? " abstract".Length : + IsVirtual ? " virtual".Length : + IsStatic ? " static".Length : 0; + } + + public override int CalcBodyLen() + { + if (IsAbstract || AccessModifier == AccessModifier.Partial) + return 1; + + var len = " {".Length; + + foreach (var t in BuildBody()) + len += 1 + t.Length; + + len += " }".Length; + + return len; + } + + public override int CalcParamLen() + { + return ParameterBuilders.Sum(p => p().Length + 2); + } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + WriteMethod(tt, this, isCompact); + } +} + +static Action<GeneratedTextTransformation,Attribute> WriteAttribute = (tt,a) => +{ + tt.Write(a.Name); + + if (a.Parameters.Count > 0) + { + tt.Write("("); + + for (var i = 0; i < a.Parameters.Count; i++) + { + if (i > 0) + if (a.Parameters[i - 1].All(c => c == ' ')) + tt.Write(" "); + else + SkipSpacesAndInsert(tt, ", "); + tt.Write(a.Parameters[i]); + } + + SkipSpacesAndInsert(tt, ")"); + } +}; + +public partial class Attribute +{ + public string Name; + public List<string> Parameters = new List<string>(); + public string Conditional; + public bool IsSeparated; + + public Attribute() + { + } + + public Attribute(string name, params string[] ps) + { + Name = name; + Parameters.AddRange(ps); + } + + public virtual void Render(GeneratedTextTransformation tt) + { + WriteAttribute(tt, this); + } +} + +// Helpers. +// + +Func<string,string> ToPlural = s => s + "s"; +Func<string,string> ToSingular = s => s; + +static string LenDiff(int max, string str) +{ + var s = ""; + + while (max-- > str.Length) + s += " "; + + return s; +} + +public void WriteSpaces(int len) +{ + while (len-- > 0) + Write(" "); +} + +void RemoveSpace() +{ + Write(" "); + + while (GenerationEnvironment.Length > 0 && + (GenerationEnvironment[GenerationEnvironment.Length - 1] == ' ' || + GenerationEnvironment[GenerationEnvironment.Length - 1] == '\t')) + GenerationEnvironment.Length--; +} + +public static IEnumerable<ITree> GetTreeNodes(ITree parent) +{ + foreach (var node in parent.GetNodes()) + { + yield return node; + + foreach (var grandNode in GetTreeNodes(node)) + yield return grandNode; + } +} + +public static ITree FindNode(ITree parent, Func<ITree,bool> func) +{ + foreach (var node in parent.GetNodes()) + { + if (func(node)) + return node; + + var n = FindNode(node, func); + + if (n != null) + return n; + } + + return null; +} + +static void SkipSpacesAndInsert(GeneratedTextTransformation tt, string value) +{ + var l = tt.GenerationEnvironment.Length; + + for (; l > 0 && tt.GenerationEnvironment[l - 1] == ' '; l--) + { + } + + tt.GenerationEnvironment.Insert(l, value); +} + + +string ToCamelCase(string name) +{ + var n = 0; + + foreach (var c in name) + { + if (char.IsUpper(c)) + n++; + else + break; + } + + if (n == 0) + return name; + + if (n == name.Length) + return name.ToLower(); + + n = Math.Max(1, n - 1); + + return name.Substring(0, n).ToLower() + name.Substring(n); +} + +event Action<Property,string,object> SetPropertyValueAction; + +void SetPropertyValue(Property propertyObject, string propertyName, object value) +{ + if (SetPropertyValueAction != null) + SetPropertyValueAction(propertyObject, propertyName, value); +} + +static string ToStringLiteral(string value) +{ + if (value == null) + return "null"; + + var sb = new StringBuilder("\""); + + foreach (var chr in value) + { + switch (chr) + { + case '\t': sb.Append("\\t"); break; + case '\n': sb.Append("\\n"); break; + case '\r': sb.Append("\\r"); break; + case '\\': sb.Append("\\\\"); break; + case '"' : sb.Append("\\\""); break; + case '\0': sb.Append("\\0"); break; + case '\u0085': + case '\u2028': + case '\u2029': + sb.Append($"\\u{(ushort)chr:X4}"); break; + default: sb.Append(chr); break; + } + } + + sb.Append('"'); + + return sb.ToString(); +} + +#> diff --git a/src/Version/LinqToDB.Templates/Validation.ttinclude b/src/Version/LinqToDB.Templates/Validation.ttinclude new file mode 100644 index 0000000000000000000000000000000000000000..45a7e84399626f034eb6674ddff2808f2d83a61c --- /dev/null +++ b/src/Version/LinqToDB.Templates/Validation.ttinclude @@ -0,0 +1,189 @@ +<# + { + var beforeGenerateModel = BeforeGenerateModel; + BeforeGenerateModel = () => + { + beforeGenerateModel(); + ValidationImpl(); + }; + } +#> +<#+ +void ValidationImpl() +{ + foreach (Class cl in GetTreeNodes(Model).OfType<Class>()) + { + var validationGroup = new MemberGroup + { + Region = "Validation", + }; + + var props = GetTreeNodes(cl).OfType<Property>().Where(p => p.CustomValidation).ToList(); + + if (props.Count > 0) + { + if (!Model.Usings.Contains("System.Collections.Generic")) + Model.Usings.Add("System.Collections.Generic"); + + var isValid = new Method(() => "bool", "IsValid", new Func<string>[] { () => cl.Name + " obj" }) { IsStatic = true }; + var validator = new Class("CustomValidator", isValid) { IsStatic = true, }; + var partialGroup = new MemberGroup { IsCompact = true }; + + validationGroup.Members.Add(new Field(() => "int", "_isValidCounter") { Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } }); + validationGroup.Members.Add(validator); + validationGroup.Members.Add(partialGroup); + + isValid.BodyBuilders.Add(() => new [] + { + "try", + "{", + "\tobj._isValidCounter++;", + "" + }); + + var ret = "\treturn "; + + for (var idx = 0; idx < props.Count; idx++) + { + var i = idx; + var p = props[i]; + + var name = p.Name.Trim(); + var mname = "Validate" + name; + + cl.Attributes.Add( + new Attribute("CustomValidation", + "typeof(" + cl.Name + ".CustomValidator)", + ToStringLiteral(mname)) + { + IsSeparated = true + }); + + isValid.BodyBuilders.Add(() => new [] { + "\tvar flag" + i + " = ValidationResult.Success == " + mname + "(obj, obj." + name + ");" }); + + ret += (i == 0 ? "" : " || ") + "flag" + i; + + var validate = new Method(() => "ValidationResult", mname, + new Func<string>[] { () => cl.Name + " obj", () => p.BuildType().Trim() + " value" }) { IsStatic = true }; + + validate.BodyBuilders.Add(() => new [] + { + "var list = new List<ValidationResult>();", + "", + "Validator.TryValidateProperty(", + "\tvalue,", + "\tnew ValidationContext(obj, null, null) { MemberName = NameOf" + name + " }, list);", + "", + "obj." + mname + "(value, list);", + "", + "if (list.Count > 0)", + "{", + "\tforeach (var result in list)", + "\t\tforeach (var name in result.MemberNames)", + "\t\t\tobj.AddError(name, result.ErrorMessage);", + "", + "\treturn list[0];", + "}", + "", + "obj.RemoveError(NameOf" + name + ");", + "", + "return ValidationResult.Success;" + }); + + validator.Members.Add(validate); + + partialGroup.Members.Add(new Method( + () => "void", + mname, + new Func<string>[] + { + () => p.BuildType().Trim() + " value", + () => "List<ValidationResult> validationResults", + }) + { + AccessModifier = AccessModifier.Partial, + }); + } + + isValid.BodyBuilders.Add(() => new [] + { + "", + ret + ";", + "}", + "finally", + "{", + "\tobj._isValidCounter--;", + "}" + }); + } + + props = GetTreeNodes(cl).OfType<Property>().Where(p => p.ValidateProperty && p.HasSetter).ToList(); + + if (props.Count > 0) + { + foreach (var p in props) + { + var setBody = p.BuildSetBody().ToList(); + if (setBody.Count > 0) + setBody.Insert(0, ""); + + setBody.Insert(0, "if (_validationLockCounter == 0)"); + setBody.Insert(1, "{"); + + if (p.CustomValidation) + { + setBody.Insert(2, "\tvar validationResult = CustomValidator.Validate" + p.Name.Trim() + "(this, value);"); + setBody.Insert(3, "\tif (validationResult != ValidationResult.Success)"); + setBody.Insert(4, "\t\tthrow new ValidationException(validationResult, null, null);"); + setBody.Insert(5, "}"); + } + else + { + setBody.Insert(2, "\tValidator.ValidateProperty("); + setBody.Insert(3, "\t\tvalue,"); + setBody.Insert(4, string.Format("\t\tnew ValidationContext(this, null, null) {{ MemberName = NameOf{0} }});", p.Name.Trim())); + setBody.Insert(5, "}"); + } + + p.SetBodyBuilders.Clear(); + p.SetBodyBuilders.Add(() => setBody.ToArray()); + } + + validationGroup.Members.Add(new Field(() => "int", "_validationLockCounter") + { + AccessModifier = AccessModifier.Private, + InitValue = "0", + Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } + }); + + validationGroup.Members.Add(new Method (() => "void", "LockValidation", null, () => new[] { "_validationLockCounter++;" })); + validationGroup.Members.Add(new Method (() => "void", "UnlockValidation", null, () => new[] { "_validationLockCounter--;" })); + } + + if (validationGroup.Members.Count > 0) + { + if (!Model.Usings.Contains("System.ComponentModel.DataAnnotations")) + Model.Usings.Add("System.ComponentModel.DataAnnotations"); + + cl.Members.Add(validationGroup); + cl.SetTree(); + } + } +} + +partial class Property +{ + public bool CustomValidation; + public bool ValidateProperty; + + public bool Validate + { + set + { + CustomValidation = value; + ValidateProperty = value; + } + } +} +#> diff --git a/src/Version/NLog.config b/src/Version/NLog.config new file mode 100644 index 0000000000000000000000000000000000000000..7a0f3aa130d54048b05fae55068b588eafed2eac --- /dev/null +++ b/src/Version/NLog.config @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" ?> +<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" + autoReload="true" + throwExceptions="false" + internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> + + <!-- optional, add some variables + https://github.com/nlog/NLog/wiki/Configuration-file#variables + --> + <variable name="myvar" value="myvalue"/> + + <!-- + See https://github.com/nlog/nlog/wiki/Configuration-file + for information on customizing logging rules and outputs. + --> + <targets> + + <!-- + add your targets here + See https://github.com/nlog/NLog/wiki/Targets for possible targets. + See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers. + --> + + <!-- + Write events to a file with the date in the filename. + <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log" + layout="${longdate} ${uppercase:${level}} ${message}" /> + --> + </targets> + + <rules> + <!-- add your logging rules here --> + + <!-- + Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f" + <logger name="*" minlevel="Debug" writeTo="f" /> + --> + </rules> +</nlog> diff --git a/src/Version/NLog.xsd b/src/Version/NLog.xsd new file mode 100644 index 0000000000000000000000000000000000000000..16d888c8a12847595252b8cd0a4a220397b9584f --- /dev/null +++ b/src/Version/NLog.xsd @@ -0,0 +1,3556 @@ +<?xml version="1.0" encoding="utf-8"?> +<xs:schema id="NLog" targetNamespace="http://www.nlog-project.org/schemas/NLog.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.nlog-project.org/schemas/NLog.xsd"> + <xs:element name="nlog" type="NLogConfiguration" /> + <xs:complexType name="NLogConfiguration"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="extensions" type="NLogExtensions" /> + <xs:element name="include" type="NLogInclude" /> + <xs:element name="variable" type="NLogVariable" /> + <xs:element name="targets" type="NLogTargets" /> + <xs:element name="rules" type="NLogRules" /> + <xs:element name="time" type="TimeSource" /> + </xs:choice> + <xs:attribute name="autoReload" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Watch config file for changes and reload automatically.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogToConsole" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Print internal NLog messages to the console. Default value is: false</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogToConsoleError" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Print internal NLog messages to the console error output. Default value is: false</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogFile" type="xs:string"> + <xs:annotation> + <xs:documentation>Write internal NLog messages to the specified file.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogLevel" type="NLogLevel"> + <xs:annotation> + <xs:documentation>Log level threshold for internal log messages. Default value is: Info.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="globalThreshold" type="NLogLevel"> + <xs:annotation> + <xs:documentation>Global log level threshold for application log messages. Messages below this level won't be logged.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="throwExceptions" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Throw an exception when there is an internal error. Default value is: false. Not recommend to set to true in production!</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="throwConfigExceptions" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Throw an exception when there is a configuration error. If not set, determined by throwExceptions.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepVariablesOnReload" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogToTrace" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="internalLogIncludeTimestamp" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Write timestamps for internal NLog messages. Default value is: true.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useInvariantCulture" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="parseMessageTemplates" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Perform message template parsing and formatting of LogEvent messages (true = Always, false = Never, empty = Auto Detect). Default value is: empty.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLogTargets"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="default-wrapper" type="WrapperTargetBase" /> + <xs:element name="default-target-parameters" type="Target" /> + <xs:element name="target" type="Target" /> + <xs:element name="wrapper-target" type="WrapperTargetBase" /> + <xs:element name="compound-target" type="CompoundTargetBase" /> + </xs:choice> + <xs:attribute name="async" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes).</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLogRules"> + <xs:sequence minOccurs="0" maxOccurs="unbounded"> + <xs:element name="logger" type="NLogLoggerRule" /> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NLogExtensions"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="add" type="NLogExtensionsAdd" /> + </xs:choice> + </xs:complexType> + <xs:complexType name="NLogExtensionsAdd"> + <xs:attribute name="prefix" type="xs:string"> + <xs:annotation> + <xs:documentation>Prefix for targets/layout renderers/filters/conditions loaded from this assembly.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="assemblyFile" type="xs:string"> + <xs:annotation> + <xs:documentation>Load NLog extensions from the specified file (*.dll)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="assembly" type="xs:string"> + <xs:annotation> + <xs:documentation>Load NLog extensions from the specified assembly. Assembly name should be fully qualified.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLogLoggerRule"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="filters" type="NLogFilters" /> + </xs:choice> + <xs:attribute name="name" use="optional"> + <xs:annotation> + <xs:documentation>Name of the logger. May include wildcard characters ('*' or '?').</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="levels" type="NLogLevelList"> + <xs:annotation> + <xs:documentation>Comma separated list of levels that this rule matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="minlevel" type="NLogLevel"> + <xs:annotation> + <xs:documentation>Minimum level that this rule matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxlevel" type="NLogLevel"> + <xs:annotation> + <xs:documentation>Maximum level that this rule matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="level" type="NLogLevel"> + <xs:annotation> + <xs:documentation>Level that this rule matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="writeTo" type="NLogTargetIDList"> + <xs:annotation> + <xs:documentation>Comma separated list of target names.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="final" type="xs:boolean" default="false"> + <xs:annotation> + <xs:documentation>Ignore further rules if this one matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ruleName" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation>Rule identifier to allow rule lookup with Configuration.FindRuleByName and Configuration.RemoveRuleByName.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLogFilters"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="when" type="when" /> + <xs:element name="whenContains" type="whenContains" /> + <xs:element name="whenEqual" type="whenEqual" /> + <xs:element name="whenNotContains" type="whenNotContains" /> + <xs:element name="whenNotEqual" type="whenNotEqual" /> + <xs:element name="whenRepeated" type="whenRepeated" /> + </xs:choice> + <xs:attribute name="defaultAction" type="FilterResult"> + <xs:annotation> + <xs:documentation>Default action if none of the filters match.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:simpleType name="NLogLevel"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Off" /> + <xs:enumeration value="Trace" /> + <xs:enumeration value="Debug" /> + <xs:enumeration value="Info" /> + <xs:enumeration value="Warn" /> + <xs:enumeration value="Error" /> + <xs:enumeration value="Fatal" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="LineEndingMode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Default" /> + <xs:enumeration value="CRLF" /> + <xs:enumeration value="CR" /> + <xs:enumeration value="LF" /> + <xs:enumeration value="None" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLogLevelList"> + <xs:restriction base="xs:string"> + <xs:pattern value="(|Trace|Debug|Info|Warn|Error|Fatal)(,(Trace|Debug|Info|Warn|Error|Fatal))*" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="NLogInclude"> + <xs:attribute name="file" type="SimpleLayoutAttribute" use="required"> + <xs:annotation> + <xs:documentation>Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreErrors" type="xs:boolean" use="optional" default="false"> + <xs:annotation> + <xs:documentation>Ignore any errors in the include file.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLogVariable"> + <xs:choice minOccurs="0" maxOccurs="1"> + <xs:element name="value" minOccurs="0" maxOccurs="1" type="xs:string"> + <xs:annotation> + <xs:documentation>Variable value. Note, the 'value' attribute has precedence over this one.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + <xs:attribute name="name" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>Variable name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="value" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Variable value.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:simpleType name="NLogTargetIDList"> + <xs:restriction base="xs:string"> + <xs:pattern value="(|([a-zA-Z][a-zA-Z0-9_\-]*))(,([a-zA-Z][a-zA-Z0-9_\-]*))*" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="Target" abstract="true"></xs:complexType> + <xs:complexType name="TargetRef"> + <xs:attribute name="name" type="xs:string" use="required" /> + </xs:complexType> + <xs:complexType name="WrapperTargetBase" abstract="true"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="target" type="Target" minOccurs="1" maxOccurs="1" /> + <xs:element name="wrapper-target" type="WrapperTargetBase" minOccurs="1" maxOccurs="1" /> + <xs:element name="compound-target" type="CompoundTargetBase" minOccurs="1" maxOccurs="1" /> + <xs:element name="target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + <xs:element name="wrapper-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + <xs:element name="compound-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="CompoundTargetBase" abstract="true"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="target" type="Target" minOccurs="1" maxOccurs="unbounded" /> + <xs:element name="wrapper-target" type="WrapperTargetBase" minOccurs="1" maxOccurs="1" /> + <xs:element name="compound-target" type="CompoundTargetBase" minOccurs="1" maxOccurs="1" /> + <xs:element name="target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + <xs:element name="wrapper-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + <xs:element name="compound-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Filter" abstract="true"></xs:complexType> + <xs:complexType name="TimeSource" abstract="true"></xs:complexType> + <xs:simpleType name="SimpleLayoutAttribute"> + <xs:restriction base="xs:string"> + <xs:pattern value=".*" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="Condition"> + <xs:restriction base="xs:string"> + <xs:minLength value="1" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="AsyncWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="batchSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="forceLockingQueue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="fullBatchSizeWriteLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="overflowAction" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction" /> + <xs:element name="queueLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="timeToSleepBetweenBatches" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="batchSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of log events that should be processed in a batch by the lazy writer thread.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="forceLockingQueue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether to use the locking queue, instead of a lock-free concurrent queue The locking queue is less concurrent when many logger threads, but reduces memory allocation</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="fullBatchSizeWriteLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="overflowAction" type="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction"> + <xs:annotation> + <xs:documentation>Action to be taken when the lazy writer thread request queue count exceeds the set limit.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="queueLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>Limit on the number of requests in the lazy writer thread request queue.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="timeToSleepBetweenBatches" type="xs:integer"> + <xs:annotation> + <xs:documentation>Time in milliseconds to sleep between batches. (1 or less means trigger on new activity)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Grow" /> + <xs:enumeration value="Discard" /> + <xs:enumeration value="Block" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="AutoFlushWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="asyncFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="flushOnConditionOnly" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="asyncFlush" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Delay the flush until the LogEvent has been confirmed as written</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="condition" type="Condition"> + <xs:annotation> + <xs:documentation>Condition expression. Log events who meet this condition will cause a flush on the wrapped target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="flushOnConditionOnly" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Only flush when LogEvent matches condition. Ignore explicit-flush, config-reload-flush and shutdown-flush</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="BufferingWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="flushTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="overflowAction" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.BufferingTargetWrapperOverflowAction" /> + <xs:element name="slidingTimeout" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="bufferSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of log events to be buffered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="flushTimeout" type="xs:integer"> + <xs:annotation> + <xs:documentation>Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="overflowAction" type="NLog.Targets.Wrappers.BufferingTargetWrapperOverflowAction"> + <xs:annotation> + <xs:documentation>Action to take if the buffer overflows.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="slidingTimeout" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to use sliding timeout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.Wrappers.BufferingTargetWrapperOverflowAction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Flush" /> + <xs:enumeration value="Discard" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="Chainsaw"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" /> + <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" /> + <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" /> + <xs:element name="sslProtocols" minOccurs="0" maxOccurs="1" type="System.Security.Authentication.SslProtocols" /> + <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepAliveTimeSeconds" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.NLogViewerParameterInfo" /> + <xs:element name="ndlcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeSourceInfo" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="loggerName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="includeNLogData" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeCallSite" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="appInfo" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="ndcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>Encoding to be used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Instance of that is used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="lineEnding" type="LineEndingMode"> + <xs:annotation> + <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxMessageSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum message size in bytes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="newLine" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="address" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Network address.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepConnection" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxConnections" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="sslProtocols" type="System.Security.Authentication.SslProtocols"> + <xs:annotation> + <xs:documentation>Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxQueueSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum queue size.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepAliveTimeSeconds" type="xs:integer"> + <xs:annotation> + <xs:documentation>The number of seconds a connection will remain idle before the first keep-alive probe is sent</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ndlcItemSeparator" type="xs:string"> + <xs:annotation> + <xs:documentation>NDLC item separator.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeSourceInfo" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include source info (file name and line number) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="loggerName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Renderer for log4j:event logger-xml-attribute (Default ${logger})</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNLogData" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include NLog-specific extensions to log4j schema.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the stack.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include stack contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include dictionary contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include dictionary contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeCallSite" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include call site (class and method name) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log events</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="appInfo" type="xs:string"> + <xs:annotation> + <xs:documentation>AppInfo field. By default it's the friendly name of the current AppDomain.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ndcItemSeparator" type="xs:string"> + <xs:annotation> + <xs:documentation>NDC item separator.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.NetworkTargetConnectionsOverflowAction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="AllowNewConnnection" /> + <xs:enumeration value="DiscardMessage" /> + <xs:enumeration value="Block" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.NetworkTargetOverflowAction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Error" /> + <xs:enumeration value="Split" /> + <xs:enumeration value="Discard" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="System.Security.Authentication.SslProtocols"> + <xs:restriction base="xs:string"> + <xs:enumeration value="None" /> + <xs:enumeration value="Ssl2" /> + <xs:enumeration value="Ssl3" /> + <xs:enumeration value="Tls" /> + <xs:enumeration value="Tls11" /> + <xs:enumeration value="Tls12" /> + <xs:enumeration value="Tls13" /> + <xs:enumeration value="Default" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="NLog.Targets.NLogViewerParameterInfo"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeEmptyValue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that should be use to calculate the value for the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Viewer parameter name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEmptyValue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether an attribute with empty value should be included in the output</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="ColoredConsole"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="enableAnsiOutput" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="errorStream" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="detectOutputRedirected" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="useDefaultRowHighlightingRules" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="highlight-row" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleRowHighlightingRule" /> + <xs:element name="highlight-word" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleWordHighlightingRule" /> + <xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text to be rendered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="detectConsoleAvailable" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="enableAnsiOutput" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Enables output using ANSI Color Codes</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>The encoding for writing messages to the .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="errorStream" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="detectOutputRedirected" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to auto-check if the console has been redirected to file - Disables coloring logic when System.Console.IsOutputRedirected = true</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useDefaultRowHighlightingRules" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to use default row highlighting rules.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="autoFlush" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to auto-flush after </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.ConsoleOutputColor"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Black" /> + <xs:enumeration value="DarkBlue" /> + <xs:enumeration value="DarkGreen" /> + <xs:enumeration value="DarkCyan" /> + <xs:enumeration value="DarkRed" /> + <xs:enumeration value="DarkMagenta" /> + <xs:enumeration value="DarkYellow" /> + <xs:enumeration value="Gray" /> + <xs:enumeration value="DarkGray" /> + <xs:enumeration value="Blue" /> + <xs:enumeration value="Green" /> + <xs:enumeration value="Cyan" /> + <xs:enumeration value="Red" /> + <xs:enumeration value="Magenta" /> + <xs:enumeration value="Yellow" /> + <xs:enumeration value="White" /> + <xs:enumeration value="NoChange" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="NLog.Targets.ConsoleRowHighlightingRule"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" /> + <xs:element name="backgroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" /> + <xs:element name="foregroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" /> + </xs:choice> + <xs:attribute name="condition" type="Condition"> + <xs:annotation> + <xs:documentation>Condition that must be met in order to set the specified foreground and background color.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="backgroundColor" type="NLog.Targets.ConsoleOutputColor"> + <xs:annotation> + <xs:documentation>Background color.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="foregroundColor" type="NLog.Targets.ConsoleOutputColor"> + <xs:annotation> + <xs:documentation>Foreground color.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLog.Targets.ConsoleWordHighlightingRule"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="compileRegex" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="regex" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="text" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="wholeWords" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="backgroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" /> + <xs:element name="foregroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" /> + </xs:choice> + <xs:attribute name="compileRegex" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreCase" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore case when comparing texts.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="regex" type="xs:string"> + <xs:annotation> + <xs:documentation>Regular expression to be matched. You must specify either text or regex.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="text" type="xs:string"> + <xs:annotation> + <xs:documentation>Text to be matched. You must specify either text or regex.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="wholeWords" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to match whole words only.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="backgroundColor" type="NLog.Targets.ConsoleOutputColor"> + <xs:annotation> + <xs:documentation>Background color.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="foregroundColor" type="NLog.Targets.ConsoleOutputColor"> + <xs:annotation> + <xs:documentation>Foreground color.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="Console"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="error" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="writeBuffer" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text to be rendered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="detectConsoleAvailable" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>The encoding for writing messages to the .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="error" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to send the log messages to the standard error instead of the standard output.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="autoFlush" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to auto-flush after </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="writeBuffer" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether to enable batch writing using char[]-buffers, instead of using </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Database"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="useTransactions" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="dbUserName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="dbProvider" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="dbPassword" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="dbDatabase" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="connectionStringName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="connectionString" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="dbHost" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="installConnectionString" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="install-command" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseCommandInfo" /> + <xs:element name="uninstall-command" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseCommandInfo" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseParameterInfo" /> + <xs:element name="commandText" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="commandType" minOccurs="0" maxOccurs="1" type="System.Data.CommandType" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useTransactions" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbUserName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbProvider" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the database provider.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbPassword" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepConnection" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to keep the database connection open between the log events.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbDatabase" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionStringName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the connection string (as specified in <connectionStrings> configuration section.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionString" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbHost" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="installConnectionString" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="commandText" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text of the SQL command to be run on each log level.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="commandType" type="System.Data.CommandType"> + <xs:annotation> + <xs:documentation>Type of the SQL command to be run on each log level.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="System.Data.CommandType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Text" /> + <xs:enumeration value="StoredProcedure" /> + <xs:enumeration value="TableDirect" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="NLog.Targets.DatabaseCommandInfo"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="commandType" minOccurs="0" maxOccurs="1" type="System.Data.CommandType" /> + <xs:element name="connectionString" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="ignoreFailures" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseParameterInfo" /> + <xs:element name="text" minOccurs="0" maxOccurs="1" type="Layout" /> + </xs:choice> + <xs:attribute name="commandType" type="System.Data.CommandType"> + <xs:annotation> + <xs:documentation>Type of the command.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionString" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Connection string to run the command against. If not provided, connection string from the target is used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreFailures" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore failures.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="text" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Command text.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLog.Targets.DatabaseParameterInfo"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="dbType" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="size" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="precision" minOccurs="0" maxOccurs="1" type="xs:byte" /> + <xs:element name="scale" minOccurs="0" maxOccurs="1" type="xs:byte" /> + <xs:element name="parameterType" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="format" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="culture" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Database parameter name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that should be use to calculate the value for the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="dbType" type="xs:string"> + <xs:annotation> + <xs:documentation>Database parameter DbType.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="size" type="xs:integer"> + <xs:annotation> + <xs:documentation>Database parameter size.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="precision" type="xs:byte"> + <xs:annotation> + <xs:documentation>Database parameter precision.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="scale" type="xs:byte"> + <xs:annotation> + <xs:documentation>Database parameter scale.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="parameterType" type="xs:string"> + <xs:annotation> + <xs:documentation>Type of the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="format" type="xs:string"> + <xs:annotation> + <xs:documentation>Convert format of the database parameter value .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="culture" type="xs:string"> + <xs:annotation> + <xs:documentation>Culture used for parsing parameter string-value for type-conversion</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="Debugger"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text to be rendered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Debug"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="EventLog"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="category" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="entryType" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="eventId" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="log" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="machineName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="maxKilobytes" minOccurs="0" maxOccurs="1" type="xs:long" /> + <xs:element name="maxMessageLength" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="source" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.EventLogTargetOverflowAction" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="category" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that renders event Category.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="entryType" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Optional entry type. When not set, or when not convertible to then determined by </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="eventId" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that renders event ID.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="log" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the Event Log to write to. This can be System, Application or any user-defined name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="machineName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the machine on which Event Log service is running.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxKilobytes" type="xs:long"> + <xs:annotation> + <xs:documentation>Maximum Event log size in kilobytes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxMessageLength" type="xs:integer"> + <xs:annotation> + <xs:documentation>Message length limit to write to the Event Log.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="source" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Value to be used as the event Source.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onOverflow" type="NLog.Targets.EventLogTargetOverflowAction"> + <xs:annotation> + <xs:documentation>Action to take if the message is larger than the option.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.EventLogTargetOverflowAction"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Truncate" /> + <xs:enumeration value="Split" /> + <xs:enumeration value="Discard" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="FallbackGroup"> + <xs:complexContent> + <xs:extension base="CompoundTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="returnToFirstOnSuccess" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="returnToFirstOnSuccess" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to return to the first target after any successful write.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="File"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" /> + <xs:element name="enableArchiveFileCompression" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="archiveNumbering" minOccurs="0" maxOccurs="1" type="NLog.Targets.ArchiveNumberingMode" /> + <xs:element name="archiveFileName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="archiveFileKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" /> + <xs:element name="archiveEvery" minOccurs="0" maxOccurs="1" type="NLog.Targets.FileArchivePeriod" /> + <xs:element name="archiveAboveSize" minOccurs="0" maxOccurs="1" type="xs:long" /> + <xs:element name="maxArchiveFiles" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="writeFooterOnArchivingOnly" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxLogFilenames" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="fileNameKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" /> + <xs:element name="forceManaged" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="forceMutexConcurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="replaceFileContentsOnEachWrite" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="writeBom" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="enableFileDelete" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="fileName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="archiveDateFormat" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="archiveOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="cleanupFileName" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="createDirs" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="deleteOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="fileAttributes" minOccurs="0" maxOccurs="1" type="NLog.Targets.Win32FileAttributes" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="networkWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="openFileCacheTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="openFileCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepFileOpen" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="discardAll" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="concurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="concurrentWriteAttempts" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="concurrentWriteAttemptDelay" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="openFileFlushTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text to be rendered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>File encoding.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="lineEnding" type="LineEndingMode"> + <xs:annotation> + <xs:documentation>Line ending mode.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="enableArchiveFileCompression" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to compress archive files into the zip archive format.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveNumbering" type="NLog.Targets.ArchiveNumberingMode"> + <xs:annotation> + <xs:documentation>Way file archives are numbered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveFileName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Name of the file to be used for an archive.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveFileKind" type="NLog.Targets.FilePathKind"> + <xs:annotation> + <xs:documentation>Is the an absolute or relative path?</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveEvery" type="NLog.Targets.FileArchivePeriod"> + <xs:annotation> + <xs:documentation>Indicates whether to automatically archive log files every time the specified time passes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveAboveSize" type="xs:long"> + <xs:annotation> + <xs:documentation>Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxArchiveFiles" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum number of archive files that should be kept.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="writeFooterOnArchivingOnly" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether the footer should be written only when the file is archived.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxLogFilenames" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum number of log file names that should be stored as existing.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="fileNameKind" type="NLog.Targets.FilePathKind"> + <xs:annotation> + <xs:documentation>Is the an absolute or relative path?</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="forceManaged" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="forceMutexConcurrentWrites" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether file creation calls should be synchronized by a system global mutex.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="replaceFileContentsOnEachWrite" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to replace file contents on each write instead of appending log message at the end.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="writeBom" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to write BOM (byte order mark) in created files</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="enableFileDelete" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to enable log file(s) to be deleted.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="fileName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Name of the file to write to.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveDateFormat" type="xs:string"> + <xs:annotation> + <xs:documentation>Value specifying the date format to use when archiving files.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="archiveOldFileOnStartup" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to archive old log file on startup.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="cleanupFileName" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="createDirs" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to create directories if they do not exist.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="deleteOldFileOnStartup" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to delete old log file on startup.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="fileAttributes" type="NLog.Targets.Win32FileAttributes"> + <xs:annotation> + <xs:documentation>File attributes (Windows only).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="networkWrites" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on different network hosts.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="openFileCacheTimeout" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="openFileCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepFileOpen" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to keep log file open instead of opening and closing it on each logging event.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="discardAll" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="concurrentWrites" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on the same host.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="concurrentWriteAttempts" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of times the write is appended on the file before NLog discards the log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="concurrentWriteAttemptDelay" type="xs:integer"> + <xs:annotation> + <xs:documentation>Delay in milliseconds to wait before attempting to write to the file again.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="bufferSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Log file buffer size in bytes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="openFileFlushTimeout" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum number of seconds before open files are flushed. If this number is negative or zero the files are not flushed by timer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="autoFlush" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to automatically flush the file buffers after each log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.ArchiveNumberingMode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Sequence" /> + <xs:enumeration value="Rolling" /> + <xs:enumeration value="Date" /> + <xs:enumeration value="DateAndSequence" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.FilePathKind"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Unknown" /> + <xs:enumeration value="Relative" /> + <xs:enumeration value="Absolute" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.FileArchivePeriod"> + <xs:restriction base="xs:string"> + <xs:enumeration value="None" /> + <xs:enumeration value="Year" /> + <xs:enumeration value="Month" /> + <xs:enumeration value="Day" /> + <xs:enumeration value="Hour" /> + <xs:enumeration value="Minute" /> + <xs:enumeration value="Sunday" /> + <xs:enumeration value="Monday" /> + <xs:enumeration value="Tuesday" /> + <xs:enumeration value="Wednesday" /> + <xs:enumeration value="Thursday" /> + <xs:enumeration value="Friday" /> + <xs:enumeration value="Saturday" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.Win32FileAttributes"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ReadOnly" /> + <xs:enumeration value="Hidden" /> + <xs:enumeration value="System" /> + <xs:enumeration value="Archive" /> + <xs:enumeration value="Device" /> + <xs:enumeration value="Normal" /> + <xs:enumeration value="Temporary" /> + <xs:enumeration value="SparseFile" /> + <xs:enumeration value="ReparsePoint" /> + <xs:enumeration value="Compressed" /> + <xs:enumeration value="NotContentIndexed" /> + <xs:enumeration value="Encrypted" /> + <xs:enumeration value="WriteThrough" /> + <xs:enumeration value="NoBuffering" /> + <xs:enumeration value="DeleteOnClose" /> + <xs:enumeration value="PosixSemantics" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="FilteringWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" /> + <xs:element name="filter" minOccurs="0" maxOccurs="1" type="Filter" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="condition" type="Condition"> + <xs:annotation> + <xs:documentation>Condition expression. Log events who meet this condition will be forwarded to the wrapped target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="ImpersonatingWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="domain" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="impersonationLevel" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.SecurityImpersonationLevel" /> + <xs:element name="logOnProvider" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.LogOnProviderType" /> + <xs:element name="logOnType" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.SecurityLogOnType" /> + <xs:element name="password" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="revertToSelf" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="userName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="domain" type="xs:string"> + <xs:annotation> + <xs:documentation>Windows domain name to change context to.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="impersonationLevel" type="NLog.Targets.Wrappers.SecurityImpersonationLevel"> + <xs:annotation> + <xs:documentation>Required impersonation level.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="logOnProvider" type="NLog.Targets.Wrappers.LogOnProviderType"> + <xs:annotation> + <xs:documentation>Type of the logon provider.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="logOnType" type="NLog.Targets.Wrappers.SecurityLogOnType"> + <xs:annotation> + <xs:documentation>Logon Type.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="password" type="xs:string"> + <xs:annotation> + <xs:documentation>User account password.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="revertToSelf" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to revert to the credentials of the process instead of impersonating another user.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="userName" type="xs:string"> + <xs:annotation> + <xs:documentation>Username to change context to.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.Wrappers.SecurityImpersonationLevel"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Anonymous" /> + <xs:enumeration value="Identification" /> + <xs:enumeration value="Impersonation" /> + <xs:enumeration value="Delegation" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.Wrappers.LogOnProviderType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Default" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.Wrappers.SecurityLogOnType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Interactive" /> + <xs:enumeration value="Network" /> + <xs:enumeration value="Batch" /> + <xs:enumeration value="Service" /> + <xs:enumeration value="NetworkClearText" /> + <xs:enumeration value="NewCredentials" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="LimitingWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="interval" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="messageLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="interval" type="xs:string"> + <xs:annotation> + <xs:documentation>Interval in which messages will be written up to the number of messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="messageLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum allowed number of messages written per .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="LogReceiverService"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="endpointAddress" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="endpointConfigurationName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="useOneWayContract" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="clientId" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="includeEventProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" /> + <xs:element name="useBinaryEncoding" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="endpointAddress" type="xs:string"> + <xs:annotation> + <xs:documentation>Endpoint address.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="endpointConfigurationName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the endpoint configuration in WCF configuration file.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useOneWayContract" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="clientId" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Client ID.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEventProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include per-event properties in the payload sent to the server.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useBinaryEncoding" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to use binary message encoding.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NLog.Targets.MethodCallParameter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="parameterType" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="type" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that should be use to calculate the value for the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="parameterType" type="xs:string"> + <xs:annotation> + <xs:documentation>Type of the parameter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="type" type="xs:string"> + <xs:annotation> + <xs:documentation>Type of the parameter. Obsolete alias for </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="Mail"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="replaceNewlineWithBrTagInHtml" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="priority" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="bcc" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="cc" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="addNewLines" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="html" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="from" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="body" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="subject" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="to" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="timeout" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="smtpServer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="smtpAuthentication" minOccurs="0" maxOccurs="1" type="NLog.Targets.SmtpAuthenticationMode" /> + <xs:element name="smtpUserName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="smtpPassword" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="enableSsl" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="smtpPort" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="useSystemNetMailSettings" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="pickupDirectoryLocation" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="deliveryMethod" minOccurs="0" maxOccurs="1" type="System.Net.Mail.SmtpDeliveryMethod" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Text to be rendered.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="replaceNewlineWithBrTagInHtml" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether NewLine characters in the body should be replaced with tags.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="priority" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Priority used for sending mails.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>Encoding to be used for sending e-mail.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="bcc" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="cc" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="addNewLines" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to add new lines between log entries.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="html" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to send message as HTML instead of plain text.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="from" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Sender's email address (e.g. joe@domain.com).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="body" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Mail message body (repeated for each log message send in one mail).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="subject" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Mail subject.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="to" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="timeout" type="xs:integer"> + <xs:annotation> + <xs:documentation>Indicates the SMTP client timeout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="smtpServer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>SMTP Server to be used for sending.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="smtpAuthentication" type="NLog.Targets.SmtpAuthenticationMode"> + <xs:annotation> + <xs:documentation>SMTP Authentication mode.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="smtpUserName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="smtpPassword" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="enableSsl" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="smtpPort" type="xs:integer"> + <xs:annotation> + <xs:documentation>Port number that SMTP Server is listening on.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="useSystemNetMailSettings" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether the default Settings from System.Net.MailSettings should be used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="pickupDirectoryLocation" type="xs:string"> + <xs:annotation> + <xs:documentation>Folder where applications save mail messages to be processed by the local SMTP server.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="deliveryMethod" type="System.Net.Mail.SmtpDeliveryMethod"> + <xs:annotation> + <xs:documentation>Specifies how outgoing email messages will be handled.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.SmtpAuthenticationMode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="None" /> + <xs:enumeration value="Basic" /> + <xs:enumeration value="Ntlm" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="System.Net.Mail.SmtpDeliveryMethod"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Network" /> + <xs:enumeration value="SpecifiedPickupDirectory" /> + <xs:enumeration value="PickupDirectoryFromIis" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="Memory"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="maxLogsCount" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxLogsCount" type="xs:integer"> + <xs:annotation> + <xs:documentation>Max number of items to have in memory</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="MethodCall"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="className" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="methodName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="className" type="xs:string"> + <xs:annotation> + <xs:documentation>Class name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="methodName" type="xs:string"> + <xs:annotation> + <xs:documentation>Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Network"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" /> + <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" /> + <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" /> + <xs:element name="sslProtocols" minOccurs="0" maxOccurs="1" type="System.Security.Authentication.SslProtocols" /> + <xs:element name="keepAliveTimeSeconds" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>Encoding to be used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="lineEnding" type="LineEndingMode"> + <xs:annotation> + <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxMessageSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum message size in bytes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="newLine" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="address" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Network address.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepConnection" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxConnections" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxQueueSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum queue size.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="sslProtocols" type="System.Security.Authentication.SslProtocols"> + <xs:annotation> + <xs:documentation>Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepAliveTimeSeconds" type="xs:integer"> + <xs:annotation> + <xs:documentation>The number of seconds a connection will remain idle before the first keep-alive probe is sent</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NLogViewer"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" /> + <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" /> + <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" /> + <xs:element name="sslProtocols" minOccurs="0" maxOccurs="1" type="System.Security.Authentication.SslProtocols" /> + <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="keepAliveTimeSeconds" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.NLogViewerParameterInfo" /> + <xs:element name="ndlcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeSourceInfo" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="loggerName" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="includeNLogData" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeCallSite" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="appInfo" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="ndcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>Encoding to be used.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Instance of that is used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="lineEnding" type="LineEndingMode"> + <xs:annotation> + <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxMessageSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum message size in bytes.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="newLine" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="address" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Network address.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="connectionCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepConnection" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxConnections" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction"> + <xs:annotation> + <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="sslProtocols" type="System.Security.Authentication.SslProtocols"> + <xs:annotation> + <xs:documentation>Get or set the SSL/TLS protocols. Default no SSL/TLS is used. Currently only implemented for TCP.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxQueueSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Maximum queue size.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="keepAliveTimeSeconds" type="xs:integer"> + <xs:annotation> + <xs:documentation>The number of seconds a connection will remain idle before the first keep-alive probe is sent</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ndlcItemSeparator" type="xs:string"> + <xs:annotation> + <xs:documentation>NDLC item separator.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeSourceInfo" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include source info (file name and line number) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="loggerName" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Renderer for log4j:event logger-xml-attribute (Default ${logger})</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNLogData" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include NLog-specific extensions to log4j schema.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the stack.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include stack contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include dictionary contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include dictionary contents.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeCallSite" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include call site (class and method name) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log events</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="appInfo" type="xs:string"> + <xs:annotation> + <xs:documentation>AppInfo field. By default it's the friendly name of the current AppDomain.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ndcItemSeparator" type="xs:string"> + <xs:annotation> + <xs:documentation>NDC item separator.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Null"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="formatMessage" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="formatMessage" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to perform layout calculation.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="OutputDebugString"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="PerfCounter"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="autoCreate" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="categoryName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="counterHelp" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="counterName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="counterType" minOccurs="0" maxOccurs="1" type="System.Diagnostics.PerformanceCounterType" /> + <xs:element name="incrementValue" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="instanceName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="autoCreate" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether performance counter should be automatically created.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="categoryName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the performance counter category.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="counterHelp" type="xs:string"> + <xs:annotation> + <xs:documentation>Counter help text.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="counterName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the performance counter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="counterType" type="System.Diagnostics.PerformanceCounterType"> + <xs:annotation> + <xs:documentation>Performance counter type.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="incrementValue" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>The value by which to increment the counter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="instanceName" type="xs:string"> + <xs:annotation> + <xs:documentation>Performance counter instance name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="System.Diagnostics.PerformanceCounterType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="NumberOfItems32" /> + <xs:enumeration value="NumberOfItems64" /> + <xs:enumeration value="NumberOfItemsHEX32" /> + <xs:enumeration value="NumberOfItemsHEX64" /> + <xs:enumeration value="RateOfCountsPerSecond32" /> + <xs:enumeration value="RateOfCountsPerSecond64" /> + <xs:enumeration value="CountPerTimeInterval32" /> + <xs:enumeration value="CountPerTimeInterval64" /> + <xs:enumeration value="RawFraction" /> + <xs:enumeration value="RawBase" /> + <xs:enumeration value="AverageTimer32" /> + <xs:enumeration value="AverageBase" /> + <xs:enumeration value="AverageCount64" /> + <xs:enumeration value="SampleFraction" /> + <xs:enumeration value="SampleCounter" /> + <xs:enumeration value="SampleBase" /> + <xs:enumeration value="CounterTimer" /> + <xs:enumeration value="CounterTimerInverse" /> + <xs:enumeration value="Timer100Ns" /> + <xs:enumeration value="Timer100NsInverse" /> + <xs:enumeration value="ElapsedTime" /> + <xs:enumeration value="CounterMultiTimer" /> + <xs:enumeration value="CounterMultiTimerInverse" /> + <xs:enumeration value="CounterMultiTimer100Ns" /> + <xs:enumeration value="CounterMultiTimer100NsInverse" /> + <xs:enumeration value="CounterMultiBase" /> + <xs:enumeration value="CounterDelta32" /> + <xs:enumeration value="CounterDelta64" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="PostFilteringWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="defaultFilter" minOccurs="0" maxOccurs="1" type="Condition" /> + <xs:element name="when" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.Wrappers.FilteringRule" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="defaultFilter" type="Condition"> + <xs:annotation> + <xs:documentation>Default filter to be applied when no specific rule matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NLog.Targets.Wrappers.FilteringRule"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="exists" minOccurs="0" maxOccurs="1" type="Condition" /> + <xs:element name="filter" minOccurs="0" maxOccurs="1" type="Condition" /> + </xs:choice> + <xs:attribute name="exists" type="Condition"> + <xs:annotation> + <xs:documentation>Condition to be tested.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="filter" type="Condition"> + <xs:annotation> + <xs:documentation>Resulting filter to be applied when the condition matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="RandomizeGroup"> + <xs:complexContent> + <xs:extension base="CompoundTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="RepeatingWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="repeatCount" minOccurs="0" maxOccurs="1" type="xs:integer" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="repeatCount" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of times to repeat each log message.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="RetryingWrapper"> + <xs:complexContent> + <xs:extension base="WrapperTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="retryCount" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="retryDelayMilliseconds" minOccurs="0" maxOccurs="1" type="xs:integer" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="retryCount" type="xs:integer"> + <xs:annotation> + <xs:documentation>Number of retries that should be attempted on the wrapped target in case of a failure.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="retryDelayMilliseconds" type="xs:integer"> + <xs:annotation> + <xs:documentation>Time to wait between retries in milliseconds.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="RoundRobinGroup"> + <xs:complexContent> + <xs:extension base="CompoundTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SplitGroup"> + <xs:complexContent> + <xs:extension base="CompoundTargetBase"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Trace"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="rawWrite" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout used to format log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="rawWrite" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Always use independent of </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="WebService"> + <xs:complexContent> + <xs:extension base="Target"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeBOM" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="methodName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="namespace" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="protocol" minOccurs="0" maxOccurs="1" type="NLog.Targets.WebServiceProtocol" /> + <xs:element name="proxyAddress" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="url" minOccurs="0" maxOccurs="1" type="xs:anyURI" /> + <xs:element name="escapeDataNLogLegacy" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="escapeDataRfc3986" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="preAuthenticate" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="xmlRoot" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="xmlRootNamespace" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="header" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" /> + <xs:element name="proxyType" minOccurs="0" maxOccurs="1" type="NLog.Targets.WebServiceProxyType" /> + </xs:choice> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the target.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeBOM" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="methodName" type="xs:string"> + <xs:annotation> + <xs:documentation>Web service method name. Only used with Soap.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="namespace" type="xs:string"> + <xs:annotation> + <xs:documentation>Web service namespace. Only used with Soap.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="protocol" type="NLog.Targets.WebServiceProtocol"> + <xs:annotation> + <xs:documentation>Protocol to be used when calling web service.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="proxyAddress" type="xs:string"> + <xs:annotation> + <xs:documentation>Custom proxy address, include port separated by a colon</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encoding" type="xs:string"> + <xs:annotation> + <xs:documentation>Encoding.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="url" type="xs:anyURI"> + <xs:annotation> + <xs:documentation>Web service URL.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="escapeDataNLogLegacy" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Value whether escaping be done according to the old NLog style (Very non-standard)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="escapeDataRfc3986" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="preAuthenticate" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in parameters)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="xmlRoot" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see and ).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="xmlRootNamespace" type="xs:string"> + <xs:annotation> + <xs:documentation>(optional) root namespace of the XML document, if POST of XML document chosen. (see and ).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="proxyType" type="NLog.Targets.WebServiceProxyType"> + <xs:annotation> + <xs:documentation>Proxy configuration when calling web service</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Targets.WebServiceProtocol"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Soap11" /> + <xs:enumeration value="Soap12" /> + <xs:enumeration value="HttpPost" /> + <xs:enumeration value="HttpGet" /> + <xs:enumeration value="JsonPost" /> + <xs:enumeration value="XmlPost" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Targets.WebServiceProxyType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="DefaultWebProxy" /> + <xs:enumeration value="AutoProxy" /> + <xs:enumeration value="NoProxy" /> + <xs:enumeration value="ProxyAddress" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="CompoundLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="unbounded" type="Layout" /> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded" /> + </xs:complexType> + <xs:complexType name="CsvLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="column" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.CsvColumn" /> + <xs:element name="customColumnDelimiter" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="delimiter" minOccurs="0" maxOccurs="1" type="NLog.Layouts.CsvColumnDelimiterMode" /> + <xs:element name="quoteChar" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="quoting" minOccurs="0" maxOccurs="1" type="NLog.Layouts.CsvQuotingMode" /> + <xs:element name="withHeader" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer layout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header layout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Body layout (can be repeated multiple times).</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="customColumnDelimiter" type="xs:string"> + <xs:annotation> + <xs:documentation>Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="delimiter" type="NLog.Layouts.CsvColumnDelimiterMode"> + <xs:annotation> + <xs:documentation>Column delimiter.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="quoteChar" type="xs:string"> + <xs:annotation> + <xs:documentation>Quote Character.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="quoting" type="NLog.Layouts.CsvQuotingMode"> + <xs:annotation> + <xs:documentation>Quoting mode.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="withHeader" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether CVS should include header.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="NLog.Layouts.CsvQuotingMode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="All" /> + <xs:enumeration value="Nothing" /> + <xs:enumeration value="Auto" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NLog.Layouts.CsvColumnDelimiterMode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Auto" /> + <xs:enumeration value="Comma" /> + <xs:enumeration value="Semicolon" /> + <xs:enumeration value="Tab" /> + <xs:enumeration value="Pipe" /> + <xs:enumeration value="Space" /> + <xs:enumeration value="Custom" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="NLog.Layouts.CsvColumn"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="quoting" minOccurs="0" maxOccurs="1" type="NLog.Layouts.CsvQuotingMode" /> + </xs:choice> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout of the column.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the column.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="quoting" type="NLog.Layouts.CsvQuotingMode"> + <xs:annotation> + <xs:documentation>Override of Quoting mode</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="JsonLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="attribute" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.JsonAttribute" /> + <xs:element name="excludeProperties" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeGdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxRecursionLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="renderEmptyObject" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="suppressSpaces" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="escapeForwardSlash" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="excludeProperties" type="xs:string"> + <xs:annotation> + <xs:documentation>List of property names to exclude when is true</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log event (as JSON)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeGdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxRecursionLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>How far should the JSON serializer follow object references before backing off</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="renderEmptyObject" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to render the empty object value {}</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="suppressSpaces" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to suppress the extra spaces in the output json</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="escapeForwardSlash" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Should forward slashes be escaped? If true, / will be converted to \/</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NLog.Layouts.JsonAttribute"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="encode" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="escapeUnicode" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeEmptyValue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="escapeForwardSlash" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that will be rendered as the attribute's value.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the attribute.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encode" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Determines whether or not this attribute will be Json encoded.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="escapeUnicode" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to escape non-ascii characters</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEmptyValue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether an attribute with empty value should be included in the output</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="escapeForwardSlash" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Should forward slashes be escaped? If true, / will be converted to \/</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="LayoutWithHeaderAndFooter"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + </xs:choice> + <xs:attribute name="footer" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Footer layout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="header" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Header layout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Body layout (can be repeated multiple times).</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="Log4JXmlEventLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeCallSite" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeNdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeSourceInfo" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.NLogViewerParameterInfo" /> + </xs:choice> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log events</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeCallSite" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include call site (class and method name) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the stack.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeNdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the stack.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeSourceInfo" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include source info (file name and line number) in the information sent over the network.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="SimpleLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="text" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="text" type="xs:string"> + <xs:annotation> + <xs:documentation>Layout text.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="XmlLayout"> + <xs:complexContent> + <xs:extension base="Layout"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="excludeProperties" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxRecursionLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="propertiesCollectionItemName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementKeyAttribute" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementValueAttribute" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="attribute" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.XmlAttribute" /> + <xs:element name="elementName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="element" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.XmlElement" /> + <xs:element name="elementValue" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="includeEmptyValue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="indentXml" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="elementEncode" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="excludeProperties" type="xs:string"> + <xs:annotation> + <xs:documentation>List of property names to exclude when is true</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log event (as XML)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxRecursionLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>How far should the XML serializer follow object references before backing off</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesCollectionItemName" type="xs:string"> + <xs:annotation> + <xs:documentation>XML element name to use for rendering IList-collections items</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementKeyAttribute" type="xs:string"> + <xs:annotation> + <xs:documentation>XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementName" type="xs:string"> + <xs:annotation> + <xs:documentation>XML element name to use when rendering properties</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementValueAttribute" type="xs:string"> + <xs:annotation> + <xs:documentation>XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="elementName" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the root XML element</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="elementValue" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Value inside the root XML element</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEmptyValue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether a ElementValue with empty value should be included in the output</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="indentXml" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Auto indent and create new lines</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="elementEncode" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Determines whether or not this attribute will be Xml encoded.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="NLog.Layouts.XmlAttribute"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="encode" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeEmptyValue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + </xs:choice> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout that will be rendered as the attribute's value.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the attribute.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="encode" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Determines whether or not this attribute will be Xml encoded.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEmptyValue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether an attribute with empty value should be included in the output</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="NLog.Layouts.XmlElement"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="encode" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="value" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="attribute" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.XmlAttribute" /> + <xs:element name="element" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.XmlElement" /> + <xs:element name="includeEmptyValue" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="indentXml" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="excludeProperties" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="maxRecursionLimit" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="propertiesCollectionItemName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementKeyAttribute" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementName" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="propertiesElementValueAttribute" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="encode" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Determines whether or not this attribute will be Xml encoded.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string"> + <xs:annotation> + <xs:documentation>Name of the element</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="value" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Value inside the element</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeEmptyValue" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Whether a ElementValue with empty value should be included in the output</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="indentXml" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Auto indent and create new lines</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="excludeProperties" type="xs:string"> + <xs:annotation> + <xs:documentation>List of property names to exclude when is true</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeAllProperties" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Option to include all properties from the log event (as XML)</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeMdlc" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to include contents of the dictionary.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxRecursionLimit" type="xs:integer"> + <xs:annotation> + <xs:documentation>How far should the XML serializer follow object references before backing off</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesCollectionItemName" type="xs:string"> + <xs:annotation> + <xs:documentation>XML element name to use for rendering IList-collections items</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementKeyAttribute" type="xs:string"> + <xs:annotation> + <xs:documentation>XML attribute name to use when rendering property-key When null (or empty) then key-attribute is not included</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementName" type="xs:string"> + <xs:annotation> + <xs:documentation>XML element name to use when rendering properties</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="propertiesElementValueAttribute" type="xs:string"> + <xs:annotation> + <xs:documentation>XML attribute name to use when rendering property-value When null (or empty) then value-attribute is not included and value is formatted as XML-element-value</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name="when"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="condition" type="Condition"> + <xs:annotation> + <xs:documentation>Condition expression.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:simpleType name="FilterResult"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Neutral" /> + <xs:enumeration value="Log" /> + <xs:enumeration value="Ignore" /> + <xs:enumeration value="LogFinal" /> + <xs:enumeration value="IgnoreFinal" /> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="whenContains"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="substring" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreCase" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout to be used to filter log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="substring" type="xs:string"> + <xs:annotation> + <xs:documentation>Substring to be matched.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="whenEqual"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="compareTo" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="compareTo" type="xs:string"> + <xs:annotation> + <xs:documentation>String to compare the layout to.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreCase" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout to be used to filter log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="whenNotContains"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="substring" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreCase" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout to be used to filter log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="substring" type="xs:string"> + <xs:annotation> + <xs:documentation>Substring to be matched.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="whenNotEqual"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="compareTo" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="compareTo" type="xs:string"> + <xs:annotation> + <xs:documentation>String to compare the layout to.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="ignoreCase" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout to be used to filter log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="whenRepeated"> + <xs:complexContent> + <xs:extension base="Filter"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" /> + <xs:element name="defaultFilterCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="includeFirst" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" /> + <xs:element name="maxFilterCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="maxLength" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="timeoutSeconds" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="optimizeBufferDefaultLength" minOccurs="0" maxOccurs="1" type="xs:integer" /> + <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" /> + <xs:element name="filterCountMessageAppendFormat" minOccurs="0" maxOccurs="1" type="xs:string" /> + <xs:element name="filterCountPropertyName" minOccurs="0" maxOccurs="1" type="xs:string" /> + </xs:choice> + <xs:attribute name="action" type="FilterResult"> + <xs:annotation> + <xs:documentation>Action to be taken when filter matches.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="defaultFilterCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Default number of unique filter values to expect, will automatically increase if needed</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="includeFirst" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Applies the configured action to the initial logevent that starts the timeout period. Used to configure that it should ignore all events until timeout.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="layout" type="SimpleLayoutAttribute"> + <xs:annotation> + <xs:documentation>Layout to be used to filter log messages.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxFilterCacheSize" type="xs:integer"> + <xs:annotation> + <xs:documentation>Max number of unique filter values to expect simultaneously</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="maxLength" type="xs:integer"> + <xs:annotation> + <xs:documentation>Max length of filter values, will truncate if above limit</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="timeoutSeconds" type="xs:integer"> + <xs:annotation> + <xs:documentation>How long before a filter expires, and logging is accepted again</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferDefaultLength" type="xs:integer"> + <xs:annotation> + <xs:documentation>Default buffer size for the internal buffers</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="optimizeBufferReuse" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Reuse internal buffers, and doesn't have to constantly allocate new buffers</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="filterCountMessageAppendFormat" type="xs:string"> + <xs:annotation> + <xs:documentation>Append FilterCount to the when an event is no longer filtered</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="filterCountPropertyName" type="xs:string"> + <xs:annotation> + <xs:documentation>Insert FilterCount value into when an event is no longer filtered</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AccurateLocal"> + <xs:complexContent> + <xs:extension base="TimeSource"> + <xs:choice minOccurs="0" maxOccurs="unbounded" /> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="AccurateUTC"> + <xs:complexContent> + <xs:extension base="TimeSource"> + <xs:choice minOccurs="0" maxOccurs="unbounded" /> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="FastLocal"> + <xs:complexContent> + <xs:extension base="TimeSource"> + <xs:choice minOccurs="0" maxOccurs="unbounded" /> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="FastUTC"> + <xs:complexContent> + <xs:extension base="TimeSource"> + <xs:choice minOccurs="0" maxOccurs="unbounded" /> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:schema> \ No newline at end of file diff --git a/src/Version/Program.cs b/src/Version/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..fd99572731651df448b1ac84e5030477dbc103b7 --- /dev/null +++ b/src/Version/Program.cs @@ -0,0 +1,15 @@ +using Coscine.ApiCommons; +using Coscine.Configuration; + +namespace Coscine.Api.Version +{ + class Program : AbstractProgram<ConsulConfiguration> + { + + static void Main(string[] args) + { + InitializeWebService<Startup>(); + } + + } +} diff --git a/src/Version/Properties/AssemblyInfo.cs b/src/Version/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000000000000000000000000000000000..1096c1aadb07e83e7ec581b1e51219b4d19548f5 --- /dev/null +++ b/src/Version/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Version")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Version")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d942046b-88d3-44aa-856b-6a7b5a7dcbb0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Version/Startup.cs b/src/Version/Startup.cs new file mode 100644 index 0000000000000000000000000000000000000000..446ae55a923f1aaa9addb3f5b6f98603e45d6abc --- /dev/null +++ b/src/Version/Startup.cs @@ -0,0 +1,12 @@ +using Coscine.ApiCommons; + +namespace Coscine.Api.Version +{ + public class Startup : AbstractDefaultStartup + { + public Startup() + { + + } + } +} diff --git a/src/Version/Version.csproj b/src/Version/Version.csproj new file mode 100644 index 0000000000000000000000000000000000000000..1a86d83d1b7de756a95f2234e743802a0a879b1f --- /dev/null +++ b/src/Version/Version.csproj @@ -0,0 +1,616 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props" Condition="Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props')" /> + <Import Project="..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props" Condition="Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props')" /> + <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" /> + <Import Project="..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.props" Condition="Exists('..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.props')" /> + <Import Project="..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props" Condition="Exists('..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props')" /> + <Import Project="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props')" /> + <Import Project="..\packages\Microsoft.AspNetCore.Razor.Design.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" Condition="Exists('..\packages\Microsoft.AspNetCore.Razor.Design.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props')" /> + <Import Project="..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props" Condition="Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" /> + <Import Project="..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props" Condition="Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" /> + <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" /> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{D942046B-88D3-44AA-856B-6A7B5A7DCBB0}</ProjectGuid> + <OutputType>Exe</OutputType> + <RootNamespace>Coscine.Api.Version</RootNamespace> + <AssemblyName>Coscine.Api.Version</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <Deterministic>true</Deterministic> + <NuGetPackageImportStamp> + </NuGetPackageImportStamp> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Aspose.Email, Version=20.10.0.0, Culture=neutral, PublicKeyToken=716fcc553a201e56, processorArchitecture=MSIL"> + <HintPath>..\packages\Aspose.Email.20.10.0\lib\net40\Aspose.Email.dll</HintPath> + </Reference> + <Reference Include="Consul, Version=0.7.2.6, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95, processorArchitecture=MSIL"> + <HintPath>..\packages\Consul.0.7.2.6\lib\net45\Consul.dll</HintPath> + </Reference> + <Reference Include="Coscine.ApiCommons, Version=1.10.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ApiCommons.1.10.0\lib\net461\Coscine.ApiCommons.dll</HintPath> + </Reference> + <Reference Include="Coscine.Configuration, Version=1.5.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Configuration.1.5.0\lib\net461\Coscine.Configuration.dll</HintPath> + </Reference> + <Reference Include="Coscine.Database, Version=1.24.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.24.0\lib\net461\Coscine.Database.dll</HintPath> + </Reference> + <Reference Include="Coscine.Database.T4, Version=1.24.0.0, Culture=neutral, PublicKeyToken=84b4c404a0696261, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.24.0\lib\net461\Coscine.Database.T4.dll</HintPath> + </Reference> + <Reference Include="Coscine.Logging, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Logging.1.2.0\lib\net461\Coscine.Logging.dll</HintPath> + </Reference> + <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath> + </Reference> + <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> + <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath> + </Reference> + <Reference Include="linq2db, Version=3.1.1.0, Culture=neutral, PublicKeyToken=e41013125f9e410a, processorArchitecture=MSIL"> + <HintPath>..\packages\linq2db.3.1.1\lib\net46\linq2db.dll</HintPath> + </Reference> + <Reference Include="LinqKit, Version=1.1.17.0, Culture=neutral, PublicKeyToken=bc217f8844052a91, processorArchitecture=MSIL"> + <HintPath>..\packages\LinqKit.1.1.17\lib\net45\LinqKit.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Antiforgery, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Antiforgery.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Antiforgery.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authentication, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authentication.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authentication.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authentication.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Core.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authentication.JwtBearer, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authentication.JwtBearer.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authorization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authorization.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authorization.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Authorization.Policy, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Authorization.Policy.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authorization.Policy.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Connections.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Connections.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Connections.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Cors, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Cors.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Cors.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Cryptography.Internal, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Cryptography.Internal.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Cryptography.Internal.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.DataProtection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.DataProtection.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.DataProtection.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.DataProtection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.DataProtection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.DataProtection.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Diagnostics, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Diagnostics.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Diagnostics.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Diagnostics.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Diagnostics.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Hosting, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Hosting.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Hosting.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Html.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Html.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Html.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Http, Version=2.2.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Http.2.2.2\lib\netstandard2.0\Microsoft.AspNetCore.Http.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Http.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Http.Extensions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Http.Extensions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Extensions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Http.Features, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Http.Features.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Features.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.HttpOverrides, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.HttpOverrides.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.HttpOverrides.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.JsonPatch, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.JsonPatch.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.JsonPatch.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Localization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Localization.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Localization.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.ApiExplorer, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.ApiExplorer.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.ApiExplorer.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Core, Version=2.2.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Core.2.2.2\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Cors, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Cors.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Cors.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.DataAnnotations, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.DataAnnotations.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.DataAnnotations.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Formatters.Json, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Formatters.Json.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Formatters.Json.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Localization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Localization.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Localization.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Razor.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\lib\net46\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.RazorPages, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.RazorPages.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.RazorPages.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.TagHelpers, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.TagHelpers.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.TagHelpers.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Mvc.ViewFeatures, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Mvc.ViewFeatures.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.ViewFeatures.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Razor.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Razor.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Razor.Language, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Razor.Language.2.2.0\lib\net46\Microsoft.AspNetCore.Razor.Language.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Razor.Runtime, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Razor.Runtime.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Razor.Runtime.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.ResponseCaching.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.ResponseCaching.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.ResponseCaching.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Routing, Version=2.2.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Routing.2.2.2\lib\netstandard2.0\Microsoft.AspNetCore.Routing.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Routing.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Routing.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Routing.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Server.Kestrel.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Server.Kestrel.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Core.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Https, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Server.Kestrel.Https.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Https.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets, Version=2.2.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.2.2.1\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.StaticFiles, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.StaticFiles.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.StaticFiles.dll</HintPath> + </Reference> + <Reference Include="Microsoft.AspNetCore.WebUtilities, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNetCore.WebUtilities.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.WebUtilities.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.CodeAnalysis.Common.3.0.0\lib\netstandard2.0\Microsoft.CodeAnalysis.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.CSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.3.0.0\lib\netstandard2.0\Microsoft.CodeAnalysis.CSharp.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.CodeAnalysis.Razor.2.2.0\lib\net46\Microsoft.CodeAnalysis.Razor.dll</HintPath> + </Reference> + <Reference Include="Microsoft.DotNet.PlatformAbstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.DotNet.PlatformAbstractions.2.1.0\lib\net45\Microsoft.DotNet.PlatformAbstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Caching.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Caching.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Caching.Memory, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Caching.Memory.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.2.4\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.EnvironmentVariables.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Configuration.FileExtensions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Configuration.FileExtensions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.FileExtensions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.DependencyInjection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.2.2.0\lib\net461\Microsoft.Extensions.DependencyInjection.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.DependencyModel, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.DependencyModel.2.1.0\lib\net451\Microsoft.Extensions.DependencyModel.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.FileProviders.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.FileProviders.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.FileProviders.Composite, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.FileProviders.Composite.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Composite.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.FileProviders.Embedded, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.FileProviders.Embedded.1.0.1\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Embedded.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.FileProviders.Physical, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.FileProviders.Physical.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Physical.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.FileSystemGlobbing, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.FileSystemGlobbing.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileSystemGlobbing.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Hosting.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Hosting.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Hosting.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Localization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Localization.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Localization.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Localization.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Localization.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Localization.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Logging, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Logging.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.ObjectPool, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.ObjectPool.2.2.0\lib\netstandard2.0\Microsoft.Extensions.ObjectPool.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Options, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.Primitives, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Extensions.WebEncoders, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Extensions.WebEncoders.2.2.0\lib\netstandard2.0\Microsoft.Extensions.WebEncoders.dll</HintPath> + </Reference> + <Reference Include="Microsoft.IdentityModel.JsonWebTokens, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.IdentityModel.JsonWebTokens.5.5.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll</HintPath> + </Reference> + <Reference Include="Microsoft.IdentityModel.Logging, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.IdentityModel.Logging.5.5.0\lib\net461\Microsoft.IdentityModel.Logging.dll</HintPath> + </Reference> + <Reference Include="Microsoft.IdentityModel.Protocols, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.IdentityModel.Protocols.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.dll</HintPath> + </Reference> + <Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath> + </Reference> + <Reference Include="Microsoft.IdentityModel.Tokens, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Net.Http.Headers, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Net.Http.Headers.2.2.0\lib\netstandard2.0\Microsoft.Net.Http.Headers.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Win32.Registry, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.Win32.Registry.4.5.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath> + </Reference> + <Reference Include="Namotion.Reflection, Version=1.0.11.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL"> + <HintPath>..\packages\Namotion.Reflection.1.0.11\lib\net45\Namotion.Reflection.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> + <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> + <HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath> + </Reference> + <Reference Include="NJsonSchema, Version=10.1.23.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL"> + <HintPath>..\packages\NJsonSchema.10.1.23\lib\net45\NJsonSchema.dll</HintPath> + </Reference> + <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> + <HintPath>..\packages\NLog.4.6.8\lib\net45\NLog.dll</HintPath> + </Reference> + <Reference Include="NLog.Extensions.Logging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> + <HintPath>..\packages\NLog.Extensions.Logging.1.6.1\lib\net461\NLog.Extensions.Logging.dll</HintPath> + </Reference> + <Reference Include="NLog.Web.AspNetCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> + <HintPath>..\packages\NLog.Web.AspNetCore.4.9.0\lib\net461\NLog.Web.AspNetCore.dll</HintPath> + </Reference> + <Reference Include="NSwag.Annotations, Version=13.6.2.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> + <HintPath>..\packages\NSwag.Annotations.13.6.2\lib\net45\NSwag.Annotations.dll</HintPath> + </Reference> + <Reference Include="NSwag.AspNetCore, Version=13.6.2.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> + <HintPath>..\packages\NSwag.AspNetCore.13.6.2\lib\net451\NSwag.AspNetCore.dll</HintPath> + </Reference> + <Reference Include="NSwag.Core, Version=13.6.2.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> + <HintPath>..\packages\NSwag.Core.13.6.2\lib\net45\NSwag.Core.dll</HintPath> + </Reference> + <Reference Include="NSwag.Generation, Version=13.6.2.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> + <HintPath>..\packages\NSwag.Generation.13.6.2\lib\net45\NSwag.Generation.dll</HintPath> + </Reference> + <Reference Include="NSwag.Generation.AspNetCore, Version=13.6.2.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL"> + <HintPath>..\packages\NSwag.Generation.AspNetCore.13.6.2\lib\net451\NSwag.Generation.AspNetCore.dll</HintPath> + </Reference> + <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> + <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath> + </Reference> + <Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath> + </Reference> + <Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath> + </Reference> + <Reference Include="System.ComponentModel.Composition" /> + <Reference Include="System.ComponentModel.DataAnnotations" /> + <Reference Include="System.Configuration" /> + <Reference Include="System.Core" /> + <Reference Include="System.Data.OracleClient" /> + <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.3.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.5.1\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath> + </Reference> + <Reference Include="System.Diagnostics.StackTrace, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Drawing" /> + <Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\System.IdentityModel.Tokens.Jwt.5.5.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll</HintPath> + </Reference> + <Reference Include="System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" /> + <Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath> + </Reference> + <Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll</HintPath> + </Reference> + <Reference Include="System.Net" /> + <Reference Include="System.Net.Http.WebRequest" /> + <Reference Include="System.Numerics" /> + <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath> + </Reference> + <Reference Include="System.Reflection.Metadata, Version=1.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll</HintPath> + </Reference> + <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath> + </Reference> + <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Runtime.Serialization" /> + <Reference Include="System.Security" /> + <Reference Include="System.Security.AccessControl, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll</HintPath> + </Reference> + <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Security.Cryptography.Cng, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.Cng.4.5.0\lib\net461\System.Security.Cryptography.Cng.dll</HintPath> + </Reference> + <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Security.Cryptography.Xml, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Cryptography.Xml.4.5.0\lib\net461\System.Security.Cryptography.Xml.dll</HintPath> + </Reference> + <Reference Include="System.Security.Permissions, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll</HintPath> + </Reference> + <Reference Include="System.Security.Principal.Windows, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Security.Principal.Windows.4.5.1\lib\net461\System.Security.Principal.Windows.dll</HintPath> + </Reference> + <Reference Include="System.ServiceModel" /> + <Reference Include="System.ServiceProcess" /> + <Reference Include="System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath> + </Reference> + <Reference Include="System.Text.Encodings.Web, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Text.Encodings.Web.4.5.0\lib\netstandard2.0\System.Text.Encodings.Web.dll</HintPath> + </Reference> + <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath> + </Reference> + <Reference Include="System.Threading.Thread, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Transactions" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + <Reference Include="System.Xml.XmlDocument, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll</HintPath> + <Private>True</Private> + <Private>True</Private> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Controllers\VersionController.cs" /> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Startup.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + <None Include="LinqToDB.Templates\DataAnnotations.ttinclude" /> + <None Include="LinqToDB.Templates\DataModel.ttinclude" /> + <None Include="LinqToDB.Templates\EditableObject.ttinclude" /> + <None Include="LinqToDB.Templates\Humanizer.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Access.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Access.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.DB2.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.DB2.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Firebird.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Firebird.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Informix.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Informix.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.MySql.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.MySql.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Oracle.Managed.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Oracle.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Oracle.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Oracle.x64.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Oracle.x86.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.PostgreSQL.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.PostgreSQL.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SapHana.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SapHana.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlCe.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlCe.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SQLite.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SQLite.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlServer.SqlTypes.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlServer.SqlTypes.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlServer.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.SqlServer.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Sybase.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Sybase.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.Tools.ttinclude" /> + <None Include="LinqToDB.Templates\LinqToDB.ttinclude" /> + <None Include="LinqToDB.Templates\MultipleFiles.ttinclude" /> + <None Include="LinqToDB.Templates\NotifyDataErrorInfo.ttinclude" /> + <None Include="LinqToDB.Templates\NotifyPropertyChanged.ttinclude" /> + <None Include="LinqToDB.Templates\ObsoleteAttributes.ttinclude" /> + <None Include="LinqToDB.Templates\PluralizationService.ttinclude" /> + <None Include="LinqToDB.Templates\README.md" /> + <None Include="LinqToDB.Templates\T4Model.ttinclude" /> + <None Include="LinqToDB.Templates\Validation.ttinclude" /> + <Content Include="NLog.config"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <None Include="NLog.xsd"> + <SubType>Designer</SubType> + </None> + <None Include="packages.config" /> + </ItemGroup> + <ItemGroup> + <Content Include="LinqToDB.Templates\CopyMe.Access.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.DB2.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.Firebird.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.Informix.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.MySql.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.Oracle.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.PostgreSQL.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.SapHana.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.SqlCe.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.SQLite.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.SqlServer.tt.txt" /> + <Content Include="LinqToDB.Templates\CopyMe.Sybase.tt.txt" /> + </ItemGroup> + <ItemGroup> + <Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" /> + <Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.props'))" /> + <Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" /> + <Error Condition="!Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props'))" /> + <Error Condition="!Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Razor.Design.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Razor.Design.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets'))" /> + <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props'))" /> + <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets'))" /> + <Error Condition="!Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props'))" /> + <Error Condition="!Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets'))" /> + </Target> + <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" /> + <Import Project="..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets')" /> + <Import Project="..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets" Condition="Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets')" /> + <Import Project="..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets" Condition="Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets')" /> +</Project> \ No newline at end of file diff --git a/src/Version/packages.config b/src/Version/packages.config new file mode 100644 index 0000000000000000000000000000000000000000..98e4db61cda19292530a244b9b3a4e032edda6c3 --- /dev/null +++ b/src/Version/packages.config @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Aspose.Email" version="20.10.0" targetFramework="net461" /> + <package id="Consul" version="0.7.2.6" targetFramework="net461" /> + <package id="Coscine.ApiCommons" version="1.10.0" targetFramework="net461" /> + <package id="Coscine.Configuration" version="1.5.0" targetFramework="net461" /> + <package id="Coscine.Database" version="1.24.0" targetFramework="net461" /> + <package id="Coscine.Logging" version="1.2.0" targetFramework="net461" /> + <package id="EntityFramework" version="6.4.4" targetFramework="net461" /> + <package id="linq2db" version="3.1.1" targetFramework="net461" /> + <package id="linq2db.SqlServer" version="2.6.4" targetFramework="net461" /> + <package id="linq2db.t4models" version="2.6.4" targetFramework="net461" /> + <package id="LinqKit" version="1.1.17" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Antiforgery" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authorization" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authorization.Policy" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Connections.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Cors" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Cryptography.Internal" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.DataProtection" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.DataProtection.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Diagnostics" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Diagnostics.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Hosting" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Html.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Http" version="2.2.2" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Http.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Http.Extensions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Http.Features" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.HttpOverrides" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.JsonPatch" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Localization" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Analyzers" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.ApiExplorer" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Core" version="2.2.2" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Cors" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.DataAnnotations" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Formatters.Json" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Localization" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Razor" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.Razor.Extensions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.RazorPages" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.TagHelpers" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Mvc.ViewFeatures" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Razor" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Razor.Design" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Razor.Language" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Razor.Runtime" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.ResponseCaching.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Routing" version="2.2.2" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Routing.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Server.Kestrel" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Server.Kestrel.Core" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Server.Kestrel.Https" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" version="2.2.1" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.StaticFiles" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.WebUtilities" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.CodeAnalysis.Analyzers" version="2.9.2" targetFramework="net461" /> + <package id="Microsoft.CodeAnalysis.Common" version="3.0.0" targetFramework="net461" /> + <package id="Microsoft.CodeAnalysis.CSharp" version="3.0.0" targetFramework="net461" /> + <package id="Microsoft.CodeAnalysis.Razor" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.CSharp" version="4.5.0" targetFramework="net461" /> + <package id="Microsoft.DiaSymReader.Native" version="1.7.0" targetFramework="net461" /> + <package id="Microsoft.DotNet.PlatformAbstractions" version="2.1.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.ApiDescription.Server" version="3.0.0" targetFramework="net461" developmentDependency="true" /> + <package id="Microsoft.Extensions.Caching.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Caching.Memory" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Configuration" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Configuration.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Configuration.Binder" version="2.2.4" targetFramework="net461" /> + <package id="Microsoft.Extensions.Configuration.EnvironmentVariables" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Configuration.FileExtensions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.DependencyInjection" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.DependencyModel" version="2.1.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.FileProviders.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.FileProviders.Composite" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.FileProviders.Embedded" version="1.0.1" targetFramework="net461" /> + <package id="Microsoft.Extensions.FileProviders.Physical" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.FileSystemGlobbing" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Hosting.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Localization" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Localization.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Logging" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Logging.Abstractions" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.ObjectPool" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Options" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.Primitives" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Extensions.WebEncoders" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net461" /> + <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.Win32.Registry" version="4.5.0" targetFramework="net461" /> + <package id="Namotion.Reflection" version="1.0.11" targetFramework="net461" /> + <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" /> + <package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net461" /> + <package id="NJsonSchema" version="10.1.23" targetFramework="net461" /> + <package id="NLog" version="4.6.8" targetFramework="net461" /> + <package id="NLog.Config" version="4.6.8" targetFramework="net461" /> + <package id="NLog.Extensions.Logging" version="1.6.1" targetFramework="net461" /> + <package id="NLog.Schema" version="4.6.8" targetFramework="net461" /> + <package id="NLog.Web.AspNetCore" version="4.9.0" targetFramework="net461" /> + <package id="NSwag.Annotations" version="13.6.2" targetFramework="net461" /> + <package id="NSwag.AspNetCore" version="13.6.2" targetFramework="net461" /> + <package id="NSwag.Core" version="13.6.2" targetFramework="net461" /> + <package id="NSwag.Generation" version="13.6.2" targetFramework="net461" /> + <package id="NSwag.Generation.AspNetCore" version="13.6.2" targetFramework="net461" /> + <package id="NUnit" version="3.12.0" targetFramework="net461" /> + <package id="System.AppContext" version="4.3.0" targetFramework="net461" /> + <package id="System.Buffers" version="4.5.0" targetFramework="net461" /> + <package id="System.Collections" version="4.3.0" targetFramework="net461" /> + <package id="System.Collections.Immutable" version="1.5.0" targetFramework="net461" /> + <package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" /> + <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" /> + <package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" /> + <package id="System.Diagnostics.StackTrace" version="4.3.0" targetFramework="net461" /> + <package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net461" /> + <package id="System.IdentityModel.Tokens.Jwt" version="5.5.0" targetFramework="net461" /> + <package id="System.IO" version="4.3.0" targetFramework="net461" /> + <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" /> + <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" /> + <package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" /> + <package id="System.Linq" version="4.3.0" targetFramework="net461" /> + <package id="System.Memory" version="4.5.2" targetFramework="net461" /> + <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" /> + <package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" /> + <package id="System.Runtime" version="4.3.1" targetFramework="net461" /> + <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" /> + <package id="System.Runtime.Extensions" version="4.3.1" targetFramework="net461" /> + <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" /> + <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" /> + <package id="System.Security.AccessControl" version="4.5.0" targetFramework="net461" /> + <package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net461" /> + <package id="System.Security.Cryptography.Cng" version="4.5.0" targetFramework="net461" /> + <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" /> + <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" /> + <package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net461" /> + <package id="System.Security.Cryptography.Xml" version="4.5.0" targetFramework="net461" /> + <package id="System.Security.Permissions" version="4.5.0" targetFramework="net461" /> + <package id="System.Security.Principal.Windows" version="4.5.1" targetFramework="net461" /> + <package id="System.Text.Encoding.CodePages" version="4.5.1" targetFramework="net461" /> + <package id="System.Text.Encodings.Web" version="4.5.0" targetFramework="net461" /> + <package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net461" /> + <package id="System.Threading.Thread" version="4.3.0" targetFramework="net461" /> + <package id="System.Xml.ReaderWriter" version="4.3.1" targetFramework="net461" /> + <package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net461" /> +</packages> \ No newline at end of file