Skip to content

Commit 5c24f3b

Browse files
Add the support to retrieve the seed/increment for the IDENTITY column (fixes #10).
1 parent 318a98e commit 5c24f3b

11 files changed

Lines changed: 183 additions & 46 deletions

File tree

src/Testing.Databases.SqlServer/Comparer/SqlObjectComparer.cs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace PosInformatique.Testing.Databases.SqlServer
88
{
9+
using System.Diagnostics.CodeAnalysis;
10+
911
internal sealed class SqlObjectComparer : ISqlObjectVisitor<SqlObjectDifferences?>
1012
{
1113
private readonly SqlObject source;
@@ -73,7 +75,7 @@ public static IList<SqlTableDifferences> Compare(IReadOnlyList<SqlTable> source,
7375
this.CompareProperty(column, t => t.Precision, nameof(column.Precision)),
7476
this.CompareProperty(column, t => t.Scale, nameof(column.Scale)),
7577
this.CompareProperty(column, t => t.IsNullable, nameof(column.IsNullable)),
76-
this.CompareProperty(column, t => t.IsIdentity, nameof(column.IsIdentity)),
78+
this.CompareProperty(column, t => t.Identity, nameof(column.Identity), equalityComparer: SqlColumnIdentityComparer.Instance),
7779
this.CompareProperty(column, t => t.CollationName, nameof(column.CollationName)),
7880
this.CompareProperty(column, t => t.IsComputed, nameof(column.IsComputed)),
7981
this.CompareProperty(column, t => TsqlCodeHelper.RemoveNotUsefulCharacters(t.ComputedExpression), nameof(column.ComputedExpression), t => t.ComputedExpression));
@@ -331,7 +333,7 @@ private static IReadOnlyList<SqlObjectPropertyDifference> GetPropertyDifferences
331333
return objects.SingleOrDefault(o => Equals(keySelector(o), value));
332334
}
333335

334-
private SqlObjectPropertyDifference? CompareProperty<TSqlObject>(TSqlObject target, Func<TSqlObject, object?> propertyValueForComparison, string name, Func<TSqlObject, object?>? propertyValueToDisplay = null)
336+
private SqlObjectPropertyDifference? CompareProperty<TSqlObject, TProperty>(TSqlObject target, Func<TSqlObject, TProperty?> propertyValueForComparison, string name, Func<TSqlObject, TProperty?>? propertyValueToDisplay = null, IEqualityComparer<TProperty?>? equalityComparer = null)
335337
where TSqlObject : SqlObject
336338
{
337339
var source = (TSqlObject)this.source;
@@ -344,7 +346,12 @@ private static IReadOnlyList<SqlObjectPropertyDifference> GetPropertyDifferences
344346
var sourceValue = propertyValueForComparison(source);
345347
var targetValue = propertyValueForComparison(target);
346348

347-
if (!Equals(sourceValue, targetValue))
349+
if (equalityComparer is null)
350+
{
351+
equalityComparer = EqualityComparer<TProperty?>.Default;
352+
}
353+
354+
if (!equalityComparer.Equals(sourceValue, targetValue))
348355
{
349356
return new SqlObjectPropertyDifference(name, propertyValueToDisplay(source), propertyValueToDisplay(target));
350357
}
@@ -364,5 +371,50 @@ private static IReadOnlyList<SqlObjectPropertyDifference> GetPropertyDifferences
364371

365372
return new SqlObjectDifferences<TSqlObject>((TSqlObject)this.source, target, SqlObjectDifferenceType.Different, properties!);
366373
}
374+
375+
private sealed class SqlColumnIdentityComparer : IEqualityComparer<SqlColumnIdentity?>
376+
{
377+
private SqlColumnIdentityComparer()
378+
{
379+
}
380+
381+
public static SqlColumnIdentityComparer Instance { get; } = new SqlColumnIdentityComparer();
382+
383+
public bool Equals(SqlColumnIdentity? x, SqlColumnIdentity? y)
384+
{
385+
if (x is null)
386+
{
387+
if (y is null)
388+
{
389+
return true;
390+
}
391+
392+
return false;
393+
}
394+
395+
if (y is null)
396+
{
397+
return false;
398+
}
399+
400+
if (x.Seed != y.Seed)
401+
{
402+
return false;
403+
}
404+
405+
if (x.Increment != y.Increment)
406+
{
407+
return false;
408+
}
409+
410+
return true;
411+
}
412+
413+
[ExcludeFromCodeCoverage]
414+
public int GetHashCode(SqlColumnIdentity? obj)
415+
{
416+
throw new NotImplementedException();
417+
}
418+
}
367419
}
368420
}

