Merge from Master

This commit is contained in:
Kevin Cunnane
2017-03-06 17:56:04 -08:00
14 changed files with 1593 additions and 1417 deletions

View File

@@ -7,7 +7,7 @@
"BuildToolsFolder": ".tools", "BuildToolsFolder": ".tools",
"ArtifactsFolder": "artifacts", "ArtifactsFolder": "artifacts",
"TestProjects": { "TestProjects": {
"Microsoft.SqlTools.ServiceLayer.Test": [ "Microsoft.SqlTools.ServiceLayer.UnitTests": [
"netcoreapp1.0" "netcoreapp1.0"
] ]
}, },

View File

@@ -1,123 +1,123 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="TestLocalizationConstant" xml:space="preserve"> <data name="TestLocalizationConstant" xml:space="preserve">
<value>ES_LOCALIZATION</value> <value>ES_LOCALIZATION</value>
</data> </data>
</root> </root>

View File

@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en"> <file datatype="xml" original="sr.resx" source-language="en">
<body> <body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle"> <trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source> <source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target> <target state="new">Invalid CriticalHandle!</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded"> <trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source> <source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target> <target state="new">The password has exceeded 512 bytes</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete"> <trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source> <source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target> <target state="new">Target must be specified to delete a credential</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup"> <trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source> <source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target> <target state="new">Target must be specified to check existance of a credential</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed"> <trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source> <source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target> <target state="new">Win32Credential object is already disposed</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -1,123 +1,123 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="TestLocalizationConstant" xml:space="preserve"> <data name="TestLocalizationConstant" xml:space="preserve">
<value>ES_LOCALIZATION</value> <value>ES_LOCALIZATION</value>
</data> </data>
</root> </root>

View File

