From 16b3874f285809bb8761502f6b0f9313f941b517 Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Wed, 22 Mar 2017 10:53:24 -0700 Subject: [PATCH] Remove SELECT * from edit/initialize Query (#288) * Major refactor of EditDataMetadata providers * EditMetadataFactory generates "basic" EditTableMetadata objects based entirely on SMO metadata * SmoEditTableMetadata no longer depends on SMO, making it unecessary to mock it * Renamed SmoEditTableMetadata to EditTableMetadata * EditTableMetadata can be extended with DbColumnWrappers * Moving logic for extending a EditColumnMetadata into that class * I *think* this will work for async execution of initialize tasks * Fixing unit tests for new Edit(Table|Column)Metadata classes * Async stuff that works! And passes unit tests * Adding unit tests Adding .idea to gitignore * Adding message to the EditSessionReadyEvent * Fixes from dev merge * Fixing unit tests that Rider didn't catch as failing May have been a bit heavy-handed with the async/await stuff * Couple changes as per PR comments --- .gitignore | 8 +- .../Contracts/EditSessionReadyEvent.cs | 6 + .../EditData/EditColumnMetadata.cs | 113 +++ .../EditData/EditColumnWrapper.cs | 53 - .../EditData/EditDataService.cs | 148 ++- .../EditData/EditSession.cs | 165 ++- .../EditData/EditTableMetadata.cs | 85 ++ .../EditData/IEditMetadataFactory.cs | 4 +- .../EditData/IEditTableMetadata.cs | 36 - .../EditData/SmoEditMetadataFactory.cs | 50 +- .../EditData/SmoEditTableMetadata.cs | 109 -- .../EditData/UpdateManagement/RowCreate.cs | 2 +- .../EditData/UpdateManagement/RowDelete.cs | 2 +- .../EditData/UpdateManagement/RowEdit.cs | 6 +- .../EditData/UpdateManagement/RowUpdate.cs | 2 +- .../Localization/sr.cs | 958 ++++++++++-------- .../Localization/sr.es.resx | 502 +++++++-- .../Localization/sr.resx | 244 +++-- .../Localization/sr.strings | 12 + .../Localization/sr.xlf | 30 + .../Scripting/Scripter.cs | 18 +- .../EditData/Common.cs | 83 +- .../EditData/RowCreateTests.cs | 78 +- .../EditData/RowDeleteTests.cs | 44 +- .../EditData/RowEditBaseTests.cs | 92 +- .../EditData/RowUpdateTests.cs | 69 +- .../EditData/ServiceIntegrationTests.cs | 124 +-- .../EditData/SessionTests.cs | 582 ++++++++--- ...erviceBufferFileStreamReaderWriterTests.cs | 14 +- .../Utility/TestDbColumn.cs | 103 +- 30 files changed, 2325 insertions(+), 1417 deletions(-) create mode 100644 src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnMetadata.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnWrapper.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/EditData/EditTableMetadata.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/EditData/IEditTableMetadata.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditTableMetadata.cs diff --git a/.gitignore b/.gitignore index f1ed27fd..9e83edea 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,9 @@ cross/rootfs/ [Bb]uild[Ll]og.* test*json +## Project Rider ## +.idea/ + #NUNIT *.VisualState.xml TestResult.xml @@ -169,9 +172,6 @@ publish/ *.nupkg **/packages/* -# NuGet package restore lockfiles -project.lock.json - # Windows Azure Build Output csx/ *.build.csdef @@ -243,8 +243,6 @@ $RECYCLE.BIN/ ### Linux ### -*~ - # KDE directory preferences .directory diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/Contracts/EditSessionReadyEvent.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/Contracts/EditSessionReadyEvent.cs index e0453701..a65e2174 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/Contracts/EditSessionReadyEvent.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/Contracts/EditSessionReadyEvent.cs @@ -14,6 +14,12 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.Contracts /// public string OwnerUri { get; set; } + /// + /// Message to explain why a session failed. Should only be set when + /// is false. + /// + public string Message { get; set; } + /// /// Whether or not the session is ready /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnMetadata.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnMetadata.cs new file mode 100644 index 00000000..54739ce5 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnMetadata.cs @@ -0,0 +1,113 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Data; +using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; +using Microsoft.SqlTools.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.EditData +{ + /// + /// Small class that stores information needed by the edit data service to properly process + /// edits into scripts. + /// + public class EditColumnMetadata + { + /// + /// Constructs a simple edit column metadata provider + /// + public EditColumnMetadata() + { + HasExtendedProperties = false; + } + + #region Basic Properties (properties provided by SMO) + + /// + /// If set, this is a string representation of the default value. If set to null, then the + /// column does not have a default value. + /// + public string DefaultValue { get; set; } + + /// + /// Escaped identifier for the name of the column + /// + public string EscapedName { get; set; } + + /// + /// Whether or not the column is computed + /// + public bool IsComputed { get; set; } + + /// + /// Whether or not the column is deterministically computed + /// + public bool IsDeterministic { get; set; } + + /// + /// Whether or not the column is an identity column + /// + public bool IsIdentity { get; set; } + + /// + /// The ordinal ID of the column + /// + public int Ordinal { get; set; } + + #endregion + + #region Extended Properties (properties provided by SqlClient) + + public DbColumnWrapper DbColumn { get; private set; } + + /// + /// Whether or not the column has extended properties + /// + public bool HasExtendedProperties { get; private set; } + + /// + /// Whether or not the column is calculated on the server side. This could be a computed + /// column or a identity column. + /// + public bool? IsCalculated { get; private set; } + + /// + /// Whether or not the column is used in a key to uniquely identify a row + /// + public bool? IsKey { get; private set; } + + /// + /// Whether or not the column can be trusted for uniqueness + /// + public bool? IsTrustworthyForUniqueness { get; private set; } + + #endregion + + /// + /// Extracts extended column properties from the database columns from SQL Client + /// + /// The column information provided by SQL Client + public void Extend(DbColumnWrapper dbColumn) + { + Validate.IsNotNull(nameof(dbColumn), dbColumn); + + DbColumn = dbColumn; + + // A column is trustworthy for uniqueness if it can be updated or it has an identity + // property. If both of these are false (eg, timestamp) we can't trust it to uniquely + // identify a row in the table + IsTrustworthyForUniqueness = dbColumn.IsUpdatable || dbColumn.IsIdentity.HasTrue(); + + // A key column is determined by whether it is a key + IsKey = dbColumn.IsKey; + + // A column is calculated if it is identity, computed, or otherwise not updatable + IsCalculated = IsIdentity || IsComputed || !dbColumn.IsUpdatable; + + // Mark the column as extended + HasExtendedProperties = true; + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnWrapper.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnWrapper.cs deleted file mode 100644 index b67535f3..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditColumnWrapper.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// 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.ServiceLayer.QueryExecution.Contracts; - -namespace Microsoft.SqlTools.ServiceLayer.EditData -{ - /// - /// Small class that stores information needed by the edit data service to properly process - /// edits into scripts. - /// - public class EditColumnWrapper - { - /// - /// The DB column - /// - public DbColumnWrapper DbColumn { get; set; } - - /// - /// If set, this is a string representation of the default value. If set to null, then the - /// column does not have a default value. - /// - public string DefaultValue { get; set; } - - /// - /// Escaped identifier for the name of the column - /// - public string EscapedName { get; set; } - - /// - /// Whether or not the column is calculated on the server side. This could be a computed - /// column or a identity column. - /// - public bool IsCalculated { get; set; } - - /// - /// Whether or not the column is used in a key to uniquely identify a row - /// - public bool IsKey { get; set; } - - /// - /// Whether or not the column can be trusted for uniqueness - /// - public bool IsTrustworthyForUniqueness { get; set; } - - /// - /// The ordinal ID of the column - /// - public int Ordinal { get; set; } - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditDataService.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditDataService.cs index e5e67731..1f7abc26 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditDataService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditDataService.cs @@ -13,7 +13,6 @@ using Microsoft.SqlTools.ServiceLayer.EditData.Contracts; using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts.ExecuteRequests; -using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.Utility; using ConnectionType = Microsoft.SqlTools.ServiceLayer.Connection.ConnectionType; @@ -57,10 +56,6 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData private readonly Lazy> editSessions = new Lazy>( () => new ConcurrentDictionary()); - private readonly Lazy>> initializeWaitHandles = - new Lazy>>( - () => new ConcurrentDictionary>()); - #endregion #region Properties @@ -70,12 +65,6 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// internal ConcurrentDictionary ActiveSessions => editSessions.Value; - /// - /// Dictionary mapping OwnerURIs to wait handlers for initialize tasks. Pretty much only - /// provided for unit test scenarios. - /// - internal ConcurrentDictionary> InitializeWaitHandles => initializeWaitHandles.Value; - #endregion /// @@ -159,63 +148,32 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData internal async Task HandleInitializeRequest(EditInitializeParams initParams, RequestContext requestContext) { + Func executionFailureHandler = (e) => SendSessionReadyEvent(requestContext, initParams.OwnerUri, false, e.Message); + Func executionSuccessHandler = () => SendSessionReadyEvent(requestContext, initParams.OwnerUri, true, null); + + EditSession.Connector connector = () => connectionService.GetOrOpenConnection(initParams.OwnerUri, ConnectionType.Edit); + EditSession.QueryRunner queryRunner = q => SessionInitializeQueryRunner(initParams.OwnerUri, requestContext, q); + try - { + { // Make sure we have info to process this request Validate.IsNotNullOrWhitespaceString(nameof(initParams.OwnerUri), initParams.OwnerUri); Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectName), initParams.ObjectName); Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectType), initParams.ObjectType); - // Try to add a new wait handler to the - if (!InitializeWaitHandles.TryAdd(initParams.OwnerUri, new TaskCompletionSource())) + // Create a session and add it to the session list + EditSession session = new EditSession(metadataFactory, initParams.ObjectName, initParams.ObjectType); + if (!ActiveSessions.TryAdd(initParams.OwnerUri, session)) { - throw new InvalidOperationException(SR.EditDataInitializeInProgress); + throw new InvalidOperationException(SR.EditDataSessionAlreadyExists); } - - // Setup a callback for when the query has successfully created - Func> queryCreateSuccessCallback = async query => - { - await requestContext.SendResult(new EditInitializeResult()); - return true; - }; - // Setup a callback for when the query failed to be created - Func queryCreateFailureCallback = async message => - { - await requestContext.SendError(message); - CompleteInitializeWaitHandler(initParams.OwnerUri, false); - }; - - // Setup a callback for when the query completes execution successfully - Query.QueryAsyncEventHandler queryCompleteSuccessCallback = - q => QueryCompleteCallback(q, initParams, requestContext); - - // Setup a callback for when the query completes execution with failure - Query.QueryAsyncEventHandler queryCompleteFailureCallback = async query => - { - EditSessionReadyParams readyParams = new EditSessionReadyParams - { - OwnerUri = initParams.OwnerUri, - Success = false - }; - await requestContext.SendEvent(EditSessionReadyEvent.Type, readyParams); - CompleteInitializeWaitHandler(initParams.OwnerUri, false); - }; - - // Put together a query for the results and execute it - ExecuteStringParams executeParams = new ExecuteStringParams - { - Query = $"SELECT * FROM {SqlScriptFormatter.FormatMultipartIdentifier(initParams.ObjectName)}", - OwnerUri = initParams.OwnerUri - }; - await queryExecutionService.InterServiceExecuteQuery(executeParams, requestContext, - queryCreateSuccessCallback, queryCreateFailureCallback, - queryCompleteSuccessCallback, queryCompleteFailureCallback); + // Initialize the session + session.Initialize(connector, queryRunner, executionSuccessHandler, executionFailureHandler); } catch (Exception e) { await requestContext.SendError(e.Message); - CompleteInitializeWaitHandler(initParams.OwnerUri, false); } } @@ -313,52 +271,64 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData return editSession; } - private async Task QueryCompleteCallback(Query query, EditInitializeParams initParams, - IEventSender requestContext) + private async Task SessionInitializeQueryRunner(string ownerUri, + IEventSender eventSender, string query) { - EditSessionReadyParams readyParams = new EditSessionReadyParams + // Open a task completion source, effectively creating a synchronous block + TaskCompletionSource taskCompletion = + new TaskCompletionSource(); + + // Setup callback for successful query creation + // NOTE: We do not want to set the task completion source, since we will continue executing the query after + Func> queryCreateSuccessCallback = q => Task.FromResult(true); + + // Setup callback for failed query creation + Func queryCreateFailureCallback = m => { - OwnerUri = initParams.OwnerUri + taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(null, m)); + return Task.FromResult(0); }; - try + // Setup callback for successful query execution + Query.QueryAsyncEventHandler queryCompleteSuccessCallback = q => { - // Validate the query for a editSession - ResultSet resultSet = EditSession.ValidateQueryForSession(query); + taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(q)); + return Task.FromResult(0); + }; - // Get a connection we'll use for SMO metadata lookup (and committing, later on) - DbConnection conn = await connectionService.GetOrOpenConnection(initParams.OwnerUri, ConnectionType.Edit); - var metadata = metadataFactory.GetObjectMetadata(conn, resultSet.Columns, - initParams.ObjectName, initParams.ObjectType); - - // Create the editSession and add it to the sessions list - EditSession editSession = new EditSession(resultSet, metadata); - if (!ActiveSessions.TryAdd(initParams.OwnerUri, editSession)) - { - throw new InvalidOperationException("Failed to create edit editSession, editSession already exists."); - } - readyParams.Success = true; - } - catch (Exception) + // Setup callback for failed query execution + Query.QueryAsyncEventHandler queryCompleteFailureCallback = q => { - // Request that the query be disposed - await queryExecutionService.InterServiceDisposeQuery(initParams.OwnerUri, null, null); - readyParams.Success = false; - } + taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(null)); + return Task.FromResult(0); + }; - // Send the edit session ready notification - await requestContext.SendEvent(EditSessionReadyEvent.Type, readyParams); - CompleteInitializeWaitHandler(initParams.OwnerUri, true); + // Execute the query + ExecuteStringParams executeParams = new ExecuteStringParams + { + Query = query, + OwnerUri = ownerUri + }; + await queryExecutionService.InterServiceExecuteQuery(executeParams, eventSender, + queryCreateSuccessCallback, queryCreateFailureCallback, + queryCompleteSuccessCallback, queryCompleteFailureCallback); + + // Wait for the completion source to complete, this will wait until the query has + // completed and sent all its events. + return await taskCompletion.Task; } - private void CompleteInitializeWaitHandler(string ownerUri, bool result) + private static Task SendSessionReadyEvent(IEventSender eventSender, string ownerUri, bool success, + string message) { - // If there isn't a wait handler, just ignore it - TaskCompletionSource initializeWaiter; - if (ownerUri != null && InitializeWaitHandles.TryRemove(ownerUri, out initializeWaiter)) + var sessionReadyParams = new EditSessionReadyParams { - initializeWaiter.SetResult(result); - } + OwnerUri = ownerUri, + Message = message, + Success = success + }; + + return eventSender.SendEvent(EditSessionReadyEvent.Type, sessionReadyParams); } #endregion diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditSession.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditSession.cs index bad9f4d4..b0eec669 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditSession.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditSession.cs @@ -25,28 +25,37 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData public class EditSession { - private readonly ResultSet associatedResultSet; - private readonly IEditTableMetadata objectMetadata; + private ResultSet associatedResultSet; + + private readonly IEditMetadataFactory metadataFactory; + private EditTableMetadata objectMetadata; + private readonly string objectName; + private readonly string objectType; /// /// Constructs a new edit session bound to the result set and metadat object provided /// - /// The result set of the table to be edited - /// Metadata provider for the table to be edited - public EditSession(ResultSet resultSet, IEditTableMetadata objMetadata) + /// Factory for creating metadata + /// The name of the object to edit + /// The type of the object to edit + public EditSession(IEditMetadataFactory metaFactory, string objName, string objType) { - Validate.IsNotNull(nameof(resultSet), resultSet); - Validate.IsNotNull(nameof(objMetadata), objMetadata); + Validate.IsNotNull(nameof(metaFactory), metaFactory); + Validate.IsNotNullOrWhitespaceString(nameof(objName), objName); + Validate.IsNotNullOrWhitespaceString(nameof(objType), objType); // Setup the internal state - associatedResultSet = resultSet; - objectMetadata = objMetadata; - NextRowId = associatedResultSet.RowCount; - EditCache = new ConcurrentDictionary(); + metadataFactory = metaFactory; + objectName = objName; + objectType = objType; } #region Properties + public delegate Task Connector(); + + public delegate Task QueryRunner(string query); + /// /// The task that is running to commit the changes to the db /// Internal for unit test purposes. @@ -61,12 +70,43 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// /// The cache of pending updates. Internal for unit test purposes only /// - internal ConcurrentDictionary EditCache { get; } + internal ConcurrentDictionary EditCache { get; private set; } + + /// + /// The task that is running to initialize the edit session + /// + internal Task InitializeTask { get; set; } + + /// + /// Whether or not the session has been initialized + /// + public bool IsInitialized { get; internal set; } #endregion #region Public Methods + public void Initialize(Connector connector, QueryRunner queryRunner, Func successHandler, Func errorHandler) + { + if (IsInitialized) + { + throw new InvalidOperationException(SR.EditDataSessionAlreadyInitialized); + } + + if (InitializeTask != null) + { + throw new InvalidOperationException(SR.EditDataSessionAlreadyInitializing); + } + + Validate.IsNotNull(nameof(connector), connector); + Validate.IsNotNull(nameof(queryRunner), queryRunner); + Validate.IsNotNull(nameof(successHandler), successHandler); + Validate.IsNotNull(nameof(errorHandler), errorHandler); + + // Start up the initialize process + InitializeTask = InitializeInternal(connector, queryRunner, successHandler, errorHandler); + } + /// /// Validates that a query can be used for an edit session. The target result set is returned /// @@ -100,6 +140,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// The internal ID of the newly created row public EditCreateRowResult CreateRow() { + ThrowIfNotInitialized(); + // Create a new row ID (atomically, since this could be accesses concurrently) long newRowId = NextRowId++; @@ -113,13 +155,13 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData } // Set the default values of the row if we know them - string[] defaultValues = new string[objectMetadata.Columns.Count]; - for(int i = 0; i < objectMetadata.Columns.Count; i++) + string[] defaultValues = new string[objectMetadata.Columns.Length]; + for(int i = 0; i < objectMetadata.Columns.Length; i++) { - EditColumnWrapper col = objectMetadata.Columns[i]; + EditColumnMetadata col = objectMetadata.Columns[i]; // If the column is calculated, return the calculated placeholder as the display value - if (col.IsCalculated) + if (col.IsCalculated.HasTrue()) { defaultValues[i] = SR.EditDataComputedColumnPlaceholder; } @@ -150,6 +192,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// Callback to perform if the commit process has failed at some point public void CommitEdits(DbConnection connection, Func successHandler, Func errorHandler) { + ThrowIfNotInitialized(); + Validate.IsNotNull(nameof(connection), connection); Validate.IsNotNull(nameof(successHandler), successHandler); Validate.IsNotNull(nameof(errorHandler), errorHandler); @@ -173,6 +217,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// The internal ID of the row to delete public void DeleteRow(long rowId) { + ThrowIfNotInitialized(); + // Sanity check the row ID if (rowId >= NextRowId || rowId < 0) { @@ -196,6 +242,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// An array of rows with pending edits applied public async Task GetRows(long startIndex, int rowCount) { + ThrowIfNotInitialized(); + // Get the cached rows from the result set ResultSetSubset cachedRows = startIndex < associatedResultSet.RowCount ? await associatedResultSet.GetSubset(startIndex, rowCount) @@ -249,6 +297,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// String version of the old value for the cell public string RevertCell(long rowId, int columnId) { + ThrowIfNotInitialized(); + // Attempt to get the row edit with the given ID RowEditBase pendingEdit; if (!EditCache.TryGetValue(rowId, out pendingEdit)) @@ -269,6 +319,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// The internal ID of the row to reset public void RevertRow(long rowId) { + ThrowIfNotInitialized(); + // Attempt to remove the row with the given ID RowEditBase removedEdit; if (!EditCache.TryRemove(rowId, out removedEdit)) @@ -284,6 +336,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// public string ScriptEdits(string outputPath) { + ThrowIfNotInitialized(); + // Validate the output path // @TODO: Reinstate this code once we have an interface around file generation //if (outputPath == null) @@ -328,6 +382,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// The new string value of the cell to update public EditUpdateCellResult UpdateCell(long rowId, int columnId, string newValue) { + ThrowIfNotInitialized(); + // Sanity check to make sure that the row ID is in the range of possible values if (rowId >= NextRowId || rowId < 0) { @@ -347,6 +403,38 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData #endregion + private async Task InitializeInternal(Connector connector, QueryRunner queryRunner, + Func successHandler, Func failureHandler) + { + try + { + // Step 1) Look up the SMO metadata + objectMetadata = metadataFactory.GetObjectMetadata(await connector(), objectName, objectType); + + // Step 2) Get and execute a query for the rows in the object we're looking up + EditSessionQueryExecutionState state = await queryRunner(ConstructInitializeQuery()); + if (state.Query == null) + { + // TODO: Move to SR file + string message = state.Message ?? SR.EditDataQueryFailed; + throw new Exception(message); + } + + // Step 3) Setup the internal state + associatedResultSet = ValidateQueryForSession(state.Query); + NextRowId = associatedResultSet.RowCount; + EditCache = new ConcurrentDictionary(); + IsInitialized = true; + + // Step 4) Return our success + await successHandler(); + } + catch (Exception e) + { + await failureHandler(e); + } + } + private async Task CommitEditsInternal(DbConnection connection, Func successHandler, Func errorHandler) { try @@ -378,5 +466,50 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData await errorHandler(e); } } + + private string ConstructInitializeQuery() + { + // Using the columns we know, put together a query for the rows in the table + var columns = objectMetadata.Columns.Select(col => col.EscapedName); + var columnClause = string.Join(", ", columns); + + return $"SELECT ${columnClause} FROM ${objectMetadata.EscapedMultipartName}"; + } + + private void ThrowIfNotInitialized() + { + if (!IsInitialized) + { + throw new InvalidOperationException(SR.EditDataSessionNotInitialized); + } + } + + /// + /// State object to return upon completion of an edit session intialization query + /// + public class EditSessionQueryExecutionState + { + /// + /// The query object that was used to execute the edit initialization query. If + /// null the query was not successfully executed. + /// + public Query Query { get; set; } + + /// + /// Any message that may have occurred during execution of the query (ie, exceptions). + /// If this is and are null then the error messages were + /// returned via message events. + /// + public string Message { get; set; } + + /// + /// Constructs a new instance. Sets the values of the properties. + /// + public EditSessionQueryExecutionState(Query query, string message = null) + { + Query = query; + Message = message; + } + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/EditTableMetadata.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditTableMetadata.cs new file mode 100644 index 00000000..d765ee2e --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/EditTableMetadata.cs @@ -0,0 +1,85 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Linq; +using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; +using Microsoft.SqlTools.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.EditData +{ + /// + /// Provides metadata about the table or view being edited + /// + public class EditTableMetadata + { + /// + /// Constructs a simple edit table metadata provider + /// + public EditTableMetadata() + { + HasExtendedProperties = false; + } + + #region Basic Properties (properties provided by SMO) + + /// + /// List of columns in the object being edited + /// + public EditColumnMetadata[] Columns { get; set; } + + /// + /// Full escaped multipart identifier for the object being edited + /// + public string EscapedMultipartName { get; set; } + + /// + /// Whether or not the object being edited is memory optimized + /// + public bool IsMemoryOptimized { get; set; } + + #endregion + + #region Extended Properties (properties provided by SqlClient) + + /// + /// Whether or not the table has had extended properties added to it + /// + public bool HasExtendedProperties { get; private set; } + + /// + /// List of columns that are used to uniquely identify a row + /// + public EditColumnMetadata[] KeyColumns { get; private set; } + + #endregion + + /// + /// Extracts extended column properties from the database columns from SQL Client + /// + /// The column information provided by SQL Client + public void Extend(DbColumnWrapper[] dbColumnWrappers) + { + Validate.IsNotNull(nameof(dbColumnWrappers), dbColumnWrappers); + + // Iterate over the column wrappers and improve the columns we have + for (int i = 0; i < Columns.Length; i++) + { + Columns[i].Extend(dbColumnWrappers[i]); + } + + // Determine what the key columns are + KeyColumns = Columns.Where(c => c.IsKey.HasTrue()).ToArray(); + if (KeyColumns.Length == 0) + { + // We didn't find any explicit key columns. Instead, we'll use all columns that are + // trustworthy for uniqueness (usually all the columns) + KeyColumns = Columns.Where(c => c.IsTrustworthyForUniqueness.HasTrue()).ToArray(); + } + + // Mark that the table is now extended + HasExtendedProperties = true; + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditMetadataFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditMetadataFactory.cs index 633566fa..c145d24e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditMetadataFactory.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditMetadataFactory.cs @@ -4,7 +4,6 @@ // using System.Data.Common; -using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; namespace Microsoft.SqlTools.ServiceLayer.EditData { @@ -17,10 +16,9 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// Generates a edit-ready metadata object /// /// Connection to use for getting metadata - /// List of columns from a query against the object /// Name of the object to return metadata for /// Type of the object to return metadata for /// Metadata about the object requested - IEditTableMetadata GetObjectMetadata(DbConnection connection, DbColumnWrapper[] columns, string objectName, string objectType); + EditTableMetadata GetObjectMetadata(DbConnection connection, string objectName, string objectType); } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditTableMetadata.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditTableMetadata.cs deleted file mode 100644 index 9bbe3d26..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/IEditTableMetadata.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// 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.EditData -{ - /// - /// An interface used in edit scenarios that defines properties for what columns are primary - /// keys, and other metadata of the table. - /// - public interface IEditTableMetadata - { - /// - /// All columns in the table that's being edited - /// - IReadOnlyList Columns { get; } - - /// - /// The escaped name of the table that's being edited - /// - string EscapedMultipartName { get; } - - /// - /// Whether or not this table is a memory optimized table - /// - bool IsMemoryOptimized { get; } - - /// - /// Columns that can be used to uniquely identify the a row - /// - IReadOnlyList KeyColumns { get; } - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditMetadataFactory.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditMetadataFactory.cs index 4a0930e3..c70fa51a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditMetadataFactory.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditMetadataFactory.cs @@ -4,12 +4,13 @@ // using System; +using System.Collections.Generic; using System.Data.Common; using System.Data.SqlClient; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection; -using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; namespace Microsoft.SqlTools.ServiceLayer.EditData { @@ -22,11 +23,10 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData /// Generates a edit-ready metadata object using SMO /// /// Connection to use for getting metadata - /// List of columns from a query against the object /// Name of the object to return metadata for /// Type of the object to return metadata for /// Metadata about the object requested - public IEditTableMetadata GetObjectMetadata(DbConnection connection, DbColumnWrapper[] columns, string objectName, string objectType) + public EditTableMetadata GetObjectMetadata(DbConnection connection, string objectName, string objectType) { // Get a connection to the database for SMO purposes SqlConnection sqlConn = connection as SqlConnection; @@ -44,25 +44,59 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData sqlConn = reliableConn.GetUnderlyingConnection(); } + // Connect with SMO and get the metadata for the table Server server = new Server(new ServerConnection(sqlConn)); - TableViewTableTypeBase result; + TableViewTableTypeBase smoResult; switch (objectType.ToLowerInvariant()) { case "table": - result = server.Databases[sqlConn.Database].Tables[objectName]; + smoResult = server.Databases[sqlConn.Database].Tables[objectName]; break; case "view": - result = server.Databases[sqlConn.Database].Views[objectName]; + smoResult = server.Databases[sqlConn.Database].Views[objectName]; break; default: throw new ArgumentOutOfRangeException(nameof(objectType), SR.EditDataUnsupportedObjectType(objectType)); } - if (result == null) + if (smoResult == null) { throw new ArgumentOutOfRangeException(nameof(objectName), SR.EditDataObjectMetadataNotFound); } - return new SmoEditTableMetadata(columns, result); + // Generate the edit column metadata + List editColumns = new List(); + for (int i = 0; i < smoResult.Columns.Count; i++) + { + Column smoColumn = smoResult.Columns[i]; + + // The default value may be escaped + string defaultValue = smoColumn.DefaultConstraint == null + ? null + : SqlScriptFormatter.UnwrapLiteral(smoColumn.DefaultConstraint.Text); + + EditColumnMetadata column = new EditColumnMetadata + { + DefaultValue = defaultValue, + EscapedName = SqlScriptFormatter.FormatIdentifier(smoColumn.Name), + Ordinal = i, + }; + editColumns.Add(column); + } + + // Only tables can be memory-optimized + Table smoTable = smoResult as Table; + bool isMemoryOptimized = smoTable != null && smoTable.IsMemoryOptimized; + + // Escape the parts of the name + string[] objectNameParts = {smoResult.Schema, smoResult.Name}; + string escapedMultipartName = SqlScriptFormatter.FormatMultipartIdentifier(objectNameParts); + + return new EditTableMetadata + { + Columns = editColumns.ToArray(), + EscapedMultipartName = escapedMultipartName, + IsMemoryOptimized = isMemoryOptimized, + }; } } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditTableMetadata.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditTableMetadata.cs deleted file mode 100644 index e6fa8cf0..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/SmoEditTableMetadata.cs +++ /dev/null @@ -1,109 +0,0 @@ -// -// 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 System.Linq; -using System.Diagnostics; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; -using Microsoft.SqlTools.Utility; -using Microsoft.SqlTools.ServiceLayer.Utility; - -namespace Microsoft.SqlTools.ServiceLayer.EditData -{ - /// - /// Provides metadata about the table or view being edited - /// - public class SmoEditTableMetadata : IEditTableMetadata - { - private readonly List columns; - private readonly List keyColumns; - - /// - /// Constructor that extracts useful metadata from the provided metadata objects - /// - /// DB columns from the ResultSet - /// SMO metadata object for the table/view being edited - public SmoEditTableMetadata(IList dbColumns, TableViewTableTypeBase smoObject) - { - Validate.IsNotNull(nameof(dbColumns), dbColumns); - Validate.IsNotNull(nameof(smoObject), smoObject); - - // Make sure that we have equal columns on both metadata providers - Debug.Assert(dbColumns.Count == smoObject.Columns.Count); - - // Create the columns for edit usage - columns = new List(); - for (int i = 0; i < dbColumns.Count; i++) - { - Column smoColumn = smoObject.Columns[i]; - DbColumnWrapper dbColumn = dbColumns[i]; - - // A column is trustworthy for uniqueness if it can be updated or it has an identity - // property. If both of these are false (eg, timestamp) we can't trust it to uniquely - // identify a row in the table - bool isTrustworthyForUniqueness = dbColumn.IsUpdatable || smoColumn.Identity; - - // The default value may be escaped - string defaultValue = smoColumn.DefaultConstraint == null - ? null - : SqlScriptFormatter.UnwrapLiteral(smoColumn.DefaultConstraint.Text); - - EditColumnWrapper column = new EditColumnWrapper - { - DbColumn = dbColumn, - Ordinal = i, - DefaultValue = defaultValue, - EscapedName = SqlScriptFormatter.FormatIdentifier(dbColumn.ColumnName), - IsTrustworthyForUniqueness = isTrustworthyForUniqueness, - - // A key column is determined by whether it is in the primary key and trustworthy - IsKey = smoColumn.InPrimaryKey && isTrustworthyForUniqueness, - - // A column is calculated if it is identity, computed, or otherwise not updatable - IsCalculated = smoColumn.Identity || smoColumn.Computed || !dbColumn.IsUpdatable - }; - columns.Add(column); - } - - // Determine what the key columns are - keyColumns = columns.Where(c => c.IsKey).ToList(); - if (keyColumns.Count == 0) - { - // We didn't find any explicit key columns. Instead, we'll use all columns that are - // trustworthy for uniqueness (usually all the columns) - keyColumns = columns.Where(c => c.IsTrustworthyForUniqueness).ToList(); - } - - // If a table is memory optimized it is Hekaton. If it's a view, then it can't be Hekaton - Table smoTable = smoObject as Table; - IsMemoryOptimized = smoTable != null && smoTable.IsMemoryOptimized; - - // Escape the parts of the name - string[] objectNameParts = {smoObject.Schema, smoObject.Name}; - EscapedMultipartName = SqlScriptFormatter.FormatMultipartIdentifier(objectNameParts); - } - - /// - /// Read-only list of columns in the object being edited - /// - public IReadOnlyList Columns => columns.AsReadOnly(); - - /// - /// Full escaped multipart identifier for the object being edited - /// - public string EscapedMultipartName { get; } - - /// - /// Whether or not the object being edited is memory optimized - /// - public bool IsMemoryOptimized { get; } - - /// - /// Read-only list of columns that are used to uniquely identify a row - /// - public IReadOnlyList KeyColumns => keyColumns.AsReadOnly(); - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowCreate.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowCreate.cs index b5292fa0..a86a780f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowCreate.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowCreate.cs @@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement /// Internal ID of the row that is being created /// The result set for the rows in the table we're editing /// The metadata for table we're editing - public RowCreate(long rowId, ResultSet associatedResultSet, IEditTableMetadata associatedMetadata) + public RowCreate(long rowId, ResultSet associatedResultSet, EditTableMetadata associatedMetadata) : base(rowId, associatedResultSet, associatedMetadata) { newCells = new CellUpdate[associatedResultSet.Columns.Length]; diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowDelete.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowDelete.cs index 64b0ddc9..339e9184 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowDelete.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowDelete.cs @@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement /// Internal ID of the row to be deleted /// Result set that is being edited /// Improved metadata of the object being edited - public RowDelete(long rowId, ResultSet associatedResultSet, IEditTableMetadata associatedMetadata) + public RowDelete(long rowId, ResultSet associatedResultSet, EditTableMetadata associatedMetadata) : base(rowId, associatedResultSet, associatedMetadata) { } diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowEdit.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowEdit.cs index 9df74c50..41de1d85 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowEdit.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowEdit.cs @@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement /// The internal ID of the row that is being edited /// The result set that will be updated /// Metadata provider for the object to edit - protected RowEditBase(long rowId, ResultSet associatedResultSet, IEditTableMetadata associatedMetadata) + protected RowEditBase(long rowId, ResultSet associatedResultSet, EditTableMetadata associatedMetadata) { RowId = rowId; AssociatedResultSet = associatedResultSet; @@ -58,7 +58,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement /// /// The metadata for the table this edit is associated to /// - public IEditTableMetadata AssociatedObjectMetadata { get; } + public EditTableMetadata AssociatedObjectMetadata { get; } /// /// Sort ID for a row edit. Ensures that when a collection of RowEditBase objects are @@ -162,7 +162,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement } IList row = AssociatedResultSet.GetRow(RowId); - foreach (EditColumnWrapper col in AssociatedObjectMetadata.KeyColumns) + foreach (EditColumnMetadata col in AssociatedObjectMetadata.KeyColumns) { // Put together a clause for the value of the cell DbCellValue cellData = row[col.Ordinal]; diff --git a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowUpdate.cs b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowUpdate.cs index 3342f1d7..e7f1c4e6 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowUpdate.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/EditData/UpdateManagement/RowUpdate.cs @@ -39,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement /// Internal ID of the row that will be updated with this object /// Result set for the rows of the object to update /// Metadata provider for the object to update - public RowUpdate(long rowId, ResultSet associatedResultSet, IEditTableMetadata associatedMetadata) + public RowUpdate(long rowId, ResultSet associatedResultSet, EditTableMetadata associatedMetadata) : base(rowId, associatedResultSet, associatedMetadata) { cellUpdates = new ConcurrentDictionary(); diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index f46651da..818a3b01 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer Keys.Culture = value; } } - + public static string ConnectionServiceConnectErrorNullParams { @@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionServiceConnectErrorNullParams); } - } + } public static string ConnectionServiceListDbErrorNullOwnerUri { @@ -43,7 +43,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionServiceListDbErrorNullOwnerUri); } - } + } public static string ConnectionServiceConnectionCanceled { @@ -51,7 +51,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionServiceConnectionCanceled); } - } + } public static string ConnectionParamsValidateNullOwnerUri { @@ -59,7 +59,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionParamsValidateNullOwnerUri); } - } + } public static string ConnectionParamsValidateNullConnection { @@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionParamsValidateNullConnection); } - } + } public static string ConnectionParamsValidateNullServerName { @@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ConnectionParamsValidateNullServerName); } - } + } public static string ErrorUnexpectedCodeObjectType { @@ -83,7 +83,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ErrorUnexpectedCodeObjectType); } - } + } public static string QueryServiceCancelAlreadyCompleted { @@ -91,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceCancelAlreadyCompleted); } - } + } public static string QueryServiceCancelDisposeFailed { @@ -99,7 +99,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceCancelDisposeFailed); } - } + } public static string QueryServiceQueryCancelled { @@ -107,7 +107,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceQueryCancelled); } - } + } public static string QueryServiceSubsetBatchNotCompleted { @@ -115,7 +115,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSubsetBatchNotCompleted); } - } + } public static string QueryServiceSubsetBatchOutOfRange { @@ -123,7 +123,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSubsetBatchOutOfRange); } - } + } public static string QueryServiceSubsetResultSetOutOfRange { @@ -131,7 +131,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSubsetResultSetOutOfRange); } - } + } public static string QueryServiceDataReaderByteCountInvalid { @@ -139,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceDataReaderByteCountInvalid); } - } + } public static string QueryServiceDataReaderCharCountInvalid { @@ -147,7 +147,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceDataReaderCharCountInvalid); } - } + } public static string QueryServiceDataReaderXmlCountInvalid { @@ -155,7 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceDataReaderXmlCountInvalid); } - } + } public static string QueryServiceFileWrapperWriteOnly { @@ -163,7 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceFileWrapperWriteOnly); } - } + } public static string QueryServiceFileWrapperNotInitialized { @@ -171,7 +171,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceFileWrapperNotInitialized); } - } + } public static string QueryServiceFileWrapperReadOnly { @@ -179,7 +179,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceFileWrapperReadOnly); } - } + } public static string QueryServiceAffectedOneRow { @@ -187,7 +187,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceAffectedOneRow); } - } + } public static string QueryServiceCompletedSuccessfully { @@ -195,7 +195,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceCompletedSuccessfully); } - } + } public static string QueryServiceColumnNull { @@ -203,7 +203,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceColumnNull); } - } + } public static string QueryServiceRequestsNoQuery { @@ -211,7 +211,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceRequestsNoQuery); } - } + } public static string QueryServiceQueryInvalidOwnerUri { @@ -219,7 +219,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceQueryInvalidOwnerUri); } - } + } public static string QueryServiceQueryInProgress { @@ -227,7 +227,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceQueryInProgress); } - } + } public static string QueryServiceMessageSenderNotSql { @@ -235,7 +235,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceMessageSenderNotSql); } - } + } public static string QueryServiceResultSetAddNoRows { @@ -243,7 +243,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceResultSetAddNoRows); } - } + } public static string QueryServiceSaveAsResultSetNotComplete { @@ -251,7 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSaveAsResultSetNotComplete); } - } + } public static string QueryServiceSaveAsMiscStartingError { @@ -259,7 +259,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSaveAsMiscStartingError); } - } + } public static string QueryServiceSaveAsInProgress { @@ -267,7 +267,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceSaveAsInProgress); } - } + } public static string QueryServiceResultSetNotRead { @@ -275,7 +275,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceResultSetNotRead); } - } + } public static string QueryServiceResultSetStartRowOutOfRange { @@ -283,7 +283,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceResultSetStartRowOutOfRange); } - } + } public static string QueryServiceResultSetRowCountOutOfRange { @@ -291,7 +291,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceResultSetRowCountOutOfRange); } - } + } public static string QueryServiceResultSetNoColumnSchema { @@ -299,7 +299,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceResultSetNoColumnSchema); } - } + } public static string QueryServiceExecutionPlanNotFound { @@ -307,7 +307,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.QueryServiceExecutionPlanNotFound); } - } + } public static string PeekDefinitionNoResultsError { @@ -315,7 +315,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.PeekDefinitionNoResultsError); } - } + } public static string PeekDefinitionDatabaseError { @@ -323,7 +323,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.PeekDefinitionDatabaseError); } - } + } public static string PeekDefinitionNotConnectedError { @@ -331,7 +331,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.PeekDefinitionNotConnectedError); } - } + } public static string PeekDefinitionTimedoutError { @@ -339,7 +339,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.PeekDefinitionTimedoutError); } - } + } public static string PeekDefinitionTypeNotSupportedError { @@ -347,7 +347,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.PeekDefinitionTypeNotSupportedError); } - } + } public static string ErrorEmptyStringReplacement { @@ -355,7 +355,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.ErrorEmptyStringReplacement); } - } + } public static string WorkspaceServicePositionLineOutOfRange { @@ -363,7 +363,15 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.WorkspaceServicePositionLineOutOfRange); } - } + } + + public static string EditDataObjectNotFound + { + get + { + return Keys.GetString(Keys.EditDataObjectNotFound); + } + } public static string EditDataSessionNotFound { @@ -371,7 +379,47 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataSessionNotFound); } - } + } + + public static string EditDataSessionAlreadyExists + { + get + { + return Keys.GetString(Keys.EditDataSessionAlreadyExists); + } + } + + public static string EditDataSessionNotInitialized + { + get + { + return Keys.GetString(Keys.EditDataSessionNotInitialized); + } + } + + public static string EditDataSessionAlreadyInitialized + { + get + { + return Keys.GetString(Keys.EditDataSessionAlreadyInitialized); + } + } + + public static string EditDataSessionAlreadyInitializing + { + get + { + return Keys.GetString(Keys.EditDataSessionAlreadyInitializing); + } + } + + public static string EditDataQueryFailed + { + get + { + return Keys.GetString(Keys.EditDataQueryFailed); + } + } public static string EditDataQueryNotCompleted { @@ -379,7 +427,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataQueryNotCompleted); } - } + } public static string EditDataQueryImproperResultSets { @@ -387,7 +435,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataQueryImproperResultSets); } - } + } public static string EditDataFailedAddRow { @@ -395,7 +443,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataFailedAddRow); } - } + } public static string EditDataRowOutOfRange { @@ -403,7 +451,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataRowOutOfRange); } - } + } public static string EditDataUpdatePending { @@ -411,7 +459,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataUpdatePending); } - } + } public static string EditDataUpdateNotPending { @@ -419,7 +467,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataUpdateNotPending); } - } + } public static string EditDataColumnUpdateNotPending { @@ -427,7 +475,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataColumnUpdateNotPending); } - } + } public static string EditDataObjectMetadataNotFound { @@ -435,7 +483,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataObjectMetadataNotFound); } - } + } public static string EditDataInvalidFormatBinary { @@ -443,7 +491,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataInvalidFormatBinary); } - } + } public static string EditDataInvalidFormatBoolean { @@ -451,7 +499,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataInvalidFormatBoolean); } - } + } public static string EditDataCreateScriptMissingValue { @@ -459,7 +507,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataCreateScriptMissingValue); } - } + } public static string EditDataDeleteSetCell { @@ -467,7 +515,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataDeleteSetCell); } - } + } public static string EditDataColumnIdOutOfRange { @@ -475,7 +523,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataColumnIdOutOfRange); } - } + } public static string EditDataColumnCannotBeEdited { @@ -483,7 +531,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataColumnCannotBeEdited); } - } + } public static string EditDataColumnNoKeyColumns { @@ -491,7 +539,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataColumnNoKeyColumns); } - } + } public static string EditDataScriptFilePathNull { @@ -499,7 +547,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataScriptFilePathNull); } - } + } public static string EditDataCommitInProgress { @@ -507,7 +555,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataCommitInProgress); } - } + } public static string EditDataComputedColumnPlaceholder { @@ -515,7 +563,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataComputedColumnPlaceholder); } - } + } public static string EditDataInitializeInProgress { @@ -523,7 +571,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataInitializeInProgress); } - } + } public static string EditDataTimeOver24Hrs { @@ -531,7 +579,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataTimeOver24Hrs); } - } + } public static string EditDataNullNotAllowed { @@ -539,7 +587,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EditDataNullNotAllowed); } - } + } public static string EE_BatchSqlMessageNoProcedureInfo { @@ -547,7 +595,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchSqlMessageNoProcedureInfo); } - } + } public static string EE_BatchSqlMessageWithProcedureInfo { @@ -555,7 +603,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchSqlMessageWithProcedureInfo); } - } + } public static string EE_BatchSqlMessageNoLineInfo { @@ -563,7 +611,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchSqlMessageNoLineInfo); } - } + } public static string EE_BatchError_Exception { @@ -571,7 +619,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchError_Exception); } - } + } public static string EE_BatchExecutionInfo_RowsAffected { @@ -579,7 +627,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchExecutionInfo_RowsAffected); } - } + } public static string EE_ExecutionNotYetCompleteError { @@ -587,7 +635,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionNotYetCompleteError); } - } + } public static string EE_ScriptError_Error { @@ -595,7 +643,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ScriptError_Error); } - } + } public static string EE_ScriptError_ParsingSyntax { @@ -603,7 +651,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ScriptError_ParsingSyntax); } - } + } public static string EE_ScriptError_FatalError { @@ -611,7 +659,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ScriptError_FatalError); } - } + } public static string EE_ExecutionInfo_FinalizingLoop { @@ -619,7 +667,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionInfo_FinalizingLoop); } - } + } public static string EE_ExecutionInfo_QueryCancelledbyUser { @@ -627,7 +675,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionInfo_QueryCancelledbyUser); } - } + } public static string EE_BatchExecutionError_Halting { @@ -635,7 +683,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchExecutionError_Halting); } - } + } public static string EE_BatchExecutionError_Ignoring { @@ -643,7 +691,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_BatchExecutionError_Ignoring); } - } + } public static string EE_ExecutionInfo_InitilizingLoop { @@ -651,7 +699,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionInfo_InitilizingLoop); } - } + } public static string EE_ExecutionError_CommandNotSupported { @@ -659,7 +707,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionError_CommandNotSupported); } - } + } public static string EE_ExecutionError_VariableNotFound { @@ -667,7 +715,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ExecutionError_VariableNotFound); } - } + } public static string BatchParserWrapperExecutionEngineError { @@ -675,7 +723,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionEngineError); } - } + } public static string BatchParserWrapperExecutionError { @@ -683,7 +731,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionError); } - } + } public static string BatchParserWrapperExecutionEngineBatchMessage { @@ -691,7 +739,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionEngineBatchMessage); } - } + } public static string BatchParserWrapperExecutionEngineBatchResultSetProcessing { @@ -699,7 +747,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionEngineBatchResultSetProcessing); } - } + } public static string BatchParserWrapperExecutionEngineBatchResultSetFinished { @@ -707,7 +755,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionEngineBatchResultSetFinished); } - } + } public static string BatchParserWrapperExecutionEngineBatchCancelling { @@ -715,7 +763,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParserWrapperExecutionEngineBatchCancelling); } - } + } public static string EE_ScriptError_Warning { @@ -723,7 +771,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.EE_ScriptError_Warning); } - } + } public static string TroubleshootingAssistanceMessage { @@ -731,7 +779,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.TroubleshootingAssistanceMessage); } - } + } public static string BatchParser_CircularReference { @@ -739,7 +787,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParser_CircularReference); } - } + } public static string BatchParser_CommentNotTerminated { @@ -747,7 +795,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParser_CommentNotTerminated); } - } + } public static string BatchParser_StringNotTerminated { @@ -755,7 +803,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParser_StringNotTerminated); } - } + } public static string BatchParser_IncorrectSyntax { @@ -763,7 +811,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParser_IncorrectSyntax); } - } + } public static string BatchParser_VariableNotDefined { @@ -771,7 +819,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.BatchParser_VariableNotDefined); } - } + } public static string TestLocalizationConstant { @@ -779,7 +827,7 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.TestLocalizationConstant); } - } + } public static string SqlScriptFormatterDecimalMissingPrecision { @@ -787,77 +835,77 @@ namespace Microsoft.SqlTools.ServiceLayer { return Keys.GetString(Keys.SqlScriptFormatterDecimalMissingPrecision); } - } + } public static string ConnectionServiceListDbErrorNotConnected(string uri) { return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri); - } + } public static string ConnectionServiceDbErrorDefaultNotConnected(string uri) { return Keys.GetString(Keys.ConnectionServiceDbErrorDefaultNotConnected, uri); - } + } public static string ConnectionServiceConnStringInvalidAuthType(string authType) { return Keys.GetString(Keys.ConnectionServiceConnStringInvalidAuthType, authType); - } + } public static string ConnectionServiceConnStringInvalidIntent(string intent) { return Keys.GetString(Keys.ConnectionServiceConnStringInvalidIntent, intent); - } + } public static string ConnectionParamsValidateNullSqlAuth(string component) { return Keys.GetString(Keys.ConnectionParamsValidateNullSqlAuth, component); - } + } public static string QueryServiceAffectedRows(long rows) { return Keys.GetString(Keys.QueryServiceAffectedRows, rows); - } + } public static string QueryServiceErrorFormat(int msg, int lvl, int state, int line, string newLine, string message) { return Keys.GetString(Keys.QueryServiceErrorFormat, msg, lvl, state, line, newLine, message); - } + } public static string QueryServiceQueryFailed(string message) { return Keys.GetString(Keys.QueryServiceQueryFailed, message); - } + } public static string QueryServiceSaveAsFail(string fileName, string message) { return Keys.GetString(Keys.QueryServiceSaveAsFail, fileName, message); - } + } public static string PeekDefinitionAzureError(string errorMessage) { return Keys.GetString(Keys.PeekDefinitionAzureError, errorMessage); - } + } public static string PeekDefinitionError(string errorMessage) { return Keys.GetString(Keys.PeekDefinitionError, errorMessage); - } + } public static string WorkspaceServicePositionColumnOutOfRange(int line) { return Keys.GetString(Keys.WorkspaceServicePositionColumnOutOfRange, line); - } + } public static string WorkspaceServiceBufferPositionOutOfOrder(int sLine, int sCol, int eLine, int eCol) { return Keys.GetString(Keys.WorkspaceServiceBufferPositionOutOfOrder, sLine, sCol, eLine, eCol); - } + } public static string EditDataUnsupportedObjectType(string typeName) { return Keys.GetString(Keys.EditDataUnsupportedObjectType, typeName); - } + } [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Keys @@ -865,334 +913,352 @@ namespace Microsoft.SqlTools.ServiceLayer static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(SR).GetTypeInfo().Assembly); static CultureInfo _culture = null; - - - public const string ConnectionServiceConnectErrorNullParams = "ConnectionServiceConnectErrorNullParams"; - - - public const string ConnectionServiceListDbErrorNullOwnerUri = "ConnectionServiceListDbErrorNullOwnerUri"; - - - public const string ConnectionServiceListDbErrorNotConnected = "ConnectionServiceListDbErrorNotConnected"; - - - public const string ConnectionServiceDbErrorDefaultNotConnected = "ConnectionServiceDbErrorDefaultNotConnected"; - - - public const string ConnectionServiceConnStringInvalidAuthType = "ConnectionServiceConnStringInvalidAuthType"; - - - public const string ConnectionServiceConnStringInvalidIntent = "ConnectionServiceConnStringInvalidIntent"; - - - public const string ConnectionServiceConnectionCanceled = "ConnectionServiceConnectionCanceled"; - - - public const string ConnectionParamsValidateNullOwnerUri = "ConnectionParamsValidateNullOwnerUri"; - - - public const string ConnectionParamsValidateNullConnection = "ConnectionParamsValidateNullConnection"; - - - public const string ConnectionParamsValidateNullServerName = "ConnectionParamsValidateNullServerName"; - - - public const string ConnectionParamsValidateNullSqlAuth = "ConnectionParamsValidateNullSqlAuth"; - - - public const string ErrorUnexpectedCodeObjectType = "ErrorUnexpectedCodeObjectType"; - - - public const string QueryServiceCancelAlreadyCompleted = "QueryServiceCancelAlreadyCompleted"; - - - public const string QueryServiceCancelDisposeFailed = "QueryServiceCancelDisposeFailed"; - - - public const string QueryServiceQueryCancelled = "QueryServiceQueryCancelled"; - - - public const string QueryServiceSubsetBatchNotCompleted = "QueryServiceSubsetBatchNotCompleted"; - - - public const string QueryServiceSubsetBatchOutOfRange = "QueryServiceSubsetBatchOutOfRange"; - - - public const string QueryServiceSubsetResultSetOutOfRange = "QueryServiceSubsetResultSetOutOfRange"; - - - public const string QueryServiceDataReaderByteCountInvalid = "QueryServiceDataReaderByteCountInvalid"; - - - public const string QueryServiceDataReaderCharCountInvalid = "QueryServiceDataReaderCharCountInvalid"; - - - public const string QueryServiceDataReaderXmlCountInvalid = "QueryServiceDataReaderXmlCountInvalid"; - - - public const string QueryServiceFileWrapperWriteOnly = "QueryServiceFileWrapperWriteOnly"; - - - public const string QueryServiceFileWrapperNotInitialized = "QueryServiceFileWrapperNotInitialized"; - - - public const string QueryServiceFileWrapperReadOnly = "QueryServiceFileWrapperReadOnly"; - - - public const string QueryServiceAffectedOneRow = "QueryServiceAffectedOneRow"; - - - public const string QueryServiceAffectedRows = "QueryServiceAffectedRows"; - - - public const string QueryServiceCompletedSuccessfully = "QueryServiceCompletedSuccessfully"; - - - public const string QueryServiceErrorFormat = "QueryServiceErrorFormat"; - - - public const string QueryServiceQueryFailed = "QueryServiceQueryFailed"; - - - public const string QueryServiceColumnNull = "QueryServiceColumnNull"; - - - public const string QueryServiceRequestsNoQuery = "QueryServiceRequestsNoQuery"; - - - public const string QueryServiceQueryInvalidOwnerUri = "QueryServiceQueryInvalidOwnerUri"; - - - public const string QueryServiceQueryInProgress = "QueryServiceQueryInProgress"; - - - public const string QueryServiceMessageSenderNotSql = "QueryServiceMessageSenderNotSql"; - - - public const string QueryServiceResultSetAddNoRows = "QueryServiceResultSetAddNoRows"; - - - public const string QueryServiceSaveAsResultSetNotComplete = "QueryServiceSaveAsResultSetNotComplete"; - - - public const string QueryServiceSaveAsMiscStartingError = "QueryServiceSaveAsMiscStartingError"; - - - public const string QueryServiceSaveAsInProgress = "QueryServiceSaveAsInProgress"; - - - public const string QueryServiceSaveAsFail = "QueryServiceSaveAsFail"; - - - public const string QueryServiceResultSetNotRead = "QueryServiceResultSetNotRead"; - - - public const string QueryServiceResultSetStartRowOutOfRange = "QueryServiceResultSetStartRowOutOfRange"; - - - public const string QueryServiceResultSetRowCountOutOfRange = "QueryServiceResultSetRowCountOutOfRange"; - - - public const string QueryServiceResultSetNoColumnSchema = "QueryServiceResultSetNoColumnSchema"; - - - public const string QueryServiceExecutionPlanNotFound = "QueryServiceExecutionPlanNotFound"; - - - public const string PeekDefinitionAzureError = "PeekDefinitionAzureError"; - - - public const string PeekDefinitionError = "PeekDefinitionError"; - - - public const string PeekDefinitionNoResultsError = "PeekDefinitionNoResultsError"; - - - public const string PeekDefinitionDatabaseError = "PeekDefinitionDatabaseError"; - - - public const string PeekDefinitionNotConnectedError = "PeekDefinitionNotConnectedError"; - - - public const string PeekDefinitionTimedoutError = "PeekDefinitionTimedoutError"; - - - public const string PeekDefinitionTypeNotSupportedError = "PeekDefinitionTypeNotSupportedError"; - - - public const string ErrorEmptyStringReplacement = "ErrorEmptyStringReplacement"; - - - public const string WorkspaceServicePositionLineOutOfRange = "WorkspaceServicePositionLineOutOfRange"; - - - public const string WorkspaceServicePositionColumnOutOfRange = "WorkspaceServicePositionColumnOutOfRange"; - - - public const string WorkspaceServiceBufferPositionOutOfOrder = "WorkspaceServiceBufferPositionOutOfOrder"; - - - public const string EditDataSessionNotFound = "EditDataSessionNotFound"; - - - public const string EditDataUnsupportedObjectType = "EditDataUnsupportedObjectType"; - - - public const string EditDataQueryNotCompleted = "EditDataQueryNotCompleted"; - - - public const string EditDataQueryImproperResultSets = "EditDataQueryImproperResultSets"; - - - public const string EditDataFailedAddRow = "EditDataFailedAddRow"; - - - public const string EditDataRowOutOfRange = "EditDataRowOutOfRange"; - - - public const string EditDataUpdatePending = "EditDataUpdatePending"; - - - public const string EditDataUpdateNotPending = "EditDataUpdateNotPending"; - - - public const string EditDataColumnUpdateNotPending = "EditDataColumnUpdateNotPending"; - - - public const string EditDataObjectMetadataNotFound = "EditDataObjectMetadataNotFound"; - - - public const string EditDataInvalidFormatBinary = "EditDataInvalidFormatBinary"; - - - public const string EditDataInvalidFormatBoolean = "EditDataInvalidFormatBoolean"; - - - public const string EditDataCreateScriptMissingValue = "EditDataCreateScriptMissingValue"; - - - public const string EditDataDeleteSetCell = "EditDataDeleteSetCell"; - - - public const string EditDataColumnIdOutOfRange = "EditDataColumnIdOutOfRange"; - - - public const string EditDataColumnCannotBeEdited = "EditDataColumnCannotBeEdited"; - - - public const string EditDataColumnNoKeyColumns = "EditDataColumnNoKeyColumns"; - - - public const string EditDataScriptFilePathNull = "EditDataScriptFilePathNull"; - - - public const string EditDataCommitInProgress = "EditDataCommitInProgress"; - - - public const string EditDataComputedColumnPlaceholder = "EditDataComputedColumnPlaceholder"; - - - public const string EditDataInitializeInProgress = "EditDataInitializeInProgress"; - - - public const string EditDataTimeOver24Hrs = "EditDataTimeOver24Hrs"; - - - public const string EditDataNullNotAllowed = "EditDataNullNotAllowed"; - - - public const string EE_BatchSqlMessageNoProcedureInfo = "EE_BatchSqlMessageNoProcedureInfo"; - - - public const string EE_BatchSqlMessageWithProcedureInfo = "EE_BatchSqlMessageWithProcedureInfo"; - - - public const string EE_BatchSqlMessageNoLineInfo = "EE_BatchSqlMessageNoLineInfo"; - - - public const string EE_BatchError_Exception = "EE_BatchError_Exception"; - - - public const string EE_BatchExecutionInfo_RowsAffected = "EE_BatchExecutionInfo_RowsAffected"; - - - public const string EE_ExecutionNotYetCompleteError = "EE_ExecutionNotYetCompleteError"; - - - public const string EE_ScriptError_Error = "EE_ScriptError_Error"; - - - public const string EE_ScriptError_ParsingSyntax = "EE_ScriptError_ParsingSyntax"; - - - public const string EE_ScriptError_FatalError = "EE_ScriptError_FatalError"; - - - public const string EE_ExecutionInfo_FinalizingLoop = "EE_ExecutionInfo_FinalizingLoop"; - - - public const string EE_ExecutionInfo_QueryCancelledbyUser = "EE_ExecutionInfo_QueryCancelledbyUser"; - - - public const string EE_BatchExecutionError_Halting = "EE_BatchExecutionError_Halting"; - - - public const string EE_BatchExecutionError_Ignoring = "EE_BatchExecutionError_Ignoring"; - - - public const string EE_ExecutionInfo_InitilizingLoop = "EE_ExecutionInfo_InitilizingLoop"; - - - public const string EE_ExecutionError_CommandNotSupported = "EE_ExecutionError_CommandNotSupported"; - - - public const string EE_ExecutionError_VariableNotFound = "EE_ExecutionError_VariableNotFound"; - - - public const string BatchParserWrapperExecutionEngineError = "BatchParserWrapperExecutionEngineError"; - - - public const string BatchParserWrapperExecutionError = "BatchParserWrapperExecutionError"; - - - public const string BatchParserWrapperExecutionEngineBatchMessage = "BatchParserWrapperExecutionEngineBatchMessage"; - - - public const string BatchParserWrapperExecutionEngineBatchResultSetProcessing = "BatchParserWrapperExecutionEngineBatchResultSetProcessing"; - - - public const string BatchParserWrapperExecutionEngineBatchResultSetFinished = "BatchParserWrapperExecutionEngineBatchResultSetFinished"; - - - public const string BatchParserWrapperExecutionEngineBatchCancelling = "BatchParserWrapperExecutionEngineBatchCancelling"; - - - public const string EE_ScriptError_Warning = "EE_ScriptError_Warning"; - - - public const string TroubleshootingAssistanceMessage = "TroubleshootingAssistanceMessage"; - - - public const string BatchParser_CircularReference = "BatchParser_CircularReference"; - - - public const string BatchParser_CommentNotTerminated = "BatchParser_CommentNotTerminated"; - - - public const string BatchParser_StringNotTerminated = "BatchParser_StringNotTerminated"; - - - public const string BatchParser_IncorrectSyntax = "BatchParser_IncorrectSyntax"; - - - public const string BatchParser_VariableNotDefined = "BatchParser_VariableNotDefined"; - - - public const string TestLocalizationConstant = "TestLocalizationConstant"; - - - public const string SqlScriptFormatterDecimalMissingPrecision = "SqlScriptFormatterDecimalMissingPrecision"; - + + + public const string ConnectionServiceConnectErrorNullParams = "ConnectionServiceConnectErrorNullParams"; + + + public const string ConnectionServiceListDbErrorNullOwnerUri = "ConnectionServiceListDbErrorNullOwnerUri"; + + + public const string ConnectionServiceListDbErrorNotConnected = "ConnectionServiceListDbErrorNotConnected"; + + + public const string ConnectionServiceDbErrorDefaultNotConnected = "ConnectionServiceDbErrorDefaultNotConnected"; + + + public const string ConnectionServiceConnStringInvalidAuthType = "ConnectionServiceConnStringInvalidAuthType"; + + + public const string ConnectionServiceConnStringInvalidIntent = "ConnectionServiceConnStringInvalidIntent"; + + + public const string ConnectionServiceConnectionCanceled = "ConnectionServiceConnectionCanceled"; + + + public const string ConnectionParamsValidateNullOwnerUri = "ConnectionParamsValidateNullOwnerUri"; + + + public const string ConnectionParamsValidateNullConnection = "ConnectionParamsValidateNullConnection"; + + + public const string ConnectionParamsValidateNullServerName = "ConnectionParamsValidateNullServerName"; + + + public const string ConnectionParamsValidateNullSqlAuth = "ConnectionParamsValidateNullSqlAuth"; + + + public const string ErrorUnexpectedCodeObjectType = "ErrorUnexpectedCodeObjectType"; + + + public const string QueryServiceCancelAlreadyCompleted = "QueryServiceCancelAlreadyCompleted"; + + + public const string QueryServiceCancelDisposeFailed = "QueryServiceCancelDisposeFailed"; + + + public const string QueryServiceQueryCancelled = "QueryServiceQueryCancelled"; + + + public const string QueryServiceSubsetBatchNotCompleted = "QueryServiceSubsetBatchNotCompleted"; + + + public const string QueryServiceSubsetBatchOutOfRange = "QueryServiceSubsetBatchOutOfRange"; + + + public const string QueryServiceSubsetResultSetOutOfRange = "QueryServiceSubsetResultSetOutOfRange"; + + + public const string QueryServiceDataReaderByteCountInvalid = "QueryServiceDataReaderByteCountInvalid"; + + + public const string QueryServiceDataReaderCharCountInvalid = "QueryServiceDataReaderCharCountInvalid"; + + + public const string QueryServiceDataReaderXmlCountInvalid = "QueryServiceDataReaderXmlCountInvalid"; + + + public const string QueryServiceFileWrapperWriteOnly = "QueryServiceFileWrapperWriteOnly"; + + + public const string QueryServiceFileWrapperNotInitialized = "QueryServiceFileWrapperNotInitialized"; + + + public const string QueryServiceFileWrapperReadOnly = "QueryServiceFileWrapperReadOnly"; + + + public const string QueryServiceAffectedOneRow = "QueryServiceAffectedOneRow"; + + + public const string QueryServiceAffectedRows = "QueryServiceAffectedRows"; + + + public const string QueryServiceCompletedSuccessfully = "QueryServiceCompletedSuccessfully"; + + + public const string QueryServiceErrorFormat = "QueryServiceErrorFormat"; + + + public const string QueryServiceQueryFailed = "QueryServiceQueryFailed"; + + + public const string QueryServiceColumnNull = "QueryServiceColumnNull"; + + + public const string QueryServiceRequestsNoQuery = "QueryServiceRequestsNoQuery"; + + + public const string QueryServiceQueryInvalidOwnerUri = "QueryServiceQueryInvalidOwnerUri"; + + + public const string QueryServiceQueryInProgress = "QueryServiceQueryInProgress"; + + + public const string QueryServiceMessageSenderNotSql = "QueryServiceMessageSenderNotSql"; + + + public const string QueryServiceResultSetAddNoRows = "QueryServiceResultSetAddNoRows"; + + + public const string QueryServiceSaveAsResultSetNotComplete = "QueryServiceSaveAsResultSetNotComplete"; + + + public const string QueryServiceSaveAsMiscStartingError = "QueryServiceSaveAsMiscStartingError"; + + + public const string QueryServiceSaveAsInProgress = "QueryServiceSaveAsInProgress"; + + + public const string QueryServiceSaveAsFail = "QueryServiceSaveAsFail"; + + + public const string QueryServiceResultSetNotRead = "QueryServiceResultSetNotRead"; + + + public const string QueryServiceResultSetStartRowOutOfRange = "QueryServiceResultSetStartRowOutOfRange"; + + + public const string QueryServiceResultSetRowCountOutOfRange = "QueryServiceResultSetRowCountOutOfRange"; + + + public const string QueryServiceResultSetNoColumnSchema = "QueryServiceResultSetNoColumnSchema"; + + + public const string QueryServiceExecutionPlanNotFound = "QueryServiceExecutionPlanNotFound"; + + + public const string PeekDefinitionAzureError = "PeekDefinitionAzureError"; + + + public const string PeekDefinitionError = "PeekDefinitionError"; + + + public const string PeekDefinitionNoResultsError = "PeekDefinitionNoResultsError"; + + + public const string PeekDefinitionDatabaseError = "PeekDefinitionDatabaseError"; + + + public const string PeekDefinitionNotConnectedError = "PeekDefinitionNotConnectedError"; + + + public const string PeekDefinitionTimedoutError = "PeekDefinitionTimedoutError"; + + + public const string PeekDefinitionTypeNotSupportedError = "PeekDefinitionTypeNotSupportedError"; + + + public const string ErrorEmptyStringReplacement = "ErrorEmptyStringReplacement"; + + + public const string WorkspaceServicePositionLineOutOfRange = "WorkspaceServicePositionLineOutOfRange"; + + + public const string WorkspaceServicePositionColumnOutOfRange = "WorkspaceServicePositionColumnOutOfRange"; + + + public const string WorkspaceServiceBufferPositionOutOfOrder = "WorkspaceServiceBufferPositionOutOfOrder"; + + + public const string EditDataObjectNotFound = "EditDataObjectNotFound"; + + + public const string EditDataSessionNotFound = "EditDataSessionNotFound"; + + + public const string EditDataSessionAlreadyExists = "EditDataSessionAlreadyExists"; + + + public const string EditDataSessionNotInitialized = "EditDataSessionNotInitialized"; + + + public const string EditDataSessionAlreadyInitialized = "EditDataSessionAlreadyInitialized"; + + + public const string EditDataSessionAlreadyInitializing = "EditDataSessionAlreadyInitializing"; + + + public const string EditDataUnsupportedObjectType = "EditDataUnsupportedObjectType"; + + + public const string EditDataQueryFailed = "EditDataQueryFailed"; + + + public const string EditDataQueryNotCompleted = "EditDataQueryNotCompleted"; + + + public const string EditDataQueryImproperResultSets = "EditDataQueryImproperResultSets"; + + + public const string EditDataFailedAddRow = "EditDataFailedAddRow"; + + + public const string EditDataRowOutOfRange = "EditDataRowOutOfRange"; + + + public const string EditDataUpdatePending = "EditDataUpdatePending"; + + + public const string EditDataUpdateNotPending = "EditDataUpdateNotPending"; + + + public const string EditDataColumnUpdateNotPending = "EditDataColumnUpdateNotPending"; + + + public const string EditDataObjectMetadataNotFound = "EditDataObjectMetadataNotFound"; + + + public const string EditDataInvalidFormatBinary = "EditDataInvalidFormatBinary"; + + + public const string EditDataInvalidFormatBoolean = "EditDataInvalidFormatBoolean"; + + + public const string EditDataCreateScriptMissingValue = "EditDataCreateScriptMissingValue"; + + + public const string EditDataDeleteSetCell = "EditDataDeleteSetCell"; + + + public const string EditDataColumnIdOutOfRange = "EditDataColumnIdOutOfRange"; + + + public const string EditDataColumnCannotBeEdited = "EditDataColumnCannotBeEdited"; + + + public const string EditDataColumnNoKeyColumns = "EditDataColumnNoKeyColumns"; + + + public const string EditDataScriptFilePathNull = "EditDataScriptFilePathNull"; + + + public const string EditDataCommitInProgress = "EditDataCommitInProgress"; + + + public const string EditDataComputedColumnPlaceholder = "EditDataComputedColumnPlaceholder"; + + + public const string EditDataInitializeInProgress = "EditDataInitializeInProgress"; + + + public const string EditDataTimeOver24Hrs = "EditDataTimeOver24Hrs"; + + + public const string EditDataNullNotAllowed = "EditDataNullNotAllowed"; + + + public const string EE_BatchSqlMessageNoProcedureInfo = "EE_BatchSqlMessageNoProcedureInfo"; + + + public const string EE_BatchSqlMessageWithProcedureInfo = "EE_BatchSqlMessageWithProcedureInfo"; + + + public const string EE_BatchSqlMessageNoLineInfo = "EE_BatchSqlMessageNoLineInfo"; + + + public const string EE_BatchError_Exception = "EE_BatchError_Exception"; + + + public const string EE_BatchExecutionInfo_RowsAffected = "EE_BatchExecutionInfo_RowsAffected"; + + + public const string EE_ExecutionNotYetCompleteError = "EE_ExecutionNotYetCompleteError"; + + + public const string EE_ScriptError_Error = "EE_ScriptError_Error"; + + + public const string EE_ScriptError_ParsingSyntax = "EE_ScriptError_ParsingSyntax"; + + + public const string EE_ScriptError_FatalError = "EE_ScriptError_FatalError"; + + + public const string EE_ExecutionInfo_FinalizingLoop = "EE_ExecutionInfo_FinalizingLoop"; + + + public const string EE_ExecutionInfo_QueryCancelledbyUser = "EE_ExecutionInfo_QueryCancelledbyUser"; + + + public const string EE_BatchExecutionError_Halting = "EE_BatchExecutionError_Halting"; + + + public const string EE_BatchExecutionError_Ignoring = "EE_BatchExecutionError_Ignoring"; + + + public const string EE_ExecutionInfo_InitilizingLoop = "EE_ExecutionInfo_InitilizingLoop"; + + + public const string EE_ExecutionError_CommandNotSupported = "EE_ExecutionError_CommandNotSupported"; + + + public const string EE_ExecutionError_VariableNotFound = "EE_ExecutionError_VariableNotFound"; + + + public const string BatchParserWrapperExecutionEngineError = "BatchParserWrapperExecutionEngineError"; + + + public const string BatchParserWrapperExecutionError = "BatchParserWrapperExecutionError"; + + + public const string BatchParserWrapperExecutionEngineBatchMessage = "BatchParserWrapperExecutionEngineBatchMessage"; + + + public const string BatchParserWrapperExecutionEngineBatchResultSetProcessing = "BatchParserWrapperExecutionEngineBatchResultSetProcessing"; + + + public const string BatchParserWrapperExecutionEngineBatchResultSetFinished = "BatchParserWrapperExecutionEngineBatchResultSetFinished"; + + + public const string BatchParserWrapperExecutionEngineBatchCancelling = "BatchParserWrapperExecutionEngineBatchCancelling"; + + + public const string EE_ScriptError_Warning = "EE_ScriptError_Warning"; + + + public const string TroubleshootingAssistanceMessage = "TroubleshootingAssistanceMessage"; + + + public const string BatchParser_CircularReference = "BatchParser_CircularReference"; + + + public const string BatchParser_CommentNotTerminated = "BatchParser_CommentNotTerminated"; + + + public const string BatchParser_StringNotTerminated = "BatchParser_StringNotTerminated"; + + + public const string BatchParser_IncorrectSyntax = "BatchParser_IncorrectSyntax"; + + + public const string BatchParser_VariableNotDefined = "BatchParser_VariableNotDefined"; + + + public const string TestLocalizationConstant = "TestLocalizationConstant"; + + + public const string SqlScriptFormatterDecimalMissingPrecision = "SqlScriptFormatterDecimalMissingPrecision"; + private Keys() { } @@ -1213,31 +1279,31 @@ namespace Microsoft.SqlTools.ServiceLayer { return resourceManager.GetString(key, _culture); } - + public static string GetString(string key, object arg0) { return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0); } - + public static string GetString(string key, object arg0, object arg1) { return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0, arg1); } - + public static string GetString(string key, object arg0, object arg1, object arg2, object arg3) { return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0, arg1, arg2, arg3); } - + public static string GetString(string key, object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) { return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0, arg1, arg2, arg3, arg4, arg5); } - - } - } -} + + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.es.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.es.resx index 6def9f61..c8490030 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.es.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.es.resx @@ -1,18 +1,96 @@  + + + + + + + + + + + + + + + + + + + - + + @@ -27,106 +105,322 @@ -text/microsoft-resx1.3System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Los parámetros de conexión no pueden ser nulos - OwnerUri no puede ser nulo ni estar vacío - SpecifiedUri '{0}' no tiene una conexión existente - El valor '{0}' no es válido para AuthenticationType. Los valores válidos son 'Integrated' y 'SqlLogin'. - El valor '{0}' no es válido para ApplicationIntent. Los valores válidos son 'ReadWrite' y 'ReadOnly'. - Conexión cancelada - OwnerUri no puede ser nulo ni estar vacío - El objeto de detalles de conexión no puede ser nulo - ServerName no puede ser nulo ni estar vacío - {0} no puede ser nulo ni estar vacío cuando se utiliza autenticación SqlLogin - Ya se ha completado la consulta, no se puede cancelar - La consulta fue cancelada con éxito, pero no se ha podido desechar. No se encontró el URI del propietario. - Consulta cancelada por el usuario - El lote aún no ha finalizado, - Índice de lote no puede ser menor que 0 o mayor que el número de lotes - Índice del conjunto de resultados no puede ser menor que 0 o mayor que el número de conjuntos de resultados - El número máximo de bytes a devolver debe ser mayor que cero - El número máximo de caracteres a devolver debe ser mayor que cero - El número máximo de bytes XML a devolver debe ser mayor que cero - El método de acceso no puede ser de sólo escritura - FileStreamWrapper debe inicializarse antes de realizar operaciones - Este FileStreamWrapper no se puede utilizar para escritura. - (1 fila afectada) - ({0} filas afectadas) - Comandos finalizados correctamente. - Msg {0}, nivel {1} estado {2}, línea {3} {4} {5} - Error en la consulta: {0} - (Ningún nombre de columna) - La consulta solicitada no existe - Este editor no está conectado a una base de datos - Una consulta ya está en curso para esta sesión de editor. Por favor, cancelar esta consulta o esperar su finalización. - Remitente de eventos de OnInfoMessage debe ser un objeto SqlConnection - Lector no puede ser nulo - No se puede guardar el resultado hasta que haya finalizado la ejecución de la consulta - Error interno al iniciar el guardado de la tarea - Una operacion de guardado en la misma ruta se encuentra en curso - Error al guardar {0}: {1} - No se puede leer el subconjunto, a menos que los resultados se han leído desde el servidor - Fila de inicio no puede ser menor que 0 o mayor que el número de filas en el conjunto de resultados - La cantidad de filas debe ser un entero positivo - No se pudo recuperar el esquema de columna para el conjunto de resultados - No se pudo recuperar un plan de ejecución del conjunto de resultados - Esta característica actualmente no se admite en la base de datos de SQL Azure y almacén de datos: {0} - Se ha producido un error inesperado durante la ejecución de la definición de Peek: {0} - No se encontraron resultados. - No se pudo obtener ningún objeto asociado a la base de datos. - Conéctese a un servidor. - Tiempo de espera agotado para esta operación. - Esta característica no admite actualmente este tipo de objeto. - Posición está fuera del intervalo de la línea de archivo - Posición está fuera del intervalo de la columna de la línea {0} - Posición de inicio ({0}, {1}) debe preceder o ser igual a la posición final ({2}, {3}) - Msg {0}, {1}, nivel de estado {2}, línea {3} - Msj {0}, {1}, nivel de estado {2}, procedimiento {3}, línea {4} - Msg {0}, nivel {1}, {2} de estado - Se produjo un error al procesar el lote. Mensaje de error: {0} - ({0} filas afectadas) - La ejecución anterior aún no está completa. - Se ha producido un error de secuencias de comandos. - Se encontró sintaxis incorrecta mientras se estaba analizando {0}. - Se ha producido un error grave. - La ejecución completó {0} veces... - Se canceló la consulta. - Se produjo un error mientras se ejecutaba el lote. - Se produjo un error mientras se ejecutaba el lote, pero se ha omitido el error. - Iniciando bucle de ejecución de {0} veces... - No se admite el comando {0}. - La variable {0} no se encontró. - Error de ejecución de SQL: {0} - Ejecución de contenedor del analizador por lotes: {0} se encuentra... en la línea {1}: {2} Descripción: {3} - Lote analizador contenedor ejecución motor lote mensaje recibido: mensaje: {0} mensaje detallado: {1} - Motor de ejecución de analizador contenedor lote ResultSet procesamiento por lotes: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1} - Finalizó el elemento ResultSet analizador contenedor ejecución motor los lotes. - Cancelando la ejecución por lotes del contenedor del analizador por lotes. - Advertencia de scripting. - Para obtener más información acerca de este error, vea los temas de solución de problemas en la documentación del producto. - El archivo '{0}' se incluyó recursivamente. - Falta la marca de final de comentario ' * /'. - Sin comilla de cierre después de la cadena de caracteres. - Se encontró sintaxis incorrecta al analizar '{0}'. - La variable {0} no está definida. - prueba - No se puede convertir el SqlCodeObject del Tipo {0} al Tipo {1} - Sustitución de una cadena vacía por una cadena vacía. - Sesión de edición no existe, - La consulta no ha finalizado. - La consulta no generó un único set de resultados - Falló al agregar una nueva fila a la caché de actualización - El ID de la fila ingresado, se encuentra fuera del rango de filas de la caché de edición - Una actualización está pendiente para esta fila y debe de revertirse primero - El ID de la fila ingresado no tiene actualizaciones pendientes - La metadata de la tabla o vista no pudo ser encontrada - Formato inválido para columna binaria - Columnas del tipo boolean deben de ser numéricos 1 o 0, o tipo string true o false - Falta un valor requerido de la celda - Existe una eliminación pendiente para esta fila, una actualización de celda no puede ser realizada. - El ID de la columna debe de estar en el rango de columnas de la consulta. - La columna no puede ser editada - No se encontró ninguna columna clave - Proporcione un nombre de archivo de salida - Objeto de base de datos {0} no puede ser usado para modificación. - SpecifiedUri '{0}' no tiene alguna conexión por defecto - \ No newline at end of file + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Los parámetros de conexión no pueden ser nulos + + + OwnerUri no puede ser nulo ni estar vacío + + + SpecifiedUri '{0}' no tiene una conexión existente + + + El valor '{0}' no es válido para AuthenticationType. Los valores válidos son 'Integrated' y 'SqlLogin'. + + + El valor '{0}' no es válido para ApplicationIntent. Los valores válidos son 'ReadWrite' y 'ReadOnly'. + + + Conexión cancelada + + + OwnerUri no puede ser nulo ni estar vacío + + + El objeto de detalles de conexión no puede ser nulo + + + ServerName no puede ser nulo ni estar vacío + + + {0} no puede ser nulo ni estar vacío cuando se utiliza autenticación SqlLogin + + + Ya se ha completado la consulta, no se puede cancelar + + + La consulta fue cancelada con éxito, pero no se ha podido desechar. No se encontró el URI del propietario. + + + Consulta cancelada por el usuario + + + El lote aún no ha finalizado, + + + Índice de lote no puede ser menor que 0 o mayor que el número de lotes + + + Índice del conjunto de resultados no puede ser menor que 0 o mayor que el número de conjuntos de resultados + + + El número máximo de bytes a devolver debe ser mayor que cero + + + El número máximo de caracteres a devolver debe ser mayor que cero + + + El número máximo de bytes XML a devolver debe ser mayor que cero + + + El método de acceso no puede ser de sólo escritura + + + FileStreamWrapper debe inicializarse antes de realizar operaciones + + + Este FileStreamWrapper no se puede utilizar para escritura. + + + (1 fila afectada) + + + ({0} filas afectadas) + + + Comandos finalizados correctamente. + + + Msg {0}, nivel {1} estado {2}, línea {3} {4} {5} + + + Error en la consulta: {0} + + + (Ningún nombre de columna) + + + La consulta solicitada no existe + + + Este editor no está conectado a una base de datos + + + Una consulta ya está en curso para esta sesión de editor. Por favor, cancelar esta consulta o esperar su finalización. + + + Remitente de eventos de OnInfoMessage debe ser un objeto SqlConnection + + + Lector no puede ser nulo + + + No se puede guardar el resultado hasta que haya finalizado la ejecución de la consulta + + + Error interno al iniciar el guardado de la tarea + + + Una operacion de guardado en la misma ruta se encuentra en curso + + + Error al guardar {0}: {1} + + + No se puede leer el subconjunto, a menos que los resultados se han leído desde el servidor + + + Fila de inicio no puede ser menor que 0 o mayor que el número de filas en el conjunto de resultados + + + La cantidad de filas debe ser un entero positivo + + + No se pudo recuperar el esquema de columna para el conjunto de resultados + + + No se pudo recuperar un plan de ejecución del conjunto de resultados + + + Esta característica actualmente no se admite en la base de datos de SQL Azure y almacén de datos: {0} + + + Se ha producido un error inesperado durante la ejecución de la definición de Peek: {0} + + + No se encontraron resultados. + + + No se pudo obtener ningún objeto asociado a la base de datos. + + + Conéctese a un servidor. + + + Tiempo de espera agotado para esta operación. + + + Esta característica no admite actualmente este tipo de objeto. + + + Posición está fuera del intervalo de la línea de archivo + + + Posición está fuera del intervalo de la columna de la línea {0} + + + Posición de inicio ({0}, {1}) debe preceder o ser igual a la posición final ({2}, {3}) + + + Msg {0}, {1}, nivel de estado {2}, línea {3} + + + Msj {0}, {1}, nivel de estado {2}, procedimiento {3}, línea {4} + + + Msg {0}, nivel {1}, {2} de estado + + + Se produjo un error al procesar el lote. Mensaje de error: {0} + + + ({0} filas afectadas) + + + La ejecución anterior aún no está completa. + + + Se ha producido un error de secuencias de comandos. + + + Se encontró sintaxis incorrecta mientras se estaba analizando {0}. + + + Se ha producido un error grave. + + + La ejecución completó {0} veces... + + + Se canceló la consulta. + + + Se produjo un error mientras se ejecutaba el lote. + + + Se produjo un error mientras se ejecutaba el lote, pero se ha omitido el error. + + + Iniciando bucle de ejecución de {0} veces... + + + No se admite el comando {0}. + + + La variable {0} no se encontró. + + + Error de ejecución de SQL: {0} + + + Ejecución de contenedor del analizador por lotes: {0} se encuentra... en la línea {1}: {2} Descripción: {3} + + + Lote analizador contenedor ejecución motor lote mensaje recibido: mensaje: {0} mensaje detallado: {1} + + + Motor de ejecución de analizador contenedor lote ResultSet procesamiento por lotes: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1} + + + Finalizó el elemento ResultSet analizador contenedor ejecución motor los lotes. + + + Cancelando la ejecución por lotes del contenedor del analizador por lotes. + + + Advertencia de scripting. + + + Para obtener más información acerca de este error, vea los temas de solución de problemas en la documentación del producto. + + + El archivo '{0}' se incluyó recursivamente. + + + Falta la marca de final de comentario ' * /'. + + + Sin comilla de cierre después de la cadena de caracteres. + + + Se encontró sintaxis incorrecta al analizar '{0}'. + + + La variable {0} no está definida. + + + prueba + + + No se puede convertir el SqlCodeObject del Tipo {0} al Tipo {1} + + + Sustitución de una cadena vacía por una cadena vacía. + + + Sesión de edición no existe, + + + La consulta no ha finalizado. + + + La consulta no generó un único set de resultados + + + Falló al agregar una nueva fila a la caché de actualización + + + El ID de la fila ingresado, se encuentra fuera del rango de filas de la caché de edición + + + Una actualización está pendiente para esta fila y debe de revertirse primero + + + El ID de la fila ingresado no tiene actualizaciones pendientes + + + La metadata de la tabla o vista no pudo ser encontrada + + + Formato inválido para columna binaria + + + Columnas del tipo boolean deben de ser numéricos 1 o 0, o tipo string true o false + + + Falta un valor requerido de la celda + + + Existe una eliminación pendiente para esta fila, una actualización de celda no puede ser realizada. + + + El ID de la columna debe de estar en el rango de columnas de la consulta. + + + La columna no puede ser editada + + + No se encontró ninguna columna clave + + + Proporcione un nombre de archivo de salida + + + Objeto de base de datos {0} no puede ser usado para modificación. + + + SpecifiedUri '{0}' no tiene alguna conexión por defecto + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index fa5320ad..5768fa52 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -120,451 +120,475 @@ Connection parameters cannot be null - + OwnerUri cannot be null or empty - + SpecifiedUri '{0}' does not have existing connection . Parameters: 0 - uri (string) - + Specified URI '{0}' does not have a default connection . Parameters: 0 - uri (string) - + Invalid value '{0}' for AuthenticationType. Valid values are 'Integrated' and 'SqlLogin'. . Parameters: 0 - authType (string) - + Invalid value '{0}' for ApplicationIntent. Valid values are 'ReadWrite' and 'ReadOnly'. . Parameters: 0 - intent (string) - + Connection canceled - + OwnerUri cannot be null or empty - + Connection details object cannot be null - + ServerName cannot be null or empty - + {0} cannot be null or empty when using SqlLogin authentication . Parameters: 0 - component (string) - + Cannot convert SqlCodeObject Type {0} to Type {1} - + The query has already completed, it cannot be cancelled - + Query successfully cancelled, failed to dispose query. Owner URI not found. - + Query was canceled by user - + The batch has not completed, yet - + Batch index cannot be less than 0 or greater than the number of batches - + Result set index cannot be less than 0 or greater than the number of result sets - + Maximum number of bytes to return must be greater than zero - + Maximum number of chars to return must be greater than zero - + Maximum number of XML bytes to return must be greater than zero - + Access method cannot be write-only - + FileStreamWrapper must be initialized before performing operations - + This FileStreamWrapper cannot be used for writing - + (1 row affected) - + ({0} rows affected) . Parameters: 0 - rows (long) - + Commands completed successfully. - + Msg {0}, Level {1}, State {2}, Line {3}{4}{5} . Parameters: 0 - msg (int), 1 - lvl (int), 2 - state (int), 3 - line (int), 4 - newLine (string), 5 - message (string) - + Query failed: {0} . Parameters: 0 - message (string) - + (No column name) - + The requested query does not exist - + This editor is not connected to a database - + A query is already in progress for this editor session. Please cancel this query or wait for its completion. - + Sender for OnInfoMessage event must be a SqlConnection - + Cannot add row to result buffer, data reader does not contain rows - + Result cannot be saved until query execution has completed - + Internal error occurred while starting save task - + A save request to the same path is in progress - + Failed to save {0}: {1} . Parameters: 0 - fileName (string), 1 - message (string) - + Cannot read subset unless the results have been read from the server - + Start row cannot be less than 0 or greater than the number of rows in the result set - + Row count must be a positive integer - + Could not retrieve column schema for result set - + Could not retrieve an execution plan from the result set - + This feature is currently not supported on Azure SQL DB and Data Warehouse: {0} . Parameters: 0 - errorMessage (string) - + An unexpected error occurred during Peek Definition execution: {0} . Parameters: 0 - errorMessage (string) - + No results were found. - + No database object was retrieved. - + Please connect to a server. - + Operation timed out. - + This object type is currently not supported by this feature. - + Replacement of an empty string by an empty string. - + Position is outside of file line range - + Position is outside of column range for line {0} . Parameters: 0 - line (int) - + Start position ({0}, {1}) must come before or be equal to the end position ({2}, {3}) . Parameters: 0 - sLine (int), 1 - sCol (int), 2 - eLine (int), 3 - eCol (int) - + + + Table or view requested for edit could not be found + + Edit session does not exist. - + + + Edit session already exists. + + + + Edit session has not been initialized + + + + Edit session has already been initialized + + + + Edit session has already been initialized or is in the process of initializing + + Database object {0} cannot be used for editing. . Parameters: 0 - typeName (string) - + + + Query execution failed, see messages for details + + Query has not completed execution - + Query did not generate exactly one result set - + Failed to add new row to update cache - + Given row ID is outside the range of rows in the edit cache - + An update is already pending for this row and must be reverted first - + Given row ID does not have pending update - + Give column ID does not have pending update - + Table or view metadata could not be found - + Invalid format for binary column - + Allowed values for boolean columns are 0, 1, "true", or "false" - + A required cell value is missing - + A delete is pending for this row, a cell update cannot be applied. - + Column ID must be in the range of columns for the query - + Column cannot be edited - + No key columns were found - + An output filename must be provided - + A commit task is in progress. Please wait for completion. - + <TBD> - + Another edit data initialize is in progress for this owner URI. Please wait for completion. - + TIME column values must be between 00:00:00.0000000 and 23:59:59.9999999 - + NULL is not allowed for this column - + Msg {0}, Level {1}, State {2}, Line {3} - + Msg {0}, Level {1}, State {2}, Procedure {3}, Line {4} - + Msg {0}, Level {1}, State {2} - + An error occurred while the batch was being processed. The error message is: {0} - + ({0} row(s) affected) - + The previous execution is not yet complete. - + A scripting error occurred. - + Incorrect syntax was encountered while {0} was being parsed. - + A fatal error occurred. - + Execution completed {0} times... - + You cancelled the query. - + An error occurred while the batch was being executed. - + An error occurred while the batch was being executed, but the error has been ignored. - + Starting execution loop of {0} times... - + Command {0} is not supported. - + The variable {0} could not be found. - + SQL Execution error: {0} - + Batch parser wrapper execution: {0} found... at line {1}: {2} Description: {3} - + Batch parser wrapper execution engine batch message received: Message: {0} Detailed message: {1} - + Batch parser wrapper execution engine batch ResultSet processing: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1} - + Batch parser wrapper execution engine batch ResultSet finished. - + Canceling batch parser wrapper batch execution. - + Scripting warning. - + For more information about this error, see the troubleshooting topics in the product documentation. - + File '{0}' recursively included. - + Missing end comment mark '*/'. - + Unclosed quotation mark after the character string. - + Incorrect syntax was encountered while parsing '{0}'. - + Variable {0} is not defined. - + EN_LOCALIZATION - + Decimal column is missing numeric precision or numeric scale - - + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 62c4a461..8e7b7d6f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -164,10 +164,22 @@ WorkspaceServiceBufferPositionOutOfOrder(int sLine, int sCol, int eLine, int eCo ############################################################################ # Edit Data Service +EditDataObjectNotFound = Table or view requested for edit could not be found + EditDataSessionNotFound = Edit session does not exist. +EditDataSessionAlreadyExists = Edit session already exists. + +EditDataSessionNotInitialized = Edit session has not been initialized + +EditDataSessionAlreadyInitialized = Edit session has already been initialized + +EditDataSessionAlreadyInitializing = Edit session has already been initialized or is in the process of initializing + EditDataUnsupportedObjectType(string typeName) = Database object {0} cannot be used for editing. +EditDataQueryFailed = Query execution failed, see messages for details + EditDataQueryNotCompleted = Query has not completed execution EditDataQueryImproperResultSets = Query did not generate exactly one result set diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index 094eef5f..529bd088 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -561,6 +561,36 @@ NULL is not allowed for this column + + Table or view requested for edit could not be found + Table or view requested to edit could not be found + + + + Edit session already exists. + Edit session already exists. + + + + Edit session has not been initialized + Edit session has not been initialized + + + + Edit session has already been initialized + Edit session has already been initialized + + + + Edit session has already been initialized or is in the process of initializing + Edit session has already been initialized or is in the process of initializing + + + + Query execution failed, see messages for details + Query execution failed, see messages for details + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs index 0a03f618..cbc6af55 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs @@ -29,7 +29,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting AddSupportedType(DeclarationType.Synonym, GetSynonymScripts, "Synonym", ""); AddSupportedType(DeclarationType.ScalarValuedFunction, GetScalarValuedFunctionScripts, "Function", "scalar-valued function"); AddSupportedType(DeclarationType.TableValuedFunction, GetTableValuedFunctionScripts, "Function", "table-valued function"); - } + } /// /// Script a Table using SMO @@ -50,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableScripts : " + ex.Message); return null; } - } + } /// /// Script a View using SMO @@ -71,7 +71,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetViewScripts : " + ex.Message); return null; } - } + } /// /// Script a StoredProcedure using SMO @@ -92,7 +92,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetStoredProcedureScripts : " + ex.Message); return null; } - } + } /// /// Script a UserDefinedDataType using SMO @@ -113,7 +113,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedDataTypeScripts : " + ex.Message); return null; } - } + } /// /// Script a UserDefinedTableType using SMO @@ -134,7 +134,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetUserDefinedTableTypeScripts : " + ex.Message); return null; } - } + } /// /// Script a Synonym using SMO @@ -155,7 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetSynonymScripts : " + ex.Message); return null; } - } + } /// /// Script a ScalarValuedFunction using SMO @@ -176,7 +176,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetScalarValuedFunctionScripts : " + ex.Message); return null; } - } + } /// /// Script a TableValuedFunction using SMO @@ -197,7 +197,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting Logger.Write(LogLevel.Error,"Exception at PeekDefinition GetTableValuedFunctionScripts : " + ex.Message); return null; } - } + } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/Common.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/Common.cs index 85185efc..a02dffb8 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/Common.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/Common.cs @@ -7,13 +7,13 @@ using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.EditData; using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement; using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility; -using Microsoft.SqlTools.Utility; using Moq; namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData @@ -22,18 +22,49 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { public const string OwnerUri = "testFile"; - public static IEditTableMetadata GetStandardMetadata(DbColumn[] columns, bool allKeys = true, bool isMemoryOptimized = false) + public static async Task GetCustomSession(Query q, EditTableMetadata etm) { - // Create a Column Metadata Provider + // Mock metadata factory + Mock metaFactory = new Mock(); + metaFactory + .Setup(f => f.GetObjectMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(etm); + + EditSession session = new EditSession(metaFactory.Object, "tbl", "tbl"); + + EditSession.Connector connector = () => Task.FromResult(null); + EditSession.QueryRunner queryRunner = (s) => Task.FromResult(new EditSession.EditSessionQueryExecutionState(q)); + + session.Initialize(connector, queryRunner, () => Task.FromResult(0), (e) => Task.FromResult(0)); + await session.InitializeTask; + return session; + } + + public static EditTableMetadata GetStandardMetadata(DbColumn[] columns, bool isMemoryOptimized = false) + { + // Create column metadata providers var columnMetas = columns.Select((c, i) => - new EditColumnWrapper + { + var ecm = new EditColumnMetadata { - DbColumn = new DbColumnWrapper(c), EscapedName = c.ColumnName, - Ordinal = i, - IsKey = c.IsIdentity.HasTrue() - }).ToArray(); - return GetMetadataProvider(columnMetas, allKeys, isMemoryOptimized); + Ordinal = i + }; + return ecm; + }).ToArray(); + + // Create column wrappers + var columnWrappers = columns.Select(c => new DbColumnWrapper(c)).ToArray(); + + // Create the table metadata + EditTableMetadata editTableMetadata = new EditTableMetadata + { + Columns = columnMetas, + EscapedMultipartName = "tbl", + IsMemoryOptimized = isMemoryOptimized + }; + editTableMetadata.Extend(columnWrappers); + return editTableMetadata; } public static DbColumn[] GetColumns(bool includeIdentity) @@ -42,7 +73,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData if (includeIdentity) { - columns.Add(new TestDbColumn("id", true)); + columns.Add(new TestDbColumn("id") {IsKey = true, IsIdentity = true, IsAutoIncrement = true}); } for (int i = 0; i < 3; i++) @@ -52,7 +83,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData return columns.ToArray(); } - public static ResultSet GetResultSet(DbColumn[] columns, bool includeIdentity, int rowCount = 1) + public static async Task GetQuery(DbColumn[] columns, bool includIdentity, int rowCount = 1) + { + Query q = QueryExecution.Common.GetBasicExecutedQuery(); + q.Batches[0].ResultSets[0] = await GetResultSet(columns, includIdentity, rowCount); + return q; + } + + public static async Task GetResultSet(DbColumn[] columns, bool includeIdentity, int rowCount = 1) { IEnumerable rows = includeIdentity ? Enumerable.Repeat(new object[] { "id", "1", "2", "3" }, rowCount) @@ -60,7 +98,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData var testResultSet = new TestResultSet(columns, rows); var reader = new TestDbDataReader(new[] { testResultSet }); var resultSet = new ResultSet(0, 0, MemoryFileSystem.GetFileStreamFactory()); - resultSet.ReadResultToEnd(reader, CancellationToken.None).Wait(); + await resultSet.ReadResultToEnd(reader, CancellationToken.None); return resultSet; } @@ -82,26 +120,5 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData rc.SetCell(i, "123"); } } - - public static IEditTableMetadata GetMetadataProvider(EditColumnWrapper[] columnMetas, bool allKeys = false, bool isMemoryOptimized = false) - { - // Create a table metadata provider - var tableMetaMock = new Mock(); - if (allKeys) - { - // All columns should be returned as "keys" - tableMetaMock.Setup(m => m.KeyColumns).Returns(columnMetas); - } - else - { - // All identity columns should be returned as keys - tableMetaMock.Setup(m => m.KeyColumns).Returns(columnMetas.Where(c => c.DbColumn.IsIdentity.HasTrue()).ToList()); - } - tableMetaMock.Setup(m => m.Columns).Returns(columnMetas); - tableMetaMock.Setup(m => m.IsMemoryOptimized).Returns(isMemoryOptimized); - tableMetaMock.Setup(m => m.EscapedMultipartName).Returns("tbl"); - - return tableMetaMock.Object; - } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowCreateTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowCreateTests.cs index 4c49121b..1c786cf8 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowCreateTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowCreateTests.cs @@ -22,13 +22,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData public class RowCreateTests { [Fact] - public void RowCreateConstruction() + public async Task RowCreateConstruction() { // Setup: Create the values to store const long rowId = 100; DbColumn[] columns = Common.GetColumns(false); - ResultSet rs = Common.GetResultSet(columns, false); - IEditTableMetadata etm = Common.GetStandardMetadata(columns); + ResultSet rs = await Common.GetResultSet(columns, false); + EditTableMetadata etm = Common.GetStandardMetadata(columns); // If: I create a RowCreate instance RowCreate rc = new RowCreate(rowId, rs, etm); @@ -42,13 +42,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [InlineData(true)] [InlineData(false)] - public void GetScript(bool includeIdentity) + public async Task GetScript(bool includeIdentity) { // Setup: Generate the parameters for the row create const long rowId = 100; DbColumn[] columns = Common.GetColumns(includeIdentity); - ResultSet rs = Common.GetResultSet(columns, includeIdentity); - IEditTableMetadata etm = Common.GetStandardMetadata(columns); + ResultSet rs = await Common.GetResultSet(columns, includeIdentity); + EditTableMetadata etm = Common.GetStandardMetadata(columns); // If: I ask for a script to be generated without an identity column RowCreate rc = new RowCreate(rowId, rs, etm); @@ -74,10 +74,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetScriptMissingCell() + public async Task GetScriptMissingCell() { // Setup: Generate the parameters for the row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I ask for a script to be generated without setting any values // Then: An exception should be thrown for missing cells @@ -93,8 +93,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // ... Generate the parameters for the row create const long rowId = 100; DbColumn[] columns = Common.GetColumns(includeIdentity); - ResultSet rs = Common.GetResultSet(columns, includeIdentity); - IEditTableMetadata etm = Common.GetStandardMetadata(columns); + ResultSet rs = await Common.GetResultSet(columns, includeIdentity); + EditTableMetadata etm = Common.GetStandardMetadata(columns); // ... Setup a db reader for the result of an insert var newRowReader = Common.GetNewRowDataReader(columns, includeIdentity); @@ -110,13 +110,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [InlineData(true)] [InlineData(false)] - public void GetCommand(bool includeIdentity) + public async Task GetCommand(bool includeIdentity) { // Setup: // ... Create a row create with cell updates const long rowId = 100; var columns = Common.GetColumns(includeIdentity); - var rs = Common.GetResultSet(columns, includeIdentity); + var rs = await Common.GetResultSet(columns, includeIdentity); var etm = Common.GetStandardMetadata(columns); RowCreate rc = new RowCreate(rowId, rs, etm); Common.AddCells(rc, includeIdentity); @@ -159,10 +159,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetCommandNullConnection() + public async Task GetCommandNullConnection() { // Setup: Create a row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I attempt to create a command with a null connection @@ -171,10 +171,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetCommandMissingCell() + public async Task GetCommandMissingCell() { // Setup: Generate the parameters for the row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); var mockConn = new TestSqlConnection(null); // If: I ask for a script to be generated without setting any values @@ -183,10 +183,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditRowNoAdditions() + public async Task GetEditRowNoAdditions() { // Setup: Generate a standard row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I request an edit row from the row create EditRow er = rc.GetEditRow(null); @@ -209,10 +209,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditRowWithAdditions() + public async Task GetEditRowWithAdditions() { // Setp: Generate a row create with a cell added to it - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); rc.SetCell(0, "foo"); // If: I request an edit row from the row create @@ -244,20 +244,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [InlineData(-1)] // Negative [InlineData(3)] // At edge of acceptable values [InlineData(100)] // Way too large value - public void SetCellOutOfRange(int columnId) + public async Task SetCellOutOfRange(int columnId) { // Setup: Generate a row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I attempt to set a cell on a column that is out of range, I should get an exception Assert.Throws(() => rc.SetCell(columnId, string.Empty)); } [Fact] - public void SetCellNoChange() + public async Task SetCellNoChange() { // Setup: Generate a row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I set a cell in the newly created row to something that doesn't need changing EditUpdateCellResult eucr = rc.SetCell(0, "1"); @@ -278,16 +278,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SetCellHasCorrections() + public async Task SetCellHasCorrections() { // Setup: // ... Generate a result set with a single binary column - DbColumn[] cols = {new TestDbColumn("bin", "binary", typeof(byte[]))}; + DbColumn[] cols = {new TestDbColumn + { + DataType = typeof(byte[]), + DataTypeName = "binary" + }}; object[][] rows = {}; var testResultSet = new TestResultSet(cols, rows); var testReader = new TestDbDataReader(new[] {testResultSet}); var rs = new ResultSet(0, 0, MemoryFileSystem.GetFileStreamFactory()); - rs.ReadResultToEnd(testReader, CancellationToken.None).Wait(); + await rs.ReadResultToEnd(testReader, CancellationToken.None); // ... Generate the metadata var etm = Common.GetStandardMetadata(cols); @@ -314,10 +318,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SetCellNull() + public async Task SetCellNull() { // Setup: Generate a row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I set a cell in the newly created row to null EditUpdateCellResult eucr = rc.SetCell(0, "NULL"); @@ -341,10 +345,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [InlineData(-1)] // Negative [InlineData(3)] // At edge of acceptable values [InlineData(100)] // Way too large value - public void RevertCellOutOfRange(int columnId) + public async Task RevertCellOutOfRange(int columnId) { // Setup: Generate the row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I attempt to revert a cell that is out of range // Then: I should get an exception @@ -352,10 +356,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void RevertCellNotSet() + public async Task RevertCellNotSet() { // Setup: Generate the row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); // If: I attempt to revert a cell that has not been set string result = rc.RevertCell(0); @@ -369,10 +373,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void RevertCellThatWasSet() + public async Task RevertCellThatWasSet() { // Setup: Generate the row create - RowCreate rc = GetStandardRowCreate(); + RowCreate rc = await GetStandardRowCreate(); rc.SetCell(0, "1"); // If: I attempt to revert a cell that was set @@ -386,10 +390,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData Assert.Null(rc.newCells[0]); } - private static RowCreate GetStandardRowCreate() + private static async Task GetStandardRowCreate() { var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false); + var rs = await Common.GetResultSet(cols, false); var etm = Common.GetStandardMetadata(cols); return new RowCreate(100, rs, etm); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowDeleteTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowDeleteTests.cs index 941e14ed..8ed1dd2b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowDeleteTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowDeleteTests.cs @@ -21,12 +21,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData public class RowDeleteTests { [Fact] - public void RowDeleteConstruction() + public async Task RowDeleteConstruction() { // Setup: Create the values to store DbColumn[] columns = Common.GetColumns(true); - ResultSet rs = Common.GetResultSet(columns, true); - IEditTableMetadata etm = Common.GetStandardMetadata(columns, false); + ResultSet rs = await Common.GetResultSet(columns, true); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); // If: I create a RowCreate instance RowDelete rc = new RowDelete(100, rs, etm); @@ -40,11 +40,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [InlineData(true)] [InlineData(false)] - public void GetScriptTest(bool isMemoryOptimized) + public async Task GetScriptTest(bool isMemoryOptimized) { DbColumn[] columns = Common.GetColumns(true); - ResultSet rs = Common.GetResultSet(columns, true); - IEditTableMetadata etm = Common.GetStandardMetadata(columns, false, isMemoryOptimized); + ResultSet rs = await Common.GetResultSet(columns, true); + EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized); // If: I ask for a script to be generated for delete RowDelete rd = new RowDelete(0, rs, etm); @@ -68,7 +68,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Generate the parameters for the row delete object var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); // If: I ask for the change to be applied @@ -84,13 +84,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [InlineData(false, true)] [InlineData(true, false)] [InlineData(false, false)] - public void GetCommand(bool includeIdentity, bool isMemoryOptimized) + public async Task GetCommand(bool includeIdentity, bool isMemoryOptimized) { // Setup: // ... Create a row delete var columns = Common.GetColumns(includeIdentity); - var rs = Common.GetResultSet(columns, includeIdentity); - var etm = Common.GetStandardMetadata(columns, !includeIdentity, isMemoryOptimized); + var rs = await Common.GetResultSet(columns, includeIdentity); + var etm = Common.GetStandardMetadata(columns, isMemoryOptimized); RowDelete rd = new RowDelete(0, rs, etm); // ... Mock db connection for building the command @@ -128,10 +128,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetCommandNullConnection() + public async Task GetCommandNullConnection() { // Setup: Create a row delete - RowDelete rd = GetStandardRowDelete(); + RowDelete rd = await GetStandardRowDelete(); // If: I attempt to create a command with a null connection // Then: It should throw an exception @@ -139,11 +139,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditRow() + public async Task GetEditRow() { // Setup: Create a row delete var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); RowDelete rd = new RowDelete(0, rs, etm); @@ -173,10 +173,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditNullRow() + public async Task GetEditNullRow() { // Setup: Create a row delete - RowDelete rd = GetStandardRowDelete(); + RowDelete rd = await GetStandardRowDelete(); // If: I attempt to get an edit row with a null cached row // Then: I should get an exception @@ -184,10 +184,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SetCell() + public async Task SetCell() { // Setup: Create a row delete - RowDelete rd = GetStandardRowDelete(); + RowDelete rd = await GetStandardRowDelete(); // If: I set a cell on a delete row edit // Then: It should throw as invalid operation @@ -195,20 +195,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void RevertCell() + public async Task RevertCell() { // Setup: Create a row delete - RowDelete rd = GetStandardRowDelete(); + RowDelete rd = await GetStandardRowDelete(); // If: I revert a cell on a delete row edit // Then: It should throw Assert.Throws(() => rd.RevertCell(0)); } - private RowDelete GetStandardRowDelete() + private async Task GetStandardRowDelete() { var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false); + var rs = await Common.GetResultSet(cols, false); var etm = Common.GetStandardMetadata(cols); return new RowDelete(0, rs, etm); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowEditBaseTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowEditBaseTests.cs index 1da82c9c..eccc5085 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowEditBaseTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowEditBaseTests.cs @@ -25,12 +25,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { [Theory] [InlineData(-1)] // Negative index + [InlineData(2)] // Equal to count of columns [InlineData(100)] // Index larger than number of columns - public void ValidateUpdatableColumnOutOfRange(int columnId) + public async Task ValidateUpdatableColumnOutOfRange(int columnId) { // Setup: Create a result set - ResultSet rs = GetResultSet( - new DbColumn[] { new TestDbColumn("id", true), new TestDbColumn("col1")}, + ResultSet rs = await GetResultSet( + new DbColumn[] { + new TestDbColumn("id") {IsKey = true, IsAutoIncrement = true, IsIdentity = true}, + new TestDbColumn("col1") + }, new object[] { "id", "1" }); // If: I validate a column ID that is out of range @@ -40,11 +44,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void ValidateUpdatableColumnNotUpdatable() + public async Task ValidateUpdatableColumnNotUpdatable() { // Setup: Create a result set with an identity column - ResultSet rs = GetResultSet( - new DbColumn[] { new TestDbColumn("id", true), new TestDbColumn("col1") }, + ResultSet rs = await GetResultSet( + new DbColumn[] { + new TestDbColumn("id") {IsKey = true, IsAutoIncrement = true, IsIdentity = true}, + new TestDbColumn("col1") + }, new object[] { "id", "1" }); // If: I validate a column ID that is not updatable @@ -55,12 +62,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [MemberData(nameof(GetWhereClauseIsNotNullData))] - public void GetWhereClauseSimple(DbColumn col, object val, string nullClause) + public async Task GetWhereClauseSimple(DbColumn col, object val, string nullClause) { // Setup: Create a result set and metadata provider with a single column var cols = new[] {col}; - ResultSet rs = GetResultSet(cols, new[] {val}); - IEditTableMetadata etm = Common.GetStandardMetadata(cols); + ResultSet rs = await GetResultSet(cols, new[] {val}); + EditTableMetadata etm = Common.GetStandardMetadata(cols); RowEditTester rt = new RowEditTester(rs, etm); rt.ValidateWhereClauseSingleKey(nullClause); @@ -71,42 +78,69 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData get { yield return new object[] {new TestDbColumn("col"), DBNull.Value, "IS NULL"}; - yield return new object[] {new TestDbColumn("col", "VARBINARY", typeof(byte[])), new byte[5], "IS NOT NULL"}; - yield return new object[] {new TestDbColumn("col", "TEXT", typeof(string)), "abc", "IS NOT NULL"}; - yield return new object[] {new TestDbColumn("col", "NTEXT", typeof(string)), "abc", "IS NOT NULL"}; + yield return new object[] { + new TestDbColumn + { + DataTypeName = "BINARY", + DataType = typeof(byte[]) + }, + new byte[5], + "IS NOT NULL" + }; + yield return new object[] + { + new TestDbColumn + { + DataType = typeof(string), + DataTypeName = "TEXT" + }, + "abc", + "IS NOT NULL" + }; + yield return new object[] + { + new TestDbColumn + { + DataType = typeof(string), + DataTypeName = "NTEXT", + + }, + "abc", + "IS NOT NULL" + }; } } [Fact] - public void GetWhereClauseMultipleKeyColumns() + public async Task GetWhereClauseMultipleKeyColumns() { // Setup: Create a result set and metadata provider with multiple key columns DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")}; - ResultSet rs = GetResultSet(cols, new object[] {"abc", "def"}); - IEditTableMetadata etm = Common.GetStandardMetadata(cols); + ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"}); + EditTableMetadata etm = Common.GetStandardMetadata(cols); RowEditTester rt = new RowEditTester(rs, etm); rt.ValidateWhereClauseMultipleKeys(); } [Fact] - public void GetWhereClauseNoKeyColumns() + public async Task GetWhereClauseNoKeyColumns() { // Setup: Create a result set and metadata provider with no key columns DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")}; - ResultSet rs = GetResultSet(cols, new object[] {"abc", "def"}); - IEditTableMetadata etm = Common.GetStandardMetadata(new DbColumn[] {}); + ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"}); + EditTableMetadata etm = Common.GetStandardMetadata(new DbColumn[] {}); RowEditTester rt = new RowEditTester(rs, etm); rt.ValidateWhereClauseNoKeys(); } [Fact] - public void SortingByTypeTest() + public async Task SortingByTypeTest() { // Setup: Create a result set and metadata we can reuse var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false); + var rs = await Common.GetResultSet(cols, false); var etm = Common.GetStandardMetadata(cols); // If: I request to sort a list of the three different edit operations @@ -124,11 +158,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SortingUpdatesByRowIdTest() + public async Task SortingUpdatesByRowIdTest() { // Setup: Create a result set and metadata we can reuse var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false, 4); + var rs = await Common.GetResultSet(cols, false, 4); var etm = Common.GetStandardMetadata(cols); // If: I sort 3 edit operations of the same type @@ -147,11 +181,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SortingCreatesByRowIdTest() + public async Task SortingCreatesByRowIdTest() { // Setup: Create a result set and metadata we can reuse var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false); + var rs = await Common.GetResultSet(cols, false); var etm = Common.GetStandardMetadata(cols); // If: I sort 3 edit operations of the same type @@ -170,11 +204,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SortingDeletesByRowIdTest() + public async Task SortingDeletesByRowIdTest() { // Setup: Create a result set and metadata we can reuse var cols = Common.GetColumns(false); - var rs = Common.GetResultSet(cols, false); + var rs = await Common.GetResultSet(cols, false); var etm = Common.GetStandardMetadata(cols); // If: I sort 3 delete operations of the same type @@ -192,19 +226,19 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData Assert.Equal(1, rowEdits[2].RowId); } - private static ResultSet GetResultSet(DbColumn[] columns, object[] row) + private static async Task GetResultSet(DbColumn[] columns, object[] row) { object[][] rows = {row}; var testResultSet = new TestResultSet(columns, rows); var testReader = new TestDbDataReader(new [] {testResultSet}); var resultSet = new ResultSet(0,0, MemoryFileSystem.GetFileStreamFactory()); - resultSet.ReadResultToEnd(testReader, CancellationToken.None).Wait(); + await resultSet.ReadResultToEnd(testReader, CancellationToken.None); return resultSet; } private class RowEditTester : RowEditBase { - public RowEditTester(ResultSet rs, IEditTableMetadata meta) : base(0, rs, meta) { } + public RowEditTester(ResultSet rs, EditTableMetadata meta) : base(0, rs, meta) { } public void ValidateColumn(int columnId) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowUpdateTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowUpdateTests.cs index 5a0ed1c2..dad02c20 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowUpdateTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/RowUpdateTests.cs @@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Setup: Create the values to store const long rowId = 0; ResultSet rs = QueryExecution.Common.GetBasicExecutedBatch().ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); // If: I create a RowUpdate instance RowUpdate rc = new RowUpdate(rowId, rs, etm); @@ -40,10 +40,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SetCell() + public async Task SetCell() { // Setup: Create a row update - RowUpdate ru = GetStandardRowUpdate(); + RowUpdate ru = await GetStandardRowUpdate(); // If: I set a cell that can be updated EditUpdateCellResult eucr = ru.SetCell(0, "col1"); @@ -69,7 +69,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Generate a result set with a single binary column - DbColumn[] cols = { new TestDbColumn("bin", "binary", typeof(byte[])) }; + DbColumn[] cols = + { + new TestDbColumn + { + DataType = typeof(byte[]), + DataTypeName = "binary" + } + }; object[][] rows = { new object[]{new byte[] {0x00}}}; var testResultSet = new TestResultSet(cols, rows); var testReader = new TestDbDataReader(new[] { testResultSet }); @@ -102,12 +109,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void SetCellImplicitRevertTest() + public async Task SetCellImplicitRevertTest() { // Setup: Create a fake table to update DbColumn[] columns = Common.GetColumns(true); - ResultSet rs = Common.GetResultSet(columns, true); - IEditTableMetadata etm = Common.GetStandardMetadata(columns); + ResultSet rs = await Common.GetResultSet(columns, true); + EditTableMetadata etm = Common.GetStandardMetadata(columns); // If: // ... I add updates to all the cells in the row @@ -139,12 +146,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [InlineData(true)] [InlineData(false)] - public void GetScriptTest(bool isMemoryOptimized) + public async Task GetScriptTest(bool isMemoryOptimized) { // Setup: Create a fake table to update DbColumn[] columns = Common.GetColumns(true); - ResultSet rs = Common.GetResultSet(columns, true); - IEditTableMetadata etm = Common.GetStandardMetadata(columns, false, isMemoryOptimized); + ResultSet rs = await Common.GetResultSet(columns, true); + EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized); // If: I ask for a script to be generated for update RowUpdate ru = new RowUpdate(0, rs, etm); @@ -177,13 +184,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [InlineData(true, false)] [InlineData(false, true)] [InlineData(false, false)] - public void GetCommand(bool includeIdentity, bool isMemoryOptimized) + public async Task GetCommand(bool includeIdentity, bool isMemoryOptimized) { // Setup: // ... Create a row update with cell updates var columns = Common.GetColumns(includeIdentity); - var rs = Common.GetResultSet(columns, includeIdentity); - var etm = Common.GetStandardMetadata(columns, !includeIdentity, isMemoryOptimized); + var rs = await Common.GetResultSet(columns, includeIdentity); + var etm = Common.GetStandardMetadata(columns, isMemoryOptimized); RowUpdate ru = new RowUpdate(0, rs, etm); Common.AddCells(ru, includeIdentity); @@ -231,10 +238,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetCommandNullConnection() + public async Task GetCommandNullConnection() { // Setup: Create a row update - RowUpdate ru = GetStandardRowUpdate(); + RowUpdate ru = await GetStandardRowUpdate(); // If: I attempt to create a command with a null connection // Then: It should throw an exception @@ -242,11 +249,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditRow() + public async Task GetEditRow() { // Setup: Create a row update with a cell set var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); ru.SetCell(0, "foo"); @@ -282,10 +289,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void GetEditNullRow() + public async Task GetEditNullRow() { // Setup: Create a row update - RowUpdate ru = GetStandardRowUpdate(); + RowUpdate ru = await GetStandardRowUpdate(); // If: I attempt to get an edit row with a null cached row // Then: I should get an exception @@ -300,8 +307,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Setup: // ... Create a row update (no cell updates needed) var columns = Common.GetColumns(includeIdentity); - var rs = Common.GetResultSet(columns, includeIdentity); - var etm = Common.GetStandardMetadata(columns, !includeIdentity); + var rs = await Common.GetResultSet(columns, includeIdentity); + var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); long oldBytesWritten = rs.totalBytesWritten; @@ -323,8 +330,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Setup: // ... Create a row update (no cell updates needed) var columns = Common.GetColumns(true); - var rs = Common.GetResultSet(columns, true); - var etm = Common.GetStandardMetadata(columns, false); + var rs = await Common.GetResultSet(columns, true); + var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); // If: I ask for the changes to be applied with a null db reader @@ -336,12 +343,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [InlineData(-1)] // Negative [InlineData(3)] // At edge of acceptable values [InlineData(100)] // Way too large value - public void RevertCellOutOfRange(int columnId) + public async Task RevertCellOutOfRange(int columnId) { // Setup: // ... Create a row update (no cell updates needed) var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); @@ -351,12 +358,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void RevertCellNotSet() + public async Task RevertCellNotSet() { // Setup: // ... Create a row update (no cell updates needed) var columns = Common.GetColumns(true); - var rs = Common.GetResultSet(columns, true); + var rs = await Common.GetResultSet(columns, true); var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); @@ -371,12 +378,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void RevertCellThatWasSet() + public async Task RevertCellThatWasSet() { // Setup: // ... Create a row update var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); RowUpdate ru = new RowUpdate(0, rs, etm); ru.SetCell(0, "1"); @@ -392,10 +399,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData Assert.DoesNotContain(0, ru.cellUpdates.Keys); } - private RowUpdate GetStandardRowUpdate() + private async Task GetStandardRowUpdate() { var columns = Common.GetColumns(false); - var rs = Common.GetResultSet(columns, false); + var rs = await Common.GetResultSet(columns, false); var etm = Common.GetStandardMetadata(columns); return new RowUpdate(0, rs, etm); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/ServiceIntegrationTests.cs index e83221ba..1307df3e 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/ServiceIntegrationTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/ServiceIntegrationTests.cs @@ -50,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Setup: // ... Create an edit data service with a session var eds = new EditDataService(null, null, null); - eds.ActiveSessions[Common.OwnerUri] = GetDefaultSession(); + eds.ActiveSessions[Common.OwnerUri] = await GetDefaultSession(); // ... Create a session param that returns the common owner uri var mockParams = new EditCreateRowParams { OwnerUri = Common.OwnerUri }; @@ -94,7 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Create an edit data service with a session var eds = new EditDataService(null, null, null); - eds.ActiveSessions[Common.OwnerUri] = GetDefaultSession(); + eds.ActiveSessions[Common.OwnerUri] = await GetDefaultSession(); // If: I ask to dispose of an existing session var efv = new EventFlowValidator() @@ -117,7 +117,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Create an edit data service with a session var eds = new EditDataService(null, null, null); - eds.ActiveSessions[Constants.OwnerUri] = GetDefaultSession(); + eds.ActiveSessions[Constants.OwnerUri] = await GetDefaultSession(); // If: I validly ask to delete a row var efv = new EventFlowValidator() @@ -139,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Create an edit data service with a session var eds = new EditDataService(null, null, null); - eds.ActiveSessions[Constants.OwnerUri] = GetDefaultSession(); + eds.ActiveSessions[Constants.OwnerUri] = await GetDefaultSession(); // If: I ask to create a row from a non existant session var efv = new EventFlowValidator() @@ -161,7 +161,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Create an edit data service with a session that has an pending edit var eds = new EditDataService(null, null, null); - var session = GetDefaultSession(); + var session = await GetDefaultSession(); session.EditCache[0] = new Mock().Object; eds.ActiveSessions[Constants.OwnerUri] = session; @@ -185,7 +185,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: Create an edit data service with a session var eds = new EditDataService(null, null, null); - var session = GetDefaultSession(); + var session = await GetDefaultSession(); eds.ActiveSessions[Constants.OwnerUri] = session; var edit = new Mock(); edit.Setup(e => e.SetCell(It.IsAny(), It.IsAny())).Returns(new EditUpdateCellResult @@ -223,7 +223,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Setup: Create an edit data service with a session // Setup: Create an edit data service with a session var eds = new EditDataService(null, null, null); - var session = GetDefaultSession(); + var session = await GetDefaultSession(); eds.ActiveSessions[Constants.OwnerUri] = session; // If: I validly ask for rows @@ -277,119 +277,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // ... There should not be a session Assert.Empty(eds.ActiveSessions); - - // ... There should not be a wait handler - Assert.Empty(eds.InitializeWaitHandles); } - [Fact] - public async Task InitializeInProgress() - { - // Setup: Create an edit data service with an "in-progress initialize" - var eds = new EditDataService(null, null, null); - eds.InitializeWaitHandles[Common.OwnerUri] = new TaskCompletionSource(); - - // If: - // ... I ask to initialize a session when an initialize task is already in progress - var initParams = new EditInitializeParams - { - ObjectName = "table", - OwnerUri = Common.OwnerUri, - ObjectType = "table" - }; - var efv = new EventFlowValidator() - .AddErrorValidation(Assert.NotNull) - .Complete(); - await eds.HandleInitializeRequest(initParams, efv.Object); - - // Then: - // ... An error event should have been raised - efv.Validate(); - - // ... There should not be a session - Assert.Empty(eds.ActiveSessions); - } - - [Fact] - public async Task InitializeQueryCreateFailed() - { - // Setup: - // ... Create a query execution service that will throw on creation of the query - var qes = QueryExecution.Common.GetPrimedExecutionService(null, false, false, null); - - // ... Create an edit data service that uses the mocked up query service - var eds = new EditDataService(qes, null, null); - - // If: - // ... I initialize a session - var initParams = new EditInitializeParams - { - ObjectName = "table", - OwnerUri = Common.OwnerUri, - ObjectType = "table" - }; - var efv = new EventFlowValidator() - .AddErrorValidation(Assert.NotEmpty) - .Complete(); - await eds.HandleInitializeRequest(initParams, efv.Object); - - // Then: - // ... We should have gotten an error back - efv.Validate(); - - // ... There should not be any sessions created - Assert.Empty(eds.ActiveSessions); - - // ... There should not be a wait handle - Assert.Empty(eds.InitializeWaitHandles); - } - - [Fact] - public async Task InitializeQueryExecutionFails() - { - // Setup: - // ... Create a query execution service that will throw on execution of the query - var qes = QueryExecution.Common.GetPrimedExecutionService(null, true, true, null); - - // ... Create an edit data service that uses the mocked up query service - var eds = new EditDataService(qes, null, null); - - // If: - // ... I initialize a session - var initParams = new EditInitializeParams - { - ObjectName = "table", - OwnerUri = Common.OwnerUri, - ObjectType = "table" - }; - var efv = new EventFlowValidator() - .AddResultValidation(Assert.NotNull) - .AddEventValidation(EditSessionReadyEvent.Type, esrp => - { - Assert.NotNull(esrp); - Assert.False(esrp.Success); - }).Complete(); - await eds.HandleInitializeRequest(initParams, efv.Object); - await eds.InitializeWaitHandles[Common.OwnerUri].Task; - - // Then: - // ... We should have started execution, but failed - efv.Validate(); - - // ... There should not be any sessions created - Assert.Empty(eds.ActiveSessions); - - // ... There should not be a wait handle. It should have been cleaned up by now - Assert.Empty(eds.InitializeWaitHandles); - } - - private static EditSession GetDefaultSession() + private static async Task GetDefaultSession() { // ... Create a session with a proper query and metadata Query q = QueryExecution.Common.GetBasicExecutedQuery(); ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + EditSession s = await Common.GetCustomSession(q, etm); return s; } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/SessionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/SessionTests.cs index 59ed75f8..50837834 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/SessionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/EditData/SessionTests.cs @@ -28,40 +28,55 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region Construction Tests [Fact] - public void SessionConstructionNullQuery() + public void SessionConstructionNullMetadataFactory() { - // If: I create a session object without a null query + // If: I create a session object with a null metadata factory // Then: It should throw an exception - Assert.Throws(() => new EditSession(null, Common.GetStandardMetadata(new DbColumn[] {}))); + Assert.Throws(() => new EditSession(null, Constants.OwnerUri, Constants.OwnerUri)); } - [Fact] - public void SessionConstructionNullMetadataProvider() + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" \t\r\n")] + public void SessionConstructionNullObjectName(string objName) { - // If: I create a session object without a null metadata provider + // If: I create a session object with a null or whitespace object name // Then: It should throw an exception - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - Assert.Throws(() => new EditSession(rs, null)); + Mock mockFactory = new Mock(); + Assert.Throws(() => new EditSession(mockFactory.Object, objName, Constants.OwnerUri)); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" \t\r\n")] + public void SessionConstructionNullObjectType(string objType) + { + // If: I create a session object with a null or whitespace object type + // Then: It should throw an exception + Mock mockFactory = new Mock(); + Assert.Throws(() => new EditSession(mockFactory.Object, Constants.OwnerUri, objType)); } [Fact] public void SessionConstructionValid() { - // If: I create a session object with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + // If: I create a session object with a proper arguments + Mock mockFactory = new Mock(); + EditSession s = new EditSession(mockFactory.Object, Constants.OwnerUri, Constants.OwnerUri); // Then: - // ... The edit cache should exist and be empty - Assert.NotNull(s.EditCache); - Assert.Empty(s.EditCache); + // ... The edit cache should not exist + Assert.Null(s.EditCache); + + // ... The session shouldn't be initialized + Assert.False(s.IsInitialized); + Assert.Null(s.EditCache); Assert.Null(s.CommitTask); - // ... The next row ID should be equivalent to the number of rows in the result set - Assert.Equal(q.Batches[0].ResultSets[0].RowCount, s.NextRowId); + // ... The next row ID should be the default long + Assert.Equal(default(long), s.NextRowId); } #endregion @@ -118,15 +133,28 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region Create Row Tests [Fact] - public void CreateRowAddFailure() + public void CreateRowNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to create a row without initializing + // Then: I should get an exception + Assert.Throws(() => s.CreateRow()); + } + + [Fact] + public async Task CreateRowAddFailure() { // NOTE: This scenario should theoretically never occur, but is tested for completeness // Setup: // ... Create a session with a proper query and metadata Query q = QueryExecution.Common.GetBasicExecutedQuery(); ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + EditSession s = await Common.GetCustomSession(q, etm); // ... Add a mock edit to the edit cache to cause the .TryAdd to fail var mockEdit = new Mock().Object; @@ -145,13 +173,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void CreateRowSuccess() + public async Task CreateRowSuccess() { // Setup: Create a session with a proper query and metadata Query q = QueryExecution.Common.GetBasicExecutedQuery(); ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + EditSession s = await Common.GetCustomSession(q, etm); // If: I add a row to the session EditCreateRowResult result = s.CreateRow(); @@ -172,48 +200,48 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void CreateRowDefaultTest() + public async Task CreateRowDefaultTest() { // Setup: // ... We will have 3 columns - DbColumn[] cols = + DbColumnWrapper[] cols = { - new TestDbColumn("col1", false), // No default - new TestDbColumn("col2", false), // Has default (defined below) - new TestDbColumn("filler", false) // Filler column so we can use the common code + new DbColumnWrapper(new TestDbColumn("col1")), // No default + new DbColumnWrapper(new TestDbColumn("col2")), // Has default (defined below) + new DbColumnWrapper(new TestDbColumn("filler")) // Filler column so we can use the common code }; // ... Metadata provider will return 3 columns - EditColumnWrapper[] metas = + EditColumnMetadata[] metas = { - new EditColumnWrapper // No default + new EditColumnMetadata // No default { - DbColumn = new DbColumnWrapper(cols[0]), DefaultValue = null, EscapedName = cols[0].ColumnName, - Ordinal = 0, - IsKey = false }, - new EditColumnWrapper // Has default + new EditColumnMetadata // Has default { - DbColumn = new DbColumnWrapper(cols[1]), DefaultValue = "default", EscapedName = cols[0].ColumnName, - Ordinal = 0, - IsKey = false }, - new EditColumnWrapper() + new EditColumnMetadata() }; - var etm = Common.GetMetadataProvider(metas, true); + var etm = new EditTableMetadata + { + Columns = metas, + EscapedMultipartName = "tbl", + IsMemoryOptimized = false + }; + etm.Extend(cols); // ... Create a result set - var rs = Common.GetResultSet(cols, false, 1); + var q = await Common.GetQuery(cols, false); // ... Create a session from all this - var session = new EditSession(rs, etm); + EditSession s = await Common.GetCustomSession(q, etm); // If: I add a row to the session, on a table that has defaults - var result = session.CreateRow(); + var result = s.CreateRow(); // Then: // ... Result should not be null, new row ID should be > 0 @@ -233,13 +261,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData [Theory] [MemberData(nameof(RowIdOutOfRangeData))] - public void RowIdOutOfRange(long rowId, Action testAction) + public async Task RowIdOutOfRange(long rowId, Action testAction) { // Setup: Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // If: I delete a row that is out of range for the result set // Then: I should get an exception @@ -253,26 +278,260 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData // Delete Row Action delAction = (s, l) => s.DeleteRow(l); yield return new object[] { -1L, delAction }; + yield return new object[] {(long) QueryExecution.Common.StandardRows, delAction}; yield return new object[] { 100L, delAction }; // Update Cell Action upAction = (s, l) => s.UpdateCell(l, 0, null); yield return new object[] { -1L, upAction }; + yield return new object[] {(long) QueryExecution.Common.StandardRows, upAction}; yield return new object[] { 100L, upAction }; + + // Revert Row + Action revertRowAction = (s, l) => s.RevertRow(l); + yield return new object[] {-1L, revertRowAction}; + yield return new object[] {0L, revertRowAction}; // This is invalid b/c there isn't an edit pending for this row + yield return new object[] {(long) QueryExecution.Common.StandardRows, revertRowAction}; + yield return new object[] {100L, revertRowAction}; + + // Revert Cell + Action revertCellAction = (s, l) => s.RevertCell(l, 0); + yield return new object[] {-1L, revertRowAction}; + yield return new object[] {0L, revertRowAction}; // This is invalid b/c there isn't an edit pending for this row + yield return new object[] {(long) QueryExecution.Common.StandardRows, revertRowAction}; + yield return new object[] {100L, revertRowAction}; } } + #region Initialize Tests + + [Fact] + public void InitializeAlreadyInitialized() + { + // Setup: + // ... Create a session and fake that it has been initialized + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + s.IsInitialized = true; + + // If: I initialize it + // Then: I should get an exception + Assert.Throws(() => s.Initialize(null, null, null, null)); + } + + [Fact] + public void InitializeAlreadyInitializing() + { + // Setup: + // ... Create a session and fake that it is in progress of initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + s.InitializeTask = new Task(() => { }); + + // If: I initialize it + // Then: I should get an exception + Assert.Throws(() => s.Initialize(null, null, null, null)); + } + + [Theory] + [MemberData(nameof(InitializeNullParamsData))] + public void InitializeNullParams(EditSession.Connector c, EditSession.QueryRunner qr, + Func sh, Func fh) + { + // Setup: + // ... Create a session that hasn't been initialized + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I initialize it with a missing parameter + // Then: It should throw an exception + Assert.ThrowsAny(() => s.Initialize(c, qr, sh, fh)); + } + + public static IEnumerable InitializeNullParamsData + { + get + { + yield return new object[] {null, DoNothingQueryRunner, DoNothingSuccessHandler, DoNothingFailureHandler}; + yield return new object[] {DoNothingConnector, null, DoNothingSuccessHandler, DoNothingFailureHandler}; + yield return new object[] {DoNothingConnector, DoNothingQueryRunner, null, DoNothingFailureHandler}; + yield return new object[] {DoNothingConnector, DoNothingQueryRunner, DoNothingSuccessHandler, null}; + } + } + + [Fact] + public async Task InitializeMetadataFails() + { + // Setup: + // ... Create a metadata factory that throws + Mock emf = new Mock(); + emf.Setup(f => f.GetObjectMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(); + + // ... Create a session that hasn't been initialized + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // ... Create a mock for verifying the failure handler will be called + var successHandler = DoNothingSuccessMock; + var failureHandler = DoNothingFailureMock; + + // If: I initalize the session with a metadata factory that will fail + s.Initialize(DoNothingConnector, DoNothingQueryRunner, successHandler.Object, failureHandler.Object); + await s.InitializeTask; + + // Then: + // ... The session should not be initialized + Assert.False(s.IsInitialized); + + // ... The failure handler should have been called once + failureHandler.Verify(f => f(It.IsAny()), Times.Once); + + // ... The success handler should not have been called at all + successHandler.Verify(f => f(), Times.Never); + } + + [Fact] + public async Task InitializeQueryFailException() + { + // Setup: + // ... Create a metadata factory that will return some generic column information + var b = QueryExecution.Common.GetBasicExecutedBatch(); + var etm = Common.GetStandardMetadata(b.ResultSets[0].Columns); + Mock emf = new Mock(); + emf.Setup(f => f.GetObjectMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(etm); + + // ... Create a session that hasn't been initialized + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // ... Create a query runner that will fail via exception + Mock qr = new Mock(); + qr.Setup(r => r(It.IsAny())).Throws(new Exception("qqq")); + + // ... Create a mock for verifying the failure handler will be called + var successHandler = DoNothingSuccessMock; + var failureHandler = DoNothingFailureMock; + + // If: I initialize the session with a query runner that will fail + s.Initialize(DoNothingConnector, qr.Object, successHandler.Object, failureHandler.Object); + await s.InitializeTask; + + // Then: + // ... The session should not be initialized + Assert.False(s.IsInitialized); + + // ... The failure handler should have been called once + failureHandler.Verify(f => f(It.IsAny()), Times.Once); + + // ... The success handler should not have been called at all + successHandler.Verify(f => f(), Times.Never); + } + + [Theory] + [InlineData(null)] + [InlineData("It fail.")] + public async Task InitializeQueryFailReturnNull(string message) + { + // Setup: + // ... Create a metadata factory that will return some generic column information + var b = QueryExecution.Common.GetBasicExecutedBatch(); + var etm = Common.GetStandardMetadata(b.ResultSets[0].Columns); + Mock emf = new Mock(); + emf.Setup(f => f.GetObjectMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(etm); + + // ... Create a session that hasn't been initialized + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // ... Create a query runner that will fail via returning a null query + Mock qr = new Mock(); + qr.Setup(r => r(It.IsAny())) + .Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(null, message))); + + // ... Create a mock for verifying the failure handler will be called + var successHandler = DoNothingSuccessMock; + var failureHandler = DoNothingFailureMock; + + // If: I initialize the session with a query runner that will fail + s.Initialize(DoNothingConnector, qr.Object, successHandler.Object, failureHandler.Object); + await s.InitializeTask; + + // Then: + // ... The session should not be initialized + Assert.False(s.IsInitialized); + + // ... The failure handler should have been called once + failureHandler.Verify(f => f(It.IsAny()), Times.Once); + + // ... The success handler should not have been called at all + successHandler.Verify(f => f(), Times.Never); + } + + [Fact] + public async Task InitializeSuccess() + { + // Setup: + // ... Create a metadata factory that will return some generic column information + var q = QueryExecution.Common.GetBasicExecutedQuery(); + var rs = q.Batches[0].ResultSets[0]; + var etm = Common.GetStandardMetadata(rs.Columns); + Mock emf = new Mock(); + emf.Setup(f => f.GetObjectMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(etm); + + // ... Create a session that hasn't been initialized + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // ... Create a query runner that will return a successful query + Mock qr = new Mock(); + qr.Setup(r => r(It.IsAny())) + .Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q, null))); + + // ... Create a mock for verifying the failure handler will be called + var successHandler = DoNothingSuccessMock; + var failureHandler = DoNothingFailureMock; + + // If: I initialize the session with a query runner that will fail + s.Initialize(DoNothingConnector, qr.Object, successHandler.Object, failureHandler.Object); + await s.InitializeTask; + + // Then: + // ... The failure handler should not have been called + failureHandler.Verify(f => f(It.IsAny()), Times.Never); + + // ... The success handler should have been called + successHandler.Verify(f => f(), Times.Once); + + // ... The session should have been initialized + Assert.True(s.IsInitialized); + Assert.Equal(rs.RowCount, s.NextRowId); + Assert.NotNull(s.EditCache); + Assert.Empty(s.EditCache); + } + + #endregion + #region Delete Row Tests [Fact] - public void DeleteRowAddFailure() + public void DeleteRowNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to delete a row without initializing + // Then: I should get an exception + Assert.Throws(() => s.DeleteRow(0)); + } + + [Fact] + public async Task DeleteRowAddFailure() { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a mock edit to the edit cache to cause the .TryAdd to fail var mockEdit = new Mock().Object; @@ -288,13 +547,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void DeleteRowSuccess() + public async Task DeleteRowSuccess() { // Setup: Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + var s = await GetBasicSession(); // If: I add a row to the session s.DeleteRow(0); @@ -309,28 +565,24 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region Revert Row Tests [Fact] - public void RevertRowOutOfRange() + public void RevertRowNotInitialized() { - // Setup: Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); - // If: I revert a row that doesn't have any pending changes + // If: I ask to revert a row without initializing // Then: I should get an exception - Assert.Throws(() => s.RevertRow(0)); + Assert.Throws(() => s.RevertRow(0)); } [Fact] - public void RevertRowSuccess() + public async Task RevertRowSuccess() { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a mock edit to the edit cache to cause the .TryAdd to fail var mockEdit = new Mock().Object; @@ -346,17 +598,44 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #endregion + #region Revert Cell Tests + + [Fact] + public void RevertCellNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to revert a cell without initializing + // Then: I should get an exception + Assert.Throws(() => s.RevertCell(0, 0)); + } + + #endregion + #region Update Cell Tests [Fact] - public void UpdateCellExisting() + public void UpdateCellNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to update a cell without initializing + // Then: I should get an exception + Assert.Throws(() => s.UpdateCell(0, 0, "")); + } + + [Fact] + public async Task UpdateCellExisting() { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a mock edit to the edit cache to cause the .TryAdd to fail var mockEdit = new Mock(); @@ -373,14 +652,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void UpdateCellNew() + public async Task UpdateCellNew() { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // If: I update a cell on a row that does not have a pending edit s.UpdateCell(0, 0, ""); @@ -395,14 +671,27 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region SubSet Tests + [Fact] + public async Task SubsetNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to update a cell without initializing + // Then: I should get an exception + await Assert.ThrowsAsync(() => s.GetRows(0, 100)); + } + [Fact] public async Task GetRowsNoEdits() { // Setup: Create a session with a proper query and metadata Query q = QueryExecution.Common.GetBasicExecutedQuery(); ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + EditSession s = await Common.GetCustomSession(q, etm); // If: I ask for 3 rows from session skipping the first EditRow[] rows = await s.GetRows(1, 3); @@ -439,10 +728,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a cell update to it s.UpdateCell(1, 0, "foo"); @@ -472,10 +758,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a row deletion s.DeleteRow(1); @@ -505,10 +788,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a row creation s.CreateRow(); @@ -536,10 +816,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Create a session with a query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add a few row creations s.CreateRow(); @@ -561,17 +838,27 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region Script Edits Tests + [Fact] + public void ScriptEditsNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to script edits without initializing + // Then: I should get an exception + Assert.Throws(() => s.ScriptEdits(string.Empty)); + } + [Theory] [InlineData(null)] [InlineData("")] [InlineData(" \t\r\n")] - public void ScriptNullOrEmptyOutput(string outputPath) + public async Task ScriptNullOrEmptyOutput(string outputPath) { // Setup: Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // If: I try to script the edit cache with a null or whitespace output path // Then: It should throw an exception @@ -579,14 +866,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void ScriptProvidedOutputPath() + public async Task ScriptProvidedOutputPath() { // Setup: // ... Create a session with a proper query and metadata - Query q = QueryExecution.Common.GetBasicExecutedQuery(); - ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - EditSession s = new EditSession(rs, etm); + EditSession s = await GetBasicSession(); // ... Add two mock edits that will generate a script Mock edit = new Mock(); @@ -613,10 +897,23 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #region Commit Tests [Fact] - public void CommitNullConnection() + public void CommitEditsNotInitialized() + { + // Setup: + // ... Create a session without initializing + Mock emf = new Mock(); + EditSession s = new EditSession(emf.Object, Constants.OwnerUri, Constants.OwnerUri); + + // If: I ask to script edits without initializing + // Then: I should get an exception + Assert.Throws(() => s.CommitEdits(null, null, null)); + } + + [Fact] + public async Task CommitNullConnection() { // Setup: Create a basic session - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); // If: I attempt to commit with a null connection // Then: I should get an exception @@ -625,11 +922,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void CommitNullSuccessHandler() + public async Task CommitNullSuccessHandler() { // Setup: // ... Create a basic session - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); // ... Mock db connection DbConnection conn = new TestSqlConnection(null); @@ -640,11 +937,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void CommitNullFailureHandler() + public async Task CommitNullFailureHandler() { // Setup: // ... Create a basic session - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); // ... Mock db connection DbConnection conn = new TestSqlConnection(null); @@ -655,11 +952,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData } [Fact] - public void CommitInProgress() + public async Task CommitInProgress() { // Setup: // ... Basic session and db connection - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); DbConnection conn = new TestSqlConnection(null); // ... Mock a task that has not completed @@ -677,7 +974,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Basic session and db connection - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); DbConnection conn = new TestSqlConnection(null); // ... Add a mock commands for fun @@ -721,7 +1018,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData { // Setup: // ... Basic session and db connection - EditSession s = GetBasicSession(); + EditSession s = await GetBasicSession(); DbConnection conn = new TestSqlConnection(null); // ... Add a mock edit that will explode on generating a command @@ -760,12 +1057,51 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData #endregion - private static EditSession GetBasicSession() + private static EditSession.Connector DoNothingConnector + { + get { return () => Task.FromResult(null); } + } + + private static EditSession.QueryRunner DoNothingQueryRunner + { + get { return q => Task.FromResult(null); } + } + + private static Func DoNothingSuccessHandler + { + get { return () => Task.FromResult(0); } + } + + private static Func DoNothingFailureHandler + { + get { return e => Task.FromResult(0); } + } + + private static Mock> DoNothingSuccessMock + { + get { + Mock> successHandler = new Mock>(); + successHandler.Setup(f => f()).Returns(Task.FromResult(0)); + return successHandler; + } + } + + private static Mock> DoNothingFailureMock + { + get + { + Mock> failureHandler = new Mock>(); + failureHandler.Setup(f => f(It.IsAny())).Returns(Task.FromResult(0)); + return failureHandler; + } + } + + private static async Task GetBasicSession() { Query q = QueryExecution.Common.GetBasicExecutedQuery(); ResultSet rs = q.Batches[0].ResultSets[0]; - IEditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); - return new EditSession(rs, etm); + EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns); + return await Common.GetCustomSession(q, etm); } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs index dd5704a2..526220da 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/QueryExecution/DataStorage/ServiceBufferFileStreamReaderWriterTests.cs @@ -302,7 +302,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage }; // Setup: Create a DATE column - DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn("col", "DaTe")); + DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTe"}); foreach (DateTime value in testValues) { @@ -324,7 +324,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage }; // Setup: Create a DATETIME column - DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn("col", "DaTeTiMe")); + DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe"}); foreach (DateTime value in testValues) { @@ -353,7 +353,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage }; // Setup: Create a DATETIME column - DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn("col", "DaTeTiMe2", precision)); + DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn + { + DataTypeName = "DaTeTiMe2", + NumericScale = precision + }); foreach (DateTime value in testValues) { @@ -379,7 +383,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage }; // Setup: Create a DATETIME2 column - DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn("col", "DaTeTiMe2", 0)); + DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 0}); foreach (DateTime value in testValues) { @@ -401,7 +405,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage }; // Setup: Create a DATETIME2 column - DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn("col", "DaTeTiMe2", 255)); + DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 255}); foreach (DateTime value in testValues) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Utility/TestDbColumn.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Utility/TestDbColumn.cs index 89614470..4603ebac 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Utility/TestDbColumn.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Utility/TestDbColumn.cs @@ -4,11 +4,85 @@ using System; using System.Data.Common; +using Microsoft.SqlTools.Utility; namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility { public class TestDbColumn : DbColumn { + #region Overridden Properties + + public new bool AllowDBNull + { + get { return base.AllowDBNull.HasTrue(); } + set { base.AllowDBNull = value; } + } + + public new string ColumnName + { + get { return base.ColumnName; } + set { base.ColumnName = value; } + } + + public new int ColumnSize + { + get { return base.ColumnSize ?? -1; } + set { base.ColumnSize = value; } + } + + public new Type DataType + { + get { return base.DataType; } + set { base.DataType = value; } + } + + public new string DataTypeName + { + get { return base.DataTypeName; } + set { base.DataTypeName = value; } + } + + public new bool IsAutoIncrement + { + get { return base.IsAutoIncrement.HasTrue(); } + set { base.IsAutoIncrement = value; } + } + + public new bool IsLong + { + get { return base.IsLong.HasTrue(); } + set { base.IsLong = value; } + } + + public new bool IsIdentity + { + get { return base.IsIdentity.HasTrue(); } + set { base.IsIdentity = value; } + } + + public new bool IsKey + { + get { return base.IsKey.HasTrue(); } + set { base.IsKey = value; } + } + + public new int NumericScale + { + get { return base.NumericScale ?? -1; } + set { base.NumericScale = value; } + } + + #endregion + + public TestDbColumn() + { + base.ColumnName = "col"; + } + + /// + /// Constructs a basic DbColumn that is an NVARCHAR(128) NULL + /// + /// Name of the column public TestDbColumn(string columnName) { base.IsLong = false; @@ -18,34 +92,5 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility base.DataType = typeof(string); base.DataTypeName = "nvarchar"; } - - public TestDbColumn(string columnName, string columnType) - : this(columnName) - { - base.DataTypeName = columnType; - } - - public TestDbColumn(string columnName, string columnType, Type columnDataType) - { - base.IsLong = false; - base.ColumnName = columnName; - base.ColumnSize = 128; - base.AllowDBNull = true; - base.DataType = columnDataType; - base.DataTypeName = columnType; - } - - public TestDbColumn(string columnName, string columnType, int scale) - : this(columnName, columnType) - { - base.NumericScale = scale; - } - - public TestDbColumn(string columnName, bool isAutoIncrement) - : this(columnName) - { - base.IsAutoIncrement = isAutoIncrement; - base.IsIdentity = isAutoIncrement; - } } }