src/Testing.Databases.SqlServer/ObjectModel/SqlColumn.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ internal SqlColumn(
7070
/// <summary>
7171
/// Gets a value indicating whether if the column is identity.
7272
/// </summary>
73-
public bool IsIdentity { get; internal set; }
73+
public SqlColumnIdentity? Identity { get; internal set; }
7474

7575
/// <summary>
7676
/// Gets a value indicating whether if the column is computed.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="SqlColumnIdentity.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace PosInformatique.Testing.Databases
8+
{
9+
/// <summary>
10+
/// Represents the <see cref="SqlColumn.Identity"/> information when
11+
/// a <see cref="SqlColumn"/> is an <c>IDENTITY</c> column.
12+
/// </summary>
13+
public class SqlColumnIdentity
14+
{
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="SqlColumnIdentity"/> class.
17+
/// </summary>
18+
/// <param name="seed">Seed of the <c>IDENTITY</c> column.</param>
19+
/// <param name="increment">Increment of the <c>IDENTITY</c> column.</param>
20+
public SqlColumnIdentity(int seed, int increment)
21+
{
22+
this.Seed = seed;
23+
this.Increment = increment;
24+
}
25+
26+
/// <summary>
27+
/// Gets the seed of the <c>IDENTITY</c> column.
28+
/// </summary>
29+
public int Seed { get; }
30+
31+
/// <summary>
32+
/// Gets the increment of the <c>IDENTITY</c> column.
33+
/// </summary>
34+
public int Increment { get; }
35+
36+
/// <inheritdoc />
37+
public override string ToString()
38+
{
39+
return $"(Seed: {this.Seed}, Increment: {this.Increment})";
40+
}
41+
}
42+
}

src/Testing.Databases.SqlServer/SqlServerDatabaseObjectExtensions.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,18 @@ private static async Task<ILookup<int, DataRow>> GetColumnsAsync(SqlServerDataba
298298
[c].[collation_name] AS [CollationName],
299299
[c].[is_nullable] AS [IsNullable],
300300
[c].[is_identity] AS [IsIdentity],
301+
[ic].[seed_value] AS [IdentitySeed],
302+
[ic].[increment_value] AS [IdentityIncrement],
301303
[c].[is_computed] AS [IsComputed],
302304
[cc].[definition] AS [ComputedExpression]
303305
FROM
304306
[sys].[columns] AS [c]
305307
LEFT OUTER JOIN
306308
[sys].[computed_columns] AS [cc]
307-
ON ([c].[object_id] = [cc].[object_id] AND [c].[column_id] = [cc].[column_id]),
309+
ON ([c].[object_id] = [cc].[object_id] AND [c].[column_id] = [cc].[column_id])
310+
LEFT OUTER JOIN
311+
[sys].[identity_columns] AS [ic]
312+
ON ([c].[object_id] = [ic].[object_id] AND [c].[column_id] = [ic].[column_id]),
308313
[sys].[tables] AS [t],
309314
[sys].[types] AS [ty]
310315
WHERE
@@ -500,6 +505,13 @@ private static SqlCheckConstraint ToCheckConstraint(DataRow row)
500505

501506
private static SqlColumn ToColumn(DataRow row, DataRow? defaultConstraintRow)
502507
{
508+
SqlColumnIdentity? identity = null;
509+
510+
if ((bool)row["IsIdentity"] == true)
511+
{
512+
identity = new SqlColumnIdentity((int)row["IdentitySeed"], (int)row["IdentityIncrement"]);
513+
}
514+
503515
return new SqlColumn(
504516
(string)row["Name"],
505517
Convert.ToInt32(row["Position"], CultureInfo.InvariantCulture),
@@ -512,7 +524,7 @@ private static SqlColumn ToColumn(DataRow row, DataRow? defaultConstraintRow)
512524
ComputedExpression = NullIfDbNull<string>(row["ComputedExpression"]),
513525
DefaultConstraint = defaultConstraintRow != null ? ToDefaultConstraint(defaultConstraintRow) : null,
514526
IsComputed = (bool)row["IsComputed"],
515-
IsIdentity = (bool)row["IsIdentity"],
527+
Identity = identity,
516528
IsNullable = (bool)row["IsNullable"],
517529
};
518530
}

tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableDifference.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[MaxLength] VARCHAR(50) NOT NULL,
66
[Precision] DECIMAL(10, 2) NOT NULL,
77
[Scale] DECIMAL(10, 2) NOT NULL,
8-
[Identity] INT NOT NULL IDENTITY,
8+
[Identity] INT NOT NULL IDENTITY (2, 3),
99
[ForeignKeyId] INT NULL,
1010
[Computed] AS [Scale] + [Precision],
1111
[SourceColumn] INT NOT NULL,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CREATE TABLE [dbo].[TableIdentical]
22
(
3-
[Id] INT NOT NULL,
3+
[Id] INT IDENTITY (4, 5) NOT NULL,
44
[ForeignKeyId] INT NOT NULL CONSTRAINT DF_TableIdentical_ForeignKeyId DEFAULT (1 + 2 + 3),
55
[IncludeColumn] INT NOT NULL,
66
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CREATE TABLE [dbo].[TableWithDifferentPrimaryKey]
22
(
3-
[Id] INT NOT NULL,
3+
[Id] INT IDENTITY (10, 20) NOT NULL,
44

55
CONSTRAINT [PK_TableWithDifferentPrimaryKey_Source] PRIMARY KEY CLUSTERED ([Id] ASC)
66
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CREATE TABLE [dbo].[TableWithDifferentPrimaryKey]
22
(
3-
[Id] INT NOT NULL,
3+
[Id] INT IDENTITY (1, 2) NOT NULL,
44

55
CONSTRAINT [PK_TableWithDifferentPrimaryKey_Target] PRIMARY KEY CLUSTERED ([Id] ASC)
66
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="SqlColumnIdentityTest.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace PosInformatique.Testing.Databases.Tests
8+
{
9+
public class SqlColumnIdentityTest
10+
{
11+
[Fact]
12+
public void ToStringTest()
13+
{
14+
var column = new SqlColumnIdentity(1, 2);
15+
16+
column.ToString().Should().Be("(Seed: 1, Increment: 2)");
17+
}
18+
}
19+
}

tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.CompareAsync.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
Source: 2
4343
Target: 4
4444
- Identity
45-
* IsIdentity:
46-
Source: True
47-
Target: False
45+
* Identity:
46+
Source: (Seed: 2, Increment: 3)
47+
Target: <No value>
4848
- Computed
4949
* Scale:
5050
Source: 2
@@ -166,6 +166,11 @@
166166
Target: 2
167167
- dbo.TableTarget (Missing in the source)
168168
- dbo.TableWithDifferentPrimaryKey
169+
------ Columns ------
170+
- Id
171+
* Identity:
172+
Source: (Seed: 10, Increment: 20)
173+
Target: (Seed: 1, Increment: 2)
169174
------ Indexes ------
170175
- PK_TableWithDifferentPrimaryKey_Target (Missing in the source)
171176
- PK_TableWithDifferentPrimaryKey_Source (Missing in the target)

0 commit comments

Comments
 (0)