@@ -1,82 +1,82 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd"> <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en"> <file datatype="xml" original="sr.resx" source-language="en">
<body> <body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle"> <trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source> <source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target> <target state="new">Invalid CriticalHandle!</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded"> <trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source> <source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target> <target state="new">The password has exceeded 512 bytes</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete"> <trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source> <source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target> <target state="new">Target must be specified to delete a credential</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup"> <trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source> <source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target> <target state="new">Target must be specified to check existance of a credential</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed"> <trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source> <source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target> <target state="new">Win32Credential object is already disposed</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="HostingUnexpectedEndOfStream"> <trans-unit id="HostingUnexpectedEndOfStream">
<source>MessageReader's input stream ended unexpectedly, terminating</source> <source>MessageReader's input stream ended unexpectedly, terminating</source>
<target state="new">MessageReader's input stream ended unexpectedly, terminating</target> <target state="new">MessageReader's input stream ended unexpectedly, terminating</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="HostingHeaderMissingColon"> <trans-unit id="HostingHeaderMissingColon">
<source>Message header must separate key and value using ':'</source> <source>Message header must separate key and value using ':'</source>
<target state="new">Message header must separate key and value using ':'</target> <target state="new">Message header must separate key and value using ':'</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthHeader"> <trans-unit id="HostingHeaderMissingContentLengthHeader">
<source>Fatal error: Content-Length header must be provided</source> <source>Fatal error: Content-Length header must be provided</source>
<target state="new">Fatal error: Content-Length header must be provided</target> <target state="new">Fatal error: Content-Length header must be provided</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthValue"> <trans-unit id="HostingHeaderMissingContentLengthValue">
<source>Fatal error: Content-Length value is not an integer</source> <source>Fatal error: Content-Length value is not an integer</source>
<target state="new">Fatal error: Content-Length value is not an integer</target> <target state="new">Fatal error: Content-Length value is not an integer</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="ServiceAlreadyRegistered"> <trans-unit id="ServiceAlreadyRegistered">
<source>Cannot register service for type {0}, one or more services already registered</source> <source>Cannot register service for type {0}, one or more services already registered</source>
<target state="new">Cannot register service for type {0}, one or more services already registered</target> <target state="new">Cannot register service for type {0}, one or more services already registered</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="MultipleServicesFound"> <trans-unit id="MultipleServicesFound">
<source>Multiple services found for type {0}, expected only 1</source> <source>Multiple services found for type {0}, expected only 1</source>
<target state="new">Multiple services found for type {0}, expected only 1</target> <target state="new">Multiple services found for type {0}, expected only 1</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="IncompatibleServiceForExtensionLoader"> <trans-unit id="IncompatibleServiceForExtensionLoader">
<source>Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</source> <source>Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</source>
<target state="new">Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</target> <target state="new">Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="ServiceProviderNotSet"> <trans-unit id="ServiceProviderNotSet">
<source>SetServiceProvider() was not called to establish the required service provider</source> <source>SetServiceProvider() was not called to establish the required service provider</source>
<target state="new">SetServiceProvider() was not called to establish the required service provider</target> <target state="new">SetServiceProvider() was not called to establish the required service provider</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="ServiceNotFound"> <trans-unit id="ServiceNotFound">
<source>Service {0} was not found in the service provider</source> <source>Service {0} was not found in the service provider</source>
<target state="new">Service {0} was not found in the service provider</target> <target state="new">Service {0} was not found in the service provider</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="ServiceNotOfExpectedType"> <trans-unit id="ServiceNotOfExpectedType">
<source>Service of Type {0} is not compatible with registered Type {1}</source> <source>Service of Type {0} is not compatible with registered Type {1}</source>
<target state="new">Service of Type {0} is not compatible with registered Type {1}</target> <target state="new">Service of Type {0} is not compatible with registered Type {1}</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -12,16 +12,89 @@ using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
{ {
/// <summary> /// <summary>
/// This class caches server information for subsequent use /// This class caches server information for subsequent use
/// </summary> /// </summary>
internal static class CachedServerInfo internal class CachedServerInfo
{ {
/// <summary>
/// Singleton service instance
/// </summary>
private static readonly Lazy<CachedServerInfo> instance
= new Lazy<CachedServerInfo>(() => new CachedServerInfo());
/// <summary>
/// Gets the singleton instance
/// </summary>
public static CachedServerInfo Instance
{
get
{
return instance.Value;
}
}
public enum CacheVariable { public enum CacheVariable {
IsSqlDw, IsSqlDw,
IsAzure IsAzure
} }
#region CacheKey implementation
internal class CacheKey : IEquatable<CacheKey>
{
private string dataSource;
private string dbName;
public CacheKey(SqlConnectionStringBuilder builder)
{
Validate.IsNotNull(nameof(builder), builder);
dataSource = builder.DataSource;
dbName = GetDatabaseName(builder);
}
internal static string GetDatabaseName(SqlConnectionStringBuilder builder)
{
string dbName = string.Empty;
if (!string.IsNullOrEmpty((builder.InitialCatalog)))
{
dbName = builder.InitialCatalog;
}
else if (!string.IsNullOrEmpty((builder.AttachDBFilename)))
{
dbName = builder.AttachDBFilename;
}
return dbName;
}
public override bool Equals(object obj)
{
if (obj == null) { return false; }
CacheKey keyObj = obj as CacheKey;
if (keyObj == null) { return false; }
else { return Equals(keyObj); }
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = (hash * 23) + (dataSource != null ? dataSource.GetHashCode() : 0);
hash = (hash * 23) + (dbName != null ? dbName.GetHashCode() : 0);
return hash;
}
}
public bool Equals(CacheKey other)
{
return string.Equals(dataSource, other.dataSource, StringComparison.OrdinalIgnoreCase)
&& string.Equals(dbName, other.dbName, StringComparison.OrdinalIgnoreCase);
}
}
#endregion
private struct CachedInfo private struct CachedInfo
{ {
public bool IsAzure; public bool IsAzure;
@@ -29,38 +102,43 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
public bool IsSqlDw; public bool IsSqlDw;
} }
private static ConcurrentDictionary<string, CachedInfo> _cache;
private static object _cacheLock;
private const int _maxCacheSize = 1024; private const int _maxCacheSize = 1024;
private const int _deleteBatchSize = 512; private const int _deleteBatchSize = 512;
private const int MinimalQueryTimeoutSecondsForAzure = 300; private const int MinimalQueryTimeoutSecondsForAzure = 300;
static CachedServerInfo() private ConcurrentDictionary<CacheKey, CachedInfo> _cache;
private object _cacheLock;
/// <summary>
/// Internal constructor for testing purposes. For all code use, please use the <see cref="CachedServerInfo.Instance"/>
/// default instance.
/// </summary>
internal CachedServerInfo()
{ {
_cache = new ConcurrentDictionary<string, CachedInfo>(StringComparer.OrdinalIgnoreCase); _cache = new ConcurrentDictionary<CacheKey, CachedInfo>();
_cacheLock = new object(); _cacheLock = new object();
} }
public static int GetQueryTimeoutSeconds(IDbConnection connection) public int GetQueryTimeoutSeconds(IDbConnection connection)
{ {
string dataSource = SafeGetDataSourceFromConnection(connection); SqlConnectionStringBuilder connStringBuilder = SafeGetConnectionStringFromConnection(connection);
return GetQueryTimeoutSeconds(dataSource); return GetQueryTimeoutSeconds(connStringBuilder);
} }
public static int GetQueryTimeoutSeconds(string dataSource) public int GetQueryTimeoutSeconds(SqlConnectionStringBuilder builder)
{ {
//keep existing behavior and return the default ambient settings //keep existing behavior and return the default ambient settings
//if the provided data source is null or whitespace, or the original //if the provided data source is null or whitespace, or the original
//setting is already 0 which means no limit. //setting is already 0 which means no limit.
int originalValue = AmbientSettings.QueryTimeoutSeconds; int originalValue = AmbientSettings.QueryTimeoutSeconds;
if (string.IsNullOrWhiteSpace(dataSource) if (builder == null || string.IsNullOrWhiteSpace(builder.DataSource)
|| (originalValue == 0)) || (originalValue == 0))
{ {
return originalValue; return originalValue;
} }
CachedInfo info; CachedInfo info;
bool hasFound = _cache.TryGetValue(dataSource, out info); bool hasFound = TryGetCacheValue(builder, out info);
if (hasFound && info.IsAzure if (hasFound && info.IsAzure
&& originalValue < MinimalQueryTimeoutSecondsForAzure) && originalValue < MinimalQueryTimeoutSecondsForAzure)
@@ -73,55 +151,43 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
} }
} }
public static void AddOrUpdateIsAzure(IDbConnection connection, bool isAzure) public void AddOrUpdateIsAzure(IDbConnection connection, bool isAzure)
{ {
AddOrUpdateCache(connection, isAzure, CacheVariable.IsAzure); AddOrUpdateCache(connection, isAzure, CacheVariable.IsAzure);
} }
public static void AddOrUpdateIsSqlDw(IDbConnection connection, bool isSqlDw) public void AddOrUpdateIsSqlDw(IDbConnection connection, bool isSqlDw)
{ {
AddOrUpdateCache(connection, isSqlDw, CacheVariable.IsSqlDw); AddOrUpdateCache(connection, isSqlDw, CacheVariable.IsSqlDw);
} }
private static void AddOrUpdateCache(IDbConnection connection, bool newState, CacheVariable cacheVar) private void AddOrUpdateCache(IDbConnection connection, bool newState, CacheVariable cacheVar)
{ {
Validate.IsNotNull(nameof(connection), connection); Validate.IsNotNull(nameof(connection), connection);
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString);
AddOrUpdateCache(builder.DataSource, newState, cacheVar); AddOrUpdateCache(builder, newState, cacheVar);
} }
internal static void AddOrUpdateCache(string dataSource, bool newState, CacheVariable cacheVar) internal void AddOrUpdateCache(SqlConnectionStringBuilder builder, bool newState, CacheVariable cacheVar)
{ {
Validate.IsNotNullOrWhitespaceString(nameof(dataSource), dataSource); Validate.IsNotNull(nameof(builder), builder);
Validate.IsNotNullOrWhitespaceString(nameof(builder) + ".DataSource", builder.DataSource);
CachedInfo info; CachedInfo info;
bool hasFound = _cache.TryGetValue(dataSource, out info); bool hasFound = TryGetCacheValue(builder, out info);
if ((cacheVar == CacheVariable.IsSqlDw && hasFound && info.IsSqlDw == newState) || if ((cacheVar == CacheVariable.IsSqlDw && hasFound && info.IsSqlDw == newState) ||
(cacheVar == CacheVariable.IsAzure && hasFound && info.IsAzure == newState)) (cacheVar == CacheVariable.IsAzure && hasFound && info.IsAzure == newState))
{ {
// No change needed
return; return;
} }
else else
{ {
lock (_cacheLock) lock (_cacheLock)
{ {
if (! _cache.ContainsKey(dataSource)) // Clean older keys, update info, and add this back into the cache
{ CacheKey key = new CacheKey(builder);
//delete a batch of old elements when we try to add a new one and CleanupCache(key);
//the capacity limitation is hit
if (_cache.Keys.Count > _maxCacheSize - 1)
{
var keysToDelete = _cache
.OrderBy(x => x.Value.LastUpdate)
.Take(_deleteBatchSize)
.Select(pair => pair.Key);
foreach (string key in keysToDelete)
{
_cache.TryRemove(key, out info);
}
}
}
if (cacheVar == CacheVariable.IsSqlDw) if (cacheVar == CacheVariable.IsSqlDw)
{ {
@@ -132,24 +198,47 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
info.IsAzure = newState; info.IsAzure = newState;
} }
info.LastUpdate = DateTime.UtcNow; info.LastUpdate = DateTime.UtcNow;
_cache.AddOrUpdate(dataSource, info, (key, oldValue) => info); _cache.AddOrUpdate(key, info, (k, oldValue) => info);
} }
} }
} }
public static bool TryGetIsSqlDw(IDbConnection connection, out bool isSqlDw) private void CleanupCache(CacheKey newKey)
{
if (!_cache.ContainsKey(newKey))
{
//delete a batch of old elements when we try to add a new one and
//the capacity limitation is hit
if (_cache.Keys.Count > _maxCacheSize - 1)
{
var keysToDelete = _cache
.OrderBy(x => x.Value.LastUpdate)
.Take(_deleteBatchSize)
.Select(pair => pair.Key);
foreach (CacheKey key in keysToDelete)
{
CachedInfo info;
_cache.TryRemove(key, out info);
}
}
}
}
public bool TryGetIsSqlDw(IDbConnection connection, out bool isSqlDw)
{ {
Validate.IsNotNull(nameof(connection), connection); Validate.IsNotNull(nameof(connection), connection);
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString);
return TryGetIsSqlDw(builder.DataSource, out isSqlDw); return TryGetIsSqlDw(builder, out isSqlDw);
} }
public static bool TryGetIsSqlDw(string dataSource, out bool isSqlDw) public bool TryGetIsSqlDw(SqlConnectionStringBuilder builder, out bool isSqlDw)
{ {
Validate.IsNotNullOrWhitespaceString(nameof(dataSource), dataSource); Validate.IsNotNull(nameof(builder), builder);
Validate.IsNotNullOrWhitespaceString(nameof(builder) + ".DataSource", builder.DataSource);
CachedInfo info; CachedInfo info;
bool hasFound = _cache.TryGetValue(dataSource, out info); bool hasFound = TryGetCacheValue(builder, out info);
if(hasFound) if(hasFound)
{ {
@@ -161,7 +250,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
return false; return false;
} }
private static string SafeGetDataSourceFromConnection(IDbConnection connection) private static SqlConnectionStringBuilder SafeGetConnectionStringFromConnection(IDbConnection connection)
{ {
if (connection == null) if (connection == null)
{ {
@@ -171,7 +260,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
try try
{ {
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connection.ConnectionString);
return builder.DataSource; return builder;
} }
catch catch
{ {
@@ -179,5 +268,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
return null; return null;
} }
} }
private bool TryGetCacheValue(SqlConnectionStringBuilder builder, out CachedInfo value)
{
CacheKey key = new CacheKey(builder);
return _cache.TryGetValue(key, out value);
}
} }
} }

