Edit Data: Create Row with Nullable Columns (#553)

* WIP

* All the new RowCreate tests are working

* Fixing a couple bugs with the row delete and row update tests

* Regenerating localization files

* Fixing multiple iteration in tests
This commit is contained in:
Benjamin Russell
2017-11-28 14:59:48 -08:00
committed by GitHub
parent bc8aef6a15
commit 2190039df2
33 changed files with 17699 additions and 7445 deletions

View File

@@ -8,7 +8,6 @@ using System.Data.Common;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
@@ -50,7 +49,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
EditSession session = new EditSession(metaFactory.Object);
// Step 2) Initialize the Session
// Mock connector that does nothing
EditSession.Connector connector = () => Task.FromResult<DbConnection>(null);
@@ -65,46 +63,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
return session;
}
public static EditTableMetadata GetStandardMetadata(DbColumn[] columns, bool isMemoryOptimized = false, int defaultColumns = 0)
{
// Create column metadata providers
var columnMetas = columns.Select((c, i) => new EditColumnMetadata
{
EscapedName = c.ColumnName,
Ordinal = i,
DefaultValue = i < defaultColumns ? DefaultValue : null
}).ToArray();
// Create column wrappers
var columnWrappers = columns.Select(c => new DbColumnWrapper(c)).ToArray();
// Create the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetas,
EscapedMultipartName = TableName,
IsMemoryOptimized = isMemoryOptimized
};
editTableMetadata.Extend(columnWrappers);
return editTableMetadata;
}
public static DbColumn[] GetColumns(bool includeIdentity)
{
List<DbColumn> columns = new List<DbColumn>();
if (includeIdentity)
{
columns.Add(new TestDbColumn("id") {IsKey = true, IsIdentity = true, IsAutoIncrement = true});
}
for (int i = 0; i < 3; i++)
{
columns.Add(new TestDbColumn($"col{i}"));
}
return columns.ToArray();
}
public static async Task<Query> GetQuery(DbColumn[] columns, bool includIdentity, int rowCount = 1)
{
Query q = QueryExecution.Common.GetBasicExecutedQuery();
@@ -133,6 +91,32 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
return new TestDbDataReader(new [] {testResultSet}, false);
}
public static EditTableMetadata GetCustomEditTableMetadata(DbColumn[] columns)
{
// Create column metadata providers and column wrappers
var columnMetas = new List<EditColumnMetadata>();
var columnWrappers = new List<DbColumnWrapper>();
for (int i = 0; i < columns.Length; i++)
{
columnMetas.Add(new EditColumnMetadata
{
EscapedName = columns[i].ColumnName,
Ordinal = i
});
columnWrappers.Add(new DbColumnWrapper(columns[i]));
}
// Create the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetas.ToArray(),
EscapedMultipartName = TableName,
IsMemoryOptimized = false
};
editTableMetadata.Extend(columnWrappers.ToArray());
return editTableMetadata;
}
public static void AddCells(RowEditBase rc, int colsToSkip)
{
// Skip the first column since if identity, since identity columns can't be updated
@@ -141,5 +125,101 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
rc.SetCell(i, "123");
}
}
public class TestDbColumnsWithTableMetadata
{
public TestDbColumnsWithTableMetadata(bool isMemoryOptimized, bool identityCol, int defaultCols, int nullableCols)
{
List<DbColumn> dbColumns = new List<DbColumn>();
List<DbColumnWrapper> columnWrappers = new List<DbColumnWrapper>();
List<EditColumnMetadata> columnMetadatas = new List<EditColumnMetadata>();
int startingOrdinal = 0;
// Add the identity column at the front of the table
if (identityCol)
{
const string colName = "id";
DbColumn dbColumn = new TestDbColumn(colName)
{
IsKey = true,
IsIdentity = true,
IsAutoIncrement = true
};
EditColumnMetadata columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = startingOrdinal,
DefaultValue = null
};
dbColumns.Add(dbColumn);
columnWrappers.Add(new DbColumnWrapper(dbColumn));
columnMetadatas.Add(columnMetadata);
startingOrdinal++;
}
// Add each column to the table
for (int i = startingOrdinal; i < 3 + startingOrdinal; i++)
{
string colName = $"col{i}";
DbColumn dbColumn;
EditColumnMetadata columnMetadata;
if (i < defaultCols + startingOrdinal)
{
// This column will have a default value
dbColumn = new TestDbColumn(colName) {AllowDBNull = false};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = DefaultValue
};
}
else if (i < nullableCols + defaultCols + startingOrdinal)
{
// This column will be nullable
dbColumn = new TestDbColumn(colName) {AllowDBNull = true};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = null
};
}
else
{
// This column doesn't have a default value or is nullable
dbColumn = new TestDbColumn(colName) {AllowDBNull = false};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = null
};
}
dbColumns.Add(dbColumn);
columnWrappers.Add(new DbColumnWrapper(dbColumn));
columnMetadatas.Add(columnMetadata);
}
// Put together the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetadatas.ToArray(),
EscapedMultipartName = TableName,
IsMemoryOptimized = isMemoryOptimized
};
editTableMetadata.Extend(columnWrappers.ToArray());
DbColumns = dbColumns.ToArray();
TableMetadata = editTableMetadata;
}
public DbColumn[] DbColumns { get; }
public EditTableMetadata TableMetadata { get; }
}
}
}

