Skip to content

Commit

Permalink
fix merge bug
Browse files Browse the repository at this point in the history
  • Loading branch information
pwelter34 committed Jul 9, 2024
1 parent 153368d commit e5ace3c
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/FluentCommand.SqlServer/Merge/DataMergeDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public static void AutoMap<TEntity>(DataMergeDefinition mergeDefinition)

foreach (var property in typeAccessor.GetProperties())
{
string sourceColumn = property.Name;
string sourceColumn = property.Column;
string targetColumn = property.Column;
string nativeType = property.ColumnType ?? SqlTypeMapping.NativeType(property.MemberType);

Expand Down
2 changes: 1 addition & 1 deletion src/FluentCommand.SqlServer/Merge/DataMergeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private static void AppendUsingData(DataMergeDefinition mergeDefinition, List<Da
builder
.AppendLineIf(", ", s => wroteRow)
.Append(' ', TabSize)
.Append("(");
.Append("(");

for (int i = 0; i < reader.FieldCount; i++)
{
Expand Down
22 changes: 22 additions & 0 deletions test/FluentCommand.Entities/Member.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace FluentCommand.Entities;

[Table("member_user", Schema = "dbo")]
public class Member
{
[Column("Id")]
public Guid Id { get; set; }

[Column("email_address")]
public string EmailAddress { get; set; }

[Column("display_name")]
public string DisplayName { get; set; }

[Column("first_name")]
public string FirstName { get; set; }

[Column("last_name")]
public string LastName { get; set; }
}
72 changes: 62 additions & 10 deletions test/FluentCommand.SqlServer.Tests/DataMergeGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void QuoteIdentifier()
}

[Fact]
public void BuildMergeTests()
public async System.Threading.Tasks.Task BuildMergeTests()
{
var definition = new DataMergeDefinition();

Expand All @@ -79,13 +79,15 @@ public void BuildMergeTests()
var sql = DataMergeGenerator.BuildMerge(definition);
sql.Should().NotBeNullOrEmpty();

Output.WriteLine("MergeStatement:");
Output.WriteLine(sql);
await Verifier
.Verify(sql)
.UseDirectory("Snapshots")
.AddScrubber(scrubber => scrubber.Replace(definition.TemporaryTable, "#MergeTable"));
}


[Fact]
public void BuildMergeDataTests()
public async System.Threading.Tasks.Task BuildMergeDataTests()
{
var definition = new DataMergeDefinition();

Expand Down Expand Up @@ -123,8 +125,9 @@ public void BuildMergeDataTests()
var sql = DataMergeGenerator.BuildMerge(definition, listDataReader);
sql.Should().NotBeNullOrEmpty();

Output.WriteLine("MergeStatement:");
Output.WriteLine(sql);
await Verifier
.Verify(sql)
.UseDirectory("Snapshots");
}

[Fact]
Expand Down Expand Up @@ -248,7 +251,7 @@ await Verifier
}

[Fact]
public void BuildMergeDataOutputTests()
public async System.Threading.Tasks.Task BuildMergeDataOutputTests()
{
var definition = new DataMergeDefinition();

Expand Down Expand Up @@ -282,7 +285,7 @@ public void BuildMergeDataOutputTests()
},
new UserImport
{
EmailAddress = $"random.{DateTime.Now.Ticks}@email.com",
EmailAddress = $"[email protected]",
DisplayName = "Random User",
FirstName = "Random",
LastName = "User"
Expand All @@ -294,8 +297,57 @@ public void BuildMergeDataOutputTests()
var sql = DataMergeGenerator.BuildMerge(definition, dataTable);
sql.Should().NotBeNullOrEmpty();

Output.WriteLine("MergeStatement:");
Output.WriteLine(sql);
await Verifier
.Verify(sql)
.UseDirectory("Snapshots");
}

[Fact]
public async System.Threading.Tasks.Task BuildMergeDataMismatchTests()
{
var definition = new DataMergeDefinition();

DataMergeDefinition.AutoMap<Member>(definition);
definition.Columns.Should().NotBeNullOrEmpty();

var column = definition.Columns.Find(c => c.SourceColumn == "email_address");
column.Should().NotBeNull();

column.IsKey = true;
column.CanUpdate = false;

var users = new List<Member>
{
new Member
{
EmailAddress = "[email protected]",
DisplayName = "Test User",
FirstName = "Test",
LastName = "User"
},
new Member
{
EmailAddress = "[email protected]",
DisplayName = "Blah User",
FirstName = "Blah",
LastName = "User"
},
new Member
{
EmailAddress = $"[email protected]",
DisplayName = "Random User",
FirstName = "Random",
LastName = "User"
}
};

var dataTable = new ListDataReader<Member>(users);

var mergeDataStatement = DataMergeGenerator.BuildMerge(definition, dataTable);
mergeDataStatement.Should().NotBeNullOrEmpty();

await Verifier
.Verify(mergeDataStatement)
.UseDirectory("Snapshots");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ CREATE TABLE [dbo].[User] (
CONSTRAINT [PK_User] PRIMARY KEY ([Id])
);

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[member_user]') AND type in (N'U'))
CREATE TABLE [dbo].[member_user] (
[Id] uniqueidentifier NOT NULL DEFAULT (NEWSEQUENTIALID()),
[email_address] nvarchar(256) NOT NULL,
[display_name] nvarchar(256) NOT NULL,
[first_name] nvarchar(256) NULL,
[last_name] nvarchar(256) NULL,
CONSTRAINT [PK_member_user] PRIMARY KEY ([Id])
);

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UserLogin]') AND type in (N'U'))
CREATE TABLE [dbo].[UserLogin] (
[Id] uniqueidentifier NOT NULL DEFAULT (NEWSEQUENTIALID()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
MERGE INTO [dbo].[member_user] AS t
USING
(
VALUES
('00000000-0000-0000-0000-000000000000', '[email protected]', 'Test User', 'Test', 'User'),
('00000000-0000-0000-0000-000000000000', '[email protected]', 'Blah User', 'Blah', 'User'),
('00000000-0000-0000-0000-000000000000', '[email protected]', 'Random User', 'Random', 'User')
)
AS s
(
[Id], [email_address], [display_name], [first_name], [last_name]
)
ON
(
t.[email_address] = s.[email_address]
)
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[Id],
[email_address],
[display_name],
[first_name],
[last_name]
)
VALUES
(
s.[Id],
s.[email_address],
s.[display_name],
s.[first_name],
s.[last_name]
)
WHEN MATCHED THEN
UPDATE SET
t.[Id] = s.[Id],
t.[display_name] = s.[display_name],
t.[first_name] = s.[first_name],
t.[last_name] = s.[last_name]
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
MERGE INTO [dbo].[User] AS t
USING
(
VALUES
('[email protected]', 'Test User', 'Test', 'User', NULL, NULL),
('[email protected]', 'Blah User', 'Blah', 'User', NULL, NULL),
('[email protected]', 'Random User', 'Random', 'User', NULL, NULL)
)
AS s
(
[EmailAddress], [DisplayName], [FirstName], [LastName], [LockoutEnd], [LastLogin]
)
ON
(
t.[EmailAddress] = s.[EmailAddress]
)
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[EmailAddress],
[DisplayName],
[FirstName],
[LastName],
[LockoutEnd],
[LastLogin]
)
VALUES
(
s.[EmailAddress],
s.[DisplayName],
s.[FirstName],
s.[LastName],
s.[LockoutEnd],
s.[LastLogin]
)
WHEN MATCHED THEN
UPDATE SET
t.[DisplayName] = s.[DisplayName],
t.[FirstName] = s.[FirstName],
t.[LastName] = s.[LastName],
t.[LockoutEnd] = s.[LockoutEnd],
t.[LastLogin] = s.[LastLogin]
OUTPUT
$action as [Action],
DELETED.[EmailAddress] as [OriginalEmailAddress],
INSERTED.[EmailAddress] as [CurrentEmailAddress],
DELETED.[DisplayName] as [OriginalDisplayName],
INSERTED.[DisplayName] as [CurrentDisplayName],
DELETED.[FirstName] as [OriginalFirstName],
INSERTED.[FirstName] as [CurrentFirstName],
DELETED.[LastName] as [OriginalLastName],
INSERTED.[LastName] as [CurrentLastName],
DELETED.[LockoutEnd] as [OriginalLockoutEnd],
INSERTED.[LockoutEnd] as [CurrentLockoutEnd],
DELETED.[LastLogin] as [OriginalLastLogin],
INSERTED.[LastLogin] as [CurrentLastLogin];
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
MERGE INTO [dbo].[User] AS t
USING
(
VALUES
('[email protected]', 'Test User', 'Test', 'User', NULL, NULL),
('[email protected]', 'Blah User', 'Blah', 'User', NULL, NULL)
)
AS s
(
[EmailAddress], [DisplayName], [FirstName], [LastName], [LockoutEnd], [LastLogin]
)
ON
(
t.[EmailAddress] = s.[EmailAddress]
)
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[EmailAddress],
[DisplayName],
[FirstName],
[LastName],
[LockoutEnd],
[LastLogin]
)
VALUES
(
s.[EmailAddress],
s.[DisplayName],
s.[FirstName],
s.[LastName],
s.[LockoutEnd],
s.[LastLogin]
)
WHEN MATCHED THEN
UPDATE SET
t.[DisplayName] = s.[DisplayName],
t.[FirstName] = s.[FirstName],
t.[LastName] = s.[LastName],
t.[LockoutEnd] = s.[LockoutEnd],
t.[LastLogin] = s.[LastLogin]
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
MERGE INTO [dbo].[User] AS t
USING
(
SELECT
[EmailAddress],
[DisplayName],
[FirstName],
[LastName],
[LockoutEnd],
[LastLogin]
FROM [#MergeTable]
)
AS s
ON
(
t.[EmailAddress] = s.[EmailAddress]
)
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[EmailAddress],
[DisplayName],
[FirstName],
[LastName],
[LockoutEnd],
[LastLogin]
)
VALUES
(
s.[EmailAddress],
s.[DisplayName],
s.[FirstName],
s.[LastName],
s.[LockoutEnd],
s.[LastLogin]
)
WHEN MATCHED THEN
UPDATE SET
t.[DisplayName] = s.[DisplayName],
t.[FirstName] = s.[FirstName],
t.[LastName] = s.[LastName],
t.[LockoutEnd] = s.[LockoutEnd],
t.[LastLogin] = s.[LastLogin]
;

0 comments on commit e5ace3c

Please sign in to comment.