Insights generator project (#1066)

* InsightsGenerator project template files

* Add insights projects to SLN

* Setting up siggen class (#1003)

* Setting up siggen class

* fixed the learn method

* Refactoring code
Fixed compile errors

* renamed results to result

* Basic transformation logic (#1004)

* Fix a couple bugs and add a simple test (#1007)

* Fix a couple bugs and add a simple test

* More tests and bug fix

* Nara/workflow (#1006)

* added a queue processor

* ordered  using statements

* Armemon/analytics (#1008)

* Basic transformation logic

* changed some structure of siggen

* added sum and average method, as well as select rows by input name

* add insights to results

* min, max added

Co-authored-by: Karl Burtram <karlb@microsoft.com>
Co-authored-by: Aasim Khan <aasimkhan30@gmail.com>
Co-authored-by: Arslan Memon <armemon@microsoft.com>

* Added rules engine base implementation (#1005)

* Added rules engine base implementation

* update comments

* addressing comments

* adding template text to columnheaders object

* adding template text to columnheaders object

* fixing columnheaders class

* Added test

* Added Template Parser unit test in Test project

* Deleted unnecessary files and reverted the files that were modified by mistake

Co-authored-by: Jinjing Arima <jiarima@microsoft.com>

* Insights generator message handler placeholder (#1013)

* Aasim/insights/insight methods (#1014)

* Basic transformation logic

* changed some structure of siggen

* Added top and bottom insight functions

* Added top, bottom insights
Added tests for top, bottom insights

* Armemon/insights2 (#1011)

* max and min insightsperslice, and tests

* got rid of unneccesssary function

* get indexes

Co-authored-by: Arslan Memon <armemon@microsoft.com>

* Armemon/insights2 (#1012)

* max and min insightsperslice, and tests

* got rid of unneccesssary function

* get indexes

* learn for stringinputtyype

* add learn implentation

Co-authored-by: Arslan Memon <armemon@microsoft.com>

* Added Tests
Removed duplicate methods

Co-authored-by: Karl Burtram <karlb@microsoft.com>
Co-authored-by: arslan9955 <53170027+arslan9955@users.noreply.github.com>
Co-authored-by: Arslan Memon <armemon@microsoft.com>

* Armemon/insights2 (#1016)

* Basic transformation logic

* changed some structure of siggen

* Added top and bottom insight functions

* Added top, bottom insights
Added tests for top, bottom insights

* max and min insightsperslice, and tests

* got rid of unneccesssary function

* get indexes

* learn for stringinputtyype

* add learn implentation

* add unique inputs

* fix merge error

* add to result

Co-authored-by: Karl Burtram <karlb@microsoft.com>
Co-authored-by: Aasim Khan <aasimkhan30@gmail.com>
Co-authored-by: Arslan Memon <armemon@microsoft.com>

* Added all the templates (#1015)

* Added all the templates
Added a method to find matched template

* Added a function to replace # and ## values in a template

* Added ReplaceHashesInTemplate call

* Added comments

* Updated the template txt

* Updated GetTopHeadersWithHash function to add #toplist

* Updated the logic per offline discussion with Hermineh

* Update request handler contract to take array (#1020)

* added rulesengine findmatchingtemplate (#1019)

* Add support for getting DacFx deploy options from a publish profile (#995)

* add support for getting options from a publish profile

* update comments

* set values for default options if they aren't specified in the publish profile

* addressing comments

* Updating to latest DacFx for a bug fix (#1010)

* added rulesengine findmatchingtemplate

* Update DacFx deploy and generate script with options (#998)

* update deploy and generate script to accept deployment options

* add tests

* add test with option set to true

* merge

* merge

* incorporated FindMatchedTemplate

Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com>
Co-authored-by: Udeesha Gautam <46980425+udeeshagautam@users.noreply.github.com>

* -Added logic for Insights Generator Service Handler (#1017)

* -Added logic for Insights Generator Service Handler

* Fixed some logic

* Adding workflow test

* Update transform and add tests (#1024)

* Jiarima/fix rules engine logic (#1021)

* Added all the templates
Added a method to find matched template

* Added a function to replace # and ## values in a template

* Added ReplaceHashesInTemplate call

* Added comments

* Updated the template txt

* Updated GetTopHeadersWithHash function to add #toplist

* Updated the logic per offline discussion with Hermineh

* Update with the fixes

* Updated template and foreach conditions

* Added distinct

* Updated tests according to the logic change (#1026)

* Nara/remove queing (#1023)

* loc update (#914)

* loc update

* loc updates

* Add support for getting DacFx deploy options from a publish profile (#995)

* add support for getting options from a publish profile

* update comments

* set values for default options if they aren't specified in the publish profile

* addressing comments

* Updating to latest DacFx for a bug fix (#1010)

* Update DacFx deploy and generate script with options (#998)

* update deploy and generate script to accept deployment options

* add tests

* add test with option set to true

* intermediate check in for merge, transformed not working

* intermediate check in for merge, transformed not working

* added test case

* merged

Co-authored-by: khoiph1 <khoiph@microsoft.com>
Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com>
Co-authored-by: Udeesha Gautam <46980425+udeeshagautam@users.noreply.github.com>

* Output data types from transform (#1029)

* Fix bug process input_g (#1030)

* Fixed the insight generator service (#1028)

* Jiarima/added more testings (#1031)

* Added another test
Updated ReplaceHashesInTemplate function to return string instead of Template

* Added third test

* Merged

* Reverted the workflow file to match with the one in hack/insights

* Bugs fixes to hook insights up to ADS (#1033)

* Bug fixes for hack insights (#1032)

* Fixed the minColumn index bug in Data Transformation
Fixed the template matching logic.

* Adding changes from PR

* Try to fix Workflow tests

* Readd workflow tests

* Fix template load location

Co-authored-by: Aasim Khan <aasimkhan30@gmail.com>
Co-authored-by: Nara <NaraVen@users.noreply.github.com>
Co-authored-by: arslan9955 <53170027+arslan9955@users.noreply.github.com>
Co-authored-by: Arslan Memon <armemon@microsoft.com>
Co-authored-by: gadudhbh <68879970+gadudhbh@users.noreply.github.com>
Co-authored-by: Jinjing Arima <jiarima@microsoft.com>
Co-authored-by: jiarima <68882862+jiarima@users.noreply.github.com>
Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com>
Co-authored-by: Udeesha Gautam <46980425+udeeshagautam@users.noreply.github.com>
Co-authored-by: khoiph1 <khoiph@microsoft.com>
This commit is contained in:
Karl Burtram
2020-09-03 14:15:51 -07:00
committed by GitHub
parent 9784c3eaa2
commit 5cf5b59a0d
29 changed files with 2281 additions and 12 deletions

View File

@@ -0,0 +1,26 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.InsightsGenerator
{
public class DataArray
{
public enum DataType
{
Number,
String,
DateTime
}
public string[] ColumnNames { get; set; }
public string[] TransformedColumnNames { get; set; }
public DataType[] ColumnDataType { get; set; }
public object[][] Cells { get; set; }
}
}

View File

@@ -0,0 +1,164 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
namespace Microsoft.InsightsGenerator
{
public class DataTransformer
{
private class ColumnInfo
{
public int ColumnIndex { get; set; }
public int DistinctValues { get; set; }
public DataArray.DataType DataType { get; set; }
}
public DataArray Transform(DataArray array)
{
if (array == null || array.Cells == null || array.Cells.Length == 0)
{
return array;
}
DataArray.DataType[] columnDataType;
array.TransformedColumnNames = GetColumnLabels(array , out columnDataType);
array.ColumnDataType = columnDataType;
return array;
}
private string[] GetColumnLabels(DataArray array, out DataArray.DataType[] columnDataType)
{
columnDataType = new DataArray.DataType[array.ColumnNames.Length];
int columnCount = array.Cells[0].Length;
Dictionary<DataArray.DataType, List<ColumnInfo>> columnInfo = new Dictionary<DataArray.DataType, List<ColumnInfo>>();
for (int column = 0; column < columnCount; ++column)
{
int distinctValues;
DataArray.DataType dataType = GetColumnType(array, column, out distinctValues);
columnDataType[column] = dataType;
if (!columnInfo.ContainsKey(dataType))
{
columnInfo.Add(dataType, new List<ColumnInfo>());
}
columnInfo[dataType].Add(new ColumnInfo()
{
ColumnIndex = column,
DistinctValues = distinctValues,
DataType = dataType
});
}
bool containsDateTime = columnInfo.ContainsKey(DataArray.DataType.DateTime);
string[] labels = new string[columnCount];
if (containsDateTime)
{
List<ColumnInfo> dateColumns = columnInfo[DataArray.DataType.DateTime];
for (int i = 0; i < dateColumns.Count; ++i)
{
labels[dateColumns[i].ColumnIndex] = "input_t_" + i;
}
if (columnInfo.ContainsKey(DataArray.DataType.String))
{
List<ColumnInfo> stringColumns = columnInfo[DataArray.DataType.String];
for (int i = 0; i < stringColumns.Count; ++i)
{
labels[stringColumns[i].ColumnIndex] = "slicer_" + i;
}
}
}
else
{
if (columnInfo.ContainsKey(DataArray.DataType.String))
{
int maxDistinctValue = Int32.MaxValue;
int maxColumnIndex = -1;
int maxColumnLabelIndex = 0;
List<ColumnInfo> stringColumns = columnInfo[DataArray.DataType.String];
for (int i = 0; i < stringColumns.Count; ++i)
{
if (maxDistinctValue == Int32.MaxValue || maxDistinctValue < stringColumns[i].DistinctValues)
{
maxDistinctValue = stringColumns[i].DistinctValues;
maxColumnIndex = i;
maxColumnLabelIndex = stringColumns[i].ColumnIndex;
}
}
labels[maxColumnLabelIndex] = "input_g_0";
int adjustIndex = 0;
for (int i = 0; i < stringColumns.Count; ++i)
{
if (i != maxColumnIndex)
{
labels[stringColumns[i].ColumnIndex] = "slicer_" + (i - adjustIndex);
}
else
{
++adjustIndex;
}
}
}
}
if (columnInfo.ContainsKey(DataArray.DataType.Number))
{
List<ColumnInfo> numberColumns = columnInfo[DataArray.DataType.Number];
for (int i = 0; i < numberColumns.Count; ++i)
{
labels[numberColumns[i].ColumnIndex] = "output_" + i;
}
}
return labels;
}
private DataArray.DataType GetColumnType(DataArray array, int column, out int distinctValues)
{
// count number of distinct values
HashSet<object> values = new HashSet<object>();
for (int row = 0; row < array.Cells.Length; ++row)
{
if (!values.Contains(array.Cells[row][column]))
{
values.Add(array.Cells[row][column]);
}
}
distinctValues = values.Count;
// return the provided type if available
if (array.ColumnDataType != null && array.ColumnDataType.Length > column)
{
return array.ColumnDataType[column];
}
else
{
// determine the type from the first value in array
object firstValue = array.Cells[0][column];
string firstValueString = firstValue.ToString();
long longValue;
double doubleValue;
if (long.TryParse(firstValueString, out longValue) || double.TryParse(firstValueString, out doubleValue))
{
return DataArray.DataType.Number;
}
DateTime dateValue;
if (DateTime.TryParse(firstValueString, out dateValue))
{
return DataArray.DataType.DateTime;
}
return DataArray.DataType.String;
}
}
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
<PreserveCompilationContext>true</PreserveCompilationContext>
<DebugType>portable</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="**/obj/**/*.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Templates\Templates.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,44 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
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("Microsoft InsightsGenerator")]
[assembly: AssemblyDescription("Provides Microsoft InsightsGenerator services.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("SMicrosoft InsightsGenerator")]
[assembly: AssemblyCopyright("<22> Microsoft Corporation. All rights reserved.")]
[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("5b6bd4c4-7352-4762-9ad2-578b3fbd1685")]
// 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")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("Microsoft.InsightsGenerator.UnitTests")]

View File

@@ -0,0 +1,212 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Microsoft.InsightsGenerator
{
public class RulesEngine
{
public static List<Template> Templates;
public static List<string> TopListHashHeaders = new List<string>{ "#top", "#averageSlice", "#topPerslice" , "#bottom"};
public RulesEngine()
{
Templates = GetTemplates();
}
public static ColumnHeaders TemplateParser(string templateContent)
{
ColumnHeaders ch = new ColumnHeaders();
var processedText = Regex.Replace(templateContent, @",|\\n", "");
ch.Template = templateContent;
List<string> keyvalue = processedText.Split(' ').Select(s => s.Trim()).ToList();
foreach (string s in keyvalue)
{
if (s.StartsWith("#"))
{
string headers = s.Substring(1, s.Length - 1);
if (headers.StartsWith("#"))
{
ch.DoubleHashValues.Add( "##" + headers.Substring(1, headers.Length - 1));
}
else
{
if (headers != "placeHolder")
{
ch.SingleHashValues.Add("#" + headers);
}
}
}
}
return ch;
}
/// <summary>
/// Find a matched template based on the single hash values
/// </summary>
/// <param name="singleHashHeaders"></param>
/// <returns></returns>
public static string FindMatchedTemplate(List<List<string>> singleHashHeaders, DataArray columnInfo)
{
var resultTemplate = new StringBuilder();
if (Templates == null)
{
Templates = GetTemplates();
}
var headersWithSingleHash = GetTopHeadersWithHash(singleHashHeaders);
foreach (var template in Templates)
{
var columnHeaders = TemplateParser(template.Content);
var singleHashFromTemplate = columnHeaders.SingleHashValues.Distinct();
var isMatched = true;
// all the values from template needs to be found in the input from SigGen
foreach (var hashFromTemplate in singleHashFromTemplate)
{
if (!headersWithSingleHash.Contains(hashFromTemplate.ToLower()))
{
isMatched = false;
break;
}
}
if (isMatched)
{
// Replace # and ## values in template with actual values
resultTemplate.AppendLine(ReplaceHashesInTemplate(singleHashHeaders, columnInfo, template) + "\n");
}
}
// No matched Template found
return resultTemplate.ToString();
}
private static string ReplaceHashesInTemplate(List<List<string>>singleHashList, DataArray columnInfo, Template template)
{
StringBuilder modifiedTemp = new StringBuilder(template.Content);
// Replace single hash values
foreach (var line in singleHashList)
{
// Example of a single list (line):
// "top", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue "
var headerInputs = line.ToArray();
string header = "#" + headerInputs[0];
if (TopListHashHeaders.Contains(header))
{
if(!modifiedTemp.ToString().Contains(header))
{
continue;
}
//First replace the header with the second value in the list
modifiedTemp.Replace(header, headerInputs[1]);
StringBuilder remainingStr = new StringBuilder();
for (int i = 2; i < headerInputs.Length; i++)
{
// Append all the rest of the elemet in the array separated by new line
remainingStr.AppendLine(headerInputs[i]);
}
modifiedTemp.Replace("#placeHolder", remainingStr.ToString());
}
else
{
modifiedTemp.Replace("#" + headerInputs[0], headerInputs[1]);
}
}
// Replace double hash values
var transformedColumnArray = columnInfo.TransformedColumnNames.ToArray();
var columnArray = columnInfo.ColumnNames.ToArray();
for (int p = 0; p < columnInfo.TransformedColumnNames.Length; p++)
{
modifiedTemp.Replace("##" + transformedColumnArray[p], columnArray[p]);
}
return modifiedTemp.ToString();
}
private static List<string> GetTopHeadersWithHash(List<List<string>> singleHashHeaders)
{
var topHeaderList = new List<string>();
foreach (var list in singleHashHeaders)
{
topHeaderList.Add("#" + list.First().ToLower());
}
return topHeaderList;
}
/// <summary>
/// Retrieve all the templates and template ids
/// </summary>
/// <returns>All the template & id comnbination </returns>
public static List<Template> GetTemplates()
{
var templateHolder = new List<Template>();
string assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string assemblyDirectoryPath = System.IO.Path.GetDirectoryName(assemblyPath);
string templateFilePath = Path.Combine(assemblyDirectoryPath, "Templates", "templates.txt");
using (StreamReader streamReader = new StreamReader(templateFilePath, Encoding.UTF8))
{
int temId = 0;
var wholeText = streamReader.ReadToEnd();
var templateArray = wholeText.Split(new[] { "Template " }, StringSplitOptions.None).ToList();
foreach (var line in templateArray.Where(r => r != string.Empty))
{
var parts = line.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();
temId = int.Parse(parts[0]);
templateHolder.Add(new Template(temId, parts[1]));
}
return templateHolder;
}
}
}
/// <summary>
/// Template container to hold the template id + template body combination
/// </summary>
public class Template
{
public Template(int id, string content)
{
Id = id;
Content = content;
}
public int Id { get; set; }
public string Content { get; set; }
}
public class ColumnHeaders
{
public ColumnHeaders()
{
SingleHashValues = new List<string>();
DoubleHashValues = new List<string>();
Template = null;
}
public List<string> SingleHashValues { get; set; }
public List<string> DoubleHashValues { get; set; }
public string Template { get; set; }
}
}

View File

@@ -0,0 +1,462 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Globalization;
namespace Microsoft.InsightsGenerator
{
class SignatureGenerator
{
private DataArray Table;
public SignatureGeneratorResult Result;
public SignatureGenerator(DataArray table)
{
this.Table = table;
Result = new SignatureGeneratorResult();
}
public SignatureGeneratorResult Learn()
{
var stringInputIndexes = new List<int>();
var timeInputIndexes = new List<int>();
var slicerIndexes = new List<int>();
var outputIndexes = new List<int>();
for (var i = 0; i < Table.TransformedColumnNames.Length; i++)
{
if (Table.TransformedColumnNames[i].Contains("input_g"))
{
stringInputIndexes.Add(i);
}
if (Table.TransformedColumnNames[i].Contains("input_t"))
{
timeInputIndexes.Add(i);
}
if (Table.TransformedColumnNames[i].Contains("slicer"))
{
slicerIndexes.Add(i);
}
if (Table.TransformedColumnNames[i].Contains("output"))
{
outputIndexes.Add(i);
}
}
foreach (int stringIndex in stringInputIndexes)
{
foreach (int outputIndex in outputIndexes)
{
ExecuteStringInputInsights(stringIndex, outputIndex);
foreach (int slicerIndex in slicerIndexes)
{
ExecuteStringInputSlicerInsights(stringIndex, outputIndex, slicerIndex);
}
}
}
return Result;
}
public void ExecuteStringInputInsights(int inputCol, int outputCol)
{
var n = Table.Cells.Length;
if (Table.Cells.Length >8) {
n = 3;
}
OverallAverageInsights(outputCol);
OverallBottomInsights(n, inputCol, outputCol);
OverallMaxInsights(outputCol);
OverallMinInsights(outputCol);
OverallSumInsights(outputCol);
OverallTopInsights(n, inputCol, outputCol);
UniqueInputsInsight(inputCol);
}
public void ExecuteStringInputSlicerInsights(int inputCol, int outputCol, int slicerCol)
{
var n = Table.Cells.Length;
if (Table.Cells.Length > 8)
{
n = 3;
}
if (Table.Cells.Length > 50)
{
n = 5;
}
SlicedMaxInsights(slicerCol, outputCol);
SlicedAverageInsights(slicerCol, outputCol);
SlicedBottomInsights(n, inputCol, slicerCol, outputCol);
SlicedSumInsights(slicerCol, outputCol);
SlicedPercentageInsights(slicerCol, outputCol);
SlicedSumInsights(slicerCol, outputCol);
SlicedMinInsights(slicerCol, outputCol);
SlicedTopInsights(n, inputCol, slicerCol, outputCol);
}
public void UniqueInputsInsight(int inputCol)
{
List<string> insight = new List<string>();
// Adding the insight identifier
insight.Add(SignatureGeneratorResult.uniqueInputsIdentifier);
var uniqueInputs = GetUniqueColumValues(inputCol);
insight.Add(uniqueInputs.Length.ToString());
insight.AddRange(uniqueInputs);
Result.Insights.Add(insight);
}
public void OverallTopInsights(long n, int inputColumn, int outputColumn)
{
List<string> insight = new List<string>();
// Adding the insight identifier
insight.Add(SignatureGeneratorResult.topInsightIdentifier);
insight.AddRange(GenericTop(Table.Cells, n, inputColumn, outputColumn));
Result.Insights.Add(insight);
}
public void SlicedTopInsights(long n, int inputColumn, int sliceColumn, int outputColumn)
{
List<string> insight = new List<string>();
// Adding the insight identifier
insight.Add(SignatureGeneratorResult.topSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceColumn);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceColumn, slice.ToString());
insight.AddRange(GenericTop(sliceTable, n, inputColumn, outputColumn));
}
Result.Insights.Add(insight);
}
public List<string> GenericTop(Object[][] table, long n, int inputColumn, int outputColumn)
{
List<string> insight = new List<string>();
Object[][] sortedTable = SortCellsByColumn(table, outputColumn);
double outputSum = CalculateColumnSum(sortedTable, outputColumn);
for (int i = sortedTable.Length - 1; i >= 0 && i >= sortedTable.Length - n; i--)
{
double percent = Percentage(Double.Parse(sortedTable[i][outputColumn].ToString()), outputSum);
string temp = String.Format("{0} ({1}) {2}%", sortedTable[i][inputColumn].ToString(), sortedTable[i][outputColumn].ToString(), percent);
insight.Add(temp);
}
// Adding the count of the result
insight.Insert(0, insight.Count.ToString());
return insight;
}
public void OverallBottomInsights(long n, int inputColumn, int outputColumn)
{
List<string> insight = new List<string>();
// Adding the insight identifier
insight.Add(SignatureGeneratorResult.bottomInsightIdentifier);
insight.AddRange(GenericBottom(Table.Cells, n, inputColumn, outputColumn));
Result.Insights.Add(insight);
}
public void SlicedBottomInsights(long n, int inputColumn, int sliceColumn, int outputColumn)
{
List<string> insight = new List<string>();
// Adding the insight identifier
insight.Add(SignatureGeneratorResult.bottomSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceColumn);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceColumn, slice.ToString());
insight.AddRange(GenericBottom(sliceTable, n, inputColumn, outputColumn));
}
Result.Insights.Add(insight);
}
public List<string> GenericBottom(Object[][] table, long n, int inputColumn, int outputColumn)
{
List<string> insight = new List<string>();
Object[][] sortedTable = SortCellsByColumn(table, outputColumn);
double outputSum = CalculateColumnSum(sortedTable, outputColumn);
for (int i = 0; i < n && i < sortedTable.Length; i++)
{
double percent = Percentage(Double.Parse(sortedTable[i][outputColumn].ToString()), outputSum);
string temp = String.Format("{0} ({1}) {2}%", sortedTable[i][inputColumn].ToString(), sortedTable[i][outputColumn].ToString(), percent);
insight.Add(temp);
}
// Adding the count of the result
insight.Insert(0, insight.Count.ToString());
return insight;
}
public void OverallAverageInsights(int colIndex)
{
var outputList = new List<string>();
outputList.Add(SignatureGeneratorResult.averageInsightIdentifier);
outputList.Add(CalculateColumnAverage(Table.Cells, colIndex).ToString());
Result.Insights.Add(outputList);
}
public void OverallSumInsights(int colIndex)
{
var outputList = new List<string>();
outputList.Add(SignatureGeneratorResult.sumInsightIdentifier);
outputList.Add(CalculateColumnSum(Table.Cells, colIndex).ToString());
Result.Insights.Add(outputList);
}
public void OverallMaxInsights(int colIndex)
{
var outputList = new List<string>();
outputList.Add(SignatureGeneratorResult.maxInsightIdentifier);
outputList.Add(CalculateColumnMax(Table.Cells, colIndex).ToString());
Result.Insights.Add(outputList);
}
public void OverallMinInsights(int colIndex)
{
var outputList = new List<string>();
outputList.Add(SignatureGeneratorResult.minInsightIdentifier);
outputList.Add(CalculateColumnMin(Table.Cells, colIndex).ToString());
Result.Insights.Add(outputList);
}
public void SlicedSumInsights(int sliceIndex, int colIndex)
{
var insight = new List<string>();
insight.Add(SignatureGeneratorResult.sumSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceIndex);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceIndex, slice.ToString());
insight.Add(CalculateColumnSum(sliceTable, colIndex).ToString());
}
Result.Insights.Add(insight);
}
public void SlicedMaxInsights(int sliceIndex, int colIndex)
{
var insight = new List<string>();
insight.Add(SignatureGeneratorResult.maxSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceIndex);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceIndex, slice.ToString());
insight.Add(CalculateColumnMax(sliceTable, colIndex).ToString());
}
Result.Insights.Add(insight);
}
public void SlicedMinInsights(int sliceIndex, int colIndex)
{
var insight = new List<string>();
insight.Add(SignatureGeneratorResult.minSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceIndex);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceIndex, slice.ToString());
insight.Add(CalculateColumnMin(sliceTable, colIndex).ToString());
}
Result.Insights.Add(insight);
}
public void SlicedAverageInsights(int sliceIndex, int colIndex)
{
var insight = new List<string>();
insight.Add(SignatureGeneratorResult.sumSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceIndex);
insight.Add(slices.Length.ToString());
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceIndex, slice.ToString());
insight.Add(CalculateColumnAverage(sliceTable, colIndex).ToString());
}
Result.Insights.Add(insight);
}
public void SlicedPercentageInsights(int sliceIndex, int colIndex)
{
var insight = new List<string>();
insight.Add(SignatureGeneratorResult.percentageSliceInsightIdentifier);
object[] slices = GetUniqueColumValues(sliceIndex);
insight.Add(slices.Length.ToString());
double totalSum = CalculateColumnSum(Table.Cells, colIndex);
foreach (var slice in slices)
{
insight.Add(slice.ToString());
var sliceTable = CreateSliceBucket(sliceIndex, slice.ToString());
double sliceSum = CalculateColumnSum(sliceTable, colIndex);
var percentagePerSlice = Percentage(sliceSum, totalSum);
insight.Add(percentagePerSlice.ToString());
}
Result.Insights.Add(insight);
}
private double CalculateColumnAverage(object[][] rows, int colIndex)
{
return Math.Round(CalculateColumnSum(rows, colIndex) / rows.Length, 2);
}
private double CalculateColumnSum(object[][] rows, int colIndex)
{
return Math.Round(rows.Sum(row => double.Parse(row[colIndex].ToString())), 2);
}
private double CalculateColumnPercentage(object[][] rows, int colIndex)
{
return rows.Sum(row => double.Parse(row[colIndex].ToString()));
}
private double CalculateColumnMin(object[][] rows, int colIndex)
{
return rows.Min(row => double.Parse(row[colIndex].ToString()));
}
private double CalculateColumnMax(object[][] rows, int colIndex)
{
return rows.Max(row => double.Parse(row[colIndex].ToString()));
}
private string[] GetUniqueColumValues(int colIndex)
{
return Table.Cells.Select(row => row[colIndex].ToString()).Distinct().ToArray();
}
public Object[][] CreateSliceBucket(int sliceColIndex, string sliceValue)
{
List<Object[]> slicedTable = new List<object[]>();
foreach (var row in Table.Cells)
{
if (row[sliceColIndex].Equals(sliceValue))
{
slicedTable.Add(DeepCloneRow(row));
}
}
return slicedTable.ToArray();
}
public object[][] SortCellsByColumn(Object[][] table, int colIndex)
{
var cellCopy = DeepCloneTable(table);
Comparer<Object> comparer = Comparer<Object>.Default;
switch (this.Table.ColumnDataType[colIndex])
{
case DataArray.DataType.Number:
Array.Sort<Object[]>(cellCopy, (x, y) => comparer.Compare(double.Parse(x[colIndex].ToString()), double.Parse(y[colIndex].ToString())));
break;
case DataArray.DataType.String:
Array.Sort<Object[]>(cellCopy, (x, y) => String.Compare(x[colIndex].ToString(), y[colIndex].ToString()));
break;
case DataArray.DataType.DateTime:
Array.Sort<Object[]>(cellCopy, (x, y) => DateTime.Compare(DateTime.Parse(x[colIndex].ToString()), DateTime.Parse(y[colIndex].ToString())));
break;
}
return cellCopy;
}
public Object[][] DeepCloneTable(object[][] table)
{
return table.Select(a => a.ToArray()).ToArray();
}
public Object[] DeepCloneRow(object[] row)
{
return row.Select(a => a).ToArray();
}
public double Percentage(double value, double sum)
{
return Math.Round((double)((value / sum) * 100), 2);
}
}
}
public class SignatureGeneratorResult
{
public SignatureGeneratorResult()
{
Insights = new List<List<string>>();
}
public List<List<string>> Insights { get; set; }
public static string topInsightIdentifier = "top";
public static string bottomInsightIdentifier = "bottom";
public static string topSliceInsightIdentifier = "topPerSlice";
public static string bottomSliceInsightIdentifier = "bottomPerSlice";
public static string averageInsightIdentifier = "average";
public static string sumInsightIdentifier = "sum";
public static string maxInsightIdentifier = "max";
public static string minInsightIdentifier = "min";
public static string averageSliceInsightIdentifier = "averagePerSlice";
public static string sumSliceInsightIdentifier = "sumPerSlice";
public static string percentageSliceInsightIdentifier = "percentagePerSlice";
public static string maxSliceInsightIdentifier = "maxPerSlice";
public static string minSliceInsightIdentifier = "minPerSlice";
public static string uniqueInputsIdentifier = "uniqueInputs";
}
/** Some general format about the output
* "time"/"string"
* "top", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue "
* "top", "1", " input (value) %OfValue "
* "bottom", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue "
* "average", "100"
* "mean", "100"
* "median", "100"
* "averageSlice", "#slice","nameofslice", "100", "nameofslice", "100", "nameofslice", "100"
* "topPerslice", "#slice", "nameofslice", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue ",
* "nameofslice", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue ",
* "nameofslice", "3", " input (value) %OfValue ", " input (value) %OfValue ", " input (value) %OfValue "
* ....
*
**/

View File

@@ -0,0 +1,52 @@
Template 9
There were #uniqueInputs ##input_g_0 (s), the top #top highest total ##output_0 were as follows:\n #placeHolder
Template 16
For the #slices ##SlicePar_GG_1(s), the percentage of ##OutPar_N_C_1 on #time were \n #stHData\n this was compared with #Etime where #ESlices ##SlicePar_GG_1\n #EstHData \n.
Template 17
For the #slices ##SlicePar_GG_1(s), the percentage of ##OutPar_N_C_1 for each group during the week of #time was \n #stHData\n, compared to the #Etime where #ESlices ##SlicePar_GG_1\n #EstHData \n.
Template 21
The data pattern indicates that #st have #volumeType ##OutPar_N_C_1 \n.
Template 22
The largest increase of ##OutPar_N_C_1 was on #time when it increased #increasesize% above the average value.
Template 23
The largest decrease in ##OutPar_N_C_1 was on #time when it fell below #reducesize% of the average value.
Template 24
The data trend indicates a consistent #trend over time. \n
Template 1
For the #averageSlice ##slicer_0, the volume of each is: #placeHolder
Template 2
The ##InPar_GG_1 that had largest of each ##SlicePar_GG_1 are (only top #n ##InPar_GG_1) \n
Template 3
#input had #TPer% for ##SlicePar_GG_1 #Slice \n"
Template 5
The ##InPar_GG_1 that had largest of each ##SlicePar_GG_1 are (only top #n ##InPar_GG_1) \n
Template 6
The largest and smallest ##SlicePar_GG_1 for the top #n ##InPar_GG_1 were are as follows \n
Template 7
#inp had #maxSlice the largest ##SlicePar_GG_1 #maxPer% and #minSlice the smallest ##SlicePar_GG_1 #minPer% \n
Template 8
#inp had a total of #OutPar_N_C_1 ##OutPar_N_C_1 that constitues #Per% \n \n
Template 10
There were #uniqueInputs ##InPar_GG_1(s), the total ##OutPar_N_C_1 were as follows:\n #st
Template 11
in the week #time the data contained #slices ##SlicePar_GG_1, the top #n ##SlicePar_GG_1 with highest ##OutPar_N_C_1 were as follows:\n #stHData this was compared with week #Etime with the following top #En of #Eslice ##SlicePar_GG_1\n #EstData\n
Template 12
in the week #time the data contained #slices ##SlicePar_GG_1, the top #n ##SlicePar_GG_1 with highest ##OutPar_N_C_1 were as follows:\n #stHData\n
Template 13
On day #time the data contained #slices ##SlicePar_GG_1, the top #n ##SlicePar_GG_1 with highest ##OutPar_N_C_1 were as follows:\n #stHData this was compared with day #Etime with the following top #n ##SlicePar_GG_1\n #EstHData\n
Template 14
in month #time the data contained #slices ##SlicePar_GG_1, the top #n ##SlicePar_GG_1 with highest ##OutPar_N_C_1 were as follows:\n #stData this was compared with month #Etime with the following top #n ##SlicePar_GG_1\n #EstData\n
Template 15
in month #time the data contained #slices ##SlicePar_GG_1, the top #n ##SlicePar_GG_1 with highest ##OutPar_N_C_1 were as follows:\n #stHData\n
Template 18
in the week #time the data contained #slices ##SlicePar_GG_1, the % of ##OutPar_N_C_1 for each ##SlicePar_GG_1 were as follows:\n #stHData this was compared with week #Etime with the following #En of #Eslice ##SlicePar_GG_1\n #EstHData \n
Template 19
in month #time the data contained #slices ##SlicePar_GG_1, the % of ##OutPar_N_C_1 for each ##SlicePar_GG_1 were as follows:\n #stData this was compared with month #Etime with the following #n ##SlicePar_GG_1\n #EstData\n
Template 20
in month #time the data contained #slices ##SlicePar_GG_1, the % of ##OutPar_N_C_1 for each ##SlicePar_GG_1 were as follows:\n #stData\n
Template 21
Looking at the pattern of the data it appears that #st has the #volumeType ##OutPar_N_C_1 \n
Template 22
The largest increase in ##OutPar_N_C_1 were observed on #time with an increase of #increasesize% of the avarage value of ##OutPar_N_C_1 \n
Template 23
The bottom #bottom total ##output_0 were as follows:\n #placeHolder

View File

@@ -0,0 +1,58 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.InsightsGenerator
{
public class Workflow
{
public async Task<string> ProcessInputData(DataArray rulesData,
CancellationToken cancellationToken = new CancellationToken())
{
// added cancellationToken just in case for future
cancellationToken.ThrowIfCancellationRequested();
//Get the signature result
SignatureGenerator siggen = new SignatureGenerator(rulesData);
string insights = null;
await Task.Run(() =>
{
try
{
DataTransformer transformer = new DataTransformer();
transformer.Transform(rulesData);
SignatureGeneratorResult result = siggen.Learn();
// call the rules engine processor
if (result?.Insights == null)
{
// Console.WriteLine("Failure in generating insights, Input not recognized!");
}
else
{
insights = RulesEngine.FindMatchedTemplate(result.Insights, rulesData);
// Console.WriteLine(
// $"Good News! Insights generator has provided you the chart text: \n{insights}\n");
}
}
catch (Exception)
{
// Console.WriteLine(ex.ToString());
throw;
}
}, cancellationToken);
return insights;
}
}
}

View File

@@ -29,6 +29,7 @@ using Microsoft.SqlTools.ServiceLayer.Security;
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.InsightsGenerator;
namespace Microsoft.SqlTools.ServiceLayer
{
@@ -137,6 +138,9 @@ namespace Microsoft.SqlTools.ServiceLayer
NotebookConvertService.Instance.InitializeService(serviceHost);
serviceProvider.RegisterSingleService(NotebookConvertService.Instance);
InsightsGeneratorService.Instance.InitializeService(serviceHost);
serviceProvider.RegisterSingleService(InsightsGeneratorService.Instance);
InitializeHostedServices(serviceProvider, serviceHost);
serviceHost.ServiceProvider = serviceProvider;

View File

@@ -0,0 +1,46 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.InsightsGenerator.Contracts
{
public class AccessibleChartData
{
public string[] Columns { get; set; }
public string[][] Rows { get; set; }
}
/// <summary>
/// Query insights generator parameters
/// </summary>
public class QueryInsightsGeneratorParams : GeneralRequestDetails
{
public AccessibleChartData Data { get; set; }
}
/// <summary>
/// Query insights generator result
/// </summary>
public class InsightsGeneratorResult : ResultStatus
{
public string InsightsText { get; set; }
}
/// <summary>
/// Query insights generato request type
/// </summary>
public class QueryInsightsGeneratorRequest
{
/// <summary>
/// Request definition
/// </summary>
public static readonly
RequestType<QueryInsightsGeneratorParams, InsightsGeneratorResult> Type =
RequestType<QueryInsightsGeneratorParams, InsightsGeneratorResult>.Create("insights/query");
}
}

View File

@@ -0,0 +1,78 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Threading.Tasks;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.InsightsGenerator.Contracts;
using Microsoft.InsightsGenerator;
namespace Microsoft.SqlTools.ServiceLayer.InsightsGenerator
{
/// <summary>
/// Service responsible for securing credentials in a platform-neutral manner. This provides
/// a generic API for read, save and delete credentials
/// </summary>
public class InsightsGeneratorService
{
/// <summary>
/// Singleton service instance
/// </summary>
private static Lazy<InsightsGeneratorService> instance
= new Lazy<InsightsGeneratorService>(() => new InsightsGeneratorService());
/// <summary>
/// Gets the singleton service instance
/// </summary>
public static InsightsGeneratorService Instance
{
get
{
return instance.Value;
}
}
/// <summary>
/// Initializes the service instance
/// </summary>
public void InitializeService(ServiceHost serviceHost)
{
// Insights Generatoe request handlers
serviceHost.SetRequestHandler(QueryInsightsGeneratorRequest.Type, HandleQueryInsightGeneratorRequest);
}
internal async Task HandleQueryInsightGeneratorRequest(QueryInsightsGeneratorParams parameters, RequestContext<InsightsGeneratorResult> requestContext)
{
Microsoft.InsightsGenerator.DataArray dataArray = new Microsoft.InsightsGenerator.DataArray(){
ColumnNames = parameters.Data.Columns,
Cells = parameters.Data.Rows
};
Workflow insightWorkFlow = new Workflow();
try
{
string insightText = await insightWorkFlow.ProcessInputData(dataArray);
insightText = insightText.Replace("\\n", "");
await requestContext.SendResult(new InsightsGeneratorResult()
{
InsightsText = insightText,
Success = true,
ErrorMessage = null
});
}
catch (Exception ex)
{
await requestContext.SendResult(new InsightsGeneratorResult()
{
Success = false,
ErrorMessage = ex.Message
});
}
}
}
}

View File

@@ -2321,13 +2321,13 @@
</trans-unit>
<trans-unit id="ExportBacpacTaskName">
<source>Export bacpac</source>
<target state="translated">BACPAC exportieren</target>
<target state="translated">BACPAC-Datei exportieren</target>
<note>
</note>
</trans-unit>
<trans-unit id="ImportBacpacTaskName">
<source>Import bacpac</source>
<target state="translated">BACPAC importieren</target>
<target state="translated">BACPAC-Datei importieren</target>
<note>
</note>
</trans-unit>
@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">Ungültiger Wert "{0}" für ColumnEncryption. Gültige Werte sind "Enabled" und "Disabled".</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">Ungültiger Wert "{0}" für EnclaveAttestationProtocol. Gültige Werte sind "AAS" und "HGS".</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">Für das Nachweisprotokoll und die Enclave-Nachweis-URL muss Always Encrypted auf "Enabled" festgelegt sein.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">Fehler bei der Batchausführung. Der Vorgang wird beendet.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">Es wurde ein nicht unterstütztes Token "{0}" gefunden.</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">El valor "{0}" no es válido para ComlumEncryption. Los valores válidos son "Enabled" y "Disabled".</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">El valor "{0}" no es válido para EnclaveAttestationProtocol. Los valores válidos son "AAS" y "HGS".</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">El protocolo de atestación y la dirección URL de atestación de enclave requieren que Always Encrypted esté habilitado.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">Error durante la ejecución del lote. Saliendo.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">Se ha encontrado un token no admitido {0}</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">Valeur « {0} » non valide pour ComlumEncryption. Les valeurs valides sont « Enabled » et « Disabled ».</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">Valeur « {0} » non valide pour EnclaveAttestationProtocol. Les valeurs valides sont « AAS » et « HGS ».</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">Le protocole d'attestation et l'URL d'attestation d'enclave exigent l'activation d'Always Encrypted.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">Une erreur s'est produite durant l'exécution du lot. Fermeture en cours.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">Jeton non pris en charge détecté ({0})</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">Il valore '{0}' non è valido per ComlumEncryption. I valori validi sono 'Enabled' e 'Disabled'.</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">Il valore '{0}' non è valido per EnclaveAttestationProtocol. I valori validi sono 'AAS' e 'HGS'.</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">Il protocollo di attestazione e l'URL di attestazione dell'enclave richiedono che Always Encrypted sia impostato su Abilitato.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">Si è verificato un errore durante l'esecuzione del batch. Chiusura in corso.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">È stato rilevato il token {0} non supportato</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">ComlumEncryption の値 '{0}' が無効です。有効な値は 'Enabled' と 'Disabled' です。</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">EnclaveAttestationProtocol の値 '{0}' が無効です。有効な値は、'AAS' と 'HGS' です。</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">構成証明プロトコルおよびエンクレーブ構成証明の URL では、Always Encrypted を Enabled に設定することが必要です。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">バッチの実行中にエラーが発生しました。終了します。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">サポートされていないトークン {0} が見つかりました</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1898,7 +1898,7 @@
</trans-unit>
<trans-unit id="EditDataValueTooLarge">
<source>Value {0} is too large to fit in column of type {1}</source>
<target state="translated">값 {0}이 너무 커서 {1} 유형의 열에 맞지 않습니다.</target>
<target state="translated">값 {0}이(가) 너무 커서 {1} 유형의 열에 맞지 않습니다.</target>
<note>.
Parameters: 0 - value (string), 1 - columnType (string) </note>
</trans-unit>
@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">ComlumEncryption에 대한 '{0}' 값이 잘못되었습니다. 유효한 값은 'Enabled' 및 'Disabled'입니다.</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">EnclaveAttestationProtocol에 대한 '{0}' 값이 잘못되었습니다. 유효한 값은 'AAS' 및 'HGS'입니다.</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">증명 프로토콜 및 enclave 증명 URL을 사용하려면 Always Encrypted를 Enabled(사용)로 설정해야 합니다.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">일괄 처리를 실행하는 동안 오류가 발생하여 종료합니다.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">지원되지 않는 {0} 토큰이 발생했습니다.</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">Valor inválido '{0}' para ComlumEncryption. Os valores válidos são 'Habilitado' e 'Desabilitado'.</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">Valor inválido '{0}' para EnclaveAttestationProtocol. Os valores válidos são 'AAS' e 'HGS'.</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">O Protocolo de Atestado e a URL de Atestado de Enclave exigem que a opção Always Encrypted seja definida como Habilitada.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">Erro durante a execução do lote. Saindo.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">Token sem suporte encontrado {0}</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">Недопустимое значение "{0}" для ColumnEncryption. Допустимые значения: "Enabled" (Включено) и "Disabled" (Отключено).</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">Недопустимое значение "{0}" для EnclaveAttestationProtocol. Допустимые значения: "AAS" и "HGS".</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">Протокол аттестации и URL аттестации анклава требуют задать для Always Encrypted значение Enabled (Включено).</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">При выполнении пакета возникла ошибка. Выполняется выход.</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">Обнаружен неподдерживаемый токен {0}.</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -136,13 +136,13 @@
</trans-unit>
<trans-unit id="QueryServiceAffectedOneRow">
<source>(1 row affected)</source>
<target state="translated">1 行受到影响</target>
<target state="translated">(1 行受到影响)</target>
<note>
</note>
</trans-unit>
<trans-unit id="QueryServiceAffectedRows">
<source>({0} rows affected)</source>
<target state="translated">{0} 行受到影响</target>
<target state="translated">({0} 行受到影响)</target>
<note>.
Parameters: 0 - rows (long) </note>
</trans-unit>
@@ -1922,7 +1922,7 @@
</trans-unit>
<trans-unit id="StoredProcedureScriptParameterComment">
<source>-- TODO: Set parameter values here.</source>
<target state="translated">-- 待办事项在此处设置参数值</target>
<target state="translated">-- 待办事项: 在此处设置参数值</target>
<note>
</note>
</trans-unit>
@@ -2209,13 +2209,13 @@
</trans-unit>
<trans-unit id="CreateSessionFailed">
<source>Failed to create session: {0}</source>
<target state="translated">创建会话失败{0}</target>
<target state="translated">创建会话失败: {0}</target>
<note>.
Parameters: 0 - error (String) </note>
</trans-unit>
<trans-unit id="PauseSessionFailed">
<source>Failed to pause session: {0}</source>
<target state="translated">暂停会话失败{0}</target>
<target state="translated">暂停会话失败: {0}</target>
<note>.
Parameters: 0 - error (String) </note>
</trans-unit>
@@ -2321,13 +2321,13 @@
</trans-unit>
<trans-unit id="ExportBacpacTaskName">
<source>Export bacpac</source>
<target state="translated">导出 DACPAC</target>
<target state="translated">导出 BACPAC</target>
<note>
</note>
</trans-unit>
<trans-unit id="ImportBacpacTaskName">
<source>Import bacpac</source>
<target state="translated">导入 DACPAC</target>
<target state="translated">导入 BACPAC</target>
<note>
</note>
</trans-unit>
@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">ComlumEncryption 的值“{0}”无效。有效值为 "Enabled" 和 "Disabled"。</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">EnclaveAttestationProtocol 的值“{0}”无效。有效值为 "AAS" 和 "HGS"。</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">证明协议和 Enclave 证明 URL 需要将 Always Encrypted 设置为“启用”。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">在执行批处理期间遇到错误。正在退出。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">遇到不支持的令牌 {0}</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -784,13 +784,13 @@
</trans-unit>
<trans-unit id="SchemaHierarchy_MasterKey">
<source>Master Key</source>
<target state="translated">主要索引鍵</target>
<target state="translated">主要金鑰</target>
<note>
</note>
</trans-unit>
<trans-unit id="SchemaHierarchy_MasterKeys">
<source>Master Keys</source>
<target state="translated">主要索引鍵</target>
<target state="translated">主要金鑰</target>
<note>
</note>
</trans-unit>
@@ -2391,6 +2391,36 @@
<note>.
Parameters: 0 - filePath (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidColumnEncryptionSetting">
<source>Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</source>
<target state="translated">ComlumEncryption 的值 '{0}' 無效。有效值為 'Enabled' 及 'Disabled'。</target>
<note>.
Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>
<target state="translated">EnclaveAttestationProtocol 的值 '{0}' 無效。有效值為 'AAS' 及 'HGS'。</target>
<note>.
Parameters: 0 - enclaveAttestationProtocol (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination">
<source>The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.</source>
<target state="translated">證明通訊協定與記憶體保護區證明 URL 需要將 Always Encrypted 設定為「啟用」。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdExitOnError">
<source>An error was encountered during execution of batch. Exiting.</source>
<target state="translated">執行批次期間發生錯誤,結束中。</target>
<note>
</note>
</trans-unit>
<trans-unit id="SqlCmdUnsupportedToken">
<source>Encountered unsupported token {0}</source>
<target state="translated">發現不支援的權杖 {0}</target>
<note>
</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -34,6 +34,7 @@
<ProjectReference Include="../Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj" />
<ProjectReference Include="../Microsoft.Kusto.ServiceLayer/Microsoft.Kusto.ServiceLayer.csproj" />
<ProjectReference Include="../Microsoft.InsightsGenerator/Microsoft.InsightsGenerator.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="$(PkgMicrosoft_SqlServer_DacFx)\lib\netstandard2.0\Microsoft.Data.Tools.Schema.SqlTasks.targets">