View File

@@ -10,7 +10,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -27,26 +26,46 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Create the values to store
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
// If: I create a RowCreate instance
RowCreate rc = new RowCreate(rowId, rs, etm);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(rowId, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
#region GetScript Tests
[Fact]
public async Task GetScriptMissingCell()
public static IEnumerable<object[]> GetScriptMissingCellsData
{
get
{
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 2}; // 02
yield return new object[] {true, 0, 0, 4}; // 03
yield return new object[] {true, 0, 1, 4}; // 06
yield return new object[] {true, 1, 0, 4}; // 12
yield return new object[] {true, 1, 1, 4}; // 16
yield return new object[] {false, 0, 0, 1}; // 21
yield return new object[] {false, 0, 0, 3}; // 22
yield return new object[] {false, 0, 1, 3}; // 25
yield return new object[] {false, 1, 0, 3}; // 31
yield return new object[] {false, 1, 1, 3}; // 35
}
}
[Theory]
[MemberData(nameof(GetScriptMissingCellsData))]
public async Task GetScriptMissingCell(bool includeIdentity, int defaultCols, int nullableCols, int valuesToSkipSetting)
{
// Setup: Generate the parameters for the row create
RowCreate rc = await GetStandardRowCreate();
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
@@ -57,31 +76,49 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
get
{
yield return new object[] {true, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, no defaults, all values set
yield return new object[] {true, 2, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, some defaults, all values set
yield return new object[] {true, 2, 2, new RegexExpectedOutput(2, 2, 0)}; // Has identity, some defaults, defaults not set
yield return new object[] {true, 4, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, all defaults, all values set
yield return new object[] {true, 4, 4, null}; // Has identity, all defaults, defaults not set
yield return new object[] {false, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, no defaults, all values set
yield return new object[] {false, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, some defaults, all values set
yield return new object[] {false, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // No identity, some defaults, defaults not set
yield return new object[] {false, 3, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, all defaults, all values set
yield return new object[] {false, 3, 3, null}; // No identity, all defaults, defaults not set
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 01
yield return new object[] {true, 0, 1, 1, new RegexExpectedOutput(3, 3, 0)}; // 04
yield return new object[] {true, 0, 1, 2, new RegexExpectedOutput(2, 2, 0)}; // 05
yield return new object[] {true, 0, 3, 1, new RegexExpectedOutput(3, 3, 0)}; // 07
yield return new object[] {true, 0, 3, 2, new RegexExpectedOutput(2, 2, 0)}; // 08
yield return new object[] {true, 0, 3, 4, null}; // 09
yield return new object[] {true, 1, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 10
yield return new object[] {true, 1, 0, 2, new RegexExpectedOutput(2, 2, 0)}; // 11
yield return new object[] {true, 1, 1, 1, new RegexExpectedOutput(3, 3, 0)}; // 13
yield return new object[] {true, 1, 1, 2, new RegexExpectedOutput(2, 2, 0)}; // 14
yield return new object[] {true, 1, 1, 3, new RegexExpectedOutput(1, 1, 0)}; // 15
yield return new object[] {true, 3, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 17
yield return new object[] {true, 3, 0, 2, new RegexExpectedOutput(2, 2, 0)}; // 18
yield return new object[] {true, 3, 0, 4, null}; // 19
yield return new object[] {false, 0, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 20
yield return new object[] {false, 0, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // 23
yield return new object[] {false, 0, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // 24
yield return new object[] {false, 0, 3, 0, new RegexExpectedOutput(3, 3, 0)}; // 26
yield return new object[] {false, 0, 3, 1, new RegexExpectedOutput(2, 2, 0)}; // 27
yield return new object[] {false, 0, 3, 3, null}; // 28
yield return new object[] {false, 1, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 29
yield return new object[] {false, 1, 0, 1, new RegexExpectedOutput(2, 2, 0)}; // 30
yield return new object[] {false, 1, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // 32
yield return new object[] {false, 1, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // 33
yield return new object[] {false, 1, 1, 2, new RegexExpectedOutput(1, 1, 0)}; // 34
yield return new object[] {false, 3, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 36
yield return new object[] {false, 3, 0, 1, new RegexExpectedOutput(2, 2, 0)}; // 37
yield return new object[] {false, 3, 0, 3, null}; // 38
}
}
[Theory]
[MemberData(nameof(GetScriptData))]
public async Task GetScript(bool includeIdentity, int defaultCols, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
public async Task GetScript(bool includeIdentity, int colsWithDefaultConstraints, int colsThatAllowNull, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity, defaultCols);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, colsWithDefaultConstraints, colsThatAllowNull);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Create a row create and set the appropriate number of cells
RowCreate rc = new RowCreate(100, rs, etm);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
Common.AddCells(rc, valuesToSkipSetting);
// If: I ask for the script for the row insert
@@ -137,15 +174,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup:
// ... Generate the parameters for the row create
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Setup a db reader for the result of an insert
var newRowReader = Common.GetNewRowDataReader(columns, includeIdentity);
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
// If: I ask for the change to be applied
RowCreate rc = new RowCreate(rowId, rs, etm);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
await rc.ApplyChanges(newRowReader);
// Then: The result set should have an additional row in it
@@ -164,16 +200,41 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Then: It should throw an exception
Assert.Throws<ArgumentNullException>(() => rc.GetCommand(null));
}
[Fact]
public async Task GetCommandMissingCellNoDefault()
{
// Setup: Generate the parameters for the row create
RowCreate rc = await GetStandardRowCreate();
var mockConn = new TestSqlConnection(null);
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
public static IEnumerable<object[]> GetCommandMissingCellsData
{
get
{
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 2}; // 02
yield return new object[] {true, 0, 0, 4}; // 03
yield return new object[] {true, 0, 1, 4}; // 06
yield return new object[] {true, 1, 0, 4}; // 12
yield return new object[] {true, 1, 1, 4}; // 16
yield return new object[] {false, 0, 0, 1}; // 21
yield return new object[] {false, 0, 0, 3}; // 22
yield return new object[] {false, 0, 1, 3}; // 25
yield return new object[] {false, 1, 0, 3}; // 31
yield return new object[] {false, 1, 1, 3}; // 35
}
}
[Theory]
[MemberData(nameof(GetCommandMissingCellsData))]
public async Task GetCommandMissingCellNoDefault(bool includeIdentity, int defaultCols, int nullableCols,
int valuesToSkip)
{
// Setup:
// ... Generate the row create object
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// ... Create a mock db connection for building the command
var mockConn = new TestSqlConnection();
// If: I ask for a script to be generated without setting all the required values
// Then: An exception should be thrown for the missing cells
Assert.Throws<InvalidOperationException>(() => rc.GetCommand(mockConn));
}
@@ -181,35 +242,53 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
get
{
yield return new object[] {true, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, no defaults, all values set
yield return new object[] {true, 2, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, some defaults, all values set
yield return new object[] {true, 2, 2, new RegexExpectedOutput(2, 2, 4)}; // Has identity, some defaults, defaults not set
yield return new object[] {true, 4, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, all defaults, all values set
yield return new object[] {true, 4, 4, new RegexExpectedOutput(0, 0, 4)}; // Has identity, all defaults, defaults not set
yield return new object[] {false, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, no defaults, all values set
yield return new object[] {false, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, some defaults, all values set
yield return new object[] {false, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // No identity, some defaults, defaults not set
yield return new object[] {false, 3, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, all defaults, all values set
yield return new object[] {false, 3, 3, new RegexExpectedOutput(0, 0, 3)}; // No identity, all defaults, defaults not set
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 01
yield return new object[] {true, 0, 1, 1, new RegexExpectedOutput(3, 3, 4)}; // 04
yield return new object[] {true, 0, 1, 2, new RegexExpectedOutput(2, 2, 4)}; // 05
yield return new object[] {true, 0, 3, 1, new RegexExpectedOutput(3, 3, 4)}; // 07
yield return new object[] {true, 0, 3, 2, new RegexExpectedOutput(2, 2, 4)}; // 08
yield return new object[] {true, 0, 3, 4, new RegexExpectedOutput(0, 0, 4)}; // 09
yield return new object[] {true, 1, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 10
yield return new object[] {true, 1, 0, 2, new RegexExpectedOutput(2, 2, 4)}; // 11
yield return new object[] {true, 1, 1, 1, new RegexExpectedOutput(3, 3, 4)}; // 13
yield return new object[] {true, 1, 1, 2, new RegexExpectedOutput(2, 2, 4)}; // 14
yield return new object[] {true, 1, 1, 3, new RegexExpectedOutput(1, 1, 4)}; // 15
yield return new object[] {true, 3, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 17
yield return new object[] {true, 3, 0, 2, new RegexExpectedOutput(2, 2, 4)}; // 18
yield return new object[] {true, 3, 0, 4, new RegexExpectedOutput(0, 0, 4)}; // 19
yield return new object[] {false, 0, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 20
yield return new object[] {false, 0, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // 23
yield return new object[] {false, 0, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // 24
yield return new object[] {false, 0, 3, 0, new RegexExpectedOutput(3, 3, 3)}; // 26
yield return new object[] {false, 0, 3, 1, new RegexExpectedOutput(2, 2, 3)}; // 27
yield return new object[] {false, 0, 3, 3, new RegexExpectedOutput(0, 0, 3)}; // 28
yield return new object[] {false, 1, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 29
yield return new object[] {false, 1, 0, 1, new RegexExpectedOutput(2, 2, 3)}; // 30
yield return new object[] {false, 1, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // 32
yield return new object[] {false, 1, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // 33
yield return new object[] {false, 1, 1, 2, new RegexExpectedOutput(1, 1, 3)}; // 34
yield return new object[] {false, 3, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 36
yield return new object[] {false, 3, 0, 1, new RegexExpectedOutput(2, 2, 3)}; // 37
yield return new object[] {false, 3, 0, 3, new RegexExpectedOutput(0, 0, 3)}; // 38
}
}
[Theory]
[MemberData(nameof(GetCommandData))]
public async Task GetCommand(bool includeIdentity, int defaultCols, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
public async Task GetCommand(bool includeIdentity, int defaultCols, int nullableCols, int valuesToSkip, RegexExpectedOutput expectedOutput)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity, defaultCols);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(null);
// ... Create a row create and set the appropriate number of cells
RowCreate rc = new RowCreate(100, rs, etm);
Common.AddCells(rc, valuesToSkipSetting);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
Common.AddCells(rc, valuesToSkip);
// If: I ask for the command for the row insert
DbCommand cmd = rc.GetCommand(mockConn);
@@ -304,10 +383,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Generate a row create with default values
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, columns.Length);
RowCreate rc = new RowCreate(rowId, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 3, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// If: I request an edit row from the row create
EditRow er = rc.GetEditRow(null);
@@ -335,10 +413,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Generate a row create with an identity column
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, true);
RowCreate rc = new RowCreate(rowId, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// If: I request an edit row from the row created
EditRow er = rc.GetEditRow(null);
@@ -463,7 +540,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
await rs.ReadResultToEnd(testReader, CancellationToken.None);
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
var etm = Common.GetCustomEditTableMetadata(cols);
// ... Create the row create
RowCreate rc = new RowCreate(100, rs, etm);
@@ -492,7 +569,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SetCellNull()
{
// Setup: Generate a row create
RowCreate rc = await GetStandardRowCreate();
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 3);
var rs = await Common.GetResultSet(data.DbColumns, false);
var rc = new RowCreate(100, rs, data.TableMetadata);
// If: I set a cell in the newly created row to null
const string nullValue = "NULL";
@@ -534,16 +613,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RevertCellNotSet(bool hasDefaultValues)
[InlineData(1)]
[InlineData(0)]
public async Task RevertCellNotSet(int defaultCols)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, hasDefaultValues ? 1 : 0);
RowCreate rc = new RowCreate(100, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// If: I attempt to revert a cell that has not been set
EditRevertCellResult result = rc.RevertCell(0);
@@ -553,7 +631,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(result);
// ... We should get back an edit cell with a value based on the default value
string expectedDisplayValue = hasDefaultValues ? Common.DefaultValue : string.Empty;
string expectedDisplayValue = defaultCols > 0 ? Common.DefaultValue : string.Empty;
Assert.NotNull(result.Cell);
Assert.Equal(expectedDisplayValue, result.Cell.DisplayValue);
Assert.False(result.Cell.IsNull); // TODO: Modify to support null defaults
@@ -566,16 +644,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RevertCellThatWasSet(bool hasDefaultValues)
[InlineData(1)]
[InlineData(0)]
public async Task RevertCellThatWasSet(int defaultCols)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, hasDefaultValues ? 1 : 0);
RowCreate rc = new RowCreate(100, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
rc.SetCell(0, "1");
// If: I attempt to revert a cell that was set
@@ -586,7 +663,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(result);
// ... We should get back an edit cell with a value based on the default value
string expectedDisplayValue = hasDefaultValues ? Common.DefaultValue : string.Empty;
string expectedDisplayValue = defaultCols > 0 ? Common.DefaultValue : string.Empty;
Assert.NotNull(result.Cell);
Assert.Equal(expectedDisplayValue, result.Cell.DisplayValue);
Assert.False(result.Cell.IsNull); // TODO: Modify to support null defaults
@@ -602,10 +679,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private static async Task<RowCreate> GetStandardRowCreate()
{
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
return new RowCreate(100, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowCreate(100, rs, data.TableMetadata);
}
public class RegexExpectedOutput
@@ -617,9 +693,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
ExpectedOutColumns = expectedOutColumns;
}
public int ExpectedInColumns { get; set; }
public int ExpectedInValues { get; set; }
public int ExpectedOutColumns { get; set; }
public int ExpectedInColumns { get; }
public int ExpectedInValues { get; }
public int ExpectedOutColumns { get; }
}
}
}

View File

@@ -8,7 +8,6 @@ using System.Data.Common;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -24,17 +23,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task RowDeleteConstruction()
{
// Setup: Create the values to store
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I create a RowCreate instance
RowDelete rc = new RowDelete(100, rs, etm);
RowDelete rc = new RowDelete(100, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(100, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
[Theory]
@@ -42,12 +40,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
[InlineData(false)]
public async Task GetScriptTest(bool isMemoryOptimized)
{
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I ask for a script to be generated for delete
RowDelete rd = new RowDelete(0, rs, etm);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
string script = rd.GetScript();
// Then:
@@ -55,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(script);
// ... It should be formatted as a delete script
string scriptStart = $"DELETE FROM {etm.EscapedMultipartName}";
string scriptStart = $"DELETE FROM {data.TableMetadata.EscapedMultipartName}";
if (isMemoryOptimized)
{
scriptStart += " WITH(SNAPSHOT)";
@@ -67,12 +64,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task ApplyChanges()
{
// Setup: Generate the parameters for the row delete object
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I ask for the change to be applied
RowDelete rd = new RowDelete(0, rs, etm);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
await rd.ApplyChanges(null); // Reader not used, can be null
// Then : The result set should have one less row in it
@@ -88,10 +84,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row delete
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
RowDelete rd = new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(null);
@@ -117,7 +112,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... There should be a table
string tbl = m.Groups[1].Value;
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
// ... There should be as many where components as there are keys
string[] whereComponents = m.Groups[2].Value.Split(new[] {"AND"}, StringSplitOptions.None);
@@ -142,10 +137,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetEditRow()
{
// Setup: Create a row delete
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowDelete rd = new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
// If: I attempt to get an edit row
DbCellValue[] cells = rs.GetRow(0).ToArray();
@@ -208,10 +202,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private async Task<RowDelete> GetStandardRowDelete()
{
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
return new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowDelete(0, rs, data.TableMetadata);
}
}
}

View File

@@ -47,7 +47,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
new TestDbColumn("col1")
},
new object[] { "id", "1" });
var etm = Common.GetStandardMetadata(rs.Columns);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
// If: I validate a column ID that is out of range
// Then: It should throw
@@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
new TestDbColumn("col1")
},
new object[] { "id", "1" });
var etm = Common.GetStandardMetadata(rs.Columns);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
// If: I validate a column ID that is not updatable
// Then: It should throw
@@ -80,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with a single column
var cols = new[] {col};
ResultSet rs = await GetResultSet(cols, new[] {val});
EditTableMetadata etm = Common.GetStandardMetadata(cols);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(cols);
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseSingleKey(nullClause);
@@ -130,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with multiple key columns
DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")};
ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"});
EditTableMetadata etm = Common.GetStandardMetadata(cols);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(cols);
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseMultipleKeys();
@@ -142,7 +142,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with no key columns
DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")};
ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"});
EditTableMetadata etm = Common.GetStandardMetadata(new DbColumn[] {});
EditTableMetadata etm = Common.GetCustomEditTableMetadata(new DbColumn[] {});
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseNoKeys();
@@ -152,16 +152,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingByTypeTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I request to sort a list of the three different edit operations
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowDelete(0, rs, etm),
new RowUpdate(0, rs, etm),
new RowCreate(0, rs, etm)
new RowDelete(0, rs, data.TableMetadata),
new RowUpdate(0, rs, data.TableMetadata),
new RowCreate(0, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -174,16 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingUpdatesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false, 4);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false, 4);
// If: I sort 3 edit operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowUpdate(3, rs, etm),
new RowUpdate(1, rs, etm),
new RowUpdate(2, rs, etm)
new RowUpdate(3, rs, data.TableMetadata),
new RowUpdate(1, rs, data.TableMetadata),
new RowUpdate(2, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -197,16 +195,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingCreatesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I sort 3 edit operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowCreate(3, rs, etm),
new RowCreate(1, rs, etm),
new RowCreate(2, rs, etm)
new RowCreate(3, rs, data.TableMetadata),
new RowCreate(1, rs, data.TableMetadata),
new RowCreate(2, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -220,16 +217,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingDeletesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I sort 3 delete operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowDelete(1, rs, etm),
new RowDelete(3, rs, etm),
new RowDelete(2, rs, etm)
new RowDelete(1, rs, data.TableMetadata),
new RowDelete(3, rs, data.TableMetadata),
new RowDelete(2, rs, data.TableMetadata)
};
rowEdits.Sort();

View File

@@ -9,7 +9,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -23,20 +22,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public class RowUpdateTests
{
[Fact]
public void RowUpdateConstruction()
public async Task RowUpdateConstruction()
{
// Setup: Create the values to store
const long rowId = 0;
ResultSet rs = QueryExecution.Common.GetBasicExecutedBatch().ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I create a RowUpdate instance
RowUpdate rc = new RowUpdate(rowId, rs, etm);
RowUpdate rc = new RowUpdate(rowId, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(rowId, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
[Fact]
@@ -88,7 +87,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
rs.ReadResultToEnd(testReader, CancellationToken.None).Wait();
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
var etm = Common.GetCustomEditTableMetadata(cols);
// ... Create the row update
RowUpdate ru = new RowUpdate(0, rs, etm);
@@ -121,13 +120,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SetCellImplicitRevertTest()
{
// Setup: Create a fake table to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If:
// ... I add updates to all the cells in the row
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, 1);
// ... Then I update a cell back to it's old value
@@ -159,16 +157,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.All(updateSplit, s => Assert.Equal(2, s.Split('=').Length));
}
[Fact]
public async Task SetCellImplicitRowRevertTests()
{
// Setup: Create a fake column to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If:
// ... I add updates to one cell in the row
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(1, "qqq");
// ... Then I update the cell to its original value
@@ -198,12 +196,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetScriptTest(bool isMemoryOptimized)
{
// Setup: Create a fake table to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I ask for a script to be generated for update
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, 1);
string script = ru.GetScript();
@@ -223,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
string tbl = m.Groups[1].Value;
string updates = m.Groups[2].Value;
string[] updateSplit = updates.Split(',');
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
Assert.Equal(3, updateSplit.Length);
Assert.All(updateSplit, s => Assert.Equal(2, s.Split('=').Length));
}
@@ -237,10 +234,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update with cell updates
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, includeIdentity ? 1 : 0);
// ... Mock db connection for building the command
@@ -268,7 +264,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... There should be a table
string tbl = m.Groups[1].Value;
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
// ... There should be 3 parameters for input
string[] inCols = m.Groups[2].Value.Split(',');
@@ -301,10 +297,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetEditRow()
{
// Setup: Create a row update with a cell set
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "foo");
// If: I attempt to get an edit row
@@ -356,14 +351,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
long oldBytesWritten = rs.totalBytesWritten;
// ... Setup a db reader for the result of an update
var newRowReader = Common.GetNewRowDataReader(columns, includeIdentity);
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
// If: I ask for the change to be applied
await ru.ApplyChanges(newRowReader);
@@ -379,10 +373,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(true);
var rs = await Common.GetResultSet(columns, true);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, true);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I ask for the changes to be applied with a null db reader
// Then: I should get an exception
@@ -397,10 +390,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I attempt to revert a cell that is out of range
// Then: I should get an exception
@@ -412,10 +404,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(true);
var rs = await Common.GetResultSet(columns, true);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, true);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I attempt to revert a cell that has not been set
EditRevertCellResult result = ru.RevertCell(0);
@@ -441,10 +432,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "qqq");
ru.SetCell(1, "qqq");
@@ -472,10 +462,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "qqq");
// If: I attempt to revert a cell that was set
@@ -499,10 +488,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private async Task<RowUpdate> GetStandardRowUpdate()
{
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
return new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowUpdate(0, rs, data.TableMetadata);
}
}
}

View File

@@ -16,7 +16,6 @@ using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts.ExecuteRequests;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Test.Common.RequestContextMocking;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Moq;
using Xunit;
@@ -357,7 +356,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
var cols = mockQueryResults[0].Columns;
// ... Create a metadata factory that will return some generic column information
var etm = Common.GetStandardMetadata(cols.ToArray());
var etm = Common.GetCustomEditTableMetadata(cols.ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -442,7 +441,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
return s;
}

View File

@@ -130,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// ... Add a mock edit to the edit cache to cause the .TryAdd to fail
@@ -155,7 +155,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];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// If: I add a row to the session
@@ -212,7 +212,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
etm.Extend(cols);
// ... Create a result set
var q = await Common.GetQuery(cols, false);
var q = await Common.GetQuery(cols.Cast<DbColumn>().ToArray(), false);
// ... Create a session from all this
EditSession s = await Common.GetCustomSession(q, etm);
@@ -273,10 +273,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Revert Cell
Action<EditSession, long> 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};
yield return new object[] {-1L, revertCellAction};
yield return new object[] {0L, revertCellAction}; // This is invalid b/c there isn't an edit pending for this row
yield return new object[] {(long) QueryExecution.Common.StandardRows, revertCellAction};
yield return new object[] {100L, revertCellAction};
}
}
@@ -410,7 +410,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// 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);
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -449,7 +449,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// 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);
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -488,7 +488,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... 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);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -499,7 +499,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a query runner that will return a successful query
Mock<EditSession.QueryRunner> qr = new Mock<EditSession.QueryRunner>();
qr.Setup(r => r(It.IsAny<string>()))
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q, null)));
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q)));
// ... Create a mock for verifying the failure handler will be called
var successHandler = DoNothingSuccessMock;
@@ -755,7 +755,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];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// If: I ask for 3 rows from session skipping the first
@@ -1129,15 +1129,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryWithoutLimit()
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows without a limit
EditInitializeFiltering eif = new EditInitializeFiltering
{
LimitResults = null
};
string query = EditSession.ConstructInitializeQuery(etm, eif);
string query = EditSession.ConstructInitializeQuery(data.TableMetadata, eif);
// Then:
// ... The query should look like a select statement
@@ -1146,10 +1145,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.True(match.Success);
// ... There should be columns in it
Assert.Equal(etm.Columns.Length, match.Groups[1].Value.Split(',').Length);
Assert.Equal(data.DbColumns.Length, match.Groups[1].Value.Split(',').Length);
// ... The table name should be in it
Assert.Equal(etm.EscapedMultipartName, match.Groups[2].Value);
Assert.Equal(data.TableMetadata.EscapedMultipartName, match.Groups[2].Value);
// ... It should NOT have a TOP clause in it
Assert.DoesNotContain("TOP", query);
@@ -1159,8 +1158,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryNegativeLimit()
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows with a negative limit
// Then: An exception should be thrown
@@ -1168,7 +1166,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
LimitResults = -1
};
Assert.Throws<ArgumentOutOfRangeException>(() => EditSession.ConstructInitializeQuery(etm, eif));
Assert.Throws<ArgumentOutOfRangeException>(() => EditSession.ConstructInitializeQuery(data.TableMetadata, eif));
}
[Theory]
@@ -1178,15 +1176,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryWithLimit(int limit)
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows without a limit
EditInitializeFiltering eif = new EditInitializeFiltering
{
LimitResults = limit
};
string query = EditSession.ConstructInitializeQuery(etm, eif);
string query = EditSession.ConstructInitializeQuery(data.TableMetadata, eif);
// Then:
// ... The query should look like a select statement
@@ -1195,10 +1192,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.True(match.Success);
// ... There should be columns in it
Assert.Equal(etm.Columns.Length, match.Groups[2].Value.Split(',').Length);
Assert.Equal(data.DbColumns.Length, match.Groups[2].Value.Split(',').Length);
// ... The table name should be in it
Assert.Equal(etm.EscapedMultipartName, match.Groups[3].Value);
Assert.Equal(data.TableMetadata.EscapedMultipartName, match.Groups[3].Value);
// ... The top count should be equal to what we provided
int limitFromQuery;
@@ -1251,7 +1248,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
return await Common.GetCustomSession(q, etm);
}
}

View File

@@ -0,0 +1,58 @@
ID | Identity Column | Default Cols | Nullable Cols | Values Set | INSERT VALID | In Cols | In Vals | Out Vals
---+-----------------+--------------+---------------+------------+--------------------------------------------------------------+------------------------------
01 | Y | 0 (None) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
02 | Y | 0 (None) | 0 (None) | 2/2 | INVALID - Values missing | N/A | N/A | N/A
03 | Y | 0 (None) | 0 (None) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
04 | Y | 0 (None) | 1 (Some) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
05 | Y | 0 (None) | 1 (Some) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
06 | Y | 0 (None) | 1 (Some) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
07 | Y | 0 (None) | 3 (All) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
08 | Y | 0 (None) | 3 (All) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
09 | Y | 0 (None) | 3 (All) | 0/4 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 4
10 | Y | 1 (Some) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
11 | Y | 1 (Some) | 0 (None) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
12 | Y | 1 (Some) | 0 (None) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
13 | Y | 1 (Some) | 1 (Some) | 3/1 | INSERT INTO [test] (col1, col2, col3) VALUES ('a', 'b', 'c') | 3 | 3 | 4
14 | Y | 1 (Some) | 1 (Some) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
15 | Y | 1 (Some) | 1 (Some) | 1/3 | INSERT INTO [test] (col3) VALUES ('c') | 1 | 1 | 4
16 | Y | 1 (Some) | 1 (Some) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
17 | Y | 3 (All) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
18 | Y | 3 (All) | 0 (None) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
19 | Y | 3 (All) | 0 (None) | 0/4 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 4
!! | Y | 3 (All) | 1 (Some) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 1 (Some) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 1 (Some) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
20 | N | 0 (None) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
21 | N | 0 (None) | 0 (None) | 2/1 | INVALID - Values missing | N/A | N/A | N/A
22 | N | 0 (None) | 0 (None) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
23 | N | 0 (None) | 1 (Some) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
24 | N | 0 (None) | 1 (Some) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
25 | N | 0 (None) | 1 (Some) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
26 | N | 0 (None) | 3 (All) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
27 | N | 0 (None) | 3 (All) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
28 | N | 0 (None) | 3 (All) | 0/3 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 3
29 | N | 1 (Some) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
30 | N | 1 (Some) | 0 (None) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
31 | N | 1 (Some) | 0 (None) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
32 | N | 1 (Some) | 1 (Some) | 3/0 | INSERT INTO [test] (col1, col2, col3) VALUES ('a', 'b', 'c') | 3 | 3 | 3
33 | N | 1 (Some) | 1 (Some) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
34 | N | 1 (Some) | 1 (Some) | 1/2 | INSERT INTO [test] (col3) VALUES ('c') | 1 | 1 | 3
35 | N | 1 (Some) | 1 (Some) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A
36 | N | 3 (All) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
37 | N | 3 (All) | 0 (None) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
38 | N | 3 (All) | 0 (None) | 0/3 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 3
!! | N | 3 (All) | 1 (Some) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 1 (Some) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 1 (Some) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A