Object Explorer Service (#311)

* moving OE service from an old branch
This commit is contained in:
Leila Lali
2017-04-11 15:50:20 -07:00
committed by GitHub
parent 90861b7d9e
commit d903ba56a9
58 changed files with 15013 additions and 1057 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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; }
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
{
}
}

View File

@@ -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
}
}

View File

@@ -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>());
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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;
}
#>

View File

@@ -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>

View File

@@ -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);
}
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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;
}
#>

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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";
}
}