View File

@@ -407,7 +407,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
public static void SetCommandTimeout(IDbCommand cmd) public static void SetCommandTimeout(IDbCommand cmd)
{ {
Validate.IsNotNull(nameof(cmd), cmd); Validate.IsNotNull(nameof(cmd), cmd);
cmd.CommandTimeout = CachedServerInfo.GetQueryTimeoutSeconds(cmd.Connection); cmd.CommandTimeout = CachedServerInfo.Instance.GetQueryTimeoutSeconds(cmd.Connection);
} }
@@ -773,7 +773,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
try try
{ {
CachedServerInfo.AddOrUpdateIsAzure(connection, serverInfo.IsCloud); CachedServerInfo.Instance.AddOrUpdateIsAzure(connection, serverInfo.IsCloud);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -109,10 +109,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
//This is assuming that it is highly unlikely for a connection to change between instances. //This is assuming that it is highly unlikely for a connection to change between instances.
//Hence any subsequent calls to this method will just return the cached value and not //Hence any subsequent calls to this method will just return the cached value and not
//verify again if this is a SQL DW database connection or not. //verify again if this is a SQL DW database connection or not.
if (!CachedServerInfo.TryGetIsSqlDw(conn, out _isSqlDwDatabase)) if (!CachedServerInfo.Instance.TryGetIsSqlDw(conn, out _isSqlDwDatabase))
{ {
_isSqlDwDatabase = ReliableConnectionHelper.IsSqlDwDatabase(conn); _isSqlDwDatabase = ReliableConnectionHelper.IsSqlDwDatabase(conn);
CachedServerInfo.AddOrUpdateIsSqlDw(conn, _isSqlDwDatabase);; CachedServerInfo.Instance.AddOrUpdateIsSqlDw(conn, _isSqlDwDatabase);;
} }
return _isSqlDwDatabase; return _isSqlDwDatabase;
@@ -137,7 +137,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
{ {
cmd.CommandText = string.Format(CultureInfo.InvariantCulture, setLockTimeout, AmbientSettings.LockTimeoutMilliSeconds); cmd.CommandText = string.Format(CultureInfo.InvariantCulture, setLockTimeout, AmbientSettings.LockTimeoutMilliSeconds);
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = CachedServerInfo.GetQueryTimeoutSeconds(conn); cmd.CommandTimeout = CachedServerInfo.Instance.GetQueryTimeoutSeconds(conn);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
@@ -157,7 +157,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
// Configure the connection with proper ANSI settings and lock timeout // Configure the connection with proper ANSI settings and lock timeout
using (IDbCommand cmd = conn.CreateCommand()) using (IDbCommand cmd = conn.CreateCommand())
{ {
cmd.CommandTimeout = CachedServerInfo.GetQueryTimeoutSeconds(conn); cmd.CommandTimeout = CachedServerInfo.Instance.GetQueryTimeoutSeconds(conn);
if (!isSqlDw) if (!isSqlDw)
{ {
cmd.CommandText = @"SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON; cmd.CommandText = @"SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;

View File

@@ -1,199 +1,199 @@
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.SqlParser.Intellisense; using Microsoft.SqlServer.Management.SqlParser.Intellisense;
using Microsoft.SqlTools.Utility; using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
internal partial class PeekDefinition internal partial class PeekDefinition
{ {
private void Initialize() private void Initialize()
{ {
AddSupportedType(DeclarationType.Table, GetTableScripts, "Table", "table"); AddSupportedType(DeclarationType.Table, GetTableScripts, "Table", "table");
AddSupportedType(DeclarationType.View, GetViewScripts, "View", "view"); AddSupportedType(DeclarationType.View, GetViewScripts, "View", "view");
AddSupportedType(DeclarationType.StoredProcedure, GetStoredProcedureScripts, "Procedure", "stored procedure"); AddSupportedType(DeclarationType.StoredProcedure, GetStoredProcedureScripts, "Procedure", "stored procedure");
AddSupportedType(DeclarationType.UserDefinedDataType, GetUserDefinedDataTypeScripts, "Type", "user-defined data type"); AddSupportedType(DeclarationType.UserDefinedDataType, GetUserDefinedDataTypeScripts, "Type", "user-defined data type");
AddSupportedType(DeclarationType.UserDefinedTableType, GetUserDefinedTableTypeScripts, "Type", "user-defined table type"); AddSupportedType(DeclarationType.UserDefinedTableType, GetUserDefinedTableTypeScripts, "Type", "user-defined table type");
AddSupportedType(DeclarationType.Synonym, GetSynonymScripts, "Synonym", ""); AddSupportedType(DeclarationType.Synonym, GetSynonymScripts, "Synonym", "");
AddSupportedType(DeclarationType.ScalarValuedFunction, GetScalarValuedFunctionScripts, "Function", "scalar-valued function"); AddSupportedType(DeclarationType.ScalarValuedFunction, GetScalarValuedFunctionScripts, "Function", "scalar-valued function");
AddSupportedType(DeclarationType.TableValuedFunction, GetTableValuedFunctionScripts, "Function", "table-valued function"); AddSupportedType(DeclarationType.TableValuedFunction, GetTableValuedFunctionScripts, "Function", "table-valued function");
} }
/// <summary> /// <summary>
/// Script a Table using SMO /// Script a Table using SMO
/// </summary> /// </summary>
/// <param name="objectName">Table name</param> /// <param name="objectName">Table name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetTableScripts(string objectName, string schemaName) internal StringCollection GetTableScripts(string objectName, string schemaName)
{ {
try try
{ {
Table smoObject = string.IsNullOrEmpty(schemaName) ? new Table(this.Database, objectName) : new Table(this.Database, objectName, schemaName); Table smoObject = string.IsNullOrEmpty(schemaName) ? new Table(this.Database, objectName) : new Table(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a View using SMO /// Script a View using SMO
/// </summary> /// </summary>
/// <param name="objectName">View name</param> /// <param name="objectName">View name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetViewScripts(string objectName, string schemaName) internal StringCollection GetViewScripts(string objectName, string schemaName)
{ {
try try
{ {
View smoObject = string.IsNullOrEmpty(schemaName) ? new View(this.Database, objectName) : new View(this.Database, objectName, schemaName); View smoObject = string.IsNullOrEmpty(schemaName) ? new View(this.Database, objectName) : new View(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetViewScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetViewScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a StoredProcedure using SMO /// Script a StoredProcedure using SMO
/// </summary> /// </summary>
/// <param name="objectName">StoredProcedure name</param> /// <param name="objectName">StoredProcedure name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetStoredProcedureScripts(string objectName, string schemaName) internal StringCollection GetStoredProcedureScripts(string objectName, string schemaName)
{ {
try try
{ {
StoredProcedure smoObject = string.IsNullOrEmpty(schemaName) ? new StoredProcedure(this.Database, objectName) : new StoredProcedure(this.Database, objectName, schemaName); StoredProcedure smoObject = string.IsNullOrEmpty(schemaName) ? new StoredProcedure(this.Database, objectName) : new StoredProcedure(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetStoredProcedureScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetStoredProcedureScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a UserDefinedDataType using SMO /// Script a UserDefinedDataType using SMO
/// </summary> /// </summary>
/// <param name="objectName">UserDefinedDataType name</param> /// <param name="objectName">UserDefinedDataType name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetUserDefinedDataTypeScripts(string objectName, string schemaName) internal StringCollection GetUserDefinedDataTypeScripts(string objectName, string schemaName)
{ {
try try
{ {
UserDefinedDataType smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedDataType(this.Database, objectName) : new UserDefinedDataType(this.Database, objectName, schemaName); UserDefinedDataType smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedDataType(this.Database, objectName) : new UserDefinedDataType(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedDataTypeScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedDataTypeScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a UserDefinedTableType using SMO /// Script a UserDefinedTableType using SMO
/// </summary> /// </summary>
/// <param name="objectName">UserDefinedTableType name</param> /// <param name="objectName">UserDefinedTableType name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetUserDefinedTableTypeScripts(string objectName, string schemaName) internal StringCollection GetUserDefinedTableTypeScripts(string objectName, string schemaName)
{ {
try try
{ {
UserDefinedTableType smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedTableType(this.Database, objectName) : new UserDefinedTableType(this.Database, objectName, schemaName); UserDefinedTableType smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedTableType(this.Database, objectName) : new UserDefinedTableType(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedTableTypeScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedTableTypeScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a Synonym using SMO /// Script a Synonym using SMO
/// </summary> /// </summary>
/// <param name="objectName">Synonym name</param> /// <param name="objectName">Synonym name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetSynonymScripts(string objectName, string schemaName) internal StringCollection GetSynonymScripts(string objectName, string schemaName)
{ {
try try
{ {
Synonym smoObject = string.IsNullOrEmpty(schemaName) ? new Synonym(this.Database, objectName) : new Synonym(this.Database, objectName, schemaName); Synonym smoObject = string.IsNullOrEmpty(schemaName) ? new Synonym(this.Database, objectName) : new Synonym(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetSynonymScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetSynonymScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a ScalarValuedFunction using SMO /// Script a ScalarValuedFunction using SMO
/// </summary> /// </summary>
/// <param name="objectName">ScalarValuedFunction name</param> /// <param name="objectName">ScalarValuedFunction name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetScalarValuedFunctionScripts(string objectName, string schemaName) internal StringCollection GetScalarValuedFunctionScripts(string objectName, string schemaName)
{ {
try try
{ {
UserDefinedFunction smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedFunction(this.Database, objectName) : new UserDefinedFunction(this.Database, objectName, schemaName); UserDefinedFunction smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedFunction(this.Database, objectName) : new UserDefinedFunction(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetScalarValuedFunctionScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetScalarValuedFunctionScripts : " + ex.Message);
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Script a TableValuedFunction using SMO /// Script a TableValuedFunction using SMO
/// </summary> /// </summary>
/// <param name="objectName">TableValuedFunction name</param> /// <param name="objectName">TableValuedFunction name</param>
/// <param name="schemaName">Schema name</param> /// <param name="schemaName">Schema name</param>
/// <returns>String collection of scripts</returns> /// <returns>String collection of scripts</returns>
internal StringCollection GetTableValuedFunctionScripts(string objectName, string schemaName) internal StringCollection GetTableValuedFunctionScripts(string objectName, string schemaName)
{ {
try try
{ {
UserDefinedFunction smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedFunction(this.Database, objectName) : new UserDefinedFunction(this.Database, objectName, schemaName); UserDefinedFunction smoObject = string.IsNullOrEmpty(schemaName) ? new UserDefinedFunction(this.Database, objectName) : new UserDefinedFunction(this.Database, objectName, schemaName);
smoObject.Refresh(); smoObject.Refresh();
return smoObject.Script(); return smoObject.Script();
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableValuedFunctionScripts : " + ex.Message); Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableValuedFunctionScripts : " + ex.Message);
return null; return null;
} }
} }
} }
} }

View File

@@ -1,144 +1,144 @@
<#@ template debug="false" hostspecific="true" language="C#" #> <#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #> <#@ output extension=".cs" #>
<#@ assembly name="System.Xml.dll" #> <#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System" #> <#@ import namespace="System" #>
<#@ import namespace="System.Globalization" #> <#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Text" #> <#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #> <#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #> <#@ import namespace="System.IO" #>
// //
// Copyright (c) Microsoft. All rights reserved. // Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.SqlParser.Intellisense; using Microsoft.SqlServer.Management.SqlParser.Intellisense;
using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
internal partial class PeekDefinition internal partial class PeekDefinition
{ {
<# <#
/// ///
/// Generate Initialize method /// Generate Initialize method
/// ///
var indent = " "; var indent = " ";
var directory = Path.GetDirectoryName(Host.TemplateFile); var directory = Path.GetDirectoryName(Host.TemplateFile);
string xmlFile = Path.Combine(directory, "PeekDefinitionSupportedTypes.xml"); string xmlFile = Path.Combine(directory, "PeekDefinitionSupportedTypes.xml");
var supportedTypes = GetSupportedTypes(xmlFile); var supportedTypes = GetSupportedTypes(xmlFile);
if (supportedTypes != null && supportedTypes.Count > 0) if (supportedTypes != null && supportedTypes.Count > 0)
{ {
WriteLine("private void Initialize()"); WriteLine("private void Initialize()");
PushIndent(indent); PushIndent(indent);
PushIndent(indent); PushIndent(indent);
WriteLine("{"); WriteLine("{");
PushIndent(indent); PushIndent(indent);
foreach(var typeProperty in supportedTypes) foreach(var typeProperty in supportedTypes)
{ {
string functionCall = string.Format("AddSupportedType(DeclarationType.{0}, Get{0}Scripts, \"{1}\", \"{2}\");", typeProperty["Name"], typeProperty["CreateSyntax"], typeProperty["QuickInfoType"]); string functionCall = string.Format("AddSupportedType(DeclarationType.{0}, Get{0}Scripts, \"{1}\", \"{2}\");", typeProperty["Name"], typeProperty["CreateSyntax"], typeProperty["QuickInfoType"]);
WriteLine(functionCall); WriteLine(functionCall);
} }
PopIndent(); PopIndent();
WriteLine("}\n"); WriteLine("}\n");
/// ///
/// Generate scriptGetters for each type /// Generate scriptGetters for each type
/// ///
foreach(var typeProperty in supportedTypes) foreach(var typeProperty in supportedTypes)
{ {
string statement; string statement;
// Write comments // Write comments
WriteLine("/// <summary>"); WriteLine("/// <summary>");
WriteLine(string.Format("/// Script a {0} using SMO", typeProperty["Name"])); WriteLine(string.Format("/// Script a {0} using SMO", typeProperty["Name"]));
WriteLine("/// </summary>"); WriteLine("/// </summary>");
WriteLine(string.Format("/// <param name=\"objectName\">{0} name</param>", typeProperty["Name"])); WriteLine(string.Format("/// <param name=\"objectName\">{0} name</param>", typeProperty["Name"]));
WriteLine(string.Format("/// <param name=\"schemaName\">Schema name</param>")); WriteLine(string.Format("/// <param name=\"schemaName\">Schema name</param>"));
WriteLine("/// <returns>String collection of scripts</returns>"); WriteLine("/// <returns>String collection of scripts</returns>");
WriteLine(string.Format("internal StringCollection Get{0}Scripts(string objectName, string schemaName)", typeProperty["Name"])); WriteLine(string.Format("internal StringCollection Get{0}Scripts(string objectName, string schemaName)", typeProperty["Name"]));
WriteLine("{"); WriteLine("{");
PushIndent(indent); PushIndent(indent);
// Write try block to retrieve object and return script // Write try block to retrieve object and return script
WriteLine("try"); WriteLine("try");
WriteLine("{"); WriteLine("{");
if(typeProperty["SupportsSchemaQuery"].IndexOf("true", StringComparison.OrdinalIgnoreCase) >= 0) if(typeProperty["SupportsSchemaQuery"].IndexOf("true", StringComparison.OrdinalIgnoreCase) >= 0)
{ {
statement = string.Format("{0} smoObject = string.IsNullOrEmpty(schemaName) ? new {0}(this.Database, objectName) : new {0}(this.Database, objectName, schemaName);", typeProperty["AccessClass"]); statement = string.Format("{0} smoObject = string.IsNullOrEmpty(schemaName) ? new {0}(this.Database, objectName) : new {0}(this.Database, objectName, schemaName);", typeProperty["AccessClass"]);
} }
else else
{ {
statement = string.Format("{0} smoObject = new {0}(this.Database, objectName);", typeProperty["Name"]); statement = string.Format("{0} smoObject = new {0}(this.Database, objectName);", typeProperty["Name"]);
} }
PushIndent(indent); PushIndent(indent);
WriteLine(statement); WriteLine(statement);
WriteLine("smoObject.Refresh();"); WriteLine("smoObject.Refresh();");
WriteLine("return smoObject.Script();"); WriteLine("return smoObject.Script();");
PopIndent(); PopIndent();
WriteLine("}"); WriteLine("}");
// Write catch block to catch and log exceptions // Write catch block to catch and log exceptions
WriteLine("catch (Exception ex)"); WriteLine("catch (Exception ex)");
WriteLine("{"); WriteLine("{");
PushIndent(indent); PushIndent(indent);
statement = string.Format("LogLevel.Error,\"Exception at PeekDefinition Get{0}Scripts : \" + ex.Message", typeProperty["Name"]); statement = string.Format("LogLevel.Error,\"Exception at PeekDefinition Get{0}Scripts : \" + ex.Message", typeProperty["Name"]);
WriteLine("Logger.Write(" + statement + ");"); WriteLine("Logger.Write(" + statement + ");");
WriteLine("return null;"); WriteLine("return null;");
PopIndent(); PopIndent();
WriteLine("}"); WriteLine("}");
PopIndent(); PopIndent();
WriteLine("}\n"); WriteLine("}\n");
} }
} }
PopIndent(); PopIndent();
PopIndent(); PopIndent();
#> #>
} }
} }
<#+ <#+
/// ///
/// Get the supported types from the xml file /// Get the supported types from the xml file
/// ///
public static List<Dictionary<string, string>> GetSupportedTypes(string xmlFile) public static List<Dictionary<string, string>> GetSupportedTypes(string xmlFile)
{ {
List<Dictionary<string, string>> typeList = null; List<Dictionary<string, string>> typeList = null;
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
doc.Load(xmlFile); doc.Load(xmlFile);
XmlNodeList supportedTypes = doc.SelectNodes("/SupportedTypes/Type"); XmlNodeList supportedTypes = doc.SelectNodes("/SupportedTypes/Type");
if (supportedTypes != null) if (supportedTypes != null)
{ {
typeList = new List<Dictionary<string, string>>(); typeList = new List<Dictionary<string, string>>();
foreach (var type in supportedTypes) foreach (var type in supportedTypes)
{ {
XmlElement node = type as XmlElement; XmlElement node = type as XmlElement;
if (node != null) if (node != null)
{ {
string typeName = (node["Name"] != null) ? node["Name"].InnerText : null; string typeName = (node["Name"] != null) ? node["Name"].InnerText : null;
string createSyntax = (node["CreateSyntax"] != null) ? node["CreateSyntax"].InnerText : null; string createSyntax = (node["CreateSyntax"] != null) ? node["CreateSyntax"].InnerText : null;
string accessClass = (node["AccessClass"] != null) ? node["AccessClass"].InnerText : null; string accessClass = (node["AccessClass"] != null) ? node["AccessClass"].InnerText : null;
string supportsSchemaQuery = (node["SupportsSchemaQuery"] != null) ? node["SupportsSchemaQuery"].InnerText : null; string supportsSchemaQuery = (node["SupportsSchemaQuery"] != null) ? node["SupportsSchemaQuery"].InnerText : null;
string quickInfoType = (node["QuickInfoType"] != null) ? node["QuickInfoType"].InnerText : null; string quickInfoType = (node["QuickInfoType"] != null) ? node["QuickInfoType"].InnerText : null;
if (typeName != null && createSyntax != null && accessClass != null && supportsSchemaQuery!= null) if (typeName != null && createSyntax != null && accessClass != null && supportsSchemaQuery!= null)
{ {
Dictionary<string, string> typeProperties = new Dictionary<string, string>(); Dictionary<string, string> typeProperties = new Dictionary<string, string>();
typeProperties.Add("Name", typeName); typeProperties.Add("Name", typeName);
typeProperties.Add("CreateSyntax", createSyntax); typeProperties.Add("CreateSyntax", createSyntax);
typeProperties.Add("AccessClass", accessClass); typeProperties.Add("AccessClass", accessClass);
typeProperties.Add("SupportsSchemaQuery", supportsSchemaQuery); typeProperties.Add("SupportsSchemaQuery", supportsSchemaQuery);
typeProperties.Add("QuickInfoType", quickInfoType); typeProperties.Add("QuickInfoType", quickInfoType);
typeList.Add(typeProperties); typeList.Add(typeProperties);
} }
} }
} }
} }
return typeList; return typeList;
} }
#> #>

View File

@@ -1,123 +1,123 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="TestLocalizationConstant" xml:space="preserve"> <data name="TestLocalizationConstant" xml:space="preserve">
<value>ES_LOCALIZATION</value> <value>ES_LOCALIZATION</value>
</data> </data>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,6 @@ using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Xunit; using Xunit;
using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.ReliableConnectionHelper;
using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy;
using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy.TimeBasedRetryPolicy; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy.TimeBasedRetryPolicy;
using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.SqlSchemaModelErrorCodes; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.SqlSchemaModelErrorCodes;

View File

@@ -5,6 +5,7 @@
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection; using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
using Xunit; using Xunit;
using System.Data.SqlClient;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
{ {
@@ -13,18 +14,70 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
/// </summary> /// </summary>
public class CachedServerInfoTests public class CachedServerInfoTests
{ {
private CachedServerInfo cache;
public CachedServerInfoTests()
{
cache = new CachedServerInfo();
}
[Fact]
public void CacheMatchesNullDbNameToEmptyString()
{
// Set sqlDw result into cache
string dataSource = "testDataSource";
bool isSqlDwResult;
SqlConnectionStringBuilder testSource = new SqlConnectionStringBuilder
{
DataSource = dataSource,
InitialCatalog = string.Empty
};
cache.AddOrUpdateCache(testSource, true, CachedServerInfo.CacheVariable.IsSqlDw);
// Expect the same returned result
Assert.True(cache.TryGetIsSqlDw(testSource, out isSqlDwResult));
Assert.True(isSqlDwResult);
// And expect the same for the null string
Assert.True(cache.TryGetIsSqlDw(new SqlConnectionStringBuilder
{
DataSource = dataSource
// Initial Catalog is null. Can't set explicitly as this throws
}, out isSqlDwResult));
Assert.True(isSqlDwResult);
// But expect false for a different DB
Assert.False(cache.TryGetIsSqlDw(new SqlConnectionStringBuilder
{
DataSource = dataSource,
InitialCatalog = "OtherDb"
}, out isSqlDwResult));
}
[Theory] [Theory]
[InlineData(true)] // is SqlDW instance [InlineData(null, true)] // is SqlDW instance
[InlineData(false)] // is not a SqlDw Instance [InlineData("", true)] // is SqlDW instance
public void AddOrUpdateIsSqlDw(bool state) [InlineData("myDb", true)] // is SqlDW instance
[InlineData(null, false)] // is not a SqlDw Instance
[InlineData("", false)] // is not a SqlDw Instance
[InlineData("myDb", false)] // is not SqlDW instance
public void AddOrUpdateIsSqlDw(string dbName, bool state)
{ {
// Set sqlDw result into cache // Set sqlDw result into cache
bool isSqlDwResult; bool isSqlDwResult;
CachedServerInfo.AddOrUpdateCache("testDataSource", state, CachedServerInfo.CacheVariable.IsSqlDw); SqlConnectionStringBuilder testSource = new SqlConnectionStringBuilder
{
DataSource = "testDataSource"
};
if (dbName != null)
{
testSource.InitialCatalog = dbName;
}
cache.AddOrUpdateCache(testSource, state, CachedServerInfo.CacheVariable.IsSqlDw);
// Expect the same returned result // Expect the same returned result
Assert.True(CachedServerInfo.TryGetIsSqlDw("testDataSource", out isSqlDwResult)); Assert.True(cache.TryGetIsSqlDw(testSource, out isSqlDwResult));
Assert.Equal(isSqlDwResult, state); Assert.Equal(isSqlDwResult, state);
} }
@@ -35,18 +88,22 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
{ {
// Set sqlDw result into cache // Set sqlDw result into cache
bool isSqlDwResult; bool isSqlDwResult;
CachedServerInfo.AddOrUpdateCache("testDataSource", state, CachedServerInfo.CacheVariable.IsSqlDw); SqlConnectionStringBuilder testSource = new SqlConnectionStringBuilder
{
DataSource = "testDataSource"
};
cache.AddOrUpdateCache(testSource, state, CachedServerInfo.CacheVariable.IsSqlDw);
// Expect the same returned result // Expect the same returned result
Assert.True(CachedServerInfo.TryGetIsSqlDw("testDataSource", out isSqlDwResult)); Assert.True(cache.TryGetIsSqlDw(testSource, out isSqlDwResult));
Assert.Equal(isSqlDwResult, state); Assert.Equal(isSqlDwResult, state);
// Toggle isSqlDw cache state // Toggle isSqlDw cache state
bool isSqlDwResultToggle; bool isSqlDwResultToggle;
CachedServerInfo.AddOrUpdateCache("testDataSource", !state, CachedServerInfo.CacheVariable.IsSqlDw); cache.AddOrUpdateCache(testSource, !state, CachedServerInfo.CacheVariable.IsSqlDw);
// Expect the oppisite returned result // Expect the oppisite returned result
Assert.True(CachedServerInfo.TryGetIsSqlDw("testDataSource", out isSqlDwResultToggle)); Assert.True(cache.TryGetIsSqlDw(testSource, out isSqlDwResultToggle));
Assert.Equal(isSqlDwResultToggle, !state); Assert.Equal(isSqlDwResultToggle, !state);
} }
@@ -55,19 +112,40 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
public void AddOrUpdateIsSqlDwFalseToggle() public void AddOrUpdateIsSqlDwFalseToggle()
{ {
bool state = true; bool state = true;
SqlConnectionStringBuilder testSource = new SqlConnectionStringBuilder
{
DataSource = "testDataSource"
};
SqlConnectionStringBuilder sameServerDifferentDb = new SqlConnectionStringBuilder
{
DataSource = "testDataSource",
InitialCatalog = "myDb"
};
SqlConnectionStringBuilder differentServerSameDb = new SqlConnectionStringBuilder
{
DataSource = "testDataSource2",
InitialCatalog = ""
};
cache.AddOrUpdateCache(testSource, state, CachedServerInfo.CacheVariable.IsSqlDw);
cache.AddOrUpdateCache(sameServerDifferentDb, !state, CachedServerInfo.CacheVariable.IsSqlDw);
cache.AddOrUpdateCache(differentServerSameDb, !state, CachedServerInfo.CacheVariable.IsSqlDw);
// Expect the same returned result
// Set sqlDw result into cache // Set sqlDw result into cache
bool isSqlDwResult; bool isSqlDwResult;
bool isSqlDwResult2; bool isSqlDwResult2;
CachedServerInfo.AddOrUpdateCache("testDataSource", state, CachedServerInfo.CacheVariable.IsSqlDw); bool isSqlDwResult3;
CachedServerInfo.AddOrUpdateCache("testDataSource2", !state, CachedServerInfo.CacheVariable.IsSqlDw); Assert.True(cache.TryGetIsSqlDw(testSource, out isSqlDwResult));
Assert.True(cache.TryGetIsSqlDw(sameServerDifferentDb, out isSqlDwResult2));
// Expect the same returned result Assert.True(cache.TryGetIsSqlDw(differentServerSameDb, out isSqlDwResult3));
Assert.True(CachedServerInfo.TryGetIsSqlDw("testDataSource", out isSqlDwResult));
Assert.True(CachedServerInfo.TryGetIsSqlDw("testDataSource2", out isSqlDwResult2));
// Assert cache is set on a per connection basis // Assert cache is set on a per connection basis
Assert.Equal(isSqlDwResult, state); Assert.Equal(isSqlDwResult, state);
Assert.Equal(isSqlDwResult2, !state); Assert.Equal(isSqlDwResult2, !state);
Assert.Equal(isSqlDwResult3, !state);
} }
@@ -75,7 +153,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
public void AskforSqlDwBeforeCached() public void AskforSqlDwBeforeCached()
{ {
bool isSqlDwResult; bool isSqlDwResult;
Assert.False(CachedServerInfo.TryGetIsSqlDw("testDataSourceWithNoCache", out isSqlDwResult)); Assert.False(cache.TryGetIsSqlDw(new SqlConnectionStringBuilder
{
DataSource = "testDataSourceUnCached"
},
out isSqlDwResult));
} }
} }
} }