Changes to fix code review comments and bug with handling empty batches

This commit is contained in:
Benjamin Russell
2016-08-24 15:25:13 -07:00
parent 48c7bbaa9f
commit 0371e17028
5 changed files with 124 additions and 35 deletions

View File

@@ -38,15 +38,31 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </summary>
public bool HasExecuted { get; set; }
/// <summary>
/// Internal representation of the messages so we can modify internally
/// </summary>
private List<string> resultMessages;
/// <summary>
/// Messages that have come back from the server
/// </summary>
public List<string> ResultMessages { get; set; }
public IEnumerable<string> ResultMessages
{
get { return resultMessages; }
}
/// <summary>
/// Internal representation of the result sets so we can modify internally
/// </summary>
private List<ResultSet> resultSets;
/// <summary>
/// The result sets of the batch execution
/// </summary>
public List<ResultSet> ResultSets { get; set; }
public IEnumerable<ResultSet> ResultSets
{
get { return resultSets; }
}
/// <summary>
/// Property for generating a set result set summaries from the result sets
@@ -67,7 +83,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// <summary>
/// The 0-indexed line number that this batch started on
/// </summary>
private int StartLine { get; set; }
internal int StartLine { get; set; }
#endregion
@@ -81,10 +97,10 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
// Initialize the internal state
BatchText = batchText;
StartLine = startLine - 1;
StartLine = startLine - 1; // -1 to make sure that the line number of the batch is 0-indexed, since SqlParser gives 1-indexed line numbers
HasExecuted = false;
ResultSets = new List<ResultSet>();
ResultMessages = new List<string>();
resultSets = new List<ResultSet>();
resultMessages = new List<string>();
}
/// <summary>
@@ -125,7 +141,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
if (!reader.HasRows && reader.FieldCount == 0)
{
// Create a message with the number of affected rows -- IF the query affects rows
ResultMessages.Add(reader.RecordsAffected >= 0
resultMessages.Add(reader.RecordsAffected >= 0
? string.Format(RowsAffectedFormat, reader.RecordsAffected)
: "Command(s) completed successfully.");
continue;
@@ -145,10 +161,10 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
}
// Add the result set to the results of the query
ResultSets.Add(resultSet);
resultSets.Add(resultSet);
// Add a message for the number of rows the query returned
ResultMessages.Add(string.Format(RowsAffectedFormat, resultSet.Rows.Count));
resultMessages.Add(string.Format(RowsAffectedFormat, resultSet.Rows.Count));
} while (await reader.NextResultAsync(cancellationToken));
}
}
@@ -187,14 +203,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
public ResultSetSubset GetSubset(int resultSetIndex, int startRow, int rowCount)
{
// Sanity check to make sure we have valid numbers
if (resultSetIndex < 0 || resultSetIndex >= ResultSets.Count)
if (resultSetIndex < 0 || resultSetIndex >= resultSets.Count)
{
throw new ArgumentOutOfRangeException(nameof(resultSetIndex), "Result set index cannot be less than 0" +
"or greater than the number of result sets");
}
// Retrieve the result set
return ResultSets[resultSetIndex].GetSubset(startRow, rowCount);
return resultSets[resultSetIndex].GetSubset(startRow, rowCount);
}
#region Private Helpers
@@ -208,7 +224,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// <param name="args">Arguments from the event</param>
private void StoreDbMessage(object sender, SqlInfoMessageEventArgs args)
{
ResultMessages.Add(args.Message);
resultMessages.Add(args.Message);
}
/// <summary>
@@ -232,13 +248,13 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
string message = String.Format("Msg {0}, Level {1}, State {2}, Line {3}{4}{5}",
sqlError.Number, sqlError.Class, sqlError.State, lineNumber,
Environment.NewLine, sqlError.Message);
ResultMessages.Add(message);
resultMessages.Add(message);
}
}
}
else
{
ResultMessages.Add(dbe.Message);
resultMessages.Add(dbe.Message);
}
}

View File

@@ -60,6 +60,8 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </summary>
private ConnectionInfo EditorConnection { get; set; }
private bool HasExecuteBeenCalled { get; set; }
/// <summary>
/// Whether or not the query has completed executed, regardless of success or failure
/// </summary>
@@ -68,9 +70,10 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </remarks>
public bool HasExecuted
{
get { return Batches.All(b => b.HasExecuted); }
get { return Batches.Length == 0 ? HasExecuteBeenCalled : Batches.All(b => b.HasExecuted); }
internal set
{
HasExecuteBeenCalled = value;
foreach (var batch in Batches)
{
batch.HasExecuted = value;
@@ -94,7 +97,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
public Query(string queryText, ConnectionInfo connection, QueryExecutionSettings settings)
{
// Sanity check for input
if (String.IsNullOrEmpty(queryText))
if (string.IsNullOrEmpty(queryText))
{
throw new ArgumentNullException(nameof(queryText), "Query text cannot be null");
}
@@ -117,7 +120,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
{
BatchSeparator = settings.BatchSeparator
});
Batches = parseResult.Script.Batches.Select(b => new Batch(b.Sql, b.StartLocation.LineNumber)).ToArray();
// NOTE: We only want to process batches that have statements (ie, ignore comments and empty lines)
Batches = parseResult.Script.Batches.Where(b => b.Statements.Count > 0)
.Select(b => new Batch(b.Sql, b.StartLocation.LineNumber)).ToArray();
}
/// <summary>
@@ -125,6 +130,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </summary>
public async Task Execute()
{
// Mark that we've internally executed
HasExecuteBeenCalled = true;
// Don't actually execute if there aren't any batches to execute
if (Batches.Length == 0)
{
return;
}
// Open up a connection for querying the database
string connectionString = ConnectionService.BuildConnectionString(EditorConnection.ConnectionDetails);
using (DbConnection conn = EditorConnection.Factory.CreateSqlConnection(connectionString))