mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-27 01:25:42 -05:00
@@ -52,7 +52,7 @@ namespace Microsoft.SqlTools.Hosting
|
||||
|
||||
protected IMultiServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
public void SetServiceProvider(IMultiServiceProvider provider)
|
||||
public virtual void SetServiceProvider(IMultiServiceProvider provider)
|
||||
{
|
||||
ServiceProvider = provider;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
/// <summary>
|
||||
/// Open a connection with the specified ConnectParams
|
||||
/// </summary>
|
||||
public async Task<ConnectionCompleteParams> Connect(ConnectParams connectionParams)
|
||||
public virtual async Task<ConnectionCompleteParams> Connect(ConnectParams connectionParams)
|
||||
{
|
||||
// Validate parameters
|
||||
ConnectionCompleteParams validationResults = ValidateConnectParams(connectionParams);
|
||||
|
||||
@@ -11,6 +11,7 @@ using Microsoft.SqlTools.ServiceLayer.EditData;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||
using Microsoft.SqlTools.ServiceLayer.Metadata;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.Scripting;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
@@ -85,6 +86,7 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
serviceProvider.RegisterSingleService(ScriptingService.Instance);
|
||||
|
||||
InitializeHostedServices(serviceProvider, serviceHost);
|
||||
serviceHost.ServiceProvider = serviceProvider;
|
||||
|
||||
serviceHost.InitializeRequestHandlers();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,426 +1,426 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, 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="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<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>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: 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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<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:sequence>
|
||||
<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="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ConnectionServiceConnectErrorNullParams" xml:space="preserve">
|
||||
<value>Los parámetros de conexión no pueden ser nulos</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceListDbErrorNullOwnerUri" xml:space="preserve">
|
||||
<value>OwnerUri no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceListDbErrorNotConnected" xml:space="preserve">
|
||||
<value>SpecifiedUri '{0}' no tiene una conexión existente</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnStringInvalidAuthType" xml:space="preserve">
|
||||
<value>El valor '{0}' no es válido para AuthenticationType. Los valores válidos son 'Integrated' y 'SqlLogin'.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnStringInvalidIntent" xml:space="preserve">
|
||||
<value>El valor '{0}' no es válido para ApplicationIntent. Los valores válidos son 'ReadWrite' y 'ReadOnly'.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnectionCanceled" xml:space="preserve">
|
||||
<value>Conexión cancelada</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullOwnerUri" xml:space="preserve">
|
||||
<value>OwnerUri no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullConnection" xml:space="preserve">
|
||||
<value>El objeto de detalles de conexión no puede ser nulo</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullServerName" xml:space="preserve">
|
||||
<value>ServerName no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullSqlAuth" xml:space="preserve">
|
||||
<value>{0} no puede ser nulo ni estar vacío cuando se utiliza autenticación SqlLogin</value>
|
||||
</data>
|
||||
<data name="QueryServiceCancelAlreadyCompleted" xml:space="preserve">
|
||||
<value>Ya se ha completado la consulta, no se puede cancelar</value>
|
||||
</data>
|
||||
<data name="QueryServiceCancelDisposeFailed" xml:space="preserve">
|
||||
<value>La consulta fue cancelada con éxito, pero no se ha podido desechar. No se encontró el URI del propietario.</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryCancelled" xml:space="preserve">
|
||||
<value>Consulta cancelada por el usuario</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetBatchNotCompleted" xml:space="preserve">
|
||||
<value>El lote aún no ha finalizado,</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetBatchOutOfRange" xml:space="preserve">
|
||||
<value>Índice de lote no puede ser menor que 0 o mayor que el número de lotes</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetResultSetOutOfRange" xml:space="preserve">
|
||||
<value>Índice del conjunto de resultados no puede ser menor que 0 o mayor que el número de conjuntos de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderByteCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de bytes a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderCharCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de caracteres a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderXmlCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de bytes XML a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperWriteOnly" xml:space="preserve">
|
||||
<value>El método de acceso no puede ser de sólo escritura</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperNotInitialized" xml:space="preserve">
|
||||
<value>FileStreamWrapper debe inicializarse antes de realizar operaciones</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperReadOnly" xml:space="preserve">
|
||||
<value>Este FileStreamWrapper no se puede utilizar para escritura.</value>
|
||||
</data>
|
||||
<data name="QueryServiceAffectedOneRow" xml:space="preserve">
|
||||
<value>(1 fila afectada)</value>
|
||||
</data>
|
||||
<data name="QueryServiceAffectedRows" xml:space="preserve">
|
||||
<value>({0} filas afectadas)</value>
|
||||
</data>
|
||||
<data name="QueryServiceCompletedSuccessfully" xml:space="preserve">
|
||||
<value>Comandos finalizados correctamente.</value>
|
||||
</data>
|
||||
<data name="QueryServiceErrorFormat" xml:space="preserve">
|
||||
<value>Msg {0}, nivel {1} estado {2}, línea {3} {4} {5}</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryFailed" xml:space="preserve">
|
||||
<value>Error en la consulta: {0}</value>
|
||||
</data>
|
||||
<data name="QueryServiceColumnNull" xml:space="preserve">
|
||||
<value>(Ningún nombre de columna)</value>
|
||||
</data>
|
||||
<data name="QueryServiceRequestsNoQuery" xml:space="preserve">
|
||||
<value>La consulta solicitada no existe</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryInvalidOwnerUri" xml:space="preserve">
|
||||
<value>Este editor no está conectado a una base de datos</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryInProgress" xml:space="preserve">
|
||||
<value>Una consulta ya está en curso para esta sesión de editor. Por favor, cancelar esta consulta o esperar su finalización.</value>
|
||||
</data>
|
||||
<data name="QueryServiceMessageSenderNotSql" xml:space="preserve">
|
||||
<value>Remitente de eventos de OnInfoMessage debe ser un objeto SqlConnection</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetReaderNull" xml:space="preserve">
|
||||
<value>Lector no puede ser nulo</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsResultSetNotComplete" xml:space="preserve">
|
||||
<value>No se puede guardar el resultado hasta que haya finalizado la ejecución de la consulta</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsMiscStartingError" xml:space="preserve">
|
||||
<value>Error interno al iniciar el guardado de la tarea</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsInProgress" xml:space="preserve">
|
||||
<value>Una operacion de guardado en la misma ruta se encuentra en curso</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsFail" xml:space="preserve">
|
||||
<value>Error al guardar {0}: {1}</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetNotRead" xml:space="preserve">
|
||||
<value>No se puede leer el subconjunto, a menos que los resultados se han leído desde el servidor</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetStartRowOutOfRange" xml:space="preserve">
|
||||
<value>Fila de inicio no puede ser menor que 0 o mayor que el número de filas en el conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetRowCountOutOfRange" xml:space="preserve">
|
||||
<value>La cantidad de filas debe ser un entero positivo</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetNoColumnSchema" xml:space="preserve">
|
||||
<value>No se pudo recuperar el esquema de columna para el conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceExecutionPlanNotFound" xml:space="preserve">
|
||||
<value>No se pudo recuperar un plan de ejecución del conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionAzureError" xml:space="preserve">
|
||||
<value>Esta característica actualmente no se admite en la base de datos de SQL Azure y almacén de datos: {0}</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionError" xml:space="preserve">
|
||||
<value>Se ha producido un error inesperado durante la ejecución de la definición de Peek: {0}</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionNoResultsError" xml:space="preserve">
|
||||
<value>No se encontraron resultados.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionDatabaseError" xml:space="preserve">
|
||||
<value>No se pudo obtener ningún objeto asociado a la base de datos.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionNotConnectedError" xml:space="preserve">
|
||||
<value>Conéctese a un servidor.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionTimedoutError" xml:space="preserve">
|
||||
<value>Tiempo de espera agotado para esta operación.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionTypeNotSupportedError" xml:space="preserve">
|
||||
<value>Esta característica no admite actualmente este tipo de objeto.</value>
|
||||
</data>
|
||||
<data name="WorkspaceServicePositionLineOutOfRange" xml:space="preserve">
|
||||
<value>Posición está fuera del intervalo de la línea de archivo</value>
|
||||
</data>
|
||||
<data name="WorkspaceServicePositionColumnOutOfRange" xml:space="preserve">
|
||||
<value>Posición está fuera del intervalo de la columna de la línea {0}</value>
|
||||
</data>
|
||||
<data name="WorkspaceServiceBufferPositionOutOfOrder" xml:space="preserve">
|
||||
<value>Posición de inicio ({0}, {1}) debe preceder o ser igual a la posición final ({2}, {3})</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageNoProcedureInfo" xml:space="preserve">
|
||||
<value>Msg {0}, {1}, nivel de estado {2}, línea {3}</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageWithProcedureInfo" xml:space="preserve">
|
||||
<value>Msj {0}, {1}, nivel de estado {2}, procedimiento {3}, línea {4}</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageNoLineInfo" xml:space="preserve">
|
||||
<value>Msg {0}, nivel {1}, {2} de estado</value>
|
||||
</data>
|
||||
<data name="EE_BatchError_Exception" xml:space="preserve">
|
||||
<value>Se produjo un error al procesar el lote. Mensaje de error: {0}</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionInfo_RowsAffected" xml:space="preserve">
|
||||
<value>({0} filas afectadas)</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionNotYetCompleteError" xml:space="preserve">
|
||||
<value>La ejecución anterior aún no está completa.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_Error" xml:space="preserve">
|
||||
<value>Se ha producido un error de secuencias de comandos.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_ParsingSyntax" xml:space="preserve">
|
||||
<value>Se encontró sintaxis incorrecta mientras se estaba analizando {0}.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_FatalError" xml:space="preserve">
|
||||
<value>Se ha producido un error grave.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_FinalizingLoop" xml:space="preserve">
|
||||
<value>La ejecución completó {0} veces...</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_QueryCancelledbyUser" xml:space="preserve">
|
||||
<value>Se canceló la consulta.</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionError_Halting" xml:space="preserve">
|
||||
<value>Se produjo un error mientras se ejecutaba el lote.</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionError_Ignoring" xml:space="preserve">
|
||||
<value>Se produjo un error mientras se ejecutaba el lote, pero se ha omitido el error.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_InitilizingLoop" xml:space="preserve">
|
||||
<value>Iniciando bucle de ejecución de {0} veces...</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionError_CommandNotSupported" xml:space="preserve">
|
||||
<value>No se admite el comando {0}.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionError_VariableNotFound" xml:space="preserve">
|
||||
<value>La variable {0} no se encontró.</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineError" xml:space="preserve">
|
||||
<value>Error de ejecución de SQL: {0}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionError" xml:space="preserve">
|
||||
<value>Ejecución de contenedor del analizador por lotes: {0} se encuentra... en la línea {1}: {2} Descripción: {3}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchMessage" xml:space="preserve">
|
||||
<value>Lote analizador contenedor ejecución motor lote mensaje recibido: mensaje: {0} mensaje detallado: {1}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetProcessing" xml:space="preserve">
|
||||
<value>Motor de ejecución de analizador contenedor lote ResultSet procesamiento por lotes: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetFinished" xml:space="preserve">
|
||||
<value>Finalizó el elemento ResultSet analizador contenedor ejecución motor los lotes.</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchCancelling" xml:space="preserve">
|
||||
<value>Cancelando la ejecución por lotes del contenedor del analizador por lotes.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_Warning" xml:space="preserve">
|
||||
<value>Advertencia de scripting.</value>
|
||||
</data>
|
||||
<data name="TroubleshootingAssistanceMessage" xml:space="preserve">
|
||||
<value>Para obtener más información acerca de este error, vea los temas de solución de problemas en la documentación del producto.</value>
|
||||
</data>
|
||||
<data name="BatchParser_CircularReference" xml:space="preserve">
|
||||
<value>El archivo '{0}' se incluyó recursivamente.</value>
|
||||
</data>
|
||||
<data name="BatchParser_CommentNotTerminated" xml:space="preserve">
|
||||
<value>Falta la marca de final de comentario ' * /'.</value>
|
||||
</data>
|
||||
<data name="BatchParser_StringNotTerminated" xml:space="preserve">
|
||||
<value>Sin comilla de cierre después de la cadena de caracteres.</value>
|
||||
</data>
|
||||
<data name="BatchParser_IncorrectSyntax" xml:space="preserve">
|
||||
<value>Se encontró sintaxis incorrecta al analizar '{0}'.</value>
|
||||
</data>
|
||||
<data name="BatchParser_VariableNotDefined" xml:space="preserve">
|
||||
<value>La variable {0} no está definida.</value>
|
||||
</data>
|
||||
<data name="TestLocalizationConstant" xml:space="preserve">
|
||||
<value>prueba</value>
|
||||
</data>
|
||||
<data name="ErrorUnexpectedCodeObjectType" xml:space="preserve">
|
||||
<value>No se puede convertir el SqlCodeObject del Tipo {0} al Tipo {1}</value>
|
||||
</data>
|
||||
<data name="ErrorEmptyStringReplacement" xml:space="preserve">
|
||||
<value>Sustitución de una cadena vacía por una cadena vacía.</value>
|
||||
</data>
|
||||
<data name="EditDataSessionNotFound" xml:space="preserve">
|
||||
<value>Sesión de edición no existe,</value>
|
||||
</data>
|
||||
<data name="EditDataQueryNotCompleted" xml:space="preserve">
|
||||
<value>La consulta no ha finalizado.</value>
|
||||
</data>
|
||||
<data name="EditDataQueryImproperResultSets" xml:space="preserve">
|
||||
<value>La consulta no generó un único set de resultados</value>
|
||||
</data>
|
||||
<data name="EditDataFailedAddRow" xml:space="preserve">
|
||||
<value>Falló al agregar una nueva fila a la caché de actualización</value>
|
||||
</data>
|
||||
<data name="EditDataRowOutOfRange" xml:space="preserve">
|
||||
<value>El ID de la fila ingresado, se encuentra fuera del rango de filas de la caché de edición</value>
|
||||
</data>
|
||||
<data name="EditDataUpdatePending" xml:space="preserve">
|
||||
<value>Una actualización está pendiente para esta fila y debe de revertirse primero</value>
|
||||
</data>
|
||||
<data name="EditDataUpdateNotPending" xml:space="preserve">
|
||||
<value>El ID de la fila ingresado no tiene actualizaciones pendientes</value>
|
||||
</data>
|
||||
<data name="EditDataObjectMetadataNotFound" xml:space="preserve">
|
||||
<value>La metadata de la tabla o vista no pudo ser encontrada</value>
|
||||
</data>
|
||||
<data name="EditDataInvalidFormatBinary" xml:space="preserve">
|
||||
<value>Formato inválido para columna binaria</value>
|
||||
</data>
|
||||
<data name="EditDataInvalidFormatBoolean" xml:space="preserve">
|
||||
<value>Columnas del tipo boolean deben de ser numéricos 1 o 0, o tipo string true o false</value>
|
||||
</data>
|
||||
<data name="EditDataCreateScriptMissingValue" xml:space="preserve">
|
||||
<value>Falta un valor requerido de la celda</value>
|
||||
</data>
|
||||
<data name="EditDataDeleteSetCell" xml:space="preserve">
|
||||
<value>Existe una eliminación pendiente para esta fila, una actualización de celda no puede ser realizada.</value>
|
||||
</data>
|
||||
<data name="EditDataColumnIdOutOfRange" xml:space="preserve">
|
||||
<value>El ID de la columna debe de estar en el rango de columnas de la consulta.</value>
|
||||
</data>
|
||||
<data name="EditDataColumnCannotBeEdited" xml:space="preserve">
|
||||
<value>La columna no puede ser editada</value>
|
||||
</data>
|
||||
<data name="EditDataColumnNoKeyColumns" xml:space="preserve">
|
||||
<value>No se encontró ninguna columna clave</value>
|
||||
</data>
|
||||
<data name="EditDataScriptFilePathNull" xml:space="preserve">
|
||||
<value>Proporcione un nombre de archivo de salida</value>
|
||||
</data>
|
||||
<data name="EditDataUnsupportedObjectType" xml:space="preserve">
|
||||
<value>Objeto de base de datos {0} no puede ser usado para modificación.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceDbErrorDefaultNotConnected" xml:space="preserve">
|
||||
<value>SpecifiedUri '{0}' no tiene alguna conexión por defecto</value>
|
||||
</data>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, 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="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<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>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: 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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<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:sequence>
|
||||
<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="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ConnectionServiceConnectErrorNullParams" xml:space="preserve">
|
||||
<value>Los parámetros de conexión no pueden ser nulos</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceListDbErrorNullOwnerUri" xml:space="preserve">
|
||||
<value>OwnerUri no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceListDbErrorNotConnected" xml:space="preserve">
|
||||
<value>SpecifiedUri '{0}' no tiene una conexión existente</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnStringInvalidAuthType" xml:space="preserve">
|
||||
<value>El valor '{0}' no es válido para AuthenticationType. Los valores válidos son 'Integrated' y 'SqlLogin'.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnStringInvalidIntent" xml:space="preserve">
|
||||
<value>El valor '{0}' no es válido para ApplicationIntent. Los valores válidos son 'ReadWrite' y 'ReadOnly'.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceConnectionCanceled" xml:space="preserve">
|
||||
<value>Conexión cancelada</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullOwnerUri" xml:space="preserve">
|
||||
<value>OwnerUri no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullConnection" xml:space="preserve">
|
||||
<value>El objeto de detalles de conexión no puede ser nulo</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullServerName" xml:space="preserve">
|
||||
<value>ServerName no puede ser nulo ni estar vacío</value>
|
||||
</data>
|
||||
<data name="ConnectionParamsValidateNullSqlAuth" xml:space="preserve">
|
||||
<value>{0} no puede ser nulo ni estar vacío cuando se utiliza autenticación SqlLogin</value>
|
||||
</data>
|
||||
<data name="QueryServiceCancelAlreadyCompleted" xml:space="preserve">
|
||||
<value>Ya se ha completado la consulta, no se puede cancelar</value>
|
||||
</data>
|
||||
<data name="QueryServiceCancelDisposeFailed" xml:space="preserve">
|
||||
<value>La consulta fue cancelada con éxito, pero no se ha podido desechar. No se encontró el URI del propietario.</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryCancelled" xml:space="preserve">
|
||||
<value>Consulta cancelada por el usuario</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetBatchNotCompleted" xml:space="preserve">
|
||||
<value>El lote aún no ha finalizado,</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetBatchOutOfRange" xml:space="preserve">
|
||||
<value>Índice de lote no puede ser menor que 0 o mayor que el número de lotes</value>
|
||||
</data>
|
||||
<data name="QueryServiceSubsetResultSetOutOfRange" xml:space="preserve">
|
||||
<value>Índice del conjunto de resultados no puede ser menor que 0 o mayor que el número de conjuntos de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderByteCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de bytes a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderCharCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de caracteres a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceDataReaderXmlCountInvalid" xml:space="preserve">
|
||||
<value>El número máximo de bytes XML a devolver debe ser mayor que cero</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperWriteOnly" xml:space="preserve">
|
||||
<value>El método de acceso no puede ser de sólo escritura</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperNotInitialized" xml:space="preserve">
|
||||
<value>FileStreamWrapper debe inicializarse antes de realizar operaciones</value>
|
||||
</data>
|
||||
<data name="QueryServiceFileWrapperReadOnly" xml:space="preserve">
|
||||
<value>Este FileStreamWrapper no se puede utilizar para escritura.</value>
|
||||
</data>
|
||||
<data name="QueryServiceAffectedOneRow" xml:space="preserve">
|
||||
<value>(1 fila afectada)</value>
|
||||
</data>
|
||||
<data name="QueryServiceAffectedRows" xml:space="preserve">
|
||||
<value>({0} filas afectadas)</value>
|
||||
</data>
|
||||
<data name="QueryServiceCompletedSuccessfully" xml:space="preserve">
|
||||
<value>Comandos finalizados correctamente.</value>
|
||||
</data>
|
||||
<data name="QueryServiceErrorFormat" xml:space="preserve">
|
||||
<value>Msg {0}, nivel {1} estado {2}, línea {3} {4} {5}</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryFailed" xml:space="preserve">
|
||||
<value>Error en la consulta: {0}</value>
|
||||
</data>
|
||||
<data name="QueryServiceColumnNull" xml:space="preserve">
|
||||
<value>(Ningún nombre de columna)</value>
|
||||
</data>
|
||||
<data name="QueryServiceRequestsNoQuery" xml:space="preserve">
|
||||
<value>La consulta solicitada no existe</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryInvalidOwnerUri" xml:space="preserve">
|
||||
<value>Este editor no está conectado a una base de datos</value>
|
||||
</data>
|
||||
<data name="QueryServiceQueryInProgress" xml:space="preserve">
|
||||
<value>Una consulta ya está en curso para esta sesión de editor. Por favor, cancelar esta consulta o esperar su finalización.</value>
|
||||
</data>
|
||||
<data name="QueryServiceMessageSenderNotSql" xml:space="preserve">
|
||||
<value>Remitente de eventos de OnInfoMessage debe ser un objeto SqlConnection</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetReaderNull" xml:space="preserve">
|
||||
<value>Lector no puede ser nulo</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsResultSetNotComplete" xml:space="preserve">
|
||||
<value>No se puede guardar el resultado hasta que haya finalizado la ejecución de la consulta</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsMiscStartingError" xml:space="preserve">
|
||||
<value>Error interno al iniciar el guardado de la tarea</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsInProgress" xml:space="preserve">
|
||||
<value>Una operacion de guardado en la misma ruta se encuentra en curso</value>
|
||||
</data>
|
||||
<data name="QueryServiceSaveAsFail" xml:space="preserve">
|
||||
<value>Error al guardar {0}: {1}</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetNotRead" xml:space="preserve">
|
||||
<value>No se puede leer el subconjunto, a menos que los resultados se han leído desde el servidor</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetStartRowOutOfRange" xml:space="preserve">
|
||||
<value>Fila de inicio no puede ser menor que 0 o mayor que el número de filas en el conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetRowCountOutOfRange" xml:space="preserve">
|
||||
<value>La cantidad de filas debe ser un entero positivo</value>
|
||||
</data>
|
||||
<data name="QueryServiceResultSetNoColumnSchema" xml:space="preserve">
|
||||
<value>No se pudo recuperar el esquema de columna para el conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="QueryServiceExecutionPlanNotFound" xml:space="preserve">
|
||||
<value>No se pudo recuperar un plan de ejecución del conjunto de resultados</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionAzureError" xml:space="preserve">
|
||||
<value>Esta característica actualmente no se admite en la base de datos de SQL Azure y almacén de datos: {0}</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionError" xml:space="preserve">
|
||||
<value>Se ha producido un error inesperado durante la ejecución de la definición de Peek: {0}</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionNoResultsError" xml:space="preserve">
|
||||
<value>No se encontraron resultados.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionDatabaseError" xml:space="preserve">
|
||||
<value>No se pudo obtener ningún objeto asociado a la base de datos.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionNotConnectedError" xml:space="preserve">
|
||||
<value>Conéctese a un servidor.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionTimedoutError" xml:space="preserve">
|
||||
<value>Tiempo de espera agotado para esta operación.</value>
|
||||
</data>
|
||||
<data name="PeekDefinitionTypeNotSupportedError" xml:space="preserve">
|
||||
<value>Esta característica no admite actualmente este tipo de objeto.</value>
|
||||
</data>
|
||||
<data name="WorkspaceServicePositionLineOutOfRange" xml:space="preserve">
|
||||
<value>Posición está fuera del intervalo de la línea de archivo</value>
|
||||
</data>
|
||||
<data name="WorkspaceServicePositionColumnOutOfRange" xml:space="preserve">
|
||||
<value>Posición está fuera del intervalo de la columna de la línea {0}</value>
|
||||
</data>
|
||||
<data name="WorkspaceServiceBufferPositionOutOfOrder" xml:space="preserve">
|
||||
<value>Posición de inicio ({0}, {1}) debe preceder o ser igual a la posición final ({2}, {3})</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageNoProcedureInfo" xml:space="preserve">
|
||||
<value>Msg {0}, {1}, nivel de estado {2}, línea {3}</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageWithProcedureInfo" xml:space="preserve">
|
||||
<value>Msj {0}, {1}, nivel de estado {2}, procedimiento {3}, línea {4}</value>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageNoLineInfo" xml:space="preserve">
|
||||
<value>Msg {0}, nivel {1}, {2} de estado</value>
|
||||
</data>
|
||||
<data name="EE_BatchError_Exception" xml:space="preserve">
|
||||
<value>Se produjo un error al procesar el lote. Mensaje de error: {0}</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionInfo_RowsAffected" xml:space="preserve">
|
||||
<value>({0} filas afectadas)</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionNotYetCompleteError" xml:space="preserve">
|
||||
<value>La ejecución anterior aún no está completa.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_Error" xml:space="preserve">
|
||||
<value>Se ha producido un error de secuencias de comandos.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_ParsingSyntax" xml:space="preserve">
|
||||
<value>Se encontró sintaxis incorrecta mientras se estaba analizando {0}.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_FatalError" xml:space="preserve">
|
||||
<value>Se ha producido un error grave.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_FinalizingLoop" xml:space="preserve">
|
||||
<value>La ejecución completó {0} veces...</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_QueryCancelledbyUser" xml:space="preserve">
|
||||
<value>Se canceló la consulta.</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionError_Halting" xml:space="preserve">
|
||||
<value>Se produjo un error mientras se ejecutaba el lote.</value>
|
||||
</data>
|
||||
<data name="EE_BatchExecutionError_Ignoring" xml:space="preserve">
|
||||
<value>Se produjo un error mientras se ejecutaba el lote, pero se ha omitido el error.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionInfo_InitilizingLoop" xml:space="preserve">
|
||||
<value>Iniciando bucle de ejecución de {0} veces...</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionError_CommandNotSupported" xml:space="preserve">
|
||||
<value>No se admite el comando {0}.</value>
|
||||
</data>
|
||||
<data name="EE_ExecutionError_VariableNotFound" xml:space="preserve">
|
||||
<value>La variable {0} no se encontró.</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineError" xml:space="preserve">
|
||||
<value>Error de ejecución de SQL: {0}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionError" xml:space="preserve">
|
||||
<value>Ejecución de contenedor del analizador por lotes: {0} se encuentra... en la línea {1}: {2} Descripción: {3}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchMessage" xml:space="preserve">
|
||||
<value>Lote analizador contenedor ejecución motor lote mensaje recibido: mensaje: {0} mensaje detallado: {1}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetProcessing" xml:space="preserve">
|
||||
<value>Motor de ejecución de analizador contenedor lote ResultSet procesamiento por lotes: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1}</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetFinished" xml:space="preserve">
|
||||
<value>Finalizó el elemento ResultSet analizador contenedor ejecución motor los lotes.</value>
|
||||
</data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchCancelling" xml:space="preserve">
|
||||
<value>Cancelando la ejecución por lotes del contenedor del analizador por lotes.</value>
|
||||
</data>
|
||||
<data name="EE_ScriptError_Warning" xml:space="preserve">
|
||||
<value>Advertencia de scripting.</value>
|
||||
</data>
|
||||
<data name="TroubleshootingAssistanceMessage" xml:space="preserve">
|
||||
<value>Para obtener más información acerca de este error, vea los temas de solución de problemas en la documentación del producto.</value>
|
||||
</data>
|
||||
<data name="BatchParser_CircularReference" xml:space="preserve">
|
||||
<value>El archivo '{0}' se incluyó recursivamente.</value>
|
||||
</data>
|
||||
<data name="BatchParser_CommentNotTerminated" xml:space="preserve">
|
||||
<value>Falta la marca de final de comentario ' * /'.</value>
|
||||
</data>
|
||||
<data name="BatchParser_StringNotTerminated" xml:space="preserve">
|
||||
<value>Sin comilla de cierre después de la cadena de caracteres.</value>
|
||||
</data>
|
||||
<data name="BatchParser_IncorrectSyntax" xml:space="preserve">
|
||||
<value>Se encontró sintaxis incorrecta al analizar '{0}'.</value>
|
||||
</data>
|
||||
<data name="BatchParser_VariableNotDefined" xml:space="preserve">
|
||||
<value>La variable {0} no está definida.</value>
|
||||
</data>
|
||||
<data name="TestLocalizationConstant" xml:space="preserve">
|
||||
<value>prueba</value>
|
||||
</data>
|
||||
<data name="ErrorUnexpectedCodeObjectType" xml:space="preserve">
|
||||
<value>No se puede convertir el SqlCodeObject del Tipo {0} al Tipo {1}</value>
|
||||
</data>
|
||||
<data name="ErrorEmptyStringReplacement" xml:space="preserve">
|
||||
<value>Sustitución de una cadena vacía por una cadena vacía.</value>
|
||||
</data>
|
||||
<data name="EditDataSessionNotFound" xml:space="preserve">
|
||||
<value>Sesión de edición no existe,</value>
|
||||
</data>
|
||||
<data name="EditDataQueryNotCompleted" xml:space="preserve">
|
||||
<value>La consulta no ha finalizado.</value>
|
||||
</data>
|
||||
<data name="EditDataQueryImproperResultSets" xml:space="preserve">
|
||||
<value>La consulta no generó un único set de resultados</value>
|
||||
</data>
|
||||
<data name="EditDataFailedAddRow" xml:space="preserve">
|
||||
<value>Falló al agregar una nueva fila a la caché de actualización</value>
|
||||
</data>
|
||||
<data name="EditDataRowOutOfRange" xml:space="preserve">
|
||||
<value>El ID de la fila ingresado, se encuentra fuera del rango de filas de la caché de edición</value>
|
||||
</data>
|
||||
<data name="EditDataUpdatePending" xml:space="preserve">
|
||||
<value>Una actualización está pendiente para esta fila y debe de revertirse primero</value>
|
||||
</data>
|
||||
<data name="EditDataUpdateNotPending" xml:space="preserve">
|
||||
<value>El ID de la fila ingresado no tiene actualizaciones pendientes</value>
|
||||
</data>
|
||||
<data name="EditDataObjectMetadataNotFound" xml:space="preserve">
|
||||
<value>La metadata de la tabla o vista no pudo ser encontrada</value>
|
||||
</data>
|
||||
<data name="EditDataInvalidFormatBinary" xml:space="preserve">
|
||||
<value>Formato inválido para columna binaria</value>
|
||||
</data>
|
||||
<data name="EditDataInvalidFormatBoolean" xml:space="preserve">
|
||||
<value>Columnas del tipo boolean deben de ser numéricos 1 o 0, o tipo string true o false</value>
|
||||
</data>
|
||||
<data name="EditDataCreateScriptMissingValue" xml:space="preserve">
|
||||
<value>Falta un valor requerido de la celda</value>
|
||||
</data>
|
||||
<data name="EditDataDeleteSetCell" xml:space="preserve">
|
||||
<value>Existe una eliminación pendiente para esta fila, una actualización de celda no puede ser realizada.</value>
|
||||
</data>
|
||||
<data name="EditDataColumnIdOutOfRange" xml:space="preserve">
|
||||
<value>El ID de la columna debe de estar en el rango de columnas de la consulta.</value>
|
||||
</data>
|
||||
<data name="EditDataColumnCannotBeEdited" xml:space="preserve">
|
||||
<value>La columna no puede ser editada</value>
|
||||
</data>
|
||||
<data name="EditDataColumnNoKeyColumns" xml:space="preserve">
|
||||
<value>No se encontró ninguna columna clave</value>
|
||||
</data>
|
||||
<data name="EditDataScriptFilePathNull" xml:space="preserve">
|
||||
<value>Proporcione un nombre de archivo de salida</value>
|
||||
</data>
|
||||
<data name="EditDataUnsupportedObjectType" xml:space="preserve">
|
||||
<value>Objeto de base de datos {0} no puede ser usado para modificación.</value>
|
||||
</data>
|
||||
<data name="ConnectionServiceDbErrorDefaultNotConnected" xml:space="preserve">
|
||||
<value>SpecifiedUri '{0}' no tiene alguna conexión por defecto</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -599,4 +599,656 @@
|
||||
<value>Decimal column is missing numeric precision or numeric scale</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="TreeNodeError" xml:space="preserve">
|
||||
<value>Error expanding: {0}</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="ServerNodeConnectionError" xml:space="preserve">
|
||||
<value>Error connecting to {0}</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Aggregates" xml:space="preserve">
|
||||
<value>Aggregates</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerRoles" xml:space="preserve">
|
||||
<value>Server Roles</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ApplicationRoles" xml:space="preserve">
|
||||
<value>Application Roles</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Assemblies" xml:space="preserve">
|
||||
<value>Assemblies</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_AssemblyFiles" xml:space="preserve">
|
||||
<value>Assembly Files</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_AsymmetricKeys" xml:space="preserve">
|
||||
<value>Asymmetric Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseAsymmetricKeys" xml:space="preserve">
|
||||
<value>Asymmetric Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DataCompressionOptions" xml:space="preserve">
|
||||
<value>Data Compression Options</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Certificates" xml:space="preserve">
|
||||
<value>Certificates</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FileTables" xml:space="preserve">
|
||||
<value>FileTables</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseCertificates" xml:space="preserve">
|
||||
<value>Certificates</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_CheckConstraints" xml:space="preserve">
|
||||
<value>Check Constraints</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Columns" xml:space="preserve">
|
||||
<value>Columns</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Constraints" xml:space="preserve">
|
||||
<value>Constraints</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Contracts" xml:space="preserve">
|
||||
<value>Contracts</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Credentials" xml:space="preserve">
|
||||
<value>Credentials</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ErrorMessages" xml:space="preserve">
|
||||
<value>Error Messages</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerRoleMembership" xml:space="preserve">
|
||||
<value>Server Role Membership</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseOptions" xml:space="preserve">
|
||||
<value>Database Options</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseRoles" xml:space="preserve">
|
||||
<value>Database Roles</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_RoleMemberships" xml:space="preserve">
|
||||
<value>Role Memberships</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseTriggers" xml:space="preserve">
|
||||
<value>Database Triggers</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DefaultConstraints" xml:space="preserve">
|
||||
<value>Default Constraints</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Defaults" xml:space="preserve">
|
||||
<value>Defaults</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Sequences" xml:space="preserve">
|
||||
<value>Sequences</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Endpoints" xml:space="preserve">
|
||||
<value>Endpoints</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_EventNotifications" xml:space="preserve">
|
||||
<value>Event Notifications</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerEventNotifications" xml:space="preserve">
|
||||
<value>Server Event Notifications</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExtendedProperties" xml:space="preserve">
|
||||
<value>Extended Properties</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FileGroups" xml:space="preserve">
|
||||
<value>Filegroups</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ForeignKeys" xml:space="preserve">
|
||||
<value>Foreign Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FullTextCatalogs" xml:space="preserve">
|
||||
<value>Full-Text Catalogs</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FullTextIndexes" xml:space="preserve">
|
||||
<value>Full-Text Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Functions" xml:space="preserve">
|
||||
<value>Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Indexes" xml:space="preserve">
|
||||
<value>Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_InlineFunctions" xml:space="preserve">
|
||||
<value>Inline Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Keys" xml:space="preserve">
|
||||
<value>Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_LinkedServers" xml:space="preserve">
|
||||
<value>Linked Servers</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_LinkedServerLogins" xml:space="preserve">
|
||||
<value>Linked Server Logins</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Logins" xml:space="preserve">
|
||||
<value>Logins</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_MasterKey" xml:space="preserve">
|
||||
<value>Master Key</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_MasterKeys" xml:space="preserve">
|
||||
<value>Master Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_MessageTypes" xml:space="preserve">
|
||||
<value>Message Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_MultiSelectFunctions" xml:space="preserve">
|
||||
<value>Table-Valued Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Parameters" xml:space="preserve">
|
||||
<value>Parameters</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_PartitionFunctions" xml:space="preserve">
|
||||
<value>Partition Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_PartitionSchemes" xml:space="preserve">
|
||||
<value>Partition Schemes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Permissions" xml:space="preserve">
|
||||
<value>Permissions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_PrimaryKeys" xml:space="preserve">
|
||||
<value>Primary Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Programmability" xml:space="preserve">
|
||||
<value>Programmability</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Queues" xml:space="preserve">
|
||||
<value>Queues</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_RemoteServiceBindings" xml:space="preserve">
|
||||
<value>Remote Service Bindings</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ReturnedColumns" xml:space="preserve">
|
||||
<value>Returned Columns</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Roles" xml:space="preserve">
|
||||
<value>Roles</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Routes" xml:space="preserve">
|
||||
<value>Routes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Rules" xml:space="preserve">
|
||||
<value>Rules</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Schemas" xml:space="preserve">
|
||||
<value>Schemas</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Security" xml:space="preserve">
|
||||
<value>Security</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerObjects" xml:space="preserve">
|
||||
<value>Server Objects</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Management" xml:space="preserve">
|
||||
<value>Management</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerTriggers" xml:space="preserve">
|
||||
<value>Triggers</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServiceBroker" xml:space="preserve">
|
||||
<value>Service Broker</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Services" xml:space="preserve">
|
||||
<value>Services</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Signatures" xml:space="preserve">
|
||||
<value>Signatures</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_LogFiles" xml:space="preserve">
|
||||
<value>Log Files</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Statistics" xml:space="preserve">
|
||||
<value>Statistics</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Storage" xml:space="preserve">
|
||||
<value>Storage</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_StoredProcedures" xml:space="preserve">
|
||||
<value>Stored Procedures</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SymmetricKeys" xml:space="preserve">
|
||||
<value>Symmetric Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Synonyms" xml:space="preserve">
|
||||
<value>Synonyms</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Tables" xml:space="preserve">
|
||||
<value>Tables</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Triggers" xml:space="preserve">
|
||||
<value>Triggers</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Types" xml:space="preserve">
|
||||
<value>Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_UniqueKeys" xml:space="preserve">
|
||||
<value>Unique Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_UserDefinedDataTypes" xml:space="preserve">
|
||||
<value>User-Defined Data Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_UserDefinedTypes" xml:space="preserve">
|
||||
<value>User-Defined Types (CLR)</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Users" xml:space="preserve">
|
||||
<value>Users</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Views" xml:space="preserve">
|
||||
<value>Views</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_XmlIndexes" xml:space="preserve">
|
||||
<value>XML Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_XMLSchemaCollections" xml:space="preserve">
|
||||
<value>XML Schema Collections</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_UserDefinedTableTypes" xml:space="preserve">
|
||||
<value>User-Defined Table Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FilegroupFiles" xml:space="preserve">
|
||||
<value>Files</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="MissingCaption" xml:space="preserve">
|
||||
<value>Missing Caption</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_BrokerPriorities" xml:space="preserve">
|
||||
<value>Broker Priorities</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_CryptographicProviders" xml:space="preserve">
|
||||
<value>Cryptographic Providers</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseAuditSpecifications" xml:space="preserve">
|
||||
<value>Database Audit Specifications</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseEncryptionKeys" xml:space="preserve">
|
||||
<value>Database Encryption Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_EventSessions" xml:space="preserve">
|
||||
<value>Event Sessions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_FullTextStopLists" xml:space="preserve">
|
||||
<value>Full Text Stoplists</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ResourcePools" xml:space="preserve">
|
||||
<value>Resource Pools</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerAudits" xml:space="preserve">
|
||||
<value>Audits</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerAuditSpecifications" xml:space="preserve">
|
||||
<value>Server Audit Specifications</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SpatialIndexes" xml:space="preserve">
|
||||
<value>Spatial Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_WorkloadGroups" xml:space="preserve">
|
||||
<value>Workload Groups</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SqlFiles" xml:space="preserve">
|
||||
<value>SQL Files</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerFunctions" xml:space="preserve">
|
||||
<value>Server Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SqlType" xml:space="preserve">
|
||||
<value>SQL Type</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerOptions" xml:space="preserve">
|
||||
<value>Server Options</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseDiagrams" xml:space="preserve">
|
||||
<value>Database Diagrams</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemTables" xml:space="preserve">
|
||||
<value>System Tables</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_Databases" xml:space="preserve">
|
||||
<value>Databases</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemContracts" xml:space="preserve">
|
||||
<value>System Contracts</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemDatabases" xml:space="preserve">
|
||||
<value>System Databases</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemMessageTypes" xml:space="preserve">
|
||||
<value>System Message Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemQueues" xml:space="preserve">
|
||||
<value>System Queues</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemServices" xml:space="preserve">
|
||||
<value>System Services</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemStoredProcedures" xml:space="preserve">
|
||||
<value>System Stored Procedures</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemViews" xml:space="preserve">
|
||||
<value>System Views</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DataTierApplications" xml:space="preserve">
|
||||
<value>Data-tier Applications</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExtendedStoredProcedures" xml:space="preserve">
|
||||
<value>Extended Stored Procedures</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemAggregateFunctions" xml:space="preserve">
|
||||
<value>Aggregate Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemApproximateNumerics" xml:space="preserve">
|
||||
<value>Approximate Numerics</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemBinaryStrings" xml:space="preserve">
|
||||
<value>Binary Strings</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemCharacterStrings" xml:space="preserve">
|
||||
<value>Character Strings</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemCLRDataTypes" xml:space="preserve">
|
||||
<value>CLR Data Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemConfigurationFunctions" xml:space="preserve">
|
||||
<value>Configuration Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemCursorFunctions" xml:space="preserve">
|
||||
<value>Cursor Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemDataTypes" xml:space="preserve">
|
||||
<value>System Data Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTime" xml:space="preserve">
|
||||
<value>Date and Time</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTimeFunctions" xml:space="preserve">
|
||||
<value>Date and Time Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemExactNumerics" xml:space="preserve">
|
||||
<value>Exact Numerics</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemFunctions" xml:space="preserve">
|
||||
<value>System Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemHierarchyIdFunctions" xml:space="preserve">
|
||||
<value>Hierarchy Id Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemMathematicalFunctions" xml:space="preserve">
|
||||
<value>Mathematical Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemMetadataFunctions" xml:space="preserve">
|
||||
<value>Metadata Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemOtherDataTypes" xml:space="preserve">
|
||||
<value>Other Data Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemOtherFunctions" xml:space="preserve">
|
||||
<value>Other Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemRowsetFunctions" xml:space="preserve">
|
||||
<value>Rowset Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemSecurityFunctions" xml:space="preserve">
|
||||
<value>Security Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemSpatialDataTypes" xml:space="preserve">
|
||||
<value>Spatial Data Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemStringFunctions" xml:space="preserve">
|
||||
<value>String Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemSystemStatisticalFunctions" xml:space="preserve">
|
||||
<value>System Statistical Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemTextAndImageFunctions" xml:space="preserve">
|
||||
<value>Text and Image Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemUnicodeCharacterStrings" xml:space="preserve">
|
||||
<value>Unicode Character Strings</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_AggregateFunctions" xml:space="preserve">
|
||||
<value>Aggregate Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ScalarValuedFunctions" xml:space="preserve">
|
||||
<value>Scalar-valued Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_TableValuedFunctions" xml:space="preserve">
|
||||
<value>Table-valued Functions</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SystemExtendedStoredProcedures" xml:space="preserve">
|
||||
<value>System Extended Stored Procedures</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_BuiltInType" xml:space="preserve">
|
||||
<value>Built-in Types</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_BuiltInServerRole" xml:space="preserve">
|
||||
<value>Built-in Server Roles</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_UserWithPassword" xml:space="preserve">
|
||||
<value>User with Password</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SearchPropertyList" xml:space="preserve">
|
||||
<value>Search Property List</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SecurityPolicies" xml:space="preserve">
|
||||
<value>Security Policies</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SecurityPredicates" xml:space="preserve">
|
||||
<value>Security Predicates</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerRole" xml:space="preserve">
|
||||
<value>Server Role</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SearchPropertyLists" xml:space="preserve">
|
||||
<value>Search Property Lists</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ColumnStoreIndexes" xml:space="preserve">
|
||||
<value>Column Store Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_TableTypeIndexes" xml:space="preserve">
|
||||
<value>Table Type Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ServerInstance" xml:space="preserve">
|
||||
<value>ServerInstance</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SelectiveXmlIndexes" xml:space="preserve">
|
||||
<value>Selective XML Indexes</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_XmlNamespaces" xml:space="preserve">
|
||||
<value>XML Namespaces</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_XmlTypedPromotedPaths" xml:space="preserve">
|
||||
<value>XML Typed Promoted Paths</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_SqlTypedPromotedPaths" xml:space="preserve">
|
||||
<value>T-SQL Typed Promoted Paths</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_DatabaseScopedCredentials" xml:space="preserve">
|
||||
<value>Database Scoped Credentials</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExternalDataSources" xml:space="preserve">
|
||||
<value>External Data Sources</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExternalFileFormats" xml:space="preserve">
|
||||
<value>External File Formats</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExternalResources" xml:space="preserve">
|
||||
<value>External Resources</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ExternalTables" xml:space="preserve">
|
||||
<value>External Tables</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_AlwaysEncryptedKeys" xml:space="preserve">
|
||||
<value>Always Encrypted Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ColumnMasterKeys" xml:space="preserve">
|
||||
<value>Column Master Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SchemaHierarchy_ColumnEncryptionKeys" xml:space="preserve">
|
||||
<value>Column Encryption Keys</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -293,3 +293,333 @@ TestLocalizationConstant = test
|
||||
# Utilities
|
||||
|
||||
SqlScriptFormatterDecimalMissingPrecision = Decimal column is missing numeric precision or numeric scale
|
||||
|
||||
############################################################################
|
||||
# Object Explorer Service
|
||||
|
||||
TreeNodeError = Error expanding: {0}
|
||||
|
||||
ServerNodeConnectionError = Error connecting to {0}
|
||||
|
||||
SchemaHierarchy_Aggregates = Aggregates
|
||||
|
||||
SchemaHierarchy_ServerRoles = Server Roles
|
||||
|
||||
SchemaHierarchy_ApplicationRoles = Application Roles
|
||||
|
||||
SchemaHierarchy_Assemblies = Assemblies
|
||||
|
||||
SchemaHierarchy_AssemblyFiles = Assembly Files
|
||||
|
||||
SchemaHierarchy_AsymmetricKeys = Asymmetric Keys
|
||||
|
||||
SchemaHierarchy_DatabaseAsymmetricKeys = Asymmetric Keys
|
||||
|
||||
SchemaHierarchy_DataCompressionOptions = Data Compression Options
|
||||
|
||||
SchemaHierarchy_Certificates = Certificates
|
||||
|
||||
SchemaHierarchy_FileTables = FileTables
|
||||
|
||||
SchemaHierarchy_DatabaseCertificates = Certificates
|
||||
|
||||
SchemaHierarchy_CheckConstraints = Check Constraints
|
||||
|
||||
SchemaHierarchy_Columns = Columns
|
||||
|
||||
SchemaHierarchy_Constraints = Constraints
|
||||
|
||||
SchemaHierarchy_Contracts = Contracts
|
||||
|
||||
SchemaHierarchy_Credentials = Credentials
|
||||
|
||||
SchemaHierarchy_ErrorMessages = Error Messages
|
||||
|
||||
SchemaHierarchy_ServerRoleMembership = Server Role Membership
|
||||
|
||||
SchemaHierarchy_DatabaseOptions = Database Options
|
||||
|
||||
SchemaHierarchy_DatabaseRoles = Database Roles
|
||||
|
||||
SchemaHierarchy_RoleMemberships = Role Memberships
|
||||
|
||||
SchemaHierarchy_DatabaseTriggers = Database Triggers
|
||||
|
||||
SchemaHierarchy_DefaultConstraints = Default Constraints
|
||||
|
||||
SchemaHierarchy_Defaults = Defaults
|
||||
|
||||
SchemaHierarchy_Sequences = Sequences
|
||||
|
||||
SchemaHierarchy_Endpoints = Endpoints
|
||||
|
||||
SchemaHierarchy_EventNotifications = Event Notifications
|
||||
|
||||
SchemaHierarchy_ServerEventNotifications = Server Event Notifications
|
||||
|
||||
SchemaHierarchy_ExtendedProperties = Extended Properties
|
||||
|
||||
SchemaHierarchy_FileGroups = Filegroups
|
||||
|
||||
SchemaHierarchy_ForeignKeys = Foreign Keys
|
||||
|
||||
SchemaHierarchy_FullTextCatalogs = Full-Text Catalogs
|
||||
|
||||
SchemaHierarchy_FullTextIndexes = Full-Text Indexes
|
||||
|
||||
SchemaHierarchy_Functions = Functions
|
||||
|
||||
SchemaHierarchy_Indexes = Indexes
|
||||
|
||||
SchemaHierarchy_InlineFunctions = Inline Functions
|
||||
|
||||
SchemaHierarchy_Keys = Keys
|
||||
|
||||
SchemaHierarchy_LinkedServers = Linked Servers
|
||||
|
||||
SchemaHierarchy_LinkedServerLogins = Linked Server Logins
|
||||
|
||||
SchemaHierarchy_Logins = Logins
|
||||
|
||||
SchemaHierarchy_MasterKey = Master Key
|
||||
|
||||
SchemaHierarchy_MasterKeys = Master Keys
|
||||
|
||||
SchemaHierarchy_MessageTypes = Message Types
|
||||
|
||||
SchemaHierarchy_MultiSelectFunctions = Table-Valued Functions
|
||||
|
||||
SchemaHierarchy_Parameters = Parameters
|
||||
|
||||
SchemaHierarchy_PartitionFunctions = Partition Functions
|
||||
|
||||
SchemaHierarchy_PartitionSchemes = Partition Schemes
|
||||
|
||||
SchemaHierarchy_Permissions = Permissions
|
||||
|
||||
SchemaHierarchy_PrimaryKeys = Primary Keys
|
||||
|
||||
SchemaHierarchy_Programmability = Programmability
|
||||
|
||||
SchemaHierarchy_Queues = Queues
|
||||
|
||||
SchemaHierarchy_RemoteServiceBindings = Remote Service Bindings
|
||||
|
||||
SchemaHierarchy_ReturnedColumns = Returned Columns
|
||||
|
||||
SchemaHierarchy_Roles = Roles
|
||||
|
||||
SchemaHierarchy_Routes = Routes
|
||||
|
||||
SchemaHierarchy_Rules = Rules
|
||||
|
||||
SchemaHierarchy_Schemas = Schemas
|
||||
|
||||
SchemaHierarchy_Security = Security
|
||||
|
||||
SchemaHierarchy_ServerObjects = Server Objects
|
||||
|
||||
SchemaHierarchy_Management = Management
|
||||
|
||||
SchemaHierarchy_ServerTriggers = Triggers
|
||||
|
||||
SchemaHierarchy_ServiceBroker = Service Broker
|
||||
|
||||
SchemaHierarchy_Services = Services
|
||||
|
||||
SchemaHierarchy_Signatures = Signatures
|
||||
|
||||
SchemaHierarchy_LogFiles = Log Files
|
||||
|
||||
SchemaHierarchy_Statistics = Statistics
|
||||
|
||||
SchemaHierarchy_Storage = Storage
|
||||
|
||||
SchemaHierarchy_StoredProcedures = Stored Procedures
|
||||
|
||||
SchemaHierarchy_SymmetricKeys = Symmetric Keys
|
||||
|
||||
SchemaHierarchy_Synonyms = Synonyms
|
||||
|
||||
SchemaHierarchy_Tables = Tables
|
||||
|
||||
SchemaHierarchy_Triggers = Triggers
|
||||
|
||||
SchemaHierarchy_Types = Types
|
||||
|
||||
SchemaHierarchy_UniqueKeys = Unique Keys
|
||||
|
||||
SchemaHierarchy_UserDefinedDataTypes = User-Defined Data Types
|
||||
|
||||
SchemaHierarchy_UserDefinedTypes = User-Defined Types (CLR)
|
||||
|
||||
SchemaHierarchy_Users = Users
|
||||
|
||||
SchemaHierarchy_Views = Views
|
||||
|
||||
SchemaHierarchy_XmlIndexes = XML Indexes
|
||||
|
||||
SchemaHierarchy_XMLSchemaCollections = XML Schema Collections
|
||||
|
||||
SchemaHierarchy_UserDefinedTableTypes = User-Defined Table Types
|
||||
|
||||
SchemaHierarchy_FilegroupFiles = Files
|
||||
|
||||
MissingCaption = Missing Caption
|
||||
|
||||
SchemaHierarchy_BrokerPriorities = Broker Priorities
|
||||
|
||||
SchemaHierarchy_CryptographicProviders = Cryptographic Providers
|
||||
|
||||
SchemaHierarchy_DatabaseAuditSpecifications = Database Audit Specifications
|
||||
|
||||
SchemaHierarchy_DatabaseEncryptionKeys = Database Encryption Keys
|
||||
|
||||
SchemaHierarchy_EventSessions = Event Sessions
|
||||
|
||||
SchemaHierarchy_FullTextStopLists = Full Text Stoplists
|
||||
|
||||
SchemaHierarchy_ResourcePools = Resource Pools
|
||||
|
||||
SchemaHierarchy_ServerAudits = Audits
|
||||
|
||||
SchemaHierarchy_ServerAuditSpecifications = Server Audit Specifications
|
||||
|
||||
SchemaHierarchy_SpatialIndexes = Spatial Indexes
|
||||
|
||||
SchemaHierarchy_WorkloadGroups = Workload Groups
|
||||
|
||||
SchemaHierarchy_SqlFiles = SQL Files
|
||||
|
||||
SchemaHierarchy_ServerFunctions = Server Functions
|
||||
|
||||
SchemaHierarchy_SqlType = SQL Type
|
||||
|
||||
SchemaHierarchy_ServerOptions = Server Options
|
||||
|
||||
SchemaHierarchy_DatabaseDiagrams = Database Diagrams
|
||||
|
||||
SchemaHierarchy_SystemTables = System Tables
|
||||
|
||||
SchemaHierarchy_Databases = Databases
|
||||
|
||||
SchemaHierarchy_SystemContracts = System Contracts
|
||||
|
||||
SchemaHierarchy_SystemDatabases = System Databases
|
||||
|
||||
SchemaHierarchy_SystemMessageTypes = System Message Types
|
||||
|
||||
SchemaHierarchy_SystemQueues = System Queues
|
||||
|
||||
SchemaHierarchy_SystemServices = System Services
|
||||
|
||||
SchemaHierarchy_SystemStoredProcedures = System Stored Procedures
|
||||
|
||||
SchemaHierarchy_SystemViews = System Views
|
||||
|
||||
SchemaHierarchy_DataTierApplications = Data-tier Applications
|
||||
|
||||
SchemaHierarchy_ExtendedStoredProcedures = Extended Stored Procedures
|
||||
|
||||
SchemaHierarchy_SystemAggregateFunctions = Aggregate Functions
|
||||
|
||||
SchemaHierarchy_SystemApproximateNumerics = Approximate Numerics
|
||||
|
||||
SchemaHierarchy_SystemBinaryStrings = Binary Strings
|
||||
|
||||
SchemaHierarchy_SystemCharacterStrings = Character Strings
|
||||
|
||||
SchemaHierarchy_SystemCLRDataTypes = CLR Data Types
|
||||
|
||||
SchemaHierarchy_SystemConfigurationFunctions = Configuration Functions
|
||||
|
||||
SchemaHierarchy_SystemCursorFunctions = Cursor Functions
|
||||
|
||||
SchemaHierarchy_SystemDataTypes = System Data Types
|
||||
|
||||
SchemaHierarchy_SystemDateAndTime = Date and Time
|
||||
|
||||
SchemaHierarchy_SystemDateAndTimeFunctions = Date and Time Functions
|
||||
|
||||
SchemaHierarchy_SystemExactNumerics = Exact Numerics
|
||||
|
||||
SchemaHierarchy_SystemFunctions = System Functions
|
||||
|
||||
SchemaHierarchy_SystemHierarchyIdFunctions = Hierarchy Id Functions
|
||||
|
||||
SchemaHierarchy_SystemMathematicalFunctions = Mathematical Functions
|
||||
|
||||
SchemaHierarchy_SystemMetadataFunctions = Metadata Functions
|
||||
|
||||
SchemaHierarchy_SystemOtherDataTypes = Other Data Types
|
||||
|
||||
SchemaHierarchy_SystemOtherFunctions = Other Functions
|
||||
|
||||
SchemaHierarchy_SystemRowsetFunctions = Rowset Functions
|
||||
|
||||
SchemaHierarchy_SystemSecurityFunctions = Security Functions
|
||||
|
||||
SchemaHierarchy_SystemSpatialDataTypes = Spatial Data Types
|
||||
|
||||
SchemaHierarchy_SystemStringFunctions = String Functions
|
||||
|
||||
SchemaHierarchy_SystemSystemStatisticalFunctions = System Statistical Functions
|
||||
|
||||
SchemaHierarchy_SystemTextAndImageFunctions = Text and Image Functions
|
||||
|
||||
SchemaHierarchy_SystemUnicodeCharacterStrings = Unicode Character Strings
|
||||
|
||||
SchemaHierarchy_AggregateFunctions = Aggregate Functions
|
||||
|
||||
SchemaHierarchy_ScalarValuedFunctions = Scalar-valued Functions
|
||||
|
||||
SchemaHierarchy_TableValuedFunctions = Table-valued Functions
|
||||
|
||||
SchemaHierarchy_SystemExtendedStoredProcedures = System Extended Stored Procedures
|
||||
|
||||
SchemaHierarchy_BuiltInType = Built-in Types
|
||||
|
||||
SchemaHierarchy_BuiltInServerRole = Built-in Server Roles
|
||||
|
||||
SchemaHierarchy_UserWithPassword = User with Password
|
||||
|
||||
SchemaHierarchy_SearchPropertyList = Search Property List
|
||||
|
||||
SchemaHierarchy_SecurityPolicies = Security Policies
|
||||
|
||||
SchemaHierarchy_SecurityPredicates = Security Predicates
|
||||
|
||||
SchemaHierarchy_ServerRole = Server Role
|
||||
|
||||
SchemaHierarchy_SearchPropertyLists = Search Property Lists
|
||||
|
||||
SchemaHierarchy_ColumnStoreIndexes = Column Store Indexes
|
||||
|
||||
SchemaHierarchy_TableTypeIndexes = Table Type Indexes
|
||||
|
||||
SchemaHierarchy_ServerInstance = ServerInstance
|
||||
|
||||
SchemaHierarchy_SelectiveXmlIndexes = Selective XML Indexes
|
||||
|
||||
SchemaHierarchy_XmlNamespaces = XML Namespaces
|
||||
|
||||
SchemaHierarchy_XmlTypedPromotedPaths = XML Typed Promoted Paths
|
||||
|
||||
SchemaHierarchy_SqlTypedPromotedPaths = T-SQL Typed Promoted Paths
|
||||
|
||||
SchemaHierarchy_DatabaseScopedCredentials = Database Scoped Credentials
|
||||
|
||||
SchemaHierarchy_ExternalDataSources = External Data Sources
|
||||
|
||||
SchemaHierarchy_ExternalFileFormats = External File Formats
|
||||
|
||||
SchemaHierarchy_ExternalResources = External Resources
|
||||
|
||||
SchemaHierarchy_ExternalTables = External Tables
|
||||
|
||||
SchemaHierarchy_AlwaysEncryptedKeys = Always Encrypted Keys
|
||||
|
||||
SchemaHierarchy_ColumnMasterKeys = Column Master Keys
|
||||
|
||||
SchemaHierarchy_ColumnEncryptionKeys = Column Encryption Keys
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0D61DC2B-DA66-441D-B9D0-F76C98F780F9}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.SqlTools.ServiceLayer</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'==''">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0D61DC2B-DA66-441D-B9D0-F76C98F780F9}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.SqlTools.ServiceLayer</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'==''">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// 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.Connection.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Information returned from a <see cref="CreateSessionRequest"/>.
|
||||
/// Contains success information, a <see cref="SessionId"/> to be used when
|
||||
/// requesting expansion of nodes, and a root node to display for this area.
|
||||
/// </summary>
|
||||
public class CreateSessionResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Boolean indicating if the connection was successful
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique ID to use when sending any requests for objects in the
|
||||
/// tree under the node
|
||||
/// </summary>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Information describing the base node in the tree
|
||||
/// </summary>
|
||||
public NodeInfo RootNode { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Establishes an Object Explorer tree session for a specific connection.
|
||||
/// This will create a connection to a specific server or database, register
|
||||
/// it for use in the
|
||||
/// </summary>
|
||||
public class CreateSessionRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ConnectionDetails, CreateSessionResponse> Type =
|
||||
RequestType<ConnectionDetails, CreateSessionResponse>.Create("objectexplorer/createsession");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Information returned from a <see cref="ExpandRequest"/>.
|
||||
/// </summary>
|
||||
public class ExpandResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID to use when sending any requests for objects in the
|
||||
/// tree under the node
|
||||
/// </summary>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Information describing the expanded nodes in the tree
|
||||
/// </summary>
|
||||
public NodeInfo[] Nodes { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameters to the <see cref="ExpandRequest"/>.
|
||||
/// </summary>
|
||||
public class ExpandParams
|
||||
{
|
||||
/// <summary>
|
||||
/// The Id returned from a <see cref="CreateSessionRequest"/>. This
|
||||
/// is used to disambiguate between different trees.
|
||||
/// </summary>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path identifying the node to expand. See <see cref="NodeInfo.NodePath"/> for details
|
||||
/// </summary>
|
||||
public string NodePath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A request to expand a
|
||||
/// </summary>
|
||||
public class ExpandRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns children of a given node as a <see cref="NodeInfo"/> array.
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<ExpandParams, ExpandResponse> Type =
|
||||
RequestType<ExpandParams, ExpandResponse>.Create("objectexplorer/expand");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Information describing a Node in the Object Explorer tree.
|
||||
/// Contains information required to display the Node to the user and
|
||||
/// to know whether actions such as expanding children is possible
|
||||
/// the node
|
||||
/// </summary>
|
||||
public class NodeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Path identifying this node: for example a table will be at ["server", "database", "tables", "tableName"].
|
||||
/// This enables rapid navigation of the tree without the need for a global registry of elements.
|
||||
/// The path functions as a unique ID and is used to disambiguate the node when sending requests for expansion.
|
||||
/// A common ID is needed since processes do not share address space and need a unique identifier
|
||||
/// </summary>
|
||||
public string NodePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the node - for example Server, Database, Folder, Table
|
||||
/// </summary>
|
||||
public string NodeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Label to display to the user, describing this node.
|
||||
/// </summary>
|
||||
public string Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this a leaf node (in which case no children can be generated) or
|
||||
/// is it expandable?
|
||||
/// </summary>
|
||||
public bool IsLeaf { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters to the <see cref="ExpandRequest"/>.
|
||||
/// </summary>
|
||||
public class RefreshParams
|
||||
{
|
||||
/// <summary>
|
||||
/// The Id returned from a <see cref="CreateSessionRequest"/>. This
|
||||
/// is used to disambiguate between different trees.
|
||||
/// </summary>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path identifying the node to expand. See <see cref="NodeInfo.NodePath"/> for details
|
||||
/// </summary>
|
||||
public string[] NodePath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A request to expand a
|
||||
/// </summary>
|
||||
public class RefreshRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns children of a given node as a <see cref="NodeInfo"/> array.
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<ExpandParams, NodeInfo[]> Type =
|
||||
RequestType<ExpandParams, NodeInfo[]>.Create("objectexplorer/refresh");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="ChildFactory"/> supports creation of <see cref="TreeNode"/> children
|
||||
/// for a class of objects in the tree. The
|
||||
/// </summary>
|
||||
public abstract class ChildFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The set of applicable parents for which the factory can create children.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// the string names for each <see cref="TreeNode.NodeType"/> that
|
||||
/// this factory can create children for
|
||||
/// </returns>
|
||||
public abstract IEnumerable<string> ApplicableParents();
|
||||
|
||||
/// <summary>
|
||||
/// Expands an element in the
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IEnumerable<TreeNode> Expand(TreeNode parent);
|
||||
|
||||
public abstract bool CanCreateChild(TreeNode parent, object context);
|
||||
public abstract TreeNode CreateChild(TreeNode parent, object context);
|
||||
|
||||
// TODO Consider whether Remove operations need to be supported
|
||||
//public abstract bool CanRemoveChild(TreeNode parent, object context);
|
||||
//public abstract int GetChildIndexToRemove(TreeNode parent, object context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// 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.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection class for <see cref="TreeNode"/>
|
||||
/// </summary>
|
||||
public sealed class NodeObservableCollection : ObservableCollection<TreeNode>
|
||||
{
|
||||
public event EventHandler Initialized;
|
||||
private int? numInits;
|
||||
private static int cleanupBlocker;
|
||||
|
||||
public bool IsInitialized
|
||||
{
|
||||
get { return numInits.HasValue && numInits == 0; }
|
||||
}
|
||||
|
||||
public bool IsPopulating
|
||||
{
|
||||
get { return numInits.HasValue && numInits != 0; }
|
||||
}
|
||||
|
||||
public void BeginInit()
|
||||
{
|
||||
if (!numInits.HasValue)
|
||||
{
|
||||
numInits = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numInits = numInits + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void EndInit()
|
||||
{
|
||||
IList<TreeNode> empty = null;
|
||||
EndInit(null, ref empty);
|
||||
}
|
||||
|
||||
public void EndInit(TreeNode parent, ref IList<TreeNode> deferredChildren)
|
||||
{
|
||||
if (numInits.HasValue &&
|
||||
numInits.Value == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
DoSort();
|
||||
|
||||
if (deferredChildren != null)
|
||||
{
|
||||
// Set the parents so the children know how to sort themselves
|
||||
foreach (var item in deferredChildren)
|
||||
{
|
||||
item.Parent = parent;
|
||||
}
|
||||
|
||||
deferredChildren = deferredChildren.OrderBy(x => x).ToList();
|
||||
|
||||
// Add the deferredChildren
|
||||
foreach (var item in deferredChildren)
|
||||
{
|
||||
this.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (deferredChildren != null)
|
||||
{
|
||||
deferredChildren.Clear();
|
||||
}
|
||||
numInits = numInits - 1;
|
||||
}
|
||||
|
||||
Initialized?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
numInits = numInits - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Repositions this child in the list
|
||||
/// </summary>
|
||||
public void ReSortChild(TreeNode child)
|
||||
{
|
||||
if (child == null)
|
||||
return;
|
||||
|
||||
List<TreeNode> sorted = this.OrderBy(x => x).ToList();
|
||||
|
||||
// Remove without cleanup
|
||||
try
|
||||
{
|
||||
cleanupBlocker++;
|
||||
Remove(child);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cleanupBlocker--;
|
||||
}
|
||||
|
||||
// Then insert
|
||||
for (int i = 0; i < sorted.Count; i++)
|
||||
{
|
||||
if (sorted[i] == child)
|
||||
{
|
||||
Insert(i, child);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
// Cleanup all the children
|
||||
Cleanup(this[index]);
|
||||
|
||||
base.RemoveItem(index);
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
// Cleanup all the children
|
||||
foreach (var child in this)
|
||||
{
|
||||
Cleanup(child);
|
||||
}
|
||||
|
||||
base.ClearItems();
|
||||
}
|
||||
|
||||
private static void Cleanup(TreeNode parent)
|
||||
{
|
||||
if (cleanupBlocker > 0 ||
|
||||
parent.Parent == null)
|
||||
return;
|
||||
|
||||
// TODO implement cleanup policy / pattern
|
||||
//ICleanupPattern parentAsCleanup = parent as ICleanupPattern;
|
||||
//if (parentAsCleanup != null)
|
||||
// parentAsCleanup.DoCleanup();
|
||||
|
||||
//foreach (var child in parent.Children)
|
||||
//{
|
||||
// Cleanup(child);
|
||||
//}
|
||||
|
||||
parent.Parent = null;
|
||||
}
|
||||
|
||||
private void DoSort()
|
||||
{
|
||||
List<TreeNode> sorted = this.OrderBy(x => x).ToList();
|
||||
for (int i = 0; i < sorted.Count(); i++)
|
||||
{
|
||||
int index = IndexOf(sorted[i]);
|
||||
if (index != i)
|
||||
{
|
||||
Move(IndexOf(sorted[i]), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum listing possible node types in the object explorer tree
|
||||
/// </summary>
|
||||
// TODO Consider replacing this with an auto-gen'd version
|
||||
public enum NodeTypes
|
||||
{
|
||||
None,
|
||||
SqlServersRoot,
|
||||
DatabaseInstance,
|
||||
DacInstance,
|
||||
ServerInstance,
|
||||
ScalarValuedFunctionInstance,
|
||||
TableValuedFunctionInstance,
|
||||
AggregateFunctionInstance,
|
||||
FileGroupInstance,
|
||||
StoredProcedureInstance,
|
||||
UserDefinedTableTypeInstance,
|
||||
ViewInstance,
|
||||
TableInstance,
|
||||
HistoryTableInstance,
|
||||
Databases,
|
||||
ExternalResources,
|
||||
ServerLevelSecurity,
|
||||
ServerLevelServerObjects,
|
||||
ServerLevelManagement,
|
||||
SystemDatabases,
|
||||
ServerLevelLinkedServerLogins,
|
||||
ServerLevelServerAudits,
|
||||
ServerLevelCryptographicProviders,
|
||||
ServerLevelCredentials,
|
||||
ServerLevelServerRoles,
|
||||
ServerLevelLogins,
|
||||
ServerLevelEventSessions,
|
||||
ServerLevelServerAuditSpecifications,
|
||||
ServerLevelEventNotifications,
|
||||
ServerLevelErrorMessages,
|
||||
ServerLevelServerTriggers,
|
||||
ServerLevelLinkedServers,
|
||||
ServerLevelEndpoints,
|
||||
DacInstancesFolder,
|
||||
Tables,
|
||||
Views,
|
||||
Synonyms,
|
||||
Programmability,
|
||||
ServiceBroker,
|
||||
Storage,
|
||||
Security,
|
||||
SystemTables,
|
||||
FileTables,
|
||||
SystemViews,
|
||||
StoredProcedures,
|
||||
Functions,
|
||||
ExtendedStoredProcedures,
|
||||
DatabaseTriggers,
|
||||
Defaults,
|
||||
Rules,
|
||||
Types,
|
||||
Assemblies,
|
||||
MessageTypes,
|
||||
Contracts,
|
||||
Queues,
|
||||
Services,
|
||||
Routes,
|
||||
DatabaseAndQueueEventNotifications,
|
||||
RemoteServiceBindings,
|
||||
BrokerPriorities,
|
||||
FileGroups,
|
||||
FullTextCatalogs,
|
||||
FullTextStopLists,
|
||||
SqlLogFiles,
|
||||
PartitionFunctions,
|
||||
PartitionSchemes,
|
||||
SearchPropertyLists,
|
||||
Users,
|
||||
Roles,
|
||||
Schemas,
|
||||
AsymmetricKeys,
|
||||
Certificates,
|
||||
SymmetricKeys,
|
||||
DatabaseEncryptionKeys,
|
||||
MasterKeys,
|
||||
Signatures,
|
||||
DatabaseAuditSpecifications,
|
||||
Columns,
|
||||
Keys,
|
||||
Constraints,
|
||||
Triggers,
|
||||
Indexes,
|
||||
Statistics,
|
||||
TableValuedFunctions,
|
||||
ScalarValuedFunctions,
|
||||
AggregateFunctions,
|
||||
SystemDataTypes,
|
||||
UserDefinedDataTypes,
|
||||
UserDefinedTableTypes,
|
||||
UserDefinedTypes,
|
||||
XmlSchemaCollections,
|
||||
SystemExactNumerics,
|
||||
SystemApproximateNumerics,
|
||||
SystemDateAndTimes,
|
||||
SystemCharacterStrings,
|
||||
SystemUnicodeCharacterStrings,
|
||||
SystemBinaryStrings,
|
||||
SystemOtherDataTypes,
|
||||
SystemClrDataTypes,
|
||||
SystemSpatialDataTypes,
|
||||
UserDefinedTableTypeColumns,
|
||||
UserDefinedTableTypeKeys,
|
||||
UserDefinedTableTypeConstraints,
|
||||
SystemStoredProcedures,
|
||||
StoredProcedureParameters,
|
||||
TableValuedFunctionParameters,
|
||||
ScalarValuedFunctionParameters,
|
||||
AggregateFunctionParameters,
|
||||
DatabaseRoles,
|
||||
ApplicationRoles,
|
||||
FileGroupFiles,
|
||||
SystemMessageTypes,
|
||||
SystemContracts,
|
||||
SystemServices,
|
||||
SystemQueues,
|
||||
Sequences,
|
||||
SecurityPolicies,
|
||||
DatabaseScopedCredentials,
|
||||
ExternalTables,
|
||||
ExternalResourceInstance,
|
||||
ExternalDataSources,
|
||||
ExternalFileFormats,
|
||||
ExternalTableInstance,
|
||||
AlwaysEncryptedKeys,
|
||||
ColumnMasterKeys,
|
||||
ColumnEncryptionKeys
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
//
|
||||
// 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.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for elements in the object explorer tree. Provides common methods for tree navigation
|
||||
/// and other core functionality
|
||||
/// </summary>
|
||||
public class TreeNode : IComparable<TreeNode>
|
||||
{
|
||||
private NodeObservableCollection children = new NodeObservableCollection();
|
||||
private TreeNode parent;
|
||||
private string nodePath;
|
||||
private string label;
|
||||
private ObjectExplorerService objectExplorerService;
|
||||
public const char PathPartSeperator = '/';
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with no required inputs
|
||||
/// </summary>
|
||||
public TreeNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that accepts a label to identify the node
|
||||
/// </summary>
|
||||
/// <param name="value">Label identifying the node</param>
|
||||
public TreeNode(string value)
|
||||
{
|
||||
// We intentionally do not valid this being null or empty since
|
||||
// some nodes may need to set it
|
||||
NodeValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value describing this node
|
||||
/// </summary>
|
||||
public string NodeValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the node - for example Server, Database, Folder, Table
|
||||
/// </summary>
|
||||
public string NodeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enum defining the type of the node - for example Server, Database, Folder, Table
|
||||
/// </summary>
|
||||
public NodeTypes NodeTypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Label to display to the user, describing this node.
|
||||
/// If not explicitly set this will fall back to the <see cref="NodeValue"/> but
|
||||
/// for many nodes such as the server, the display label will be different
|
||||
/// to the value.
|
||||
/// </summary>
|
||||
public string Label {
|
||||
get
|
||||
{
|
||||
if(label == null)
|
||||
{
|
||||
return NodeValue;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
set
|
||||
{
|
||||
label = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a leaf node (in which case no children can be generated) or
|
||||
/// is it expandable?
|
||||
/// </summary>
|
||||
public bool IsAlwaysLeaf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Message to show if this Node is in an error state. This indicates
|
||||
/// that children could be retrieved
|
||||
/// </summary>
|
||||
public string ErrorStateMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parent of this node
|
||||
/// </summary>
|
||||
public TreeNode Parent
|
||||
{
|
||||
get
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
set
|
||||
{
|
||||
parent = value;
|
||||
// Reset the node path since it's no longer valid
|
||||
nodePath = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path identifying this node: for example a table will be at ["server", "database", "tables", "tableName"].
|
||||
/// This enables rapid navigation of the tree without the need for a global registry of elements.
|
||||
/// The path functions as a unique ID and is used to disambiguate the node when sending requests for expansion.
|
||||
/// A common ID is needed since processes do not share address space and need a unique identifier
|
||||
/// </summary>
|
||||
public string GetNodePath()
|
||||
{
|
||||
if (nodePath == null)
|
||||
{
|
||||
GenerateNodePath();
|
||||
}
|
||||
return nodePath;
|
||||
}
|
||||
|
||||
private void GenerateNodePath()
|
||||
{
|
||||
string path = "";
|
||||
ObjectExplorerUtils.VisitChildAndParents(this, node =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(node.NodeValue))
|
||||
{
|
||||
// Hit a node with no NodeValue. This indicates we need to stop traversing
|
||||
return false;
|
||||
}
|
||||
// Otherwise add this value to the beginning of the path and keep iterating up
|
||||
path = string.Format(CultureInfo.InvariantCulture,
|
||||
"{0}{1}{2}", node.NodeValue, string.IsNullOrEmpty(path) ? "" : PathPartSeperator.ToString(), path);
|
||||
return true;
|
||||
});
|
||||
nodePath = path;
|
||||
}
|
||||
|
||||
public TreeNode FindNodeByPath(string path)
|
||||
{
|
||||
TreeNode nodeForPath = ObjectExplorerUtils.FindNode(this, node =>
|
||||
{
|
||||
return node.GetNodePath() == path;
|
||||
}, nodeToFilter =>
|
||||
{
|
||||
return path.StartsWith(nodeToFilter.GetNodePath());
|
||||
});
|
||||
|
||||
return nodeForPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts to a <see cref="NodeInfo"/> object for serialization with just the relevant properties
|
||||
/// needed to identify the node
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public NodeInfo ToNodeInfo()
|
||||
{
|
||||
return new NodeInfo()
|
||||
{
|
||||
IsLeaf = this.IsAlwaysLeaf,
|
||||
Label = this.Label,
|
||||
NodePath = this.GetNodePath(),
|
||||
NodeType = this.NodeType
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands this node and returns its children
|
||||
/// </summary>
|
||||
/// <returns>Children as an IList. This is the raw children collection, not a copy</returns>
|
||||
public IList<TreeNode> Expand()
|
||||
{
|
||||
// TODO consider why solution explorer has separate Children and Items options
|
||||
if (children.IsInitialized)
|
||||
{
|
||||
return children;
|
||||
}
|
||||
PopulateChildren();
|
||||
return children;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a readonly view of the currently defined children for this node.
|
||||
/// This does not expand the node at all
|
||||
/// Since the tree needs to keep track of parent relationships, directly
|
||||
/// adding to the list is not supported.
|
||||
/// </summary>
|
||||
/// <returns><see cref="IList{TreeNode}"/> containing all children for this node</returns>
|
||||
public IList<TreeNode> GetChildren()
|
||||
{
|
||||
return new ReadOnlyCollection<TreeNode>(children);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a child to the list of children under this node
|
||||
/// </summary>
|
||||
/// <param name="newChild"><see cref="TreeNode"/></param>
|
||||
public void AddChild(TreeNode newChild)
|
||||
{
|
||||
Validate.IsNotNull(nameof(newChild), newChild);
|
||||
children.Add(newChild);
|
||||
newChild.Parent = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optional context to help with lookup of children
|
||||
/// </summary>
|
||||
public virtual object GetContext()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to convert context to expected format
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type to convert to</typeparam>
|
||||
/// <returns>context as expected type of null if it doesn't match</returns>
|
||||
public T GetContextAs<T>()
|
||||
where T : class
|
||||
{
|
||||
return GetContext() as T;
|
||||
}
|
||||
|
||||
public T ParentAs<T>()
|
||||
where T : TreeNode
|
||||
{
|
||||
return Parent as T;
|
||||
}
|
||||
|
||||
protected void PopulateChildren()
|
||||
{
|
||||
Debug.Assert(IsAlwaysLeaf == false);
|
||||
|
||||
SmoQueryContext context = this.GetContextAs<SmoQueryContext>();
|
||||
|
||||
if (children.IsPopulating || context == null)
|
||||
return;
|
||||
|
||||
children.Clear();
|
||||
BeginChildrenInit();
|
||||
|
||||
try
|
||||
{
|
||||
IEnumerable<ChildFactory> childFactories = context.GetObjectExplorerService().GetApplicableChildFactories(this);
|
||||
if (childFactories != null)
|
||||
{
|
||||
foreach (var factory in childFactories)
|
||||
{
|
||||
IEnumerable<TreeNode> items = factory.Expand(this);
|
||||
if (items != null)
|
||||
{
|
||||
foreach (TreeNode item in items)
|
||||
{
|
||||
children.Add(item);
|
||||
item.Parent = this;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndChildrenInit();
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginChildrenInit()
|
||||
{
|
||||
children.BeginInit();
|
||||
}
|
||||
|
||||
public void EndChildrenInit()
|
||||
{
|
||||
children.EndInit();
|
||||
// TODO consider use of deferred children and if it's necessary
|
||||
// children.EndInit(this, ref deferredChildren);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sort Priority to help when ordering elements in the tree
|
||||
/// </summary>
|
||||
public int? SortPriority { get; set; }
|
||||
|
||||
protected virtual int CompareSamePriorities(TreeNode thisItem, TreeNode otherItem)
|
||||
{
|
||||
return string.Compare(thisItem.NodeValue, otherItem.NodeValue, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public int CompareTo(TreeNode other)
|
||||
{
|
||||
|
||||
if (!this.SortPriority.HasValue &&
|
||||
!other.SortPriority.HasValue)
|
||||
{
|
||||
return CompareSamePriorities(this, other);
|
||||
}
|
||||
|
||||
if (this.SortPriority.HasValue &&
|
||||
!other.SortPriority.HasValue)
|
||||
{
|
||||
return -1; // this is above other
|
||||
}
|
||||
if (!this.SortPriority.HasValue)
|
||||
{
|
||||
return 1; // this is below other
|
||||
}
|
||||
|
||||
// Both have sort priority
|
||||
int priDiff = this.SortPriority.Value - other.SortPriority.Value;
|
||||
if (priDiff < 0)
|
||||
return -1; // this is below other
|
||||
if (priDiff == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
public class TreeNodeWithContext
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates which type of server a given node type is valid for
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ValidForFlag
|
||||
{
|
||||
Sql2005 = 0x01,
|
||||
Sql2008 = 0x02,
|
||||
Sql2012 = 0x04,
|
||||
Sql2014 = 0x08,
|
||||
Azure = 0x10,
|
||||
NotDebugInstance = 0x20,
|
||||
NotContainedUser = 0x40,
|
||||
AzureV12 = 0x80,
|
||||
Sql2016 = 0x100,
|
||||
CanConnectToMaster = 0x200,
|
||||
CanViewSecurity = 0x400,
|
||||
SqlvNext = 0x800,
|
||||
All = Sql2005 | Sql2008 | Sql2012 | Sql2014 | Sql2016 | SqlvNext | Azure | AzureV12
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
//
|
||||
// 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.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.Hosting;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
{
|
||||
/// <summary>
|
||||
/// A Service to support querying server and database information as an Object Explorer tree.
|
||||
/// The APIs used for this are modeled closely on the VSCode TreeExplorerNodeProvider API.
|
||||
/// </summary>
|
||||
public class ObjectExplorerService : HostedService<ObjectExplorerService>, IComposableService
|
||||
{
|
||||
internal const string uriPrefix = "objectexplorer://";
|
||||
|
||||
// Instance of the connection service, used to get the connection info for a given owner URI
|
||||
private ConnectionService connectionService;
|
||||
private IProtocolEndpoint serviceHost;
|
||||
private Dictionary<string, ObjectExplorerSession> sessionMap;
|
||||
private readonly Lazy<Dictionary<string, HashSet<ChildFactory>>> applicableNodeChildFactories;
|
||||
private IMultiServiceProvider serviceProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Singleton constructor
|
||||
/// </summary>
|
||||
public ObjectExplorerService()
|
||||
{
|
||||
sessionMap = new Dictionary<string, ObjectExplorerSession>();
|
||||
applicableNodeChildFactories = new Lazy<Dictionary<string, HashSet<ChildFactory>>>(() => PopulateFactories());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal for testing only
|
||||
/// </summary>
|
||||
internal ObjectExplorerService(ExtensionServiceProvider serviceProvider)
|
||||
: this()
|
||||
{
|
||||
SetServiceProvider(serviceProvider);
|
||||
}
|
||||
|
||||
private Dictionary<string, HashSet<ChildFactory>> ApplicableNodeChildFactories
|
||||
{
|
||||
get
|
||||
{
|
||||
return applicableNodeChildFactories.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// As an <see cref="IComposableService"/>, this will be set whenever the service is initialized
|
||||
/// via an <see cref="IMultiServiceProvider"/>
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
public override void SetServiceProvider(IMultiServiceProvider provider)
|
||||
{
|
||||
Validate.IsNotNull(nameof(provider), provider);
|
||||
serviceProvider = provider;
|
||||
connectionService = provider.GetService<ConnectionService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the service with the service host and registers request handlers.
|
||||
/// </summary>
|
||||
/// <param name="serviceHost">The service host instance to register with</param>
|
||||
public override void InitializeService(IProtocolEndpoint serviceHost)
|
||||
{
|
||||
this.serviceHost = serviceHost;
|
||||
// Register handlers for requests
|
||||
serviceHost.SetRequestHandler(CreateSessionRequest.Type, HandleCreateSessionRequest);
|
||||
serviceHost.SetRequestHandler(ExpandRequest.Type, HandleExpandRequest);
|
||||
}
|
||||
|
||||
internal async Task HandleCreateSessionRequest(ConnectionDetails connectionDetails, RequestContext<CreateSessionResponse> context)
|
||||
{
|
||||
Logger.Write(LogLevel.Verbose, "HandleCreateSessionRequest");
|
||||
Func<Task<CreateSessionResponse>> doCreateSession = async () =>
|
||||
{
|
||||
Validate.IsNotNull(nameof(connectionDetails), connectionDetails);
|
||||
Validate.IsNotNull(nameof(context), context);
|
||||
|
||||
string uri = GenerateUri(connectionDetails);
|
||||
|
||||
ObjectExplorerSession session;
|
||||
if (!sessionMap.TryGetValue(uri, out session))
|
||||
{
|
||||
// Establish a connection to the specified server/database
|
||||
session = await DoCreateSession(connectionDetails, uri);
|
||||
}
|
||||
|
||||
CreateSessionResponse response;
|
||||
if (session == null)
|
||||
{
|
||||
response = new CreateSessionResponse() { Success = false };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else we have a session available, response with existing session information
|
||||
response = new CreateSessionResponse()
|
||||
{
|
||||
Success = true,
|
||||
RootNode = session.Root.ToNodeInfo(),
|
||||
SessionId = session.Uri
|
||||
};
|
||||
}
|
||||
return response;
|
||||
};
|
||||
|
||||
await HandleRequestAsync(doCreateSession, context, "HandleCreateSessionRequest");
|
||||
}
|
||||
|
||||
internal async Task<NodeInfo[]> ExpandNode(ObjectExplorerSession session, string nodePath)
|
||||
{
|
||||
return await Task.Factory.StartNew(() =>
|
||||
{
|
||||
NodeInfo[] nodes = null;
|
||||
TreeNode node = session.Root.FindNodeByPath(nodePath);
|
||||
if(node != null)
|
||||
{
|
||||
nodes = node.Expand().Select(x => x.ToNodeInfo()).ToArray();
|
||||
}
|
||||
return nodes;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Establishes a new session and stores its information
|
||||
/// </summary>
|
||||
/// <returns><see cref="ObjectExplorerSession"/> object if successful, null if unsuccessful</returns>
|
||||
internal async Task<ObjectExplorerSession> DoCreateSession(ConnectionDetails connectionDetails, string uri)
|
||||
{
|
||||
ObjectExplorerSession session;
|
||||
|
||||
ConnectParams connectParams = new ConnectParams() { OwnerUri = uri, Connection = connectionDetails };
|
||||
|
||||
ConnectionCompleteParams connectionResult = await Connect(connectParams);
|
||||
if (connectionResult == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
session = ObjectExplorerSession.CreateSession(connectionResult, serviceProvider);
|
||||
sessionMap[uri] = session;
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
private async Task<ConnectionCompleteParams> Connect(ConnectParams connectParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
// open connection based on request details
|
||||
ConnectionCompleteParams result = await connectionService.Connect(connectParams);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Send a connection failed error message in this case.
|
||||
ConnectionCompleteParams result = new ConnectionCompleteParams()
|
||||
{
|
||||
Messages = ex.ToString()
|
||||
};
|
||||
await serviceHost.SendEvent(ConnectionCompleteNotification.Type, result);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task HandleExpandRequest(ExpandParams expandParams, RequestContext<ExpandResponse> context)
|
||||
{
|
||||
Logger.Write(LogLevel.Verbose, "HandleExpandRequest");
|
||||
Func<Task<ExpandResponse>> expandNode = async () =>
|
||||
{
|
||||
Validate.IsNotNull(nameof(expandParams), expandParams);
|
||||
Validate.IsNotNull(nameof(context), context);
|
||||
|
||||
string uri = expandParams.SessionId;
|
||||
ObjectExplorerSession session = null;
|
||||
NodeInfo[] nodes = null;
|
||||
if (sessionMap.ContainsKey(uri))
|
||||
{
|
||||
session = sessionMap[uri];
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: error
|
||||
}
|
||||
|
||||
|
||||
if (session != null)
|
||||
{
|
||||
// Establish a connection to the specified server/database
|
||||
nodes = await ExpandNode(session, expandParams.NodePath);
|
||||
}
|
||||
|
||||
ExpandResponse response;
|
||||
response = new ExpandResponse() { Nodes = nodes, SessionId = uri };
|
||||
return response;
|
||||
};
|
||||
|
||||
await HandleRequestAsync(expandNode, context, "HandleExpandRequest");
|
||||
}
|
||||
|
||||
private async Task HandleRequestAsync<T>(Func<Task<T>> handler, RequestContext<T> requestContext, string requestType)
|
||||
{
|
||||
Logger.Write(LogLevel.Verbose, requestType);
|
||||
|
||||
try
|
||||
{
|
||||
T result = await handler();
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await requestContext.SendError(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a URI for object explorer using a similar pattern to Mongo DB (which has URI-based database definition)
|
||||
/// as this should ensure uniqueness
|
||||
/// </summary>
|
||||
/// <param name="details"></param>
|
||||
/// <returns>string representing a URI</returns>
|
||||
/// <remarks>Internal for testing purposes only</remarks>
|
||||
internal static string GenerateUri(ConnectionDetails details)
|
||||
{
|
||||
Validate.IsNotNull("details", details);
|
||||
string uri = string.Format(CultureInfo.InvariantCulture, "{0}{1}", uriPrefix, Uri.EscapeUriString(details.ServerName));
|
||||
uri = AppendIfExists(uri, "databaseName", details.DatabaseName);
|
||||
uri = AppendIfExists(uri, "user", details.UserName);
|
||||
return uri;
|
||||
}
|
||||
|
||||
private static string AppendIfExists(string uri, string propertyName, string propertyValue)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(propertyValue))
|
||||
{
|
||||
uri += string.Format(CultureInfo.InvariantCulture, ";{0}={1}", propertyName, Uri.EscapeUriString(propertyValue));
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
public IEnumerable<ChildFactory> GetApplicableChildFactories(TreeNode item)
|
||||
{
|
||||
if (ApplicableNodeChildFactories != null)
|
||||
{
|
||||
HashSet<ChildFactory> applicableFactories;
|
||||
if (ApplicableNodeChildFactories.TryGetValue(item.NodeTypeId.ToString(), out applicableFactories))
|
||||
{
|
||||
return applicableFactories;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal Dictionary<string, HashSet<ChildFactory>> PopulateFactories()
|
||||
{
|
||||
VerifyServicesInitialized();
|
||||
|
||||
var childFactories = new Dictionary<string, HashSet<ChildFactory>>();
|
||||
// Create our list of all NodeType to ChildFactory objects so we can expand appropriately
|
||||
foreach (var factory in serviceProvider.GetServices<ChildFactory>())
|
||||
{
|
||||
var parents = factory.ApplicableParents();
|
||||
if (parents != null)
|
||||
{
|
||||
foreach (var parent in parents)
|
||||
{
|
||||
AddToApplicableChildFactories(childFactories, factory, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return childFactories;
|
||||
}
|
||||
|
||||
private void VerifyServicesInitialized()
|
||||
{
|
||||
if (serviceProvider == null)
|
||||
{
|
||||
throw new InvalidOperationException(SqlTools.Hosting.Localization.sr.ServiceProviderNotSet);
|
||||
}
|
||||
if (connectionService == null)
|
||||
{
|
||||
throw new InvalidOperationException(SqlTools.Hosting.Localization.sr.ServiceProviderNotSet);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddToApplicableChildFactories(Dictionary<string, HashSet<ChildFactory>> childFactories, ChildFactory factory, string parent)
|
||||
{
|
||||
HashSet<ChildFactory> applicableFactories;
|
||||
if (!childFactories.TryGetValue(parent, out applicableFactories))
|
||||
{
|
||||
applicableFactories = new HashSet<ChildFactory>();
|
||||
childFactories[parent] = applicableFactories;
|
||||
}
|
||||
applicableFactories.Add(factory);
|
||||
}
|
||||
|
||||
internal class ObjectExplorerSession
|
||||
{
|
||||
private ConnectionService connectionService;
|
||||
private IMultiServiceProvider serviceProvider;
|
||||
|
||||
// TODO decide whether a cache is needed to handle lookups in elements with a large # children
|
||||
//private const int Cachesize = 10000;
|
||||
//private Cache<string, NodeMapping> cache;
|
||||
|
||||
public ObjectExplorerSession(string uri, TreeNode root, IMultiServiceProvider serviceProvider, ConnectionService connectionService)
|
||||
{
|
||||
Validate.IsNotNullOrEmptyString("uri", uri);
|
||||
Validate.IsNotNull("root", root);
|
||||
Uri = uri;
|
||||
Root = root;
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.connectionService = connectionService;
|
||||
}
|
||||
|
||||
public string Uri { get; private set; }
|
||||
public TreeNode Root { get; private set; }
|
||||
|
||||
public static ObjectExplorerSession CreateSession(ConnectionCompleteParams response, IMultiServiceProvider serviceProvider)
|
||||
{
|
||||
TreeNode serverNode = new ServerNode(response, serviceProvider);
|
||||
return new ObjectExplorerSession(response.OwnerUri, serverNode, serviceProvider, serviceProvider.GetService<ConnectionService>());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// 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 Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class for Object Explorer related operations
|
||||
/// </summary>
|
||||
public static class ObjectExplorerUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Visitor that walks all nodes from the child to the root node, unless the
|
||||
/// <paramref name="visitor"/> function indicates that this should stop traversing
|
||||
/// </summary>
|
||||
/// <param name="child">node to start traversing at</param>
|
||||
/// <param name="visitor">Predicate function that accesses the tree and
|
||||
/// determines whether to stop going further up the tree</param>
|
||||
/// <returns>
|
||||
/// boolean - true to continue navigating up the tree, false to end the loop
|
||||
/// and return early
|
||||
/// </returns>
|
||||
public static bool VisitChildAndParents(TreeNode child, Predicate<TreeNode> visitor)
|
||||
{
|
||||
if (child == null)
|
||||
{
|
||||
// End case: all nodes have been visited
|
||||
return true;
|
||||
}
|
||||
|
||||
// Visit the child first, then go up the parents
|
||||
if (!visitor(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return VisitChildAndParents(child.Parent, visitor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a node by traversing the tree starting from the given node through all the children
|
||||
/// </summary>
|
||||
/// <param name="node">node to start traversing at</param>
|
||||
/// <param name="condition">Predicate function that accesses the tree and
|
||||
/// determines whether to stop going further up the tree</param>
|
||||
/// <param name="filter">Predicate function to filter the children when traversing</param>
|
||||
/// <returns>A Tree Node that matches the condition</returns>
|
||||
public static TreeNode FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter)
|
||||
{
|
||||
if(node == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (condition(node))
|
||||
{
|
||||
return node;
|
||||
}
|
||||
foreach (var child in node.GetChildren())
|
||||
{
|
||||
if (filter != null && filter(child))
|
||||
{
|
||||
TreeNode childNode = FindNode(child, condition, filter);
|
||||
if (childNode != null)
|
||||
{
|
||||
return childNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
internal partial class DatabaseInstanceTreeNode
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the context and ensures that
|
||||
/// </summary>
|
||||
protected override void EnsureContextInitialized()
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
base.EnsureContextInitialized();
|
||||
Database db = SmoObject as Database;
|
||||
if (context != null && db != null)
|
||||
{
|
||||
context.Database = db;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a folder node in the tree
|
||||
/// </summary>
|
||||
public class FolderNode : SmoTreeNode
|
||||
{
|
||||
/// <summary>
|
||||
/// For folders, this copies the context of its parent if available
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override object GetContext()
|
||||
{
|
||||
return Parent?.GetContext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For folders, searches for its parent's SMO object rather than copying for itself
|
||||
/// </summary>
|
||||
/// <returns><see cref="NamedSmoObject"/> from this parent's parent, or null if not found</returns>
|
||||
public override NamedSmoObject GetParentSmoObject()
|
||||
{
|
||||
return ParentAs<SmoTreeNode>()?.GetParentSmoObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// 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.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Server node implementation
|
||||
/// </summary>
|
||||
public class ServerNode : TreeNode
|
||||
{
|
||||
private ConnectionSummary connectionSummary;
|
||||
private ServerInfo serverInfo;
|
||||
private string connectionUri;
|
||||
private Lazy<SmoQueryContext> context;
|
||||
private ConnectionService connectionService;
|
||||
private SmoServerCreator serverCreator;
|
||||
|
||||
public ServerNode(ConnectionCompleteParams connInfo, IMultiServiceProvider serviceProvider)
|
||||
: base()
|
||||
{
|
||||
Validate.IsNotNull(nameof(connInfo), connInfo);
|
||||
Validate.IsNotNull("connInfo.ConnectionSummary", connInfo.ConnectionSummary);
|
||||
Validate.IsNotNull(nameof(serviceProvider), serviceProvider);
|
||||
|
||||
this.connectionSummary = connInfo.ConnectionSummary;
|
||||
this.serverInfo = connInfo.ServerInfo;
|
||||
this.connectionUri = connInfo.OwnerUri;
|
||||
|
||||
this.connectionService = serviceProvider.GetService<ConnectionService>();
|
||||
|
||||
this.context = new Lazy<SmoQueryContext>(() => CreateContext(serviceProvider));
|
||||
|
||||
NodeValue = connectionSummary.ServerName;
|
||||
IsAlwaysLeaf = false;
|
||||
NodeType = NodeTypes.ServerInstance.ToString();
|
||||
NodeTypeId = NodeTypes.ServerInstance;
|
||||
Label = GetConnectionLabel();
|
||||
}
|
||||
|
||||
internal SmoServerCreator ServerCreator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (serverCreator == null)
|
||||
{
|
||||
ServerCreator = new SmoServerCreator();
|
||||
}
|
||||
return serverCreator;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.serverCreator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the label to display to the user.
|
||||
/// </summary>
|
||||
internal string GetConnectionLabel()
|
||||
{
|
||||
string userName = connectionSummary.UserName;
|
||||
|
||||
// TODO Domain and username is not yet supported on .Net Core.
|
||||
// Consider passing as an input from the extension where this can be queried
|
||||
//if (string.IsNullOrWhiteSpace(userName))
|
||||
//{
|
||||
// userName = Environment.UserDomainName + @"\" + Environment.UserName;
|
||||
//}
|
||||
|
||||
// TODO Consider adding IsAuthenticatingDatabaseMaster check in the code and
|
||||
// referencing result here
|
||||
if (!string.IsNullOrWhiteSpace(connectionSummary.DatabaseName) &&
|
||||
string.Compare(connectionSummary.DatabaseName, CommonConstants.MasterDatabaseName, StringComparison.OrdinalIgnoreCase) != 0 &&
|
||||
(serverInfo.IsCloud /* || !ci.IsAuthenticatingDatabaseMaster */))
|
||||
{
|
||||
// We either have an azure with a database specified or a Denali database using a contained user
|
||||
userName += ", " + connectionSummary.DatabaseName;
|
||||
}
|
||||
|
||||
string label;
|
||||
if (string.IsNullOrWhiteSpace(userName))
|
||||
{
|
||||
label = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} ({1} {2})",
|
||||
connectionSummary.ServerName,
|
||||
"SQL Server",
|
||||
serverInfo.ServerVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
label = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} ({1} {2} - {3})",
|
||||
connectionSummary.ServerName,
|
||||
"SQL Server",
|
||||
serverInfo.ServerVersion,
|
||||
userName);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
private SmoQueryContext CreateContext(IMultiServiceProvider serviceProvider)
|
||||
{
|
||||
string exceptionMessage;
|
||||
ConnectionInfo connectionInfo;
|
||||
SqlConnection connection = null;
|
||||
// Get server object from connection
|
||||
if (!connectionService.TryFindConnection(this.connectionUri, out connectionInfo) ||
|
||||
connectionInfo.AllConnections == null || connectionInfo.AllConnections.Count == 0)
|
||||
{
|
||||
ErrorStateMessage = string.Format(CultureInfo.CurrentCulture,
|
||||
SR.ServerNodeConnectionError, connectionSummary.ServerName);
|
||||
return null;
|
||||
}
|
||||
//TODO: figure out how to use existing connections
|
||||
DbConnection dbConnection = connectionInfo.AllConnections.First();
|
||||
ReliableSqlConnection reliableSqlConnection = dbConnection as ReliableSqlConnection;
|
||||
SqlConnection sqlConnection = dbConnection as SqlConnection;
|
||||
if (reliableSqlConnection != null)
|
||||
{
|
||||
connection = reliableSqlConnection.GetUnderlyingConnection();
|
||||
}
|
||||
else if (sqlConnection != null)
|
||||
{
|
||||
connection = sqlConnection;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorStateMessage = string.Format(CultureInfo.CurrentCulture,
|
||||
SR.ServerNodeConnectionError, connectionSummary.ServerName);
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Server server = ServerCreator.Create(connection);
|
||||
return new SmoQueryContext(server, serviceProvider)
|
||||
{
|
||||
Parent = server
|
||||
};
|
||||
}
|
||||
catch (ConnectionFailureException cfe)
|
||||
{
|
||||
exceptionMessage = cfe.Message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exceptionMessage = ex.Message;
|
||||
}
|
||||
|
||||
Logger.Write(LogLevel.Error, "Exception at ServerNode.CreateContext() : " + exceptionMessage);
|
||||
this.ErrorStateMessage = string.Format(SR.TreeNodeError, exceptionMessage);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object GetContext()
|
||||
{
|
||||
return context.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal for testing purposes only
|
||||
/// </summary>
|
||||
internal class SmoServerCreator
|
||||
{
|
||||
public virtual Server Create(SqlConnection connection)
|
||||
{
|
||||
ServerConnection serverConn = new ServerConnection(connection);
|
||||
return new Server(serverConn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
public class SmoChildFactoryBase : ChildFactory
|
||||
{
|
||||
public override IEnumerable<string> ApplicableParents()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override IEnumerable<TreeNode> Expand(TreeNode parent)
|
||||
{
|
||||
//parent.BeginChildrenInit();
|
||||
try
|
||||
{
|
||||
List<TreeNode> allChildren = new List<TreeNode>();
|
||||
OnExpandPopulateFolders(allChildren, parent);
|
||||
RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent);
|
||||
OnExpandPopulateNonFolders(allChildren, parent);
|
||||
OnBeginAsyncOperations(parent);
|
||||
return allChildren;
|
||||
}
|
||||
finally
|
||||
{
|
||||
//parent.EndChildrenInit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates any folders for a given parent node
|
||||
/// </summary>
|
||||
/// <param name="allChildren">List to which nodes should be added</param>
|
||||
/// <param name="parent">Parent the nodes are being added to</param>
|
||||
protected virtual void OnExpandPopulateFolders(IList<TreeNode> allChildren, TreeNode parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates any non-folder nodes such as specific items in the tree.
|
||||
/// </summary>
|
||||
/// <param name="allChildren">List to which nodes should be added</param>
|
||||
/// <param name="parent">Parent the nodes are being added to</param>
|
||||
protected virtual void OnExpandPopulateNonFolders(IList<TreeNode> allChildren, TreeNode parent)
|
||||
{
|
||||
if (ChildQuerierTypes == null)
|
||||
{
|
||||
// This node does not support non-folder children
|
||||
return;
|
||||
}
|
||||
SmoQueryContext context = parent.GetContextAs<SmoQueryContext>();
|
||||
Validate.IsNotNull(nameof(context), context);
|
||||
IEnumerable<SmoQuerier> queriers = context.ServiceProvider.GetServices<SmoQuerier>(q => IsCompatibleQuerier(q));
|
||||
foreach (var querier in queriers)
|
||||
{
|
||||
foreach(var smoObject in querier.Query(context))
|
||||
{
|
||||
if (smoObject == null)
|
||||
{
|
||||
Console.WriteLine("smoObject should not be null");
|
||||
}
|
||||
TreeNode childNode = CreateChild(parent, smoObject);
|
||||
if (childNode != null)
|
||||
{
|
||||
allChildren.Add(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsCompatibleQuerier(SmoQuerier querier)
|
||||
{
|
||||
if (ChildQuerierTypes == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Type actualType = querier.GetType();
|
||||
foreach (Type childType in ChildQuerierTypes)
|
||||
{
|
||||
// We will accept any querier that is compatible with the listed querier type
|
||||
if (childType.IsAssignableFrom(actualType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters out invalid folders if they cannot be displayed for the current server version
|
||||
/// </summary>
|
||||
/// <param name="allChildren">List to which nodes should be added</param>
|
||||
/// <param name="parent">Parent the nodes are being added to</param>
|
||||
protected virtual void RemoveFoldersFromInvalidSqlServerVersions(IList<TreeNode> allChildren, TreeNode parent)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO Assess whether async operations node is required
|
||||
protected virtual void OnBeginAsyncOperations(TreeNode parent)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanCreateChild(TreeNode parent, object context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override TreeNode CreateChild(TreeNode parent, object context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual void InitializeChild(TreeNode child, object context)
|
||||
{
|
||||
NamedSmoObject smoObj = context as NamedSmoObject;
|
||||
if (smoObj == null)
|
||||
{
|
||||
Debug.WriteLine("context is not a NamedSmoObject. type: " + context.GetType());
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoTreeNode childAsMeItem = (SmoTreeNode)child;
|
||||
childAsMeItem.CacheInfoFromModel(smoObj);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual Type[] ChildQuerierTypes {
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any final validation of the object to be added passes, and false
|
||||
/// if validation fails. This provides a chance to filter specific items out of a list
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="contextObject"></param>
|
||||
/// <returns>boolean</returns>
|
||||
public virtual bool PassesFinalFilters(TreeNode parent, object context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper to convert non-generic Smo enumerables to generic enumerable types for easier use in
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class SmoCollectionWrapper<T> : IEnumerable<T>
|
||||
where T : SqlSmoObject
|
||||
{
|
||||
private SmoCollectionBase collection;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor which accepts a <see cref="SmoCollectionBase"/> containing the objects
|
||||
/// to wrap
|
||||
/// </summary>
|
||||
/// <param name="collection"><see cref="SmoCollectionBase"/> or null if none were set</param>
|
||||
public SmoCollectionWrapper(SmoCollectionBase collection)
|
||||
{
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IEnumerable{T}.GetEnumerator"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
foreach(Object obj in collection)
|
||||
{
|
||||
yield return (T)obj;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IEnumerable.GetEnumerator"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return collection?.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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 Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="SmoQuerier"/> handles SMO queries for one or more SMO object types.
|
||||
/// The <see cref="SupportedObjectTypes"/> property defines which types can be queried.
|
||||
///
|
||||
/// To query multiple
|
||||
/// </summary>
|
||||
public abstract class SmoQuerier : IComposableService
|
||||
{
|
||||
public abstract Type[] SupportedObjectTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Queries SMO for a collection of objects using the <see cref="SmoQueryContext"/>
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IEnumerable<SqlSmoObject> Query(SmoQueryContext context);
|
||||
|
||||
internal IMultiServiceProvider ServiceProvider
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void SetServiceProvider(IMultiServiceProvider provider)
|
||||
{
|
||||
ServiceProvider = provider;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Context object containing key properties needed to query for SMO objects
|
||||
/// </summary>
|
||||
public class SmoQueryContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a context object with a server to use as the basis for any queries
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
public SmoQueryContext(Server server, IMultiServiceProvider serviceProvider)
|
||||
{
|
||||
Server = server;
|
||||
ServiceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The server SMO will query against
|
||||
/// </summary>
|
||||
public Server Server { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional Database context object to query against
|
||||
/// </summary>
|
||||
public Database Database { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parent of a give node to use for queries
|
||||
/// </summary>
|
||||
public SmoObjectBase Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A query loader that can be used to find <see cref="SmoQuerier"/> objects
|
||||
/// for specific SMO types
|
||||
/// </summary>
|
||||
public IMultiServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to cast a parent to a specific type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T ParentAs<T>()
|
||||
where T : TreeNode
|
||||
{
|
||||
return Parent as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ObjectExplorerService"/> if available, by looking it up
|
||||
/// from the <see cref="ServiceProvider"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown if the <see cref="ServiceProvider"/> is not set or the <see cref="ObjectExplorerService"/>
|
||||
/// isn't available from that provider
|
||||
/// </exception>
|
||||
public ObjectExplorerService GetObjectExplorerService()
|
||||
{
|
||||
if (ServiceProvider == null)
|
||||
{
|
||||
throw new InvalidOperationException(SqlTools.Hosting.Localization.sr.ServiceProviderNotSet);
|
||||
}
|
||||
ObjectExplorerService service = ServiceProvider.GetService<ObjectExplorerService>();
|
||||
if (service == null)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
|
||||
SqlTools.Hosting.Localization.sr.ServiceNotFound, nameof(ObjectExplorerService)));
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
/// <summary>
|
||||
/// Copies the context for use by another node
|
||||
/// </summary>
|
||||
/// <param name="parent">New Parent to set</param>
|
||||
/// <returns>new <see cref="SmoQueryContext"/> with all fields except <see cref="Parent"/> the same</returns>
|
||||
public SmoQueryContext CopyWithParent(SmoObjectBase parent)
|
||||
{
|
||||
SmoQueryContext context = new SmoQueryContext(this.Server, this.ServiceProvider)
|
||||
{
|
||||
Database = this.Database,
|
||||
Parent = parent
|
||||
};
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
<#@ template debug="false" hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#@ assembly name="System.Xml.dll" #>
|
||||
<#@ import namespace="System" #>
|
||||
<#@ import namespace="System.Globalization" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Xml" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.IO" #>
|
||||
// This file was generated by a T4 Template. Do not modify directly, instead update the SmoQueryModelDefinition.xml file
|
||||
// and re-run the T4 template. This can be done in Visual Studio by right-click in and choosing "Run Custom Tool",
|
||||
// or from the command-line on any platform by running "build.cmd -Target=CodeGen" or "build.sh -Target=CodeGen".
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Broker;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
<#
|
||||
var directory = Path.GetDirectoryName(Host.TemplateFile);
|
||||
string xmlFile = Path.Combine(directory, "SmoQueryModelDefinition.xml");
|
||||
|
||||
/////////
|
||||
// Now generate all the Query methods
|
||||
/////////
|
||||
var allNodes = GetNodes(xmlFile);
|
||||
var indent = " ";
|
||||
foreach (var nodeName in allNodes)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, nodeName);
|
||||
IList<string> parents = GetParents(nodeElement, xmlFile, nodeName);
|
||||
string nodeType = GetNodeType(nodeElement, nodeName);
|
||||
|
||||
string queryBaseClass = "SmoQuerier";
|
||||
PushIndent(indent);
|
||||
WriteLine("");
|
||||
WriteLine(string.Format("[Export(typeof({0}))]", queryBaseClass));
|
||||
WriteLine(string.Format("internal partial class {0}Querier: {1}", nodeName, queryBaseClass));
|
||||
WriteLine("{");
|
||||
PushIndent(indent);
|
||||
|
||||
// Supported Types
|
||||
WriteLine("Type[] supportedTypes = new Type[] { typeof("+ nodeType + ") };");
|
||||
WriteLine("");
|
||||
WriteLine("public override Type[] SupportedObjectTypes { get { return supportedTypes; } }");
|
||||
WriteLine("");
|
||||
|
||||
// Query impl
|
||||
WriteLine("public override IEnumerable<SqlSmoObject> Query(SmoQueryContext context)");
|
||||
WriteLine("{");
|
||||
PushIndent(indent);
|
||||
|
||||
// TODO Allow override of the navigation path
|
||||
foreach(var parentType in parents)
|
||||
{
|
||||
string parentVar = string.Format("parent{0}", parentType);
|
||||
WriteLine(string.Format("{0} {1} = context.Parent as {0};", parentType, parentVar));
|
||||
WriteLine(string.Format("if ({0} != null)", parentVar));
|
||||
WriteLine("{");
|
||||
PushIndent(indent);
|
||||
|
||||
string navigationPath = GetNavigationPath(nodeElement, xmlFile, nodeName, parentType);
|
||||
WriteLine(string.Format("var retValue = {0}.{1};", parentVar, navigationPath));
|
||||
WriteLine("if(retValue != null)");
|
||||
WriteLine("{");
|
||||
PushIndent(indent);
|
||||
if (IsCollection(nodeElement))
|
||||
{
|
||||
WriteLine(string.Format("return new SmoCollectionWrapper<{0}>(retValue);", nodeType));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("return new SqlSmoObject[] { retValue };");
|
||||
}
|
||||
PopIndent();
|
||||
WriteLine("}");
|
||||
PopIndent();
|
||||
WriteLine("}"); // close If
|
||||
}
|
||||
|
||||
WriteLine("return Enumerable.Empty<SqlSmoObject>();");
|
||||
|
||||
PopIndent();
|
||||
WriteLine("}"); // close Query method
|
||||
PopIndent();
|
||||
WriteLine("}"); // close Class
|
||||
PopIndent();
|
||||
}
|
||||
#>
|
||||
}
|
||||
|
||||
<#+
|
||||
|
||||
public static string[] GetNodes(string xmlFile)
|
||||
{
|
||||
List<string> typesList = new List<string>();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlNodeList treeTypes = doc.SelectNodes("/SmoQueryModel/Node");
|
||||
if (treeTypes != null)
|
||||
{
|
||||
foreach (var type in treeTypes)
|
||||
{
|
||||
XmlElement element = type as XmlElement;
|
||||
if (element != null)
|
||||
{
|
||||
typesList.Add(element.GetAttribute("Name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return typesList.ToArray();
|
||||
}
|
||||
|
||||
public static XmlElement GetNodeElement(string xmlFile, string nodeName)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
return (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']", nodeName));
|
||||
}
|
||||
|
||||
public static string GetNavPathField(string xmlFile, string nodeName, string parent)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlElement navPathElement = (XmlElement)doc.SelectSingleNode(string.Format("/SmoQueryModel/Node[@Name='{0}']/NavigationPath[@Parent='{1}']", nodeName, parent));
|
||||
|
||||
return navPathElement?.GetAttribute("Field");
|
||||
}
|
||||
|
||||
public static string GetNavigationPath(XmlElement nodeElement, string xmlFile, string nodeName, string parentName)
|
||||
{
|
||||
string navPathField = GetNavPathField(xmlFile, nodeName, parentName);
|
||||
if (!string.IsNullOrEmpty(navPathField))
|
||||
{
|
||||
return navPathField;
|
||||
}
|
||||
// else use pluralized type as this is the most common scenario
|
||||
string nodeType = GetNodeType(nodeElement, nodeName);
|
||||
|
||||
string nodeTypeAccessor = IsCollection(nodeElement) ? string.Format("{0}s", nodeType) : nodeType;
|
||||
return nodeTypeAccessor;
|
||||
}
|
||||
|
||||
public static string GetNodeType(XmlElement nodeElement, string nodeName)
|
||||
{
|
||||
var type = nodeElement.GetAttribute("Type");
|
||||
if (!string.IsNullOrEmpty(type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
// Otherwise assume the type is the node name without "Sql" at the start
|
||||
var prefix = "Sql";
|
||||
return nodeName.IndexOf(prefix) == 0 ? nodeName.Substring(prefix.Length) : nodeName;
|
||||
}
|
||||
|
||||
public static bool IsCollection(XmlElement nodeElement)
|
||||
{
|
||||
var collection = nodeElement.GetAttribute("Collection");
|
||||
bool result;
|
||||
if (bool.TryParse(collection, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Default is true
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IList<string> GetParents(XmlElement nodeElement, string xmlFile, string parentName)
|
||||
{
|
||||
var parentAttr = nodeElement.GetAttribute("Parent");
|
||||
if (!string.IsNullOrEmpty(parentAttr))
|
||||
{
|
||||
return new string[] { parentAttr };
|
||||
}
|
||||
|
||||
var parentNodes = GetChildren(xmlFile, parentName, "Parent");
|
||||
if (parentNodes != null && parentNodes.Count > 0)
|
||||
{
|
||||
List<string> parents = new List<string>();
|
||||
int i = 0;
|
||||
foreach(var node in parentNodes)
|
||||
{
|
||||
parents.Add(node.InnerText);
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
// default to assuming a type is under Database
|
||||
return new string[] { "Database" };
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetChildren(string xmlFile, string parentName, string childNode)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/SmoQueryModel/Node[@Name='{0}']/{1}", parentName, childNode));
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
#>
|
||||
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
This XML file defines how to query for a given SMO type based on a parent/child or
|
||||
XPath relationship. From this file, the paths to query each type should be buildable
|
||||
into code using a T4 template.
|
||||
|
||||
Key properties:
|
||||
Name: This maps
|
||||
Type: Optional SMO type. If not specified, the Name without the Sql prefix is used
|
||||
Parent: Expected parent type. Needed to codegen the response. if there are multiple parents
|
||||
then each one
|
||||
NavigationPath: For types whose access path differs based on parent or needs custom navigation
|
||||
this can be used.
|
||||
|
||||
-->
|
||||
<SmoQueryModel>
|
||||
<!--<Node Name="SqlServer"/> -->
|
||||
<Node Name="SqlDatabase" Type="Database" Parent="Server" />
|
||||
<Node Name="SqlLinkedServerLogin" Type="LinkedServer" Parent="Server"/>
|
||||
<Node Name="SqlLogin" Type="Login" Parent="Server" />
|
||||
<Node Name="SqlServerRole" Type="" Parent="Server" >
|
||||
<NavigationPath Parent="Server" Field="Roles" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlCredential" Parent="Server" />
|
||||
<Node Name="SqlCryptographicProvider" Parent="Server" />
|
||||
<Node Name="SqlServerAudit" Type="Audit" Parent="Server" />
|
||||
<Node Name="SqlServerAuditSpecification" Type="ServerAuditSpecification" Parent="Server"/>
|
||||
|
||||
<Node Name="SqlEndpoint" Parent="Server"/>
|
||||
<Node Name="SqlLinkedServer" Parent="Server" />
|
||||
<Node Name="SqlServerDdlTrigger" Parent="Server" >
|
||||
<NavigationPath Parent="Server" Field="Triggers" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlErrorMessage" Type="UserDefinedMessage" Parent="Server" />
|
||||
|
||||
<Node Name="SqlTable" Parent="Database" />
|
||||
<Node Name="SqlView" Parent="Database" />
|
||||
|
||||
<Node Name="SqlSynonym" Parent="Database" />
|
||||
|
||||
<Node Name="SqlColumn" Parent="TableViewTableTypeBase"/>
|
||||
<Node Name="SqlIndex" Parent="TableViewTableTypeBase">
|
||||
<NavigationPath Parent="TableViewTableTypeBase" Field="Indexes" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlCheck" Parent="Table"/>
|
||||
<Node Name="SqlForeignKeyConstraint" Type="ForeignKey" Parent="Table" />
|
||||
<Node Name="SqlDefaultConstraint" Parent="Column" Collection="False" />
|
||||
<Node Name="SqlDmlTrigger" Type="Trigger" Parent="Table" />
|
||||
<Node Name="SqlFullTextIndex" Parent="Table" Collection="False" />
|
||||
<Node Name="SqlStatistic" Parent="TableViewBase"/>
|
||||
|
||||
<Node Name="SqlDatabaseDdlTrigger" Type="Trigger" Parent="Database"/>
|
||||
<Node Name="SqlAssembly" Type="SqlAssembly" Parent="Database" >
|
||||
<NavigationPath Parent="Database" Field="Assemblies" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlRule" Parent="Database" />
|
||||
<Node Name="SqlDefault" Parent="Database" />
|
||||
<Node Name="SqlSequence" Parent="Database" />
|
||||
|
||||
<Node Name="SqlSystemDataType" Parent="Server" />
|
||||
<Node Name="SqlUserDefinedDataType" Parent="Database" />
|
||||
|
||||
<Node Name="SqlUserDefinedTableType" Parent="Database" />
|
||||
<Node Name="SqlXmlSchemaCollection" />
|
||||
<Node Name="SqlUserDefinedType" />
|
||||
|
||||
<Node Name="SqlUserDefinedFunction" />
|
||||
|
||||
<Node Name="SqlUserDefinedAggregate" />
|
||||
|
||||
<Node Name="SqlFileGroup" />
|
||||
<Node Name="SqlFile" Type="DataFile" Parent="FileGroup" >
|
||||
<NavigationPath Parent="FileGroup" Field="Files" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlFullTextCatalog"/>
|
||||
<Node Name="SqlFullTextStopList" />
|
||||
<Node Name="SqlPartitionFunction"/>
|
||||
<Node Name="SqlPartitionScheme"/>
|
||||
<Node Name="SqlSearchPropertyList" />
|
||||
<Node Name="SqlUser"/>
|
||||
<Node Name="SqlSchema"/>
|
||||
<Node Name="SqlAsymmetricKey" />
|
||||
<Node Name="SqlCertificate" />
|
||||
<Node Name="SqlSymmetricKey" />
|
||||
<Node Name="SqlDatabaseEncryptionKey" Collection="False" />
|
||||
<Node Name="SqlMasterKey" Collection="False" />
|
||||
<Node Name="SqlDatabaseAuditSpecification" />
|
||||
<Node Name="SqlSecurityPolicy" >
|
||||
<NavigationPath Parent="Database" Field="SecurityPolicies" />
|
||||
</Node>
|
||||
<Node Name="SqlDatabaseCredential" Type="DatabaseScopedCredential"/>
|
||||
<Node Name="SqlRole" Type="DatabaseRole" >
|
||||
<NavigationPath Parent="Database" Field="Roles" />
|
||||
</Node>
|
||||
<Node Name="SqlApplicationRole" />
|
||||
<Node Name="SqlColumnMasterKey" />
|
||||
<Node Name="SqlColumnEncryptionKey" />
|
||||
|
||||
<Node Name="SqlServiceBroker" Type="ServiceBroker" Collection="False" />
|
||||
<Node Name="SqlService" Type="BrokerService" Parent="ServiceBroker" >
|
||||
<NavigationPath Parent="ServiceBroker" Field="Services" />
|
||||
</Node>
|
||||
<Node Name="SqlContract" Type="ServiceContract" Parent="ServiceBroker" />
|
||||
<Node Name="SqlQueue" Type="ServiceQueue" Parent="ServiceBroker" >
|
||||
<NavigationPath Parent="ServiceBroker" Field="Queues" />
|
||||
</Node>
|
||||
<Node Name="SqlRemoteServiceBinding" Parent="ServiceBroker" />
|
||||
<Node Name="SqlBrokerPriority" Parent="ServiceBroker" >
|
||||
<NavigationPath Parent="ServiceBroker" Field="Priorities" />
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlMessageType" Parent="ServiceBroker"/>
|
||||
|
||||
<Node Name="SqlExternalDataSource" />
|
||||
<Node Name="SqlExternalFileFormat" />
|
||||
|
||||
<Node Name="SqlProcedure" Type="StoredProcedure"/>
|
||||
<Node Name="SqlExtendedStoredProcedure" />
|
||||
<Node Name="SqlSubroutineParameter" Type="Parameter" >
|
||||
<Parent>StoredProcedure</Parent>
|
||||
<Parent>UserDefinedAggregate</Parent>
|
||||
<Parent>UserDefinedFunction</Parent>
|
||||
</Node>
|
||||
|
||||
<Node Name="SqlPartitionFunctionParameter" Parent="PartitionFunction" />
|
||||
|
||||
<Node Name="SqlBuiltInType" Type="SystemDataType" Parent="Server"/>
|
||||
<!-- TODO Enable all types
|
||||
<Node Name="SqlRoute"/>
|
||||
-->
|
||||
<!-- Signatures appear to be missing entirely from SMO and SSMS object explorer...
|
||||
<Node Name="SqlSignature" />
|
||||
-->
|
||||
<!-- TODO find mapping - exists in SSDT but not SSMS / SMO?
|
||||
<Node Name="SqlEventNotification" Parent="ServiceBroker" />
|
||||
-->
|
||||
<!-- TODO Requires XEvents SMO DLL in .Net Core
|
||||
<Node Name="SqlEventSession" Type="Session" />
|
||||
<Node Name="SqlServerEventNotification" Type="Event" Parent="Server" />
|
||||
-->
|
||||
</SmoQueryModel>
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// 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 Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
/// <summary>
|
||||
/// A Node in the tree representing a SMO-based object
|
||||
/// </summary>
|
||||
public class SmoTreeNode : TreeNode
|
||||
{
|
||||
public static int FolderSortPriority = 0;
|
||||
private static int _nextSortPriority = FolderSortPriority + 1; // 0 is reserved for folders
|
||||
|
||||
protected SmoQueryContext context;
|
||||
|
||||
public SmoTreeNode() : base()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnInitialize()
|
||||
{
|
||||
// TODO setup initialization
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a system (MSShipped) object?
|
||||
/// </summary>
|
||||
public bool IsMsShippedOwned { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which platforms a node is valid for
|
||||
/// </summary>
|
||||
public ValidForFlag ValidFor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an incrementing sort priority value to assist in automatically sorting
|
||||
/// elements in a tree
|
||||
/// </summary>
|
||||
public static int NextSortPriority
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.Threading.Interlocked.Increment(ref _nextSortPriority);
|
||||
}
|
||||
}
|
||||
|
||||
public NamedSmoObject SmoObject { get; private set; }
|
||||
|
||||
public virtual void CacheInfoFromModel(NamedSmoObject smoObject)
|
||||
{
|
||||
SmoObject = smoObject;
|
||||
NodeValue = smoObject.Name;
|
||||
}
|
||||
|
||||
public virtual NamedSmoObject GetParentSmoObject()
|
||||
{
|
||||
if (SmoObject != null)
|
||||
{
|
||||
return SmoObject;
|
||||
}
|
||||
// Return the parent's object, or null if it's not set / not a SmoTreeNode
|
||||
return ParentAs<SmoTreeNode>()?.GetParentSmoObject();
|
||||
}
|
||||
|
||||
public override object GetContext()
|
||||
{
|
||||
EnsureContextInitialized();
|
||||
return context;
|
||||
}
|
||||
|
||||
protected virtual void EnsureContextInitialized()
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
SmoObjectBase smoParent = GetParentSmoObject();
|
||||
SmoQueryContext parentContext = Parent?.GetContextAs<SmoQueryContext>();
|
||||
if (smoParent != null && parentContext != null)
|
||||
{
|
||||
context = parentContext.CopyWithParent(smoParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
internal partial class SystemExactNumericsChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _exactNumerics = new HashSet<string>{
|
||||
"bit",
|
||||
"tinyint",
|
||||
"smallint",
|
||||
"int",
|
||||
"bigint",
|
||||
"numeric",
|
||||
"decimal",
|
||||
"smallmoney",
|
||||
"money"
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _exactNumerics.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemApproximateNumericsChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _approxNumerics = new HashSet<string>{
|
||||
"float",
|
||||
"real"
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _approxNumerics.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemDateAndTimesChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _dateAndTime = new HashSet<string>{
|
||||
"datetime",
|
||||
"smalldatetime",
|
||||
"date",
|
||||
"time",
|
||||
"datetimeoffset",
|
||||
"datetime2",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _dateAndTime.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemCharacterStringsChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _characterStrings = new HashSet<string>{
|
||||
"char",
|
||||
"varchar",
|
||||
"text",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _characterStrings.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemUnicodeCharacterStringsChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _unicodeCharacterStrings = new HashSet<string>
|
||||
{
|
||||
"nchar",
|
||||
"nvarchar",
|
||||
"ntext",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _unicodeCharacterStrings.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemBinaryStringsChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _binaryStrings = new HashSet<string>{
|
||||
"binary",
|
||||
"varbinary",
|
||||
"image",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _binaryStrings.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemOtherDataTypesChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _otherDataTypes = new HashSet<string>{
|
||||
"sql_variant",
|
||||
"timestamp",
|
||||
"uniqueidentifier",
|
||||
"xml",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _otherDataTypes.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemClrDataTypesChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _clrDataTypes = new HashSet<string>{
|
||||
"hierarchyid",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _clrDataTypes.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal partial class SystemSpatialDataTypesChildFactory
|
||||
{
|
||||
private static readonly HashSet<string> _spatialDataTypes = new HashSet<string>{
|
||||
"geometry",
|
||||
"geography",
|
||||
};
|
||||
public override bool PassesFinalFilters(TreeNode parent, object contextObject)
|
||||
{
|
||||
NamedSmoObject smoObject = contextObject as NamedSmoObject;
|
||||
if (smoObject != null)
|
||||
{
|
||||
string name = smoObject.Name;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return _spatialDataTypes.Contains(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ServerExplorerTree>
|
||||
<Node Name="ServerInstance" LocLabel="SR.SchemaHierarchy_ServerInstance" Image="Server">
|
||||
<Child Name="Databases"/>
|
||||
<Child Name="ServerLevelSecurity"/>
|
||||
<Child Name="ServerLevelServerObjects"/>
|
||||
</Node>
|
||||
<Node Name="Databases" LocLabel="SR.SchemaHierarchy_Databases" IsAsyncLoad="" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabase" TreeNode="DatabaseInstanceTreeNode">
|
||||
<Child Name="SystemDatabases"/>
|
||||
</Node>
|
||||
<Node Name="ServerLevelSecurity" LocLabel="SR.SchemaHierarchy_Security" BaseClass="ModelBased" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12|NotContainedUser|CanViewSecurity">
|
||||
<Child Name="ServerLevelLinkedServerLogins"/>
|
||||
<Child Name="ServerLevelLogins"/>
|
||||
<Child Name="ServerLevelServerRoles"/>
|
||||
<Child Name="ServerLevelCredentials"/>
|
||||
<Child Name="ServerLevelCryptographicProviders"/>
|
||||
<Child Name="ServerLevelServerAudits"/>
|
||||
<Child Name="ServerLevelServerAuditSpecifications"/>
|
||||
<!-- TODO Support XEvents in .Net Core SMO
|
||||
<Child Name="ServerLevelEventSessions"/>
|
||||
-->
|
||||
</Node>
|
||||
<Node Name="ServerLevelServerObjects" LocLabel="SR.SchemaHierarchy_ServerObjects" BaseClass="ModelBased" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|NotContainedUser">
|
||||
<Child Name="ServerLevelEndpoints"/>
|
||||
<Child Name="ServerLevelLinkedServers"/>
|
||||
<Child Name="ServerLevelServerTriggers"/>
|
||||
<Child Name="ServerLevelErrorMessages"/>
|
||||
<!-- TODO Support XEvents in .Net Core SMO
|
||||
<Child Name="ServerLevelEventNotifications"/>
|
||||
-->
|
||||
</Node>
|
||||
|
||||
<Node Name="SystemDatabases" LocLabel="SR.SchemaHierarchy_SystemDatabases" BaseClass="Databases" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12|NotContainedUser|CanConnectToMaster"/>
|
||||
<!-- TODO Support XEvents in .Net Core SMO
|
||||
<Node Name="ServerLevelEventSessions" LocLabel="SR.SchemaHierarchy_EventSessions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventSession" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelEventNotifications" LocLabel="SR.SchemaHierarchy_ServerEventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerEventNotification"/>
|
||||
-->
|
||||
|
||||
<Node Name="ServerLevelLinkedServerLogins" LocLabel="SR.SchemaHierarchy_LinkedServerLogins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLinkedServerLogin" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelLogins" LocLabel="SR.SchemaHierarchy_Logins" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLogin"/>
|
||||
<Node Name="ServerLevelServerRoles" LocLabel="SR.SchemaHierarchy_ServerRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelCredentials" LocLabel="SR.SchemaHierarchy_Credentials" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCredential" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelCryptographicProviders" LocLabel="SR.SchemaHierarchy_CryptographicProviders" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCryptographicProvider" ValidFor="Sql2008|Sql2012|Sql2014|NotDebugInstance|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelServerAudits" LocLabel="SR.SchemaHierarchy_ServerAudits" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerAudit" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelServerAuditSpecifications" LocLabel="SR.SchemaHierarchy_ServerAuditSpecifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
|
||||
<Node Name="ServerLevelEndpoints" LocLabel="SR.SchemaHierarchy_Endpoints" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEndpoint" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="ServerLevelLinkedServers" LocLabel="SR.SchemaHierarchy_LinkedServers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlLinkedServer"/>
|
||||
<Node Name="ServerLevelServerTriggers" LocLabel="SR.SchemaHierarchy_ServerTriggers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlServerDdlTrigger"/>
|
||||
<Node Name="ServerLevelErrorMessages" LocLabel="SR.SchemaHierarchy_ErrorMessages" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlErrorMessage"/>
|
||||
|
||||
<Node Name="DatabaseInstance" LocLabel="string.Empty" Image="Database" BaseClass="ModelBased" IsAsyncLoad="" Strategy="CreateModel">
|
||||
<Child Name="Tables"/>
|
||||
<Child Name="Views"/>
|
||||
<Child Name="Synonyms"/>
|
||||
<Child Name="Programmability"/>
|
||||
<Child Name="ExternalResources"/>
|
||||
<Child Name="ServiceBroker"/>
|
||||
<Child Name="Storage"/>
|
||||
<Child Name="Security"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Tables" LocLabel="SR.SchemaHierarchy_Tables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableInstanceTreeNode">
|
||||
<Filters>
|
||||
<Filter Property="IsFileTable" Value="0" Type="bool" />
|
||||
<Filter Property="IsExternal" Value="0" Type="bool" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
<Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>TemporalTableType.None</Value>
|
||||
<Value>TemporalTableType.SystemVersioned</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
<Child Name="SystemTables"/>
|
||||
<Child Name="FileTables"/>
|
||||
<Child Name="ExternalTables"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Views" LocLabel="SR.SchemaHierarchy_Views" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewInstanceTreeNode">
|
||||
<Child Name="SystemViews"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Synonyms" LocLabel="SR.SchemaHierarchy_Synonyms" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSynonym"/>
|
||||
<Node Name="Programmability" LocLabel="SR.SchemaHierarchy_Programmability" BaseClass="ModelBased">
|
||||
<Child Name="StoredProcedures"/>
|
||||
<Child Name="Functions"/>
|
||||
<Child Name="DatabaseTriggers"/>
|
||||
<Child Name="Assemblies"/>
|
||||
<Child Name="Types"/>
|
||||
<Child Name="Rules"/>
|
||||
<Child Name="Defaults"/>
|
||||
<Child Name="Sequences"/>
|
||||
</Node>
|
||||
<Node Name="ExternalResources" LocLabel="SR.SchemaHierarchy_ExternalResources" BaseClass="ModelBased" TreeNode="ExternalResourceInstanceTreeNode" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Child Name="ExternalDataSources"/>
|
||||
<Child Name="ExternalFileFormats"/>
|
||||
</Node>
|
||||
<Node Name="ServiceBroker" LocLabel="SR.SchemaHierarchy_ServiceBroker" BaseClass="ModelBased" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext">
|
||||
<Child Name="MessageTypes"/>
|
||||
<Child Name="Contracts"/>
|
||||
<Child Name="Queues"/>
|
||||
<Child Name="Services"/>
|
||||
<!-- <Child Name="Routes"/> -->
|
||||
<Child Name="DatabaseAndQueueEventNotifications"/>
|
||||
<Child Name="RemoteServiceBindings"/>
|
||||
<Child Name="BrokerPriorities"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Storage" LocLabel="SR.SchemaHierarchy_Storage" BaseClass="ModelBased" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12">
|
||||
<Child Name="FileGroups"/>
|
||||
<Child Name="FullTextCatalogs"/>
|
||||
<Child Name="FullTextStopLists"/>
|
||||
<Child Name="SqlLogFiles"/>
|
||||
<Child Name="PartitionFunctions"/>
|
||||
<Child Name="PartitionSchemes"/>
|
||||
<Child Name="SearchPropertyLists"/>
|
||||
</Node>
|
||||
<Node Name="Security" LocLabel="SR.SchemaHierarchy_Security" BaseClass="ModelBased" >
|
||||
<Child Name="Users"/>
|
||||
<Child Name="Roles"/>
|
||||
<Child Name="Schemas"/>
|
||||
<Child Name="AsymmetricKeys"/>
|
||||
<Child Name="Certificates"/>
|
||||
<Child Name="SymmetricKeys"/>
|
||||
<Child Name="DatabaseScopedCredentials"/>
|
||||
<Child Name="DatabaseEncryptionKeys"/>
|
||||
<Child Name="MasterKeys"/>
|
||||
<Child Name="Signatures"/>
|
||||
<Child Name="DatabaseAuditSpecifications"/>
|
||||
<Child Name="SecurityPolicies"/>
|
||||
<Child Name="AlwaysEncryptedKeys"/>
|
||||
</Node>
|
||||
|
||||
<!-- Childs of Tables -->
|
||||
<Node Name="SystemTables" LocLabel="SR.SchemaHierarchy_SystemTables" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableInstanceTreeNode"/>
|
||||
<Node Name="FileTables" LocLabel="SR.SchemaHierarchy_FileTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableInstanceTreeNode" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|NotDebugInstance">
|
||||
<Filters>
|
||||
<Filter Property="IsFileTable" Value="1" Type="boolean" />
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="ExternalTables" LocLabel="SR.SchemaHierarchy_ExternalTables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="ExternalTableInstanceTreeNode" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Filters>
|
||||
<Filter Property="IsExternalTable" Value="1" Type="boolean" />
|
||||
</Filters>
|
||||
</Node>
|
||||
|
||||
<Node Name="TableInstance" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="HistoryTableInstanceTreeNode">
|
||||
<!-- TODO Add special history table handling to only return related history table instead of all! Under Table, we directly show any related history tables.-->
|
||||
<Filters>
|
||||
<Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>TemporalTableType.History</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
<Child Name="Columns"/>
|
||||
<Child Name="Keys"/>
|
||||
<Child Name="Constraints"/>
|
||||
<Child Name="Triggers"/>
|
||||
<Child Name="Indexes"/>
|
||||
<Child Name="Statistics"/>
|
||||
</Node>
|
||||
|
||||
<!-- TODO This should use display item not ChildQuerierTypes -->
|
||||
<Node Name="HistoryTableInstance" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Child Name="Columns"/>
|
||||
<Child Name="Indexes"/>
|
||||
<Child Name="Statistics"/>
|
||||
</Node>
|
||||
|
||||
<!-- TODO This should use display item not ChildQuerierTypes -->
|
||||
<Node Name="ExternalTableInstance" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails" ChildQuerierTypes="SqlTable" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Child Name="Columns"/>
|
||||
<Child Name="Statistics"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Columns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlColumn" DisableSort=""/>
|
||||
<Node Name="Keys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlIndex;SqlForeignKeyConstraint" >
|
||||
<Filters>
|
||||
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>IndexKeyType.DriPrimaryKey</Value>
|
||||
<Value>IndexKeyType.DriUniqueKey</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="Constraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/>
|
||||
<Node Name="Triggers" LocLabel="SR.SchemaHierarchy_Triggers" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlDmlTrigger"/>
|
||||
<Node Name="Indexes" LocLabel="SR.SchemaHierarchy_Indexes" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlIndex;SqlFullTextIndex">
|
||||
<Filters>
|
||||
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>IndexKeyType.None</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="Statistics" LocLabel="SR.SchemaHierarchy_Statistics" BaseClass="ModelBased" Strategy="ElementsInRelationship" ChildQuerierTypes="SqlStatistic"/>
|
||||
|
||||
<Node Name="SystemViews" LocLabel="SR.SchemaHierarchy_SystemViews" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlView" TreeNode="ViewInstanceTreeNode"/>
|
||||
|
||||
<Node Name="ViewInstance" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="Columns"/>
|
||||
<Child Name="Triggers"/>
|
||||
<Child Name="Indexes"/>
|
||||
<Child Name="Statistics"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="Functions" LocLabel="SR.SchemaHierarchy_Functions" BaseClass="ModelBased" >
|
||||
<Child Name="TableValuedFunctions"/>
|
||||
<Child Name="ScalarValuedFunctions"/>
|
||||
<Child Name="AggregateFunctions"/>
|
||||
</Node>
|
||||
<Node Name="DatabaseTriggers" LocLabel="SR.SchemaHierarchy_DatabaseTriggers" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseDdlTrigger"/>
|
||||
<Node Name="Assemblies" LocLabel="SR.SchemaHierarchy_Assemblies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlAssembly" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="Types" LocLabel="SR.SchemaHierarchy_Types" BaseClass="ModelBased" >
|
||||
<Child Name="SystemDataTypes"/>
|
||||
<Child Name="UserDefinedDataTypes"/>
|
||||
<Child Name="UserDefinedTableTypes"/>
|
||||
<Child Name="UserDefinedTypes"/>
|
||||
<Child Name="XmlSchemaCollections"/>
|
||||
</Node>
|
||||
<Node Name="Rules" LocLabel="SR.SchemaHierarchy_Rules" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRule" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="Defaults" LocLabel="SR.SchemaHierarchy_Defaults" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDefault" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="Sequences" LocLabel="SR.SchemaHierarchy_Sequences" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSequence" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
|
||||
<Node Name="SystemDataTypes" LocLabel="SR.SchemaHierarchy_SystemDataTypes" BaseClass="ModelBased" >
|
||||
<Child Name="SystemExactNumerics"/>
|
||||
<Child Name="SystemApproximateNumerics"/>
|
||||
<Child Name="SystemDateAndTimes"/>
|
||||
<Child Name="SystemCharacterStrings"/>
|
||||
<Child Name="SystemUnicodeCharacterStrings"/>
|
||||
<Child Name="SystemBinaryStrings"/>
|
||||
<Child Name="SystemOtherDataTypes"/>
|
||||
<Child Name="SystemClrDataTypes"/>
|
||||
<Child Name="SystemSpatialDataTypes"/>
|
||||
</Node>
|
||||
<Node Name="UserDefinedDataTypes" LocLabel="SR.SchemaHierarchy_UserDefinedDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedDataType"/>
|
||||
<Node Name="UserDefinedTableTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTableTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedTableType" TreeNode="UserDefinedTableTypeInstanceTreeNode" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
|
||||
<Node Name="UserDefinedTypes" LocLabel="SR.SchemaHierarchy_UserDefinedTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="XmlSchemaCollections" LocLabel="SR.SchemaHierarchy_XMLSchemaCollections" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlXmlSchemaCollection" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
|
||||
<Node Name="UserDefinedTableTypeInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="UserDefinedTableTypeColumns"/>
|
||||
<Child Name="UserDefinedTableTypeKeys"/>
|
||||
<Child Name="UserDefinedTableTypeConstraints"/>
|
||||
</Node>
|
||||
<Node Name="UserDefinedTableTypeColumns" LocLabel="SR.SchemaHierarchy_Columns" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlColumn" DisableSort=""/>
|
||||
<Node Name="UserDefinedTableTypeKeys" LocLabel="SR.SchemaHierarchy_Keys" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlIndex">
|
||||
<Filters>
|
||||
<Filter TypeToReverse="SqlIndex" Property="IndexKeyType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>IndexKeyType.DriPrimaryKey</Value>
|
||||
<Value>IndexKeyType.DriUniqueKey</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="UserDefinedTableTypeConstraints" LocLabel="SR.SchemaHierarchy_Constraints" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlDefaultConstraint;SqlCheck"/>/>
|
||||
|
||||
<Node Name="SystemExactNumerics" LocLabel="SR.SchemaHierarchy_SystemExactNumerics" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemApproximateNumerics" LocLabel="SR.SchemaHierarchy_SystemApproximateNumerics" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemDateAndTimes" LocLabel="SR.SchemaHierarchy_SystemDateAndTime" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemCharacterStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemUnicodeCharacterStrings" LocLabel="SR.SchemaHierarchy_SystemUnicodeCharacterStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemBinaryStrings" LocLabel="SR.SchemaHierarchy_SystemBinaryStrings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemOtherDataTypes" LocLabel="SR.SchemaHierarchy_SystemOtherDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBuiltInType"/>
|
||||
<Node Name="SystemClrDataTypes" LocLabel="SR.SchemaHierarchy_SystemCLRDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
|
||||
<Node Name="SystemSpatialDataTypes" LocLabel="SR.SchemaHierarchy_SystemSpatialDataTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedType" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV11|AzureV12"/>
|
||||
|
||||
<!-- Childs of ExternalResources -->
|
||||
<Node Name="ExternalDataSources" LocLabel="SR.SchemaHierarchy_ExternalDataSources" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalDataSource" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="ExternalFileFormats" LocLabel="SR.SchemaHierarchy_ExternalFileFormats" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlExternalFileFormat" ValidFor="Sql2016|SqlvNext"/>
|
||||
|
||||
<Node Name="StoredProcedures" LocLabel="SR.SchemaHierarchy_StoredProcedures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureInstanceTreeNode">
|
||||
<Child Name="SystemStoredProcedures"/>
|
||||
</Node>
|
||||
<Node Name="SystemStoredProcedures" LocLabel="SR.SchemaHierarchy_SystemStoredProcedures" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlProcedure" TreeNode="StoredProcedureInstanceTreeNode"/>
|
||||
<Node Name="StoredProcedureInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="StoredProcedureParameters"/>
|
||||
</Node>
|
||||
<Node Name="StoredProcedureParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="StoredProcedureParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
|
||||
|
||||
<Node Name="TableValuedFunctions" LocLabel="SR.SchemaHierarchy_TableValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="TableValuedFunctionInstanceTreeNode">
|
||||
<Filters>
|
||||
<Filter Property="UserDefinedFunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>UserDefinedFunctionType.Table</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="TableValuedFunctionInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="TableValuedFunctionParameters"/>
|
||||
</Node>
|
||||
<Node Name="TableValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
|
||||
|
||||
<Node Name="ScalarValuedFunctions" LocLabel="SR.SchemaHierarchy_ScalarValuedFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedFunction" TreeNode="ScalarValuedFunctionInstanceTreeNode" >
|
||||
<Filters>
|
||||
<Filter Property="UserDefinedFunctionType" Type="Enum" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Value>UserDefinedFunctionType.Table</Value>
|
||||
</Filter>
|
||||
</Filters>
|
||||
</Node>
|
||||
<Node Name="ScalarValuedFunctionInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="ScalarValuedFunctionParameters"/>
|
||||
</Node>
|
||||
<Node Name="ScalarValuedFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="FunctionParameters" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
|
||||
|
||||
<Node Name="AggregateFunctions" LocLabel="SR.SchemaHierarchy_AggregateFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUserDefinedAggregate" TreeNode="AggregateFunctionInstanceTreeNode" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="AggregateFunctionInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="" IsAsyncLoad="" Strategy="PopulateDetails">
|
||||
<Child Name="AggregateFunctionParameters"/>
|
||||
</Node>
|
||||
<Node Name="AggregateFunctionParameters" LocLabel="SR.SchemaHierarchy_Parameters" BaseClass="ModelBased" Strategy="PopulateParentDetails" ChildQuerierTypes="SqlSubroutineParameter" DisableSort=""/>
|
||||
|
||||
<!-- TODO Support Route in SMO
|
||||
<Node Name="Routes" LocLabel="SR.SchemaHierarchy_Routes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRoute"/>
|
||||
-->
|
||||
<!-- TODO support events
|
||||
<Node Name="DatabaseAndQueueEventNotifications" LocLabel="SR.SchemaHierarchy_EventNotifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlEventNotification"/>
|
||||
-->
|
||||
<Node Name="RemoteServiceBindings" LocLabel="SR.SchemaHierarchy_RemoteServiceBindings" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRemoteServiceBinding"/>
|
||||
<Node Name="BrokerPriorities" LocLabel="SR.SchemaHierarchy_BrokerPriorities" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlBrokerPriority" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
|
||||
<Node Name="FileGroups" LocLabel="SR.SchemaHierarchy_FileGroups" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFileGroup" TreeNode="FileGroupInstanceTreeNode"/>
|
||||
<Node Name="FullTextCatalogs" LocLabel="SR.SchemaHierarchy_FullTextCatalogs" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextCatalog"/>
|
||||
<Node Name="FullTextStopLists" LocLabel="SR.SchemaHierarchy_FullTextStopLists" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFullTextStopList" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="SqlLogFiles" LocLabel="SR.SchemaHierarchy_LogFiles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFile"/>
|
||||
<Node Name="PartitionFunctions" LocLabel="SR.SchemaHierarchy_PartitionFunctions" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionFunction"/>
|
||||
<Node Name="PartitionSchemes" LocLabel="SR.SchemaHierarchy_PartitionSchemes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlPartitionScheme"/>
|
||||
<Node Name="SearchPropertyLists" LocLabel="SR.SchemaHierarchy_SearchPropertyLists" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSearchPropertyList" ValidFor="Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
|
||||
<Node Name="FileGroupInstance" LocLabel="string.Empty" BaseClass="ModelBased" ChildQuerierTypes="">
|
||||
<Child Name="FileGroupFiles"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="FileGroupFiles" LocLabel="SR.SchemaHierarchy_FilegroupFiles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlFile" >
|
||||
</Node>
|
||||
|
||||
<Node Name="Users" LocLabel="SR.SchemaHierarchy_Users" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlUser"/>
|
||||
<Node Name="Roles" LocLabel="SR.SchemaHierarchy_Roles" BaseClass="ModelBased" >
|
||||
<Child Name="DatabaseRoles"/>
|
||||
<Child Name="ApplicationRoles"/>
|
||||
</Node>
|
||||
<Node Name="Schemas" LocLabel="SR.SchemaHierarchy_Schemas" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSchema"/>
|
||||
<Node Name="AsymmetricKeys" LocLabel="SR.SchemaHierarchy_AsymmetricKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlAsymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="Certificates" LocLabel="SR.SchemaHierarchy_Certificates" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlCertificate" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="SymmetricKeys" LocLabel="SR.SchemaHierarchy_SymmetricKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSymmetricKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="DatabaseEncryptionKeys" LocLabel="SR.SchemaHierarchy_DatabaseEncryptionKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseEncryptionKey" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="MasterKeys" LocLabel="SR.SchemaHierarchy_MasterKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMasterKey" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
|
||||
<!-- TODO Support signatures
|
||||
<Node Name="Signatures" LocLabel="SR.SchemaHierarchy_Signatures" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSignature" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
-->
|
||||
<Node Name="DatabaseAuditSpecifications" LocLabel="SR.SchemaHierarchy_DatabaseAuditSpecifications" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseAuditSpecification" ValidFor="Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext"/>
|
||||
<Node Name="SecurityPolicies" LocLabel="SR.SchemaHierarchy_SecurityPolicies" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlSecurityPolicy" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="DatabaseScopedCredentials" LocLabel="SR.SchemaHierarchy_DatabaseScopedCredentials" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlDatabaseCredential" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="AlwaysEncryptedKeys" LocLabel="SR.SchemaHierarchy_AlwaysEncryptedKeys" BaseClass="ModelBased" ValidFor="Sql2016|SqlvNext|AzureV12">
|
||||
<Child Name="ColumnMasterKeys"/>
|
||||
<Child Name="ColumnEncryptionKeys"/>
|
||||
</Node>
|
||||
|
||||
<Node Name="DatabaseRoles" LocLabel="SR.SchemaHierarchy_DatabaseRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlRole"/>
|
||||
<Node Name="ApplicationRoles" LocLabel="SR.SchemaHierarchy_ApplicationRoles" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlApplicationRole" ValidFor="Sql2005|Sql2008|Sql2012|Sql2014|Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="ColumnMasterKeys" LocLabel="SR.SchemaHierarchy_ColumnMasterKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnMasterKey" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
<Node Name="ColumnEncryptionKeys" LocLabel="SR.SchemaHierarchy_ColumnEncryptionKeys" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlColumnEncryptionKey" ValidFor="Sql2016|SqlvNext|AzureV12"/>
|
||||
|
||||
<Node Name="MessageTypes" LocLabel="SR.SchemaHierarchy_MessageTypes" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType">
|
||||
<Child Name="SystemMessageTypes"/>
|
||||
</Node>
|
||||
<Node Name="SystemMessageTypes" LocLabel="SR.SchemaHierarchy_SystemMessageTypes" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlMessageType"/>
|
||||
|
||||
<Node Name="Contracts" LocLabel="SR.SchemaHierarchy_Contracts" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract">
|
||||
<Child Name="SystemContracts"/>
|
||||
</Node>
|
||||
<Node Name="SystemContracts" LocLabel="SR.SchemaHierarchy_SystemContracts" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlContract"/>
|
||||
|
||||
<Node Name="Queues" LocLabel="SR.SchemaHierarchy_Queues" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue">
|
||||
<Child Name="SystemQueues"/>
|
||||
</Node>
|
||||
<Node Name="SystemQueues" LocLabel="SR.SchemaHierarchy_SystemQueues" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlQueue"/>
|
||||
|
||||
<Node Name="Services" LocLabel="SR.SchemaHierarchy_Services" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService">
|
||||
<Child Name="SystemServices"/>
|
||||
</Node>
|
||||
<Node Name="SystemServices" LocLabel="SR.SchemaHierarchy_SystemServices" BaseClass="ModelBased" IsMsShippedOwned="true" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlService"/>
|
||||
|
||||
<CodeGenOptions>
|
||||
<UniqueTreeNode Name="DatabaseInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="TableInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="ViewInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="UserDefinedTableTypeInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="StoredProcedureInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="TableValuedFunctionInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="ScalarValuedFunctionInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="AggregateFunctionInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="FileGroupInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="ExternalTableInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="ExternalResourceInstanceTreeNode"/>
|
||||
<UniqueTreeNode Name="HistoryTableInstanceTreeNode" />
|
||||
</CodeGenOptions>
|
||||
|
||||
<!-- WARNING: Specifying reverse dependencies that could load large numbers of objects will be detrimental to performance. -->
|
||||
<ReverseDependencyList>
|
||||
<ReverseDependency Type="SqlUser" DependsOn="SqlRole;SqlRoleMembership"/>
|
||||
</ReverseDependencyList>
|
||||
</ServerExplorerTree>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,387 @@
|
||||
<#@ template debug="false" hostspecific="true" language="C#" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#@ assembly name="System.Xml.dll" #>
|
||||
<#@ import namespace="System" #>
|
||||
<#@ import namespace="System.Globalization" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Xml" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.IO" #>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using Microsoft.SqlTools.ServiceLayer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
|
||||
{
|
||||
|
||||
<#
|
||||
var directory = Path.GetDirectoryName(Host.TemplateFile);
|
||||
string xmlFile = Path.Combine(directory, "TreeNodeDefinition.xml");
|
||||
|
||||
/////////
|
||||
// TODO - is Generate all the ReverseDependencies needed?
|
||||
/////////
|
||||
// var allReverseDependencies = GetReverseDependencies(xmlFile);
|
||||
// WriteLine(" internal static class TreeNodeRules");
|
||||
// WriteLine(" {");
|
||||
// WriteLine(" internal static Dictionary<Type, IList<Type>> TypeReverseDependencyMap = new Dictionary<Type, IList<Type>>()");
|
||||
// WriteLine(" {");
|
||||
// foreach (var reverseDependencyKey in allReverseDependencies.Keys)
|
||||
// {
|
||||
// bool isFirstDependentType = true;
|
||||
// StringBuilder dependentListBuilder = new StringBuilder("{");
|
||||
// foreach (var dependentType in allReverseDependencies[reverseDependencyKey])
|
||||
// {
|
||||
// if (isFirstDependentType)
|
||||
// {
|
||||
// isFirstDependentType = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dependentListBuilder.Append(",");
|
||||
// }
|
||||
//
|
||||
// dependentListBuilder.Append(string.Format(CultureInfo.InvariantCulture, " typeof({0})", dependentType));
|
||||
// }
|
||||
// dependentListBuilder.Append(" }");
|
||||
//
|
||||
// WriteLine(string.Format(CultureInfo.InvariantCulture, " {{ typeof({0}), new List<Type> {1} }}", reverseDependencyKey, dependentListBuilder.ToString()));
|
||||
// }
|
||||
// WriteLine(" };");
|
||||
// WriteLine(" }");
|
||||
// WriteLine("");
|
||||
|
||||
/////////
|
||||
// First generate all the TreeNodes
|
||||
/////////
|
||||
var allTreeNodes = GetUniqueTreeNodes(xmlFile);
|
||||
foreach (var TreeNode in allTreeNodes)
|
||||
{
|
||||
var name = TreeNode.GetAttribute("Name");
|
||||
WriteLine(string.Format(" internal sealed partial class {0} : SmoTreeNode", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" public {0}() : base()", name));
|
||||
WriteLine(" {");
|
||||
WriteLine(" NodeValue = string.Empty;");
|
||||
WriteLine(string.Format(" this.NodeType = \"{0}\";", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(string.Format(" this.NodeTypeId = NodeTypes.{0};", name.Replace("TreeNode", string.Empty)));
|
||||
WriteLine(" OnInitialize();");
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
WriteLine("");
|
||||
}
|
||||
|
||||
/////////
|
||||
// Now generate all the ChildFactories
|
||||
/////////
|
||||
var allNodes = GetNodes(xmlFile);
|
||||
foreach (var type in allNodes)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, type);
|
||||
var imageAttr = nodeElement.GetAttribute("Image");
|
||||
var isAlwaysLeaf = nodeElement.GetAttributeNode("IsAlwaysLeaf");
|
||||
var baseClass = nodeElement.GetAttribute("BaseClass");
|
||||
var strategy = nodeElement.GetAttribute("Strategy");
|
||||
var ChildQuerierTypes = nodeElement.GetAttribute("ChildQuerierTypes");
|
||||
var TreeNode = nodeElement.GetAttribute("TreeNode");
|
||||
var isAsync = nodeElement.GetAttributeNode("IsAsyncLoad");
|
||||
var disableSort = nodeElement.GetAttributeNode("DisableSort");
|
||||
|
||||
string childFactoryBaseClass = "SmoChildFactoryBase";
|
||||
|
||||
// TODO Will we need alternative child factories? If so, add code here to support this
|
||||
|
||||
if (isAlwaysLeaf == null)
|
||||
{
|
||||
WriteLine(" [Export(typeof(ChildFactory))]");
|
||||
WriteLine(" [Shared]");
|
||||
|
||||
WriteLine(string.Format(" internal partial class {0}ChildFactory : {1}", type, childFactoryBaseClass));
|
||||
|
||||
WriteLine(" {");
|
||||
WriteLine(string.Format(" public override IEnumerable<string> ApplicableParents() {{ return new[] {{ \"{0}\" }}; }}", type));
|
||||
|
||||
List<XmlElement> children = GetChildren(xmlFile, type);
|
||||
if (children.Count > 0)
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)");
|
||||
WriteLine(" {");
|
||||
foreach (var child in children)
|
||||
{
|
||||
XmlElement childAsXmlElement = GetNodeElement(xmlFile, child.GetAttribute("Name"));
|
||||
if (childAsXmlElement == null)
|
||||
{
|
||||
// TODO SHould we error with clear message that this needs to be fixed?
|
||||
continue;
|
||||
}
|
||||
string childImage = childAsXmlElement.GetAttribute("Image");
|
||||
var msShippedOwned = childAsXmlElement.GetAttributeNode("IsMsShippedOwned");
|
||||
var validFor = childAsXmlElement.GetAttribute("ValidFor");
|
||||
|
||||
if (TreeNodeExists(xmlFile, child.GetAttribute("Name") + "TreeNode"))
|
||||
{
|
||||
WriteLine(string.Format(" currentChildren.Add(new {0}TreeNode {{ SortPriority = SmoTreeNode.NextSortPriority }} );", child.GetAttribute("Name")));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(" currentChildren.Add(new FolderNode {");
|
||||
WriteLine(string.Format(" NodeValue = {0},", childAsXmlElement.GetAttribute("LocLabel")));
|
||||
WriteLine(string.Format(" NodeType = \"{0}\",", "Folder"));
|
||||
WriteLine(string.Format(" NodeTypeId = NodeTypes.{0},", child.GetAttribute("Name")));
|
||||
|
||||
if (msShippedOwned != null)
|
||||
{
|
||||
WriteLine(" IsMsShippedOwned = true,");
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(validFor))
|
||||
{
|
||||
WriteLine(string.Format(" ValidFor = {0},", GetValidForFlags(validFor)));
|
||||
}
|
||||
WriteLine(" SortPriority = SmoTreeNode.NextSortPriority,");
|
||||
WriteLine(" });");
|
||||
}
|
||||
}
|
||||
WriteLine(" }");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(strategy))
|
||||
{
|
||||
string[] allTypes = ChildQuerierTypes.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
WriteLine("");
|
||||
WriteLine(" internal override Type[] ChildQuerierTypes");
|
||||
WriteLine(" {");
|
||||
WriteLine(" get");
|
||||
WriteLine(" {");
|
||||
if (!string.IsNullOrWhiteSpace(ChildQuerierTypes))
|
||||
{
|
||||
Write(" return new [] {");
|
||||
foreach (var typeToRe in allTypes)
|
||||
{
|
||||
Write(string.Format(" typeof({0}Querier),", typeToRe));
|
||||
}
|
||||
WriteLine(" };");
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(" return new Type[0];");
|
||||
}
|
||||
WriteLine(" }");
|
||||
WriteLine(" }");
|
||||
|
||||
WriteLine("");
|
||||
|
||||
WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)");
|
||||
WriteLine(" {");
|
||||
if (string.IsNullOrWhiteSpace(TreeNode))
|
||||
{
|
||||
WriteLine(" var child = new SmoTreeNode();");
|
||||
WriteLine(" child.IsAlwaysLeaf = true;");
|
||||
}
|
||||
else
|
||||
{
|
||||
var modelNodeChildren = GetNodeElement(xmlFile, TreeNode.Replace("TreeNode",string.Empty));
|
||||
WriteLine(string.Format(" var child = new {0}();", TreeNode));
|
||||
if (modelNodeChildren.ChildNodes.Count == 0)
|
||||
{
|
||||
WriteLine(" child.IsAlwaysLeaf = true;");
|
||||
}
|
||||
}
|
||||
if (disableSort != null)
|
||||
{
|
||||
WriteLine(" child.SortPriority = SmoTreeNode.NextSortPriority;");
|
||||
}
|
||||
WriteLine(" InitializeChild(child, context);");
|
||||
WriteLine(" return child;");
|
||||
WriteLine(" }");
|
||||
}
|
||||
else if (baseClass == "ModelBased")
|
||||
{
|
||||
WriteLine("");
|
||||
WriteLine(" internal override Type[] ChildQuerierTypes { get {return null;} }");
|
||||
WriteLine("");
|
||||
// TODO Is reverse engineering strategy every needed?
|
||||
// WriteLine(" protected override ReverseEngineeringStrategy Strategy { get {return ReverseEngineeringStrategy.None;} }");
|
||||
WriteLine("");
|
||||
WriteLine(" public override TreeNode CreateChild(TreeNode parent, object context)");
|
||||
WriteLine(" {");
|
||||
WriteLine(" return null;");
|
||||
WriteLine(" }");
|
||||
}
|
||||
|
||||
WriteLine(" }");
|
||||
WriteLine("");
|
||||
}
|
||||
}
|
||||
#>
|
||||
}
|
||||
|
||||
<#+
|
||||
public static string GetValidForFlags(string validForStr)
|
||||
{
|
||||
List<string> flags = new List<string>();
|
||||
if (validForStr.Contains("Sql2005"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2005");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2008"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2008");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2012"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2012");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2014"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2014");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("Sql2016"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Sql2016");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("AzureV11"))
|
||||
{
|
||||
flags.Add("ValidForFlag.Azure");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("AzureV12"))
|
||||
{
|
||||
flags.Add("ValidForFlag.AzureV12");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("NotDebugInstance"))
|
||||
{
|
||||
flags.Add("ValidForFlag.NotDebugInstance");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("NotContainedUser"))
|
||||
{
|
||||
flags.Add("ValidForFlag.NotContainedUser");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("CanConnectToMaster"))
|
||||
{
|
||||
flags.Add("ValidForFlag.CanConnectToMaster");
|
||||
}
|
||||
|
||||
if (validForStr.Contains("CanViewSecurity"))
|
||||
{
|
||||
flags.Add("ValidForFlag.CanViewSecurity");
|
||||
}
|
||||
|
||||
return string.Join("|", flags);
|
||||
}
|
||||
public static string[] GetNodes(string xmlFile)
|
||||
{
|
||||
List<string> typesList = new List<string>();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/Node");
|
||||
if (treeTypes != null)
|
||||
{
|
||||
foreach (var type in treeTypes)
|
||||
{
|
||||
XmlElement element = type as XmlElement;
|
||||
if (element != null)
|
||||
{
|
||||
typesList.Add(element.GetAttribute("Name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return typesList.ToArray();
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<string>> GetReverseDependencies(string xmlFile)
|
||||
{
|
||||
Dictionary<string, List<string>> dependencyMap = new Dictionary<string, List<string>>();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
XmlNodeList treeTypes = doc.SelectNodes("/ServerExplorerTree/ReverseDependencyList/ReverseDependency");
|
||||
if (treeTypes != null)
|
||||
{
|
||||
foreach (var type in treeTypes)
|
||||
{
|
||||
XmlElement element = type as XmlElement;
|
||||
if (element != null)
|
||||
{
|
||||
string typeName = element.GetAttribute("Type");
|
||||
string dependency = element.GetAttribute("DependsOn");
|
||||
List<string> dependenciesForType;
|
||||
if (dependencyMap.TryGetValue(typeName, out dependenciesForType))
|
||||
{
|
||||
dependenciesForType.Add(dependency);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] allDepedencies = dependency.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
dependenciesForType = new List<string>();
|
||||
dependenciesForType.AddRange(allDepedencies);
|
||||
dependencyMap.Add(typeName, dependenciesForType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dependencyMap;
|
||||
}
|
||||
|
||||
public static XmlElement GetNodeElement(string xmlFile, string nodeName)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
return (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/Node[@Name='{0}']", nodeName));
|
||||
}
|
||||
|
||||
public static bool TreeNodeExists(string xmlFile, string TreeNode)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
var found = (XmlElement)doc.SelectSingleNode(string.Format("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode[@Name='{0}']", TreeNode));
|
||||
|
||||
return (found != null);
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetUniqueTreeNodes(string xmlFile)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes("/ServerExplorerTree/CodeGenOptions/UniqueTreeNode");
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
|
||||
public static List<XmlElement> GetChildren(string xmlFile, string parentName)
|
||||
{
|
||||
XmlElement nodeElement = GetNodeElement(xmlFile, parentName);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFile);
|
||||
|
||||
List<XmlElement> retElements = new List<XmlElement>();
|
||||
XmlNodeList nodeList = doc.SelectNodes(string.Format("/ServerExplorerTree/Node[@Name='{0}']/Child", parentName));
|
||||
foreach (var item in nodeList)
|
||||
{
|
||||
XmlElement itemAsElement = item as XmlElement;
|
||||
if (itemAsElement != null)
|
||||
{
|
||||
retElements.Add(itemAsElement);
|
||||
}
|
||||
}
|
||||
return retElements;
|
||||
}
|
||||
#>
|
||||
@@ -44,3 +44,6 @@ using System.Runtime.InteropServices;
|
||||
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.UnitTests")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.IntegrationTests")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test.Common")]
|
||||
|
||||
// Allowing internals visible access to Moq library to help testing
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.Hosting;
|
||||
using Microsoft.SqlTools.Hosting.Contracts;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
@@ -29,6 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
|
||||
/// </summary>
|
||||
private const int ShutdownTimeoutInSeconds = 120;
|
||||
public static readonly string[] CompletionTriggerCharacters = new string[] { ".", "-", ":", "\\", "[", "\"" };
|
||||
private IMultiServiceProvider serviceProvider;
|
||||
|
||||
#region Singleton Instance Code
|
||||
|
||||
@@ -54,6 +56,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
|
||||
// Initialize the shutdown activities
|
||||
shutdownCallbacks = new List<ShutdownCallback>();
|
||||
initializeCallbacks = new List<InitializeCallback>();
|
||||
}
|
||||
|
||||
public IMultiServiceProvider ServiceProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
return serviceProvider;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
serviceProvider = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Common Constant values used across multiple services
|
||||
/// </summary>
|
||||
public static class CommonConstants
|
||||
{
|
||||
public const string MasterDatabaseName = "master";
|
||||
public const string MsdbDatabaseName = "msdb";
|
||||
public const string ModelDatabaseName = "model";
|
||||
public const string TempDbDatabaseName = "tempdb";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||
using Xunit;
|
||||
using static Microsoft.SqlTools.ServiceLayer.ObjectExplorer.ObjectExplorerService;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||
{
|
||||
public class ObjectExplorerServiceTests
|
||||
{
|
||||
private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService;
|
||||
|
||||
[Fact]
|
||||
public async void CreateSessionAndExpandOnTheServerShouldReturnTheDatabases()
|
||||
{
|
||||
var query = "";
|
||||
string uri = "CreateSessionAndExpand";
|
||||
string databaseName = null;
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ObjectExplorerSession> CreateSession(string databaseName, string uri)
|
||||
{
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
ConnectionDetails details = connectParams.Connection;
|
||||
|
||||
return await _service.DoCreateSession(details, uri);
|
||||
}
|
||||
|
||||
private async Task<NodeInfo> CreateSessionAndDatabaseNode(string databaseName, ObjectExplorerSession session)
|
||||
{
|
||||
Assert.NotNull(session);
|
||||
Assert.NotNull(session.Root);
|
||||
NodeInfo nodeInfo = session.Root.ToNodeInfo();
|
||||
Assert.Equal(nodeInfo.IsLeaf, false);
|
||||
Assert.Equal(nodeInfo.NodeType, NodeTypes.ServerInstance.ToString());
|
||||
var children = session.Root.Expand();
|
||||
|
||||
//All server children should be folder nodes
|
||||
foreach (var item in children)
|
||||
{
|
||||
Assert.Equal(item.NodeType, "Folder");
|
||||
}
|
||||
|
||||
var databasesRoot = children.FirstOrDefault(x => x.NodeTypeId == NodeTypes.Databases);
|
||||
var databasesChildren = await _service.ExpandNode(session, databasesRoot.GetNodePath());
|
||||
var databases = databasesChildren.Where(x => x.NodeType == NodeTypes.DatabaseInstance.ToString());
|
||||
|
||||
//Verify the test databases is in the list
|
||||
Assert.NotNull(databases);
|
||||
var databaseNode = databases.FirstOrDefault(d => d.Label == databaseName);
|
||||
Assert.NotNull(databaseNode);
|
||||
return databaseNode;
|
||||
}
|
||||
|
||||
private void CancelConnection(string uri)
|
||||
{
|
||||
//ConnectionService.Instance.CancelConnect(new CancelConnectParams
|
||||
//{
|
||||
// OwnerUri = uri,
|
||||
// Type = ConnectionType.Default
|
||||
//});
|
||||
}
|
||||
|
||||
private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session)
|
||||
{
|
||||
if(node != null && !node.IsLeaf)
|
||||
{
|
||||
var children = await _service.ExpandNode(session, node.NodePath);
|
||||
Assert.NotNull(children);
|
||||
if(children.Count() == 0 && !node.NodePath.Contains("System") &&
|
||||
!node.NodePath.Contains("FileTables") && !node.NodePath.Contains("External Tables"))
|
||||
{
|
||||
var labaleToUpper = node.Label.ToUpper();
|
||||
if (labaleToUpper.Contains("TABLE") || labaleToUpper.Contains("StoredProcedure")
|
||||
|| labaleToUpper.Contains("VIEW"))
|
||||
{
|
||||
//TOOD: Add a better validation. For now at least check tables not to be empty
|
||||
//Assert.True(false, "The list of tables, procedure and views cannot be empty");
|
||||
}
|
||||
}
|
||||
foreach (var child in children)
|
||||
{
|
||||
//Console.WriteLine(child.Label);
|
||||
await ExpandTree(child, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void VerifyAdventureWorksDatabaseObjects()
|
||||
{
|
||||
var query = Scripts.AdventureWorksScript;
|
||||
string uri = "VerifyAdventureWorksDatabaseObjects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifySql2016Objects()
|
||||
{
|
||||
var query = LoadScript("Sql_2016_Additions.sql");
|
||||
string uri = "VerifySql2016Objects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifySqlObjects()
|
||||
{
|
||||
var query = LoadScript("Sql_Additions.sql");
|
||||
string uri = "VerifySqlObjects";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
public async void VerifyFileTableTest()
|
||||
{
|
||||
var query = LoadScript("FileTableTest.sql");
|
||||
string uri = "VerifyFileTableTest";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
public async void VerifyColumnstoreindexSql16()
|
||||
{
|
||||
var query = LoadScript("ColumnstoreindexSql16.sql");
|
||||
string uri = "VerifyColumnstoreindexSql16";
|
||||
string databaseName = null;
|
||||
|
||||
using (SqlTestDb testDb = SqlTestDb.CreateNew(TestServerType.OnPrem, false, databaseName, query, uri))
|
||||
{
|
||||
var session = await CreateSession(testDb.DatabaseName, uri);
|
||||
var databaseNodeInfo = await CreateSessionAndDatabaseNode(testDb.DatabaseName, session);
|
||||
await ExpandTree(databaseNodeInfo, session);
|
||||
CancelConnection(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private static string TestLocationDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "ObjectExplorer");
|
||||
}
|
||||
}
|
||||
|
||||
public DirectoryInfo InputFileDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
string d = Path.Combine(TestLocationDirectory, "TestScripts");
|
||||
return new DirectoryInfo(d);
|
||||
}
|
||||
}
|
||||
|
||||
public FileInfo GetInputFile(string fileName)
|
||||
{
|
||||
return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName));
|
||||
}
|
||||
|
||||
private string LoadScript(string fileName)
|
||||
{
|
||||
FileInfo inputFile = GetInputFile(fileName);
|
||||
return TestUtilities.ReadTextAndNormalizeLineEndings(inputFile.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Data.SqlClient;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
@@ -27,11 +30,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
|
||||
|
||||
}
|
||||
|
||||
public static TestConnectionResult InitLiveConnectionInfo()
|
||||
public static TestConnectionResult InitLiveConnectionInfo(string databaseName = null)
|
||||
{
|
||||
string sqlFilePath = GetTestSqlFile();
|
||||
ScriptFile scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(sqlFilePath);
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem);
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
string ownerUri = scriptFile.ClientFilePath;
|
||||
var connectionService = GetLiveTestConnectionService();
|
||||
@@ -50,6 +53,35 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
|
||||
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
|
||||
}
|
||||
|
||||
public static async Task<TestConnectionResult> InitLiveConnectionInfoAsync(string databaseName = null, string ownerUri = null)
|
||||
{
|
||||
ScriptFile scriptFile = null;
|
||||
if (string.IsNullOrEmpty(ownerUri))
|
||||
{
|
||||
string sqlFilePath = GetTestSqlFile();
|
||||
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(sqlFilePath);
|
||||
ownerUri = scriptFile.ClientFilePath;
|
||||
}
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
var connectionService = GetLiveTestConnectionService();
|
||||
var connectionResult =
|
||||
await connectionService
|
||||
.Connect(new ConnectParams
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
Connection = connectParams.Connection
|
||||
});
|
||||
if (!string.IsNullOrEmpty(connectionResult.ErrorMessage))
|
||||
{
|
||||
Console.WriteLine(connectionResult.ErrorMessage);
|
||||
}
|
||||
|
||||
ConnectionInfo connInfo = null;
|
||||
connectionService.TryFindConnection(ownerUri, out connInfo);
|
||||
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
|
||||
}
|
||||
|
||||
public static ConnectionInfo InitLiveConnectionInfoForDefinition(string databaseName = null)
|
||||
{
|
||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||
|
||||
Binary file not shown.
@@ -43,7 +43,9 @@ END
|
||||
|
||||
public static string CreateDatabaseQuery { get { return CreateDatabaseQueryInstance.Value; } }
|
||||
|
||||
public static string TestDbComplexSelectQueries { get { return TestDbSelectQueriesInstance.Value; } }
|
||||
public static string TestDbComplexSelectQueries { get { return TestDbSelectQueriesInstance.Value; } }
|
||||
|
||||
public static string AdventureWorksScript { get { return AdventureWorksScriptInstance.Value; } }
|
||||
|
||||
private static readonly Lazy<string> CreateDatabaseObjectsQueryInstance = new Lazy<string>(() =>
|
||||
{
|
||||
@@ -58,6 +60,11 @@ END
|
||||
private static readonly Lazy<string> TestDbSelectQueriesInstance = new Lazy<string>(() =>
|
||||
{
|
||||
return GetScriptFileContent(ResourceNameRefix + "TestDbTableQueries.sql");
|
||||
});
|
||||
|
||||
private static readonly Lazy<string> AdventureWorksScriptInstance = new Lazy<string>(() =>
|
||||
{
|
||||
return GetScriptFileContent(ResourceNameRefix + "AdventureWorks.sql");
|
||||
});
|
||||
|
||||
private static string GetScriptFileContent(string fileName)
|
||||
|
||||
@@ -27,13 +27,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||
/// <summary>
|
||||
/// Create the test db if not already exists
|
||||
/// </summary>
|
||||
public static SqlTestDb CreateNew(TestServerType serverType, bool doNotCleanupDb = false, string databaseName = null, string query = null)
|
||||
public static SqlTestDb CreateNew(
|
||||
TestServerType serverType,
|
||||
bool doNotCleanupDb = false,
|
||||
string databaseName = null,
|
||||
string query = null,
|
||||
string dbNamePrefix = null)
|
||||
{
|
||||
SqlTestDb testDb = new SqlTestDb();
|
||||
|
||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||
{
|
||||
databaseName = databaseName ?? GetUniqueDBName("");
|
||||
databaseName = databaseName ?? GetUniqueDBName(dbNamePrefix);
|
||||
string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName);
|
||||
TestServiceProvider.Instance.RunQuery(serverType, MasterDatabaseName, createDatabaseQuery);
|
||||
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Test database '{0}' is created", databaseName));
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE CS_Delay_Table1
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL);
|
||||
GO
|
||||
|
||||
CREATE CLUSTERED COLUMNSTORE INDEX CSI_1 ON CS_Delay_Table1
|
||||
WITH (COMPRESSION_DELAY = 100 minutes);
|
||||
GO
|
||||
|
||||
CREATE TABLE CS_Delay_Table2
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL);
|
||||
GO
|
||||
|
||||
CREATE CLUSTERED INDEX CI_Table2 ON CS_Delay_Table2 (ProductKey);
|
||||
GO
|
||||
|
||||
CREATE NONCLUSTERED COLUMNSTORE INDEX CSI_2
|
||||
ON CS_Delay_Table2
|
||||
(OrderDateKey, DueDateKey, ShipDateKey)
|
||||
WITH (COMPRESSION_DELAY = 200);
|
||||
GO
|
||||
|
||||
CREATE TABLE CS_Delay_Table3
|
||||
(ProductKey [int] NOT NULL,
|
||||
OrderDateKey [int] NOT NULL,
|
||||
DueDateKey [int] NOT NULL,
|
||||
ShipDateKey [int] NOT NULL,
|
||||
INDEX CSI_3 CLUSTERED COLUMNSTORE WITH(COMPRESSION_DELAY = 50 minute));
|
||||
GO
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
CREATE DATABASE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
ALTER DATABASE [$(DatabaseName)] SET TARGET_RECOVERY_TIME = 1 MINUTES
|
||||
GO
|
||||
USE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
ALTER DATABASE [$(DatabaseName)]
|
||||
SET FILESTREAM(
|
||||
NON_TRANSACTED_ACCESS = FULL,
|
||||
DIRECTORY_NAME = N'$(DatabaseName)'
|
||||
) WITH NO_WAIT
|
||||
|
||||
GO
|
||||
|
||||
ALTER DATABASE $(DatabaseName)
|
||||
ADD FILEGROUP [FileGroup1]
|
||||
CONTAINS FILESTREAM
|
||||
|
||||
GO
|
||||
|
||||
ALTER DATABASE $(DatabaseName)
|
||||
ADD FILE
|
||||
(NAME = 'FileTableFile'
|
||||
, FILENAME = '$(DefaultDataPath)$(DatabaseName)_FT'
|
||||
)
|
||||
TO FILEGROUP [FileGroup1]
|
||||
|
||||
GO
|
||||
|
||||
|
||||
|
||||
CREATE TABLE [dbo].[FileTablePass] AS FILETABLE WITH(
|
||||
FileTable_Directory = 'docs',
|
||||
FILETABLE_PRIMARY_KEY_CONSTRAINT_NAME=MyPk,
|
||||
FILETABLE_STREAMID_UNIQUE_CONSTRAINT_NAME=MyStreamUQ,
|
||||
FILETABLE_FULLPATH_UNIQUE_CONSTRAINT_NAME=MyPathUQ)
|
||||
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] WITH CHECK ADD CONSTRAINT [MyCheck] CHECK ((stream_id IS NOT NULL))
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] ADD CONSTRAINT [MyDefault] DEFAULT ((NULL)) FOR [name]
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] ADD CONSTRAINT [MyQU] UNIQUE NONCLUSTERED ([name] ASC)
|
||||
GO
|
||||
ALTER TABLE [dbo].[FileTablePass] WITH CHECK ADD CONSTRAINT [MyFk] FOREIGN KEY([parent_path_locator])
|
||||
REFERENCES [dbo].[FileTablePass] ([path_locator])
|
||||
GO
|
||||
CREATE TABLE [dbo].[t2] (
|
||||
[c1] INT NOT NULL,
|
||||
[c2] INT DEFAULT ((1)) NULL,
|
||||
[c3] INT DEFAULT ((1)) NOT NULL,
|
||||
[path_locator] hierarchyid,
|
||||
PRIMARY KEY CLUSTERED ([c1] ASC),
|
||||
UNIQUE NONCLUSTERED ([c2] ASC),
|
||||
CHECK ([c2] > (0))
|
||||
);
|
||||
|
||||
GO
|
||||
CREATE STATISTICS stat1
|
||||
ON dbo.[FileTablePass](stream_id)
|
||||
WITH SAMPLE 50 PERCENT;
|
||||
GO
|
||||
CREATE INDEX IX_FileTablePass_Stream_id
|
||||
ON dbo.FileTablePass(stream_id);
|
||||
GO
|
||||
|
||||
CREATE TRIGGER FileTableTrigger
|
||||
ON dbo.FileTablePass
|
||||
AFTER INSERT
|
||||
AS RAISERROR ('Block insert', 16, 10);
|
||||
GO
|
||||
CREATE INDEX IX_T2_C3
|
||||
ON [dbo].[t2](c3);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TRIGGER reminder2
|
||||
ON dbo.t2
|
||||
AFTER INSERT, UPDATE, DELETE
|
||||
AS
|
||||
PRINT 'reminder trigger';
|
||||
|
||||
GO
|
||||
|
||||
ALTER TABLE dbo.t2
|
||||
ADD CONSTRAINT FK_TO_FILETABLE FOREIGN KEY (path_locator)
|
||||
REFERENCES FileTablePass (path_locator) ;
|
||||
GO
|
||||
exec sp_addextendedproperty 'prop_ex', 'FileTable', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyPk', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyPk'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyStreamUQ', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyStreamUQ'
|
||||
exec sp_addextendedproperty 'prop_ex', 'MyPathUQ', 'SCHEMA', 'dbo', 'TABLE', 'FileTablePass', 'CONSTRAINT', 'MyPathUQ'
|
||||
|
||||
GO
|
||||
|
||||
CREATE USER test_user WITHOUT LOGIN
|
||||
GO
|
||||
|
||||
GRANT SELECT ON dbo.FileTablePass TO test_user
|
||||
GO
|
||||
@@ -0,0 +1,62 @@
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure]
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 1 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];2
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 2 AS Col1
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];3
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 3 AS Col1
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Encrypted_Additional_Numbered_Procedure];4
|
||||
( @param1 int)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
SELECT 4 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure]
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 1 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];2
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 2 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];3
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 3 AS Col1
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE [dbo].[Additional_Numbered_Procedure];4
|
||||
(@param1 int)
|
||||
AS
|
||||
SELECT 4 AS Col1
|
||||
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
ALTER DATABASE current SET COMPATIBILITY_LEVEL=130
|
||||
GO
|
||||
|
||||
/* Dropping previous master key in master db that could have been created from other runs */
|
||||
IF ( EXISTS(SELECT name FROM sys.symmetric_keys WHERE name = '##MS_DatabaseMasterKey##')) DROP MASTER KEY
|
||||
|
||||
CREATE MASTER KEY ENCRYPTION BY PASSWORD= 'Password01!';
|
||||
|
||||
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'Password01!';
|
||||
|
||||
|
||||
CREATE DATABASE SCOPED CREDENTIAL AlterEgo WITH IDENTITY = 'RettigB',
|
||||
SECRET = 'sdrlk8$40-dksli87nNN8';
|
||||
|
||||
GO
|
||||
|
||||
-- Row-Level Security
|
||||
CREATE TABLE [dbo].[Sales1]
|
||||
(
|
||||
OrderID INT,
|
||||
SalesRep SYSNAME NOT NULL,
|
||||
Product VARCHAR(10),
|
||||
Qty INT
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[Sales2]
|
||||
(
|
||||
OrderID INT,
|
||||
SalesRep SYSNAME NOT NULL,
|
||||
Product VARCHAR(10),
|
||||
Qty INT
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[fn_securitypredicate](@SalesRep AS SYSNAME)
|
||||
RETURNS TABLE
|
||||
WITH SCHEMABINDING
|
||||
AS
|
||||
RETURN SELECT 1 AS fn_securitypredicate_result
|
||||
WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'Manager';
|
||||
|
||||
|
||||
GO
|
||||
|
||||
CREATE SECURITY POLICY [dbo].[SalesFilter]
|
||||
ADD FILTER PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales1],
|
||||
ADD FILTER PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales2],
|
||||
ADD BLOCK PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales1],
|
||||
ADD BLOCK PREDICATE [dbo].[fn_securitypredicate]([SalesRep]) ON [dbo].[Sales2] AFTER UPDATE
|
||||
WITH (STATE = OFF)
|
||||
NOT FOR REPLICATION
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN MASTER KEY CMK1
|
||||
WITH (
|
||||
KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
|
||||
KEY_PATH = 'Current User/Personal/f2260f28d909d21c642a3d8e0b45a830e79a1420'
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN MASTER KEY CMK2
|
||||
WITH (
|
||||
KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
|
||||
KEY_PATH = 'Current User/Personal/f2260f28d909d21c642a3d8e0b45a830e79a1420'
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE COLUMN ENCRYPTION KEY TwoValueCEK
|
||||
WITH VALUES
|
||||
(
|
||||
COLUMN_MASTER_KEY = CMK1,
|
||||
ALGORITHM = 'RSA_OAEP',
|
||||
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F0037006300380061003100310033003400320037003800620037003000630038003100390062003900630039003400360061006600340039006500610030003200650038006200650038003400340065006C33A82ECF04A7185824B4545457AC5244CD9C219E64067B9520C0081B8399B58C2863F7494ABE3694BD87D55FFD7576FFDC47C28F94ECC99577DF4FB8FA19AA95764FEF889CDE0F176DA5897B74382FBB22756CE2921050A09201A0EB6AF3D6091014C30146EA62635EE8CBF0A8074DEDFF125CEA80D1C0F5E8C58750A07D270E2A8BF824EE4C0C156366BF26D38CCE49EBDD5639A2DF029A7DBAE5A5D111F2F2FA3246DF8C2FA83C1E542C10570FADA98F6B29478DC58CE5CBDD407CCEFCDB97814525F6F32BECA266014AC346AC39C4F185C6C0F0A24FEC4DFA015649624692DE7865B9827BA22C3B574C9FD169F822B609F902288C5880EB25F14BD990D871B1BC4BA3A5B237AF76D26354773FA2A25CF4511AF58C911E601CFCB1905128C997844EED056C2AE7F0B48700AB41307E470FF9520997D0EB0D887DE11AFE574FFE845B7DC6C03FEEE8D467236368FC0CB2FDBD54DADC65B10B3DE6C80DF8B7B3F8F3CE5BE914713EE7B1FA5B7A578359592B8A5FDFDDE5FF9F392BC87C3CD02FBA94582AC063BBB9FFAC803FD489E16BEB28C4E3374A8478C737236A0B232F5A9DDE4D119573F1AEAE94B2192B81575AD6F57E670C1B2AB91045124DFDAEC2898F3F0112026DFC93BF9391D667D1AD7ED7D4E6BB119BBCEF1D1ADA589DD3E1082C3DAD13223BE438EB9574DA04E9D8A06320CAC6D3EC21D5D1C2A0AA484C7C
|
||||
),
|
||||
(
|
||||
COLUMN_MASTER_KEY = CMK2,
|
||||
ALGORITHM = 'RSA_OAEP',
|
||||
ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F0064006500650063006200660034006100340031003000380034006200350033003200360066003200630062006200350030003600380065003900620061003000320030003600610037003800310066001DDA6134C3B73A90D349C8905782DD819B428162CF5B051639BA46EC69A7C8C8F81591A92C395711493B25DCBCCC57836E5B9F17A0713E840721D098F3F8E023ABCDFE2F6D8CC4339FC8F88630ED9EBADA5CA8EEAFA84164C1095B12AE161EABC1DF778C07F07D413AF1ED900F578FC00894BEE705EAC60F4A5090BBE09885D2EFE1C915F7B4C581D9CE3FDAB78ACF4829F85752E9FC985DEB8773889EE4A1945BD554724803A6F5DC0A2CD5EFE001ABED8D61E8449E4FAA9E4DD392DA8D292ECC6EB149E843E395CDE0F98D04940A28C4B05F747149B34A0BAEC04FFF3E304C84AF1FF81225E615B5F94E334378A0A888EF88F4E79F66CB377E3C21964AACB5049C08435FE84EEEF39D20A665C17E04898914A85B3DE23D56575EBC682D154F4F15C37723E04974DB370180A9A579BC84F6BC9B5E7C223E5CBEE721E57EE07EFDCC0A3257BBEBF9ADFFB00DBF7EF682EC1C4C47451438F90B4CF8DA709940F72CFDC91C6EB4E37B4ED7E2385B1FF71B28A1D2669FBEB18EA89F9D391D2FDDEA0ED362E6A591AC64EF4AE31CA8766C259ECB77D01A7F5C36B8418F91C1BEADDD4491C80F0016B66421B4B788C55127135DA2FA625FB7FD195FB40D90A6C67328602ECAF3EC4F5894BFD84A99EB4753BE0D22E0D4DE6A0ADFEDC80EB1B556749B4A8AD00E73B329C95827AB91C0256347E85E3C5FD6726D0E1FE82C925D3DF4A9
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE Customers (
|
||||
CustName nvarchar(60),
|
||||
SSN varchar(11)
|
||||
COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = TwoValueCEK,
|
||||
ENCRYPTION_TYPE = DETERMINISTIC ,
|
||||
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'),
|
||||
Age int NULL,
|
||||
ACTNO varchar(11)
|
||||
ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = TwoValueCEK,
|
||||
ENCRYPTION_TYPE = RANDOMIZED,
|
||||
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256')
|
||||
);
|
||||
|
||||
GO
|
||||
|
||||
USE [$(DatabaseName)]
|
||||
|
||||
GO
|
||||
|
||||
DBCC TRACEON(4631,-1)
|
||||
|
||||
GO
|
||||
|
||||
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'Password01!';
|
||||
|
||||
CREATE DATABASE SCOPED CREDENTIAL cred1 WITH IDENTITY = 'test_user', SECRET = '$(Secret)';
|
||||
|
||||
CREATE EXTERNAL DATA SOURCE eds1
|
||||
WITH (
|
||||
TYPE = HADOOP,
|
||||
LOCATION = '$(DataSourceLocation)',
|
||||
CREDENTIAL = cred1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL DATA SOURCE eds2
|
||||
WITH (
|
||||
TYPE = HADOOP,
|
||||
LOCATION = '$(DataSourceLocation)'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff1
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff2
|
||||
WITH (
|
||||
FORMAT_TYPE = ORC
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff3
|
||||
WITH (
|
||||
FORMAT_TYPE = PARQUET
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff4
|
||||
WITH (
|
||||
FORMAT_TYPE = RCFILE,
|
||||
SERDE_METHOD = 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff5
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (FIELD_TERMINATOR = '|', STRING_DELIMITER = ';', DATE_FORMAT = 'MM-dd-yyyy', USE_TYPE_DEFAULT = FALSE)
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff6
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (FIELD_TERMINATOR = '|')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff7
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff8
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|', STRING_DELIMITER = ';')
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff9
|
||||
WITH (
|
||||
FORMAT_TYPE = DELIMITEDTEXT,
|
||||
FORMAT_OPTIONS (DATE_FORMAT = 'MM-dd-yyyy', FIELD_TERMINATOR = '|', STRING_DELIMITER = ';'),
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.GzipCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff10
|
||||
WITH (
|
||||
FORMAT_TYPE = RCFILE,
|
||||
SERDE_METHOD = 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe',
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.DefaultCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff11
|
||||
WITH (
|
||||
FORMAT_TYPE = ORC,
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL FILE FORMAT eff12
|
||||
WITH (
|
||||
FORMAT_TYPE = PARQUET,
|
||||
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands1
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands2
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds2,
|
||||
FILE_FORMAT = eff1
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands3
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds2,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = VALUE,
|
||||
REJECT_VALUE = 0
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands4
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = PERCENTAGE,
|
||||
REJECT_VALUE = 30.5,
|
||||
REJECT_SAMPLE_VALUE = 10
|
||||
);
|
||||
|
||||
CREATE EXTERNAL TABLE bands5
|
||||
(
|
||||
id INTEGER NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
origin CHAR(3),
|
||||
rate FLOAT,
|
||||
experience SMALLINT
|
||||
)
|
||||
WITH (
|
||||
LOCATION = '/bands.dat',
|
||||
DATA_SOURCE = eds1,
|
||||
FILE_FORMAT = eff1,
|
||||
REJECT_TYPE = VALUE,
|
||||
REJECT_VALUE = 30
|
||||
);
|
||||
@@ -0,0 +1,298 @@
|
||||
-- create signature
|
||||
ADD SIGNATURE TO [Procedure1]
|
||||
BY CERTIFICATE [Certificate1]
|
||||
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y' ;
|
||||
GO
|
||||
--Create a queue to receive messages.
|
||||
CREATE QUEUE NotifyQueue ;
|
||||
GO
|
||||
--Create a service on the queue that references
|
||||
--the event notifications contract.
|
||||
CREATE SERVICE NotifyService
|
||||
ON QUEUE NotifyQueue
|
||||
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
|
||||
GO
|
||||
--Create the event notification on queue.
|
||||
CREATE EVENT NOTIFICATION Notify_ALTER_T1
|
||||
ON QUEUE notifyqueue
|
||||
FOR QUEUE_ACTIVATION
|
||||
TO SERVICE 'NotifyService',
|
||||
'8140a771-3c4b-4479-8ac0-81008ab17984';
|
||||
GO
|
||||
--Create the event notification on database
|
||||
CREATE EVENT NOTIFICATION Notify_ALTER_T1
|
||||
ON DATABASE
|
||||
FOR ALTER_TABLE
|
||||
TO SERVICE 'NotifyService',
|
||||
'8140a771-3c4b-4479-8ac0-81008ab17984';
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[TableFunctionWithComputedColumns]
|
||||
(
|
||||
-- Add the parameters for the function here
|
||||
@p1 int = 2,
|
||||
@p2 nchar(10) = NUll
|
||||
)
|
||||
RETURNS
|
||||
@Table_Var TABLE
|
||||
(
|
||||
-- Add the column definitions for the TABLE variable here
|
||||
c1 int,
|
||||
c2 nchar(10),
|
||||
c3 AS 1 * 3
|
||||
)
|
||||
AS
|
||||
BEGIN
|
||||
-- Fill the table variable with the rows for your result set
|
||||
INSERT INTO @Table_Var
|
||||
SELECT a.column_1, a.column_2
|
||||
FROM Table_1 a
|
||||
WHERE a.column_1 > 5
|
||||
|
||||
INSERT INTO @Table_Var
|
||||
SELECT column_1, 'From 2'
|
||||
FROM Table_2
|
||||
WHERE @p1 > column_1
|
||||
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[TableFunctionWithComputedColumnsEncrypted]
|
||||
(
|
||||
-- Add the parameters for the function here
|
||||
@p1 int = 2,
|
||||
@p2 nchar(10)
|
||||
)
|
||||
RETURNS
|
||||
@Table_Var TABLE
|
||||
(
|
||||
-- Add the column definitions for the TABLE variable here
|
||||
c1 int,
|
||||
c2 nchar(10),
|
||||
c3 AS 1 * 3
|
||||
)
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
BEGIN
|
||||
-- Fill the table variable with the rows for your result set
|
||||
INSERT INTO @Table_Var
|
||||
SELECT a.column_1, a.column_2
|
||||
FROM Table_1 a
|
||||
WHERE a.column_1 > 5
|
||||
|
||||
INSERT INTO @Table_Var
|
||||
SELECT column_1, 'From 2'
|
||||
FROM Table_2
|
||||
WHERE @p1 > column_1
|
||||
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
|
||||
Create table [dbo].[referenced_table] (C1 int, C2 int);
|
||||
|
||||
GO
|
||||
|
||||
CREATE PROCEDURE GetReferenedTable
|
||||
AS
|
||||
BEGIN
|
||||
SELECT * from [dbo].[referenced_table];
|
||||
END
|
||||
GO
|
||||
exec sp_addextendedproperty N'microsoft_database_tools_support', 'GetReferenedTable', N'SCHEMA', 'dbo', N'PROCEDURE' ,'GetReferenedTable'
|
||||
GO
|
||||
DISABLE TRIGGER [Trigger_1]
|
||||
ON DATABASE;
|
||||
GO
|
||||
|
||||
CREATE VIEW [dbo].[View_2] (c1)
|
||||
AS
|
||||
SELECT column_1 as c1
|
||||
FROM dbo.Table_1
|
||||
|
||||
GO
|
||||
|
||||
exec sp_addextendedproperty 'prop_ex', 'Table_1', 'SCHEMA', 'dbo', 'TABLE', 'Table_1'
|
||||
|
||||
GO
|
||||
|
||||
exec sp_addextendedproperty 'prop_ex', 'column_1', 'SCHEMA', 'dbo', 'TABLE', 'Table_1', 'COLUMN', 'column_1'
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.MultipleIndexTable
|
||||
( [c1] INT NOT NULL CHECK (c1 > 0),
|
||||
[c2] int default 10 null,
|
||||
PRIMARY KEY NONCLUSTERED (c1 ASC),
|
||||
UNIQUE CLUSTERED (c1 ASC, c2 DESC)
|
||||
)
|
||||
|
||||
GO
|
||||
|
||||
CREATE TRIGGER [Trigger_2]
|
||||
ON DATABASE
|
||||
FOR DROP_TABLE
|
||||
AS
|
||||
SELECT COUNT(column_1) from dbo.Table_1
|
||||
RAISERROR ('You must disable Trigger "Trigger_1" to drop synonyms!',10, 1)
|
||||
ROLLBACK
|
||||
|
||||
GO
|
||||
|
||||
SET ANSI_NULLS OFF
|
||||
GO
|
||||
|
||||
SET QUOTED_IDENTIFIER OFF
|
||||
GO
|
||||
|
||||
DISABLE TRIGGER [Trigger_1] ON DATABASE
|
||||
GO
|
||||
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.Table_3
|
||||
(
|
||||
c1 int,
|
||||
c2 int,
|
||||
) ON PartitionScheme(c1)
|
||||
|
||||
GO
|
||||
CREATE TABLE [dbo].[Different_WithAppend_Table](
|
||||
[Id] [int] IDENTITY(1,1) NOT NULL,
|
||||
[Col] [char](1) NULL
|
||||
) ON [PRIMARY]
|
||||
|
||||
GO
|
||||
|
||||
CREATE FUNCTION [dbo].[EncryptedFunctionWithConstraints]
|
||||
(@p1 INT)
|
||||
RETURNS
|
||||
@GeneratedTableName TABLE (
|
||||
[c0] INT NOT NULL PRIMARY KEY,
|
||||
[c1] INT DEFAULT ((1)) NULL,
|
||||
[c2] NCHAR (10) NULL,
|
||||
[c3] INT UNIQUE ,
|
||||
CHECK ([c1]>(0)))
|
||||
WITH ENCRYPTION
|
||||
AS
|
||||
BEGIN
|
||||
insert into @GeneratedTableName values (1,1, 'abc',1);
|
||||
RETURN
|
||||
END
|
||||
GO
|
||||
CREATE TABLE [[] (c1 int)
|
||||
GO
|
||||
CREATE TABLE []]] (c1 int)
|
||||
GO
|
||||
CREATE TABLE [asdf'[] (c1 int)
|
||||
GO
|
||||
CREATE TABLE [噂構申表5] (c1 int)
|
||||
GO
|
||||
-- Casing of NULL is explicit 'NUll'
|
||||
CREATE PROC CasingOnDefaultValue @param1 int = NUll, @param2 nvarchar(123) = N'abc'
|
||||
AS
|
||||
BEGIN
|
||||
select 1 as a
|
||||
END
|
||||
-- permissions
|
||||
GO
|
||||
CREATE USER nologon4 without login
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CasingOnDefaultValue to nologon4
|
||||
GO
|
||||
CREATE USER granter without login
|
||||
GO
|
||||
GRANT CONNECT TO granter WITH GRANT OPTION;
|
||||
GO
|
||||
DENY CONNECT TO nologon4 CASCADE AS granter;
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [噂構申表5] to nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [[] TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON []]] TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON [asdf'[] TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_1 to nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_2 to nologon4
|
||||
GO
|
||||
REVOKE SELECT ON dbo.Table_2(column_2) TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.View_1 to nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.EncryptedView(A) to nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.Procedure1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.CLR_SimpleResultsetProcedure TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.EncryptedProcedure TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CERTIFICATE :: Certificate1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.ScalarFunction1 TO nologon4
|
||||
GO
|
||||
GRANT EXECUTE ON dbo.EncryptedFunction TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.InlineFunction_1 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunction1 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.CLRTableValueFunction TO nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON TYPE::dbo.dataType To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON FULLTEXT CATALOG ::FullTextCatalog1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON XML SCHEMA COLLECTION :: dbo.XmlSchemaCollection To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ASSEMBLY :: [Geometry] To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON TYPE:: dbo.Angle To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.[Concat] To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.Synonym_1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SCHEMA :: Schema1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SYMMETRIC KEY :: SymKey1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ASYMMETRIC KEY :: AsmKey1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.Queue1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON dbo.NotifyQueue To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SERVICE :: Service1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON SERVICE :: NotifyService To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON CONTRACT :: Contract1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON MESSAGE TYPE :: MessageType1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ROUTE :: AutoCreatedLocal To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON ROUTE :: Route1 To nologon4
|
||||
GO
|
||||
GRANT VIEW DEFINITION ON REMOTE SERVICE BINDING :: ServiceBinding1 To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.referenced_table To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunctionWithComputedColumns To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.TableFunctionWithComputedColumnsEncrypted To nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.View_2 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.MultipleIndexTable TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Table_3 TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.Different_WithAppend_Table TO nologon4
|
||||
GO
|
||||
GRANT SELECT ON dbo.[EncryptedFunctionWithConstraints] TO nologon4
|
||||
GO
|
||||
@@ -8,6 +8,7 @@ using Microsoft.SqlTools.Credentials;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
using Microsoft.SqlTools.ServiceLayer.Workspace;
|
||||
@@ -43,6 +44,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
|
||||
{
|
||||
return CredentialService.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectExplorerService ObjectExplorerService
|
||||
{
|
||||
get
|
||||
{
|
||||
var serviceProvider = ServiceHost.Instance.ServiceProvider;
|
||||
return serviceProvider.GetService<ObjectExplorerService>();
|
||||
}
|
||||
}
|
||||
|
||||
public TestConnectionProfileService ConnectionProfileService
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"includeFiles": [
|
||||
"Scripts/CreateTestDatabaseObjects.sql",
|
||||
"Scripts/CreateTestDatabase.sql",
|
||||
"Scripts/TestDbTableQueries.sql"
|
||||
"Scripts/TestDbTableQueries.sql",
|
||||
"Scripts/AdventureWorks.sql"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
//
|
||||
// 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.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests covering basic operation of Node based classes
|
||||
/// </summary>
|
||||
public class NodeTests : ObjectExplorerTestBase
|
||||
{
|
||||
private string defaultOwnerUri = "objectexplorer://myserver";
|
||||
private ServerInfo defaultServerInfo;
|
||||
private ConnectionDetails defaultConnectionDetails;
|
||||
private ConnectionCompleteParams defaultConnParams;
|
||||
private string fakeConnectionString = "Data Source=server;Initial Catalog=database;Integrated Security=False;User Id=user";
|
||||
|
||||
public NodeTests()
|
||||
{
|
||||
defaultServerInfo = TestObjects.GetTestServerInfo();
|
||||
|
||||
defaultConnectionDetails = new ConnectionDetails()
|
||||
{
|
||||
DatabaseName = "master",
|
||||
ServerName = "localhost",
|
||||
UserName = "serverAdmin",
|
||||
Password = "..."
|
||||
};
|
||||
defaultConnParams = new ConnectionCompleteParams()
|
||||
{
|
||||
ServerInfo = defaultServerInfo,
|
||||
ConnectionSummary = defaultConnectionDetails,
|
||||
OwnerUri = defaultOwnerUri
|
||||
};
|
||||
|
||||
// TODO can all tests use the standard service provider?
|
||||
ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorValidatesFields()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => new ServerNode(null, ServiceProvider));
|
||||
Assert.Throws<ArgumentNullException>(() => new ServerNode(defaultConnParams, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorShouldSetValuesCorrectly()
|
||||
{
|
||||
// Given a server node with valid inputs
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// Then expect all fields set correctly
|
||||
Assert.False(node.IsAlwaysLeaf, "Server node should never be a leaf");
|
||||
Assert.Equal(defaultConnectionDetails.ServerName, node.NodeValue);
|
||||
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
|
||||
Assert.Equal(NodeTypes.ServerInstance.ToString(), node.NodeType);
|
||||
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(1, nodePath.Length);
|
||||
Assert.Equal(defaultConnectionDetails.ServerName, nodePath[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeLabelShouldIgnoreUserNameIfEmptyOrNull()
|
||||
{
|
||||
// Given no username set
|
||||
ConnectionSummary integratedAuthSummary = new ConnectionSummary()
|
||||
{
|
||||
DatabaseName = defaultConnectionDetails.DatabaseName,
|
||||
ServerName = defaultConnectionDetails.ServerName,
|
||||
UserName = null
|
||||
};
|
||||
ConnectionCompleteParams connParams = new ConnectionCompleteParams()
|
||||
{
|
||||
ConnectionSummary = integratedAuthSummary,
|
||||
ServerInfo = defaultServerInfo,
|
||||
OwnerUri = defaultOwnerUri
|
||||
};
|
||||
// When querying label
|
||||
string label = new ServerNode(connParams, ServiceProvider).Label;
|
||||
// Then only server name and version shown
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + ")";
|
||||
Assert.Equal(expectedLabel, label);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeConstructorShouldShowDbNameForCloud()
|
||||
{
|
||||
defaultServerInfo.IsCloud = true;
|
||||
|
||||
// Given a server node for a cloud DB, with master name
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// Then expect label to not include db name
|
||||
string expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
|
||||
// But given a server node for a cloud DB that's not master
|
||||
defaultConnectionDetails.DatabaseName = "NotMaster";
|
||||
node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
|
||||
// Then expect label to include db name
|
||||
expectedLabel = defaultConnectionDetails.ServerName + " (SQL Server " + defaultServerInfo.ServerVersion + " - "
|
||||
+ defaultConnectionDetails.UserName + ", " + defaultConnectionDetails.DatabaseName + ")";
|
||||
Assert.Equal(expectedLabel, node.Label);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToNodeInfoIncludeAllFields()
|
||||
{
|
||||
// Given a server connection
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
// When converting to NodeInfo
|
||||
NodeInfo info = node.ToNodeInfo();
|
||||
// Then all fields should match
|
||||
Assert.Equal(node.IsAlwaysLeaf, info.IsLeaf);
|
||||
Assert.Equal(node.Label, info.Label);
|
||||
Assert.Equal(node.NodeType, info.NodeType);
|
||||
string[] nodePath = node.GetNodePath().Split(TreeNode.PathPartSeperator);
|
||||
string[] nodeInfoPathParts = info.NodePath.Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(nodePath.Length, nodeInfoPathParts.Length);
|
||||
for (int i = 0; i < nodePath.Length; i++)
|
||||
{
|
||||
Assert.Equal(nodePath[i], nodeInfoPathParts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddChildShouldSetParent()
|
||||
{
|
||||
TreeNode parent = new TreeNode("parent");
|
||||
TreeNode child = new TreeNode("child");
|
||||
Assert.Null(child.Parent);
|
||||
parent.AddChild(child);
|
||||
Assert.Equal(parent, child.Parent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetChildrenShouldReturnReadonlyList()
|
||||
{
|
||||
TreeNode node = new TreeNode("parent");
|
||||
IList<TreeNode> children = node.GetChildren();
|
||||
Assert.Throws<NotSupportedException>(() => children.Add(new TreeNode("child")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetChildrenShouldReturnAddedNodesInOrder()
|
||||
{
|
||||
TreeNode parent = new TreeNode("parent");
|
||||
TreeNode[] expectedKids = new TreeNode[] { new TreeNode("1"), new TreeNode("2") };
|
||||
foreach (TreeNode child in expectedKids)
|
||||
{
|
||||
parent.AddChild(child);
|
||||
}
|
||||
IList<TreeNode> children = parent.GetChildren();
|
||||
Assert.Equal(expectedKids.Length, children.Count);
|
||||
for (int i = 0; i < expectedKids.Length; i++)
|
||||
{
|
||||
Assert.Equal(expectedKids[i], children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void MultiLevelTreeShouldFormatPath()
|
||||
{
|
||||
TreeNode root = new TreeNode("root");
|
||||
Assert.Equal("/root" , root.GetNodePath());
|
||||
|
||||
TreeNode level1Child1 = new TreeNode("L1C1");
|
||||
TreeNode level1Child2 = new TreeNode("L1C2");
|
||||
root.AddChild(level1Child1);
|
||||
root.AddChild(level1Child2);
|
||||
Assert.Equal("/root/L1C1" , level1Child1.GetNodePath());
|
||||
Assert.Equal("/root/L1C2", level1Child2.GetNodePath());
|
||||
|
||||
TreeNode level2Child1 = new TreeNode("L2C2");
|
||||
level1Child1.AddChild(level2Child1);
|
||||
Assert.Equal("/root/L1C1/L2C2", level2Child1.GetNodePath());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldIncludeServer()
|
||||
{
|
||||
// given a successful Server creation
|
||||
SetupAndRegisterTestConnectionService();
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to contain the server I created
|
||||
Assert.NotNull(context);
|
||||
Assert.Equal(smoServer, context.Server);
|
||||
// And the server should be the parent
|
||||
Assert.Equal(smoServer, context.Parent);
|
||||
Assert.Null(context.Database);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfSqlConnectionIsNull()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
ConnectionService connService = SetupAndRegisterTestConnectionService();
|
||||
connService.OwnerToConnectionMap.Remove(defaultOwnerUri);
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.ServerNodeConnectionError, defaultConnectionDetails.ServerName),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfConnFailureExceptionThrown()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
SetupAndRegisterTestConnectionService();
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
string expectedMsg = "ConnFailed!";
|
||||
ServerNode node = SetupServerNodeWithExceptionCreator(new ConnectionFailureException(expectedMsg));
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeContextShouldSetErrorMessageIfExceptionThrown()
|
||||
{
|
||||
// given a connectionInfo with no SqlConnection to use for queries
|
||||
SetupAndRegisterTestConnectionService();
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
string expectedMsg = "Failed!";
|
||||
ServerNode node = SetupServerNodeWithExceptionCreator(new Exception(expectedMsg));
|
||||
|
||||
// When I get the context for a ServerNode
|
||||
var context = node.GetContextAs<SmoQueryContext>();
|
||||
|
||||
// Then I expect it to be in an error state
|
||||
Assert.Null(context);
|
||||
Assert.Equal(
|
||||
string.Format(CultureInfo.CurrentCulture, SR.TreeNodeError, expectedMsg),
|
||||
node.ErrorStateMessage);
|
||||
}
|
||||
|
||||
private ConnectionService SetupAndRegisterTestConnectionService()
|
||||
{
|
||||
ConnectionService connService = TestObjects.GetTestConnectionService();
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(TestObjects.GetTestSqlConnectionFactory(),
|
||||
defaultOwnerUri, defaultConnectionDetails);
|
||||
connectionInfo.AddConnection("Default", new SqlConnection());
|
||||
|
||||
connService.OwnerToConnectionMap.Add(defaultOwnerUri, connectionInfo);
|
||||
ServiceProvider.RegisterSingleService(connService);
|
||||
return connService;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithServer(Server smoServer)
|
||||
{
|
||||
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
|
||||
creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
|
||||
.Returns(() => smoServer);
|
||||
ServerNode node = SetupServerNodeWithCreator(creator.Object);
|
||||
return node;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithExceptionCreator(Exception ex)
|
||||
{
|
||||
Mock<SmoServerCreator> creator = new Mock<SmoServerCreator>();
|
||||
creator.Setup(c => c.Create(It.IsAny<SqlConnection>()))
|
||||
.Throws(ex);
|
||||
|
||||
ServerNode node = SetupServerNodeWithCreator(creator.Object);
|
||||
return node;
|
||||
}
|
||||
|
||||
private ServerNode SetupServerNodeWithCreator(SmoServerCreator creator)
|
||||
{
|
||||
ServerNode node = new ServerNode(defaultConnParams, ServiceProvider);
|
||||
node.ServerCreator = creator;
|
||||
return node;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServerNodeChildrenShouldIncludeFoldersAndDatabases()
|
||||
{
|
||||
// Given a server with 1 database
|
||||
SetupAndRegisterTestConnectionService();
|
||||
ServiceProvider.RegisterSingleService(new ObjectExplorerService());
|
||||
|
||||
string dbName = "DB1";
|
||||
Mock<NamedSmoObject> smoObjectMock = new Mock<NamedSmoObject>();
|
||||
smoObjectMock.SetupGet(s => s.Name).Returns(dbName);
|
||||
|
||||
Mock<SqlDatabaseQuerier> querierMock = new Mock<SqlDatabaseQuerier>();
|
||||
querierMock.Setup(q => q.Query(It.IsAny<SmoQueryContext>()))
|
||||
.Returns(smoObjectMock.Object.SingleItemAsEnumerable());
|
||||
|
||||
ServiceProvider.Register<SmoQuerier>(() => new[] { querierMock.Object });
|
||||
|
||||
Server smoServer = new Server(new ServerConnection(new SqlConnection(fakeConnectionString)));
|
||||
ServerNode node = SetupServerNodeWithServer(smoServer);
|
||||
|
||||
// When I populate its children
|
||||
IList<TreeNode> children = node.Expand();
|
||||
|
||||
// Then I expect it to contain server-level folders
|
||||
Assert.Equal(3, children.Count);
|
||||
VerifyTreeNode<FolderNode>(children[0], "Folder", SR.SchemaHierarchy_Databases);
|
||||
VerifyTreeNode<FolderNode>(children[1], "Folder", SR.SchemaHierarchy_Security);
|
||||
VerifyTreeNode<FolderNode>(children[2], "Folder", SR.SchemaHierarchy_ServerObjects);
|
||||
// And the database is contained under it
|
||||
TreeNode databases = children[0];
|
||||
IList<TreeNode> dbChildren = databases.Expand();
|
||||
Assert.Equal(2, dbChildren.Count);
|
||||
Assert.Equal("System Databases", dbChildren[0].NodeValue);
|
||||
|
||||
TreeNode dbNode = dbChildren[1];
|
||||
Assert.Equal(dbName, dbNode.NodeValue);
|
||||
Assert.Equal(dbName, dbNode.Label);
|
||||
Assert.False(dbNode.IsAlwaysLeaf);
|
||||
|
||||
// Note: would like to verify Database in the context, but cannot since it's a Sealed class and isn't easily mockable
|
||||
}
|
||||
|
||||
private void VerifyTreeNode<T>(TreeNode node, string nodeType, string folderValue)
|
||||
where T : TreeNode
|
||||
{
|
||||
T nodeAsT = node as T;
|
||||
Assert.NotNull(nodeAsT);
|
||||
Assert.Equal(nodeType, nodeAsT.NodeType);
|
||||
Assert.Equal(folderValue, nodeAsT.NodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// 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.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
|
||||
public class ObjectExplorerServiceTests : ObjectExplorerTestBase
|
||||
{
|
||||
private ObjectExplorerService service;
|
||||
private Mock<ConnectionService> connectionServiceMock;
|
||||
private Mock<IProtocolEndpoint> serviceHostMock;
|
||||
public ObjectExplorerServiceTests()
|
||||
{
|
||||
connectionServiceMock = new Mock<ConnectionService>();
|
||||
serviceHostMock = new Mock<IProtocolEndpoint>();
|
||||
service = CreateOEService(connectionServiceMock.Object);
|
||||
service.InitializeService(serviceHostMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestErrorsIfConnectionDetailsIsNull()
|
||||
{
|
||||
object errorResponse = null;
|
||||
var contextMock = RequestContextMocks.Create<CreateSessionResponse>(null)
|
||||
.AddErrorHandling((errorMessage, errorCode, obj) => errorResponse = errorMessage);
|
||||
|
||||
await service.HandleCreateSessionRequest(null, contextMock.Object);
|
||||
VerifyErrorSent(contextMock);
|
||||
Assert.True(((string)errorResponse).Contains("ArgumentNullException"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestReturnsFalseOnConnectionFailure()
|
||||
{
|
||||
// Given the connection service fails to connect
|
||||
ConnectionDetails details = TestObjects.GetTestConnectionDetails();
|
||||
ConnectionCompleteParams completeParams = null;
|
||||
serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, (et, p) => completeParams = p);
|
||||
|
||||
string expectedExceptionText = "Error!!!";
|
||||
connectionServiceMock.Setup(c => c.Connect(It.IsAny<ConnectParams>()))
|
||||
.Throws(new Exception(expectedExceptionText));
|
||||
|
||||
// when creating a new session
|
||||
// then expect the create session request to return false
|
||||
await RunAndVerify<CreateSessionResponse>(
|
||||
test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext),
|
||||
verify: (actual =>
|
||||
{
|
||||
Assert.False(actual.Success);
|
||||
Assert.Null(actual.SessionId);
|
||||
Assert.Null(actual.RootNode);
|
||||
}));
|
||||
|
||||
// And expect error notification to be sent
|
||||
serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type, It.IsAny<ConnectionCompleteParams>()), Times.Once());
|
||||
Assert.NotNull(completeParams);
|
||||
Assert.True(completeParams.Messages.Contains(expectedExceptionText));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task CreateSessionRequestReturnsSuccessAndNodeInfo()
|
||||
{
|
||||
// Given the connection service fails to connect
|
||||
ConnectionDetails details = TestObjects.GetTestConnectionDetails();
|
||||
serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, null);
|
||||
|
||||
connectionServiceMock.Setup(c => c.Connect(It.IsAny<ConnectParams>()))
|
||||
.Returns((ConnectParams connectParams) => Task.FromResult(GetCompleteParamsForConnection(connectParams.OwnerUri, details)));
|
||||
|
||||
// when creating a new session
|
||||
// then expect the create session request to return false
|
||||
await RunAndVerify<CreateSessionResponse>(
|
||||
test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext),
|
||||
verify: (actual =>
|
||||
{
|
||||
Assert.True(actual.Success);
|
||||
Assert.NotNull(actual.SessionId);
|
||||
VerifyServerNode(actual.RootNode, details);
|
||||
}));
|
||||
|
||||
// And expect no error notification to be sent
|
||||
serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type,
|
||||
It.IsAny<ConnectionCompleteParams>()), Times.Never());
|
||||
}
|
||||
|
||||
private void VerifyServerNode(NodeInfo serverNode, ConnectionDetails details)
|
||||
{
|
||||
Assert.NotNull(serverNode);
|
||||
Assert.Equal(NodeTypes.ServerInstance.ToString(), serverNode.NodeType);
|
||||
string[] pathParts = serverNode.NodePath.Split(TreeNode.PathPartSeperator);
|
||||
Assert.Equal(1, pathParts.Length);
|
||||
Assert.Equal(details.ServerName, pathParts[0]);
|
||||
Assert.True(serverNode.Label.Contains(details.ServerName));
|
||||
Assert.False(serverNode.IsLeaf);
|
||||
}
|
||||
|
||||
private static ConnectionCompleteParams GetCompleteParamsForConnection(string uri, ConnectionDetails details)
|
||||
{
|
||||
return new ConnectionCompleteParams()
|
||||
{
|
||||
OwnerUri = uri,
|
||||
ConnectionSummary = new ConnectionSummary()
|
||||
{
|
||||
ServerName = details.ServerName,
|
||||
DatabaseName = details.DatabaseName,
|
||||
UserName = details.UserName
|
||||
},
|
||||
ServerInfo = TestObjects.GetTestServerInfo()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task RunAndVerify<T>(Func<RequestContext<T>, Task> test, Action<T> verify)
|
||||
{
|
||||
T result = default(T);
|
||||
var contextMock = RequestContextMocks.Create<T>(r => result = r).AddErrorHandling(null);
|
||||
await test(contextMock.Object);
|
||||
VerifyResult(contextMock, verify, result);
|
||||
}
|
||||
|
||||
private void VerifyResult<T>(Mock<RequestContext<T>> contextMock, Action<T> verify, T actual)
|
||||
{
|
||||
contextMock.Verify(c => c.SendResult(It.IsAny<T>()), Times.Once);
|
||||
contextMock.Verify(c => c.SendError(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<object>()), Times.Never);
|
||||
verify(actual);
|
||||
}
|
||||
|
||||
private void VerifyErrorSent<T>(Mock<RequestContext<T>> contextMock)
|
||||
{
|
||||
contextMock.Verify(c => c.SendResult(It.IsAny<T>()), Times.Never);
|
||||
contextMock.Verify(c => c.SendError(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<object>()), Times.Once);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// 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.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
// Base class providing common test functionality for OE tests
|
||||
public abstract class ObjectExplorerTestBase
|
||||
{
|
||||
protected RegisteredServiceProvider ServiceProvider
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
protected RegisteredServiceProvider CreateServiceProviderWithMinServices()
|
||||
{
|
||||
return CreateProvider()
|
||||
.RegisterSingleService(new ConnectionService())
|
||||
.RegisterSingleService(new ObjectExplorerService());
|
||||
}
|
||||
|
||||
protected RegisteredServiceProvider CreateProvider()
|
||||
{
|
||||
ServiceProvider = new RegisteredServiceProvider();
|
||||
return ServiceProvider;
|
||||
}
|
||||
|
||||
protected ObjectExplorerService CreateOEService(ConnectionService connService)
|
||||
{
|
||||
CreateProvider()
|
||||
.RegisterSingleService(connService)
|
||||
.RegisterSingleService(new ObjectExplorerService());
|
||||
|
||||
// Create the service using the service provider, which will initialize dependencies
|
||||
return ServiceProvider.GetService<ObjectExplorerService>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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.Linq;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||
{
|
||||
public class SmoQueryModelTests
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void ShouldFindDatabaseQuerierFromRealPath()
|
||||
{
|
||||
// Given the extension type loader is set to find SmoCollectionQuerier objects
|
||||
IMultiServiceProvider serviceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
|
||||
// When I request a database compatible querier
|
||||
SmoQuerier querier = serviceProvider.GetService<SmoQuerier>(q => q.SupportedObjectTypes.Contains(typeof(Database)));
|
||||
// Then I expect to get back the SqlDatabaseQuerier
|
||||
Assert.NotNull(querier);
|
||||
Assert.Equal(typeof(SqlDatabaseQuerier), querier.GetType());
|
||||
|
||||
// And I expect the service provider to have been set by the extension code
|
||||
Assert.NotNull(querier.ServiceProvider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldFindQuerierIfInExtensionList()
|
||||
{
|
||||
VerifyQuerierLookup(typeof(Table), typeof(SqlTableQuerier), expectExists: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldNotFindQuerierIfNotInExtensionList()
|
||||
{
|
||||
VerifyQuerierLookup(typeof(Database), null, expectExists: false);
|
||||
}
|
||||
|
||||
private static void VerifyQuerierLookup(Type smoType, Type querierType, bool expectExists)
|
||||
{
|
||||
ExtensionServiceProvider serviceProvider = ExtensionServiceProvider.Create(new Type[] {
|
||||
typeof(SqlTableQuerier),
|
||||
typeof(SqlLinkedServerQuerier)
|
||||
});
|
||||
SmoQuerier querier = serviceProvider.GetService<SmoQuerier>(q => q.SupportedObjectTypes.Contains(smoType));
|
||||
if (expectExists)
|
||||
{
|
||||
Assert.NotNull(querier);
|
||||
Assert.Equal(querierType, querier.GetType());
|
||||
Assert.NotNull(querier.ServiceProvider);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(querier);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,169 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ServiceHost
|
||||
var queryServiceErrorFormat = SR.QueryServiceErrorFormat(1, 1, 1, 1, "\n", "..");
|
||||
var queryServiceQueryFailed = SR.QueryServiceQueryFailed("..");
|
||||
var workspaceServiceBufferPositionOutOfOrder = SR.WorkspaceServiceBufferPositionOutOfOrder(1, 2, 3, 4);
|
||||
var treeNodeError = SR.TreeNodeError;
|
||||
var serverNodeConnectionError = SR.ServerNodeConnectionError;
|
||||
var schemaHierarchyAggregates = SR.SchemaHierarchy_Aggregates;
|
||||
var SchemaHierarchy_ServerRoles = SR.SchemaHierarchy_ServerRoles;
|
||||
var SchemaHierarchy_ApplicationRoles = SR.SchemaHierarchy_ApplicationRoles;
|
||||
var SchemaHierarchy_Assemblies = SR.SchemaHierarchy_Assemblies;
|
||||
var SchemaHierarchy_AssemblyFiles = SR.SchemaHierarchy_AssemblyFiles;
|
||||
var SchemaHierarchy_AsymmetricKeys = SR.SchemaHierarchy_AsymmetricKeys;
|
||||
var SchemaHierarchy_DatabaseAsymmetricKeys = SR.SchemaHierarchy_DatabaseAsymmetricKeys;
|
||||
var SchemaHierarchy_DataCompressionOptions = SR.SchemaHierarchy_DataCompressionOptions;
|
||||
var SchemaHierarchy_Certificates = SR.SchemaHierarchy_Certificates;
|
||||
var SchemaHierarchy_FileTables = SR.SchemaHierarchy_FileTables;
|
||||
var SchemaHierarchy_DatabaseCertificates = SR.SchemaHierarchy_DatabaseCertificates;
|
||||
var SchemaHierarchy_CheckConstraints = SR.SchemaHierarchy_CheckConstraints;
|
||||
var SchemaHierarchy_Columns = SR.SchemaHierarchy_Columns;
|
||||
var SchemaHierarchy_Constraints = SR.SchemaHierarchy_Constraints;
|
||||
var SchemaHierarchy_Contracts = SR.SchemaHierarchy_Contracts;
|
||||
var SchemaHierarchy_Credentials = SR.SchemaHierarchy_Credentials;
|
||||
var SchemaHierarchy_ErrorMessages = SR.SchemaHierarchy_ErrorMessages;
|
||||
var SchemaHierarchy_ServerRoleMembership = SR.SchemaHierarchy_ServerRoleMembership;
|
||||
var SchemaHierarchy_DatabaseOptions = SR.SchemaHierarchy_DatabaseOptions;
|
||||
var SchemaHierarchy_DatabaseRoles = SR.SchemaHierarchy_DatabaseRoles;
|
||||
var SchemaHierarchy_RoleMemberships = SR.SchemaHierarchy_RoleMemberships;
|
||||
var SchemaHierarchy_DatabaseTriggers = SR.SchemaHierarchy_DatabaseTriggers;
|
||||
var SchemaHierarchy_DefaultConstraints = SR.SchemaHierarchy_DefaultConstraints;
|
||||
var SchemaHierarchy_Defaults = SR.SchemaHierarchy_Defaults;
|
||||
var SchemaHierarchy_Sequences = SR.SchemaHierarchy_Sequences;
|
||||
var SchemaHierarchy_Endpoints = SR.SchemaHierarchy_Endpoints;
|
||||
var SchemaHierarchy_EventNotifications = SR.SchemaHierarchy_EventNotifications;
|
||||
var SchemaHierarchy_ServerEventNotifications = SR.SchemaHierarchy_ServerEventNotifications;
|
||||
var SchemaHierarchy_ExtendedProperties = SR.SchemaHierarchy_ExtendedProperties;
|
||||
var SchemaHierarchy_FileGroups = SR.SchemaHierarchy_FileGroups;
|
||||
var SchemaHierarchy_ForeignKeys = SR.SchemaHierarchy_ForeignKeys;
|
||||
var SchemaHierarchy_FullTextCatalogs = SR.SchemaHierarchy_FullTextCatalogs;
|
||||
var SchemaHierarchy_FullTextIndexes = SR.SchemaHierarchy_FullTextIndexes;
|
||||
var SchemaHierarchy_Functions = SR.SchemaHierarchy_Functions;
|
||||
var SchemaHierarchy_Indexes = SR.SchemaHierarchy_Indexes;
|
||||
var SchemaHierarchy_InlineFunctions = SR.SchemaHierarchy_InlineFunctions;
|
||||
var SchemaHierarchy_Keys = SR.SchemaHierarchy_Keys;
|
||||
var SchemaHierarchy_LinkedServers = SR.SchemaHierarchy_LinkedServers;
|
||||
var SchemaHierarchy_LinkedServerLogins = SR.SchemaHierarchy_LinkedServerLogins;
|
||||
var SchemaHierarchy_Logins = SR.SchemaHierarchy_Logins;
|
||||
var SchemaHierarchy_MasterKey = SR.SchemaHierarchy_MasterKey;
|
||||
var SchemaHierarchy_MasterKeys = SR.SchemaHierarchy_MasterKeys;
|
||||
var SchemaHierarchy_MessageTypes = SR.SchemaHierarchy_MessageTypes;
|
||||
var SchemaHierarchy_MultiSelectFunctions = SR.SchemaHierarchy_MultiSelectFunctions;
|
||||
var SchemaHierarchy_Parameters = SR.SchemaHierarchy_Parameters;
|
||||
var SchemaHierarchy_PartitionFunctions = SR.SchemaHierarchy_PartitionFunctions;
|
||||
var SchemaHierarchy_PartitionSchemes = SR.SchemaHierarchy_PartitionSchemes;
|
||||
var SchemaHierarchy_Permissions = SR.SchemaHierarchy_Permissions;
|
||||
var SchemaHierarchy_PrimaryKeys = SR.SchemaHierarchy_PrimaryKeys;
|
||||
var schemaHierarchyPrimaryKeys = SR.SchemaHierarchy_PrimaryKeys;
|
||||
var schemaHierarchyProgrammability = SR.SchemaHierarchy_Programmability;
|
||||
var schemaHierarchyQueues = SR.SchemaHierarchy_Queues;
|
||||
var schemaHierarchyRemoteServiceBindings = SR.SchemaHierarchy_RemoteServiceBindings;
|
||||
var schemaHierarchyReturnedColumns = SR.SchemaHierarchy_ReturnedColumns;
|
||||
var schemaHierarchyRoles = SR.SchemaHierarchy_Roles;
|
||||
var schemaHierarchyRoutes = SR.SchemaHierarchy_Routes;
|
||||
var schemaHierarchyRules = SR.SchemaHierarchy_Rules;
|
||||
var schemaHierarchySchemas = SR.SchemaHierarchy_Schemas;
|
||||
var schemaHierarchySecurity = SR.SchemaHierarchy_Security;
|
||||
var schemaHierarchyServerObjects = SR.SchemaHierarchy_ServerObjects;
|
||||
var schemaHierarchyManagement = SR.SchemaHierarchy_Management;
|
||||
var schemaHierarchyServerTriggers = SR.SchemaHierarchy_ServerTriggers;
|
||||
var schemaHierarchyServiceBroker = SR.SchemaHierarchy_ServiceBroker;
|
||||
var schemaHierarchyServices = SR.SchemaHierarchy_Services;
|
||||
var schemaHierarchySignatures = SR.SchemaHierarchy_LogFiles;
|
||||
var schemaHierarchyStatistics = SR.SchemaHierarchy_Statistics;
|
||||
var schemaHierarchyStorage = SR.SchemaHierarchy_Storage;
|
||||
var schemaHierarchyStoredProcedures = SR.SchemaHierarchy_StoredProcedures;
|
||||
var schemaHierarchySymmetricKeys = SR.SchemaHierarchy_SymmetricKeys;
|
||||
var schemaHierarchySynonyms = SR.SchemaHierarchy_Synonyms;
|
||||
var schemaHierarchyTables = SR.SchemaHierarchy_Tables;
|
||||
var schemaHierarchyTriggers = SR.SchemaHierarchy_Triggers;
|
||||
var schemaHierarchyTypes = SR.SchemaHierarchy_Types;
|
||||
var schemaHierarchyUniqueKeys = SR.SchemaHierarchy_UniqueKeys;
|
||||
var schemaHierarchyUserDefinedDataTypes = SR.SchemaHierarchy_UserDefinedDataTypes;
|
||||
var schemaHierarchyUserDefinedTypes = SR.SchemaHierarchy_UserDefinedTypes;
|
||||
var schemaHierarchyUsers = SR.SchemaHierarchy_Users;
|
||||
var schemaHierarchyViews = SR.SchemaHierarchy_Views;
|
||||
var schemaHierarchyXmlIndexes = SR.SchemaHierarchy_XmlIndexes;
|
||||
var schemaHierarchyXMLSchemaCollections = SR.SchemaHierarchy_XMLSchemaCollections;
|
||||
var schemaHierarchyUserDefinedTableTypes = SR.SchemaHierarchy_UserDefinedTableTypes;
|
||||
var schemaHierarchyFilegroupFiles = SR.SchemaHierarchy_FilegroupFiles;
|
||||
var missingCaption = SR.MissingCaption;
|
||||
var schemaHierarchyBrokerPriorities = SR.SchemaHierarchy_BrokerPriorities;
|
||||
var schemaHierarchyCryptographicProviders = SR.SchemaHierarchy_CryptographicProviders;
|
||||
var schemaHierarchyDatabaseAuditSpecifications = SR.SchemaHierarchy_DatabaseAuditSpecifications;
|
||||
var schemaHierarchyDatabaseEncryptionKeys = SR.SchemaHierarchy_DatabaseEncryptionKeys;
|
||||
var schemaHierarchyEventSessions = SR.SchemaHierarchy_EventSessions;
|
||||
var schemaHierarchyFullTextStopLists = SR.SchemaHierarchy_FullTextStopLists;
|
||||
var schemaHierarchyResourcePools = SR.SchemaHierarchy_ResourcePools;
|
||||
var schemaHierarchyServerAudits = SR.SchemaHierarchy_ServerAudits;
|
||||
var schemaHierarchyServerAuditSpecifications = SR.SchemaHierarchy_ServerAuditSpecifications;
|
||||
var schemaHierarchySpatialIndexes = SR.SchemaHierarchy_SpatialIndexes;
|
||||
var schemaHierarchyWorkloadGroups = SR.SchemaHierarchy_WorkloadGroups;
|
||||
var schemaHierarchySqlFiles = SR.SchemaHierarchy_SqlFiles;
|
||||
var schemaHierarchyServerFunctions = SR.SchemaHierarchy_ServerFunctions;
|
||||
var schemaHierarchySqlType = SR.SchemaHierarchy_SqlType;
|
||||
var schemaHierarchyServerOptions = SR.SchemaHierarchy_ServerOptions;
|
||||
var schemaHierarchyDatabaseDiagrams = SR.SchemaHierarchy_DatabaseDiagrams;
|
||||
var schemaHierarchySystemTables = SR.SchemaHierarchy_SystemTables;
|
||||
var schemaHierarchyDatabases = SR.SchemaHierarchy_Databases;
|
||||
var schemaHierarchySystemContracts = SR.SchemaHierarchy_SystemContracts;
|
||||
var schemaHierarchySystemDatabases = SR.SchemaHierarchy_SystemDatabases;
|
||||
var schemaHierarchySystemMessageTypes = SR.SchemaHierarchy_SystemMessageTypes;
|
||||
var schemaHierarchySystemQueues = SR.SchemaHierarchy_SystemQueues;
|
||||
var schemaHierarchySystemServices = SR.SchemaHierarchy_SystemServices;
|
||||
var schemaHierarchySystemStoredProcedures = SR.SchemaHierarchy_SystemStoredProcedures;
|
||||
var schemaHierarchySystemViews = SR.SchemaHierarchy_SystemViews;
|
||||
var schemaHierarchyDataTierApplications = SR.SchemaHierarchy_DataTierApplications;
|
||||
var schemaHierarchyExtendedStoredProcedures = SR.SchemaHierarchy_ExtendedStoredProcedures;
|
||||
var schemaHierarchySystemAggregateFunctions = SR.SchemaHierarchy_SystemAggregateFunctions;
|
||||
var schemaHierarchySystemApproximateNumerics = SR.SchemaHierarchy_SystemApproximateNumerics;
|
||||
var schemaHierarchySystemBinaryStrings = SR.SchemaHierarchy_SystemBinaryStrings;
|
||||
var schemaHierarchySystemCharacterStrings = SR.SchemaHierarchy_SystemCharacterStrings;
|
||||
var schemaHierarchySystemCLRDataTypes = SR.SchemaHierarchy_SystemCLRDataTypes;
|
||||
var schemaHierarchySystemConfigurationFunctions = SR.SchemaHierarchy_SystemConfigurationFunctions;
|
||||
var schemaHierarchySystemCursorFunctions = SR.SchemaHierarchy_SystemCursorFunctions;
|
||||
var schemaHierarchySystemDataTypes = SR.SchemaHierarchy_SystemDataTypes;
|
||||
var schemaHierarchySystemDateAndTime = SR.SchemaHierarchy_SystemDateAndTime;
|
||||
var schemaHierarchySystemDateAndTimeFunctions = SR.SchemaHierarchy_SystemDateAndTimeFunctions;
|
||||
var schemaHierarchySystemExactNumerics = SR.SchemaHierarchy_SystemExactNumerics;
|
||||
var schemaHierarchySystemFunctions = SR.SchemaHierarchy_SystemFunctions;
|
||||
var schemaHierarchySystemHierarchyIdFunctions = SR.SchemaHierarchy_SystemHierarchyIdFunctions;
|
||||
var schemaHierarchySystemMathematicalFunctions = SR.SchemaHierarchy_SystemMathematicalFunctions;
|
||||
var schemaHierarchySystemMetadataFunctionions = SR.SchemaHierarchy_SystemMetadataFunctions;
|
||||
var schemaHierarchySystemOtherDataTypes = SR.SchemaHierarchy_SystemOtherDataTypes;
|
||||
var schemaHierarchySystemOtherFunctions = SR.SchemaHierarchy_SystemOtherFunctions;
|
||||
var schemaHierarchySystemRowsetFunctions = SR.SchemaHierarchy_SystemRowsetFunctions;
|
||||
var schemaHierarchySystemSecurityFunctions = SR.SchemaHierarchy_SystemSecurityFunctions;
|
||||
var schemaHierarchySystemSpatialDataTypes = SR.SchemaHierarchy_SystemSpatialDataTypes;
|
||||
var schemaHierarchySystemStringFunctions = SR.SchemaHierarchy_SystemStringFunctions;
|
||||
var schemaHierarchySystemSystemStatisticalFunctions = SR.SchemaHierarchy_SystemSystemStatisticalFunctions;
|
||||
var schemaHierarchySystemTextAndImageFunctions = SR.SchemaHierarchy_SystemTextAndImageFunctions;
|
||||
var schemaHierarchySystemUnicodeCharacterStrings = SR.SchemaHierarchy_SystemUnicodeCharacterStrings;
|
||||
var schemaHierarchyAggregateFunctions = SR.SchemaHierarchy_AggregateFunctions;
|
||||
var schemaHierarchyScalarValuedFunctions = SR.SchemaHierarchy_ScalarValuedFunctions;
|
||||
var schemaHierarchyTableValuedFunctions = SR.SchemaHierarchy_TableValuedFunctions;
|
||||
var schemaHierarchySystemExtendedStoredProcedures = SR.SchemaHierarchy_SystemExtendedStoredProcedures;
|
||||
var schemaHierarchyBuiltInType = SR.SchemaHierarchy_BuiltInType;
|
||||
var schemaHierarchyBuiltInServerRole = SR.SchemaHierarchy_BuiltInServerRole;
|
||||
var schemaHierarchyUserWithPassword = SR.SchemaHierarchy_UserWithPassword;
|
||||
var schemaHierarchySearchPropertyList = SR.SchemaHierarchy_SearchPropertyList;
|
||||
var schemaHierarchySecurityPolicies = SR.SchemaHierarchy_SecurityPolicies;
|
||||
var schemaHierarchySecurityPredicates = SR.SchemaHierarchy_SecurityPredicates;
|
||||
var schemaHierarchyServerRole = SR.SchemaHierarchy_ServerRole;
|
||||
var schemaHierarchySearchPropertyLists = SR.SchemaHierarchy_SearchPropertyLists;
|
||||
var schemaHierarchyColumnStoreIndexes = SR.SchemaHierarchy_ColumnStoreIndexes;
|
||||
var schemaHierarchyTableTypeIndexes = SR.SchemaHierarchy_TableTypeIndexes;
|
||||
var schemaHierarchyServerInstance = SR.SchemaHierarchy_ServerInstance;
|
||||
var schemaHierarchySelectiveXmlIndexes = SR.SchemaHierarchy_SelectiveXmlIndexes;
|
||||
var schemaHierarchyXmlNamespaces = SR.SchemaHierarchy_XmlNamespaces;
|
||||
var schemaHierarchyXmlTypedPromotedPaths = SR.SchemaHierarchy_XmlTypedPromotedPaths;
|
||||
var schemaHierarchySqlTypedPromotedPaths = SR.SchemaHierarchy_SqlTypedPromotedPaths;
|
||||
var schemaHierarchyDatabaseScopedCredentials = SR.SchemaHierarchy_DatabaseScopedCredentials;
|
||||
var schemaHierarchyExternalDataSources = SR.SchemaHierarchy_ExternalDataSources;
|
||||
var schemaHierarchyExternalFileFormats = SR.SchemaHierarchy_ExternalFileFormats;
|
||||
var schemaHierarchyExternalResources = SR.SchemaHierarchy_ExternalResources;
|
||||
var schemaHierarchyExternalTables = SR.SchemaHierarchy_ExternalTables;
|
||||
var schemaHierarchyAlwaysEncryptedKeys = SR.SchemaHierarchy_AlwaysEncryptedKeys;
|
||||
var schemaHierarchyColumnMasterKeys = SR.SchemaHierarchy_ColumnMasterKeys;
|
||||
var schemaHierarchyColumnEncryptionKeys = SR.SchemaHierarchy_ColumnEncryptionKeys;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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.Hosting.Protocol.Contracts;
|
||||
using Moq;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
||||
{
|
||||
public static class ProtocolEndpointMocks
|
||||
{
|
||||
public static Mock<IProtocolEndpoint> AddEventHandling<TParams>(
|
||||
this Mock<IProtocolEndpoint> mock,
|
||||
EventType<TParams> expectedEvent,
|
||||
Action<EventType<TParams>, TParams> eventCallback)
|
||||
{
|
||||
var flow = mock.Setup(h => h.SendEvent(
|
||||
It.Is<EventType<TParams>>(m => m == expectedEvent),
|
||||
It.IsAny<TParams>()))
|
||||
.Returns(Task.FromResult(0));
|
||||
if (eventCallback != null)
|
||||
{
|
||||
flow.Callback(eventCallback);
|
||||
}
|
||||
|
||||
return mock;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,30 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
||||
};
|
||||
}
|
||||
|
||||
public static ServerInfo GetTestServerInfo()
|
||||
{
|
||||
return new ServerInfo()
|
||||
{
|
||||
ServerVersion = "14.0.1.0",
|
||||
ServerMajorVersion = 14,
|
||||
ServerMinorVersion = 0,
|
||||
EngineEditionId = 3,
|
||||
OsVersion = "Linux (Ubuntu 15.10)",
|
||||
IsCloud = false,
|
||||
ServerEdition = "Developer Edition",
|
||||
ServerLevel = ""
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test sql connection factory instance
|
||||
/// </summary>
|
||||
public static ISqlConnectionFactory GetTestSqlConnectionFactory()
|
||||
{
|
||||
// use mock database connection
|
||||
return new TestSqlConnectionFactory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test connection details object
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user