Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions PetaPoco.Tests.Integration/Databases/InsertTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,20 @@ public virtual void Insert_GivenTableNamePrimaryKeyNameAndAnonymousTypeWithStati
otherPerson.Height.ShouldBe(person.Height);
otherPerson.Name.ShouldBe(person.FullName);
}

[Fact]
public virtual void Insert_GivenTableWithAutoIncrementIdAndTrigger_ShouldInsertPoco()
{
var id = DB.Insert("BugInvestigation_ISSUE178", _order);

var insertedOrder =
DB.Single<Order>(
$"SELECT * FROM {DB.Provider.EscapeTableName("BugInvestigation_ISSUE178")} WHERE {DB.Provider.EscapeSqlIdentifier("Id")} = @0", _order.Id);

id.ShouldNotBeNull();
insertedOrder.Id.ShouldBe(id);
insertedOrder.ShouldBe(_order);
}

[Fact]
public virtual async Task InsertAsync_GivenPoco_ShouldBeValid()
Expand Down Expand Up @@ -432,5 +446,20 @@ public virtual async Task InsertAsync_GivenTableNamePrimaryKeyNameAndAnonymousTy
otherPerson.Height.ShouldBe(person.Height);
otherPerson.Name.ShouldBe(person.FullName);
}

[Fact]
public virtual async Task InsertAsync_GivenTableWithAutoIncrementIdAndTrigger_ShouldInsertPoco()
{
var id = await DB.InsertAsync("BugInvestigation_ISSUE178", _order);

var insertedOrder =
await DB.SingleAsync<Order>(
$"SELECT * FROM {DB.Provider.EscapeTableName("BugInvestigation_ISSUE178")} WHERE {DB.Provider.EscapeSqlIdentifier("Id")} = @0", _order.Id);

id.ShouldNotBeNull();
insertedOrder.Id.ShouldBe(id);
insertedOrder.ShouldBe(_order);
}
}

}
44 changes: 44 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/FirebirdBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,50 @@ CREATE TABLE "BugInvestigation_5TN5C4U4" (
"Column2" VARCHAR(20)
);

SET TERM !! ;
EXECUTE BLOCK AS
BEGIN
IF (EXISTS(SELECT 1 FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'BugInvestigation_ISSUE178')) THEN EXECUTE STATEMENT 'DROP TABLE "BugInvestigation_ISSUE178";';
END!!
SET TERM ; !!

CREATE TABLE "BugInvestigation_ISSUE178" (
"Id" INT PRIMARY KEY NOT NULL,
"PersonId" CHAR(36) NOT NULL,
"PoNumber" VARCHAR(15) NOT NULL,
"OrderStatus" INT NOT NULL,
"CreatedOn" TIMESTAMP NOT NULL,
"CreatedBy" VARCHAR(255) NOT NULL,
"UpdatedAt" TIMESTAMP
);

SET TERM !! ;
EXECUTE BLOCK AS BEGIN
if (exists(SELECT 1 FROM rdb$generators WHERE rdb$generator_name = 'GEN_BI_178_ID')) then execute statement 'DROP SEQUENCE GEN_BI_178_ID;';
END!!
SET TERM ; !!

CREATE SEQUENCE GEN_BI_178_ID;
ALTER SEQUENCE GEN_BI_178_ID RESTART WITH 0;

SET TERM !! ;
CREATE TRIGGER trigger_BI_178_id FOR "BugInvestigation_ISSUE178"
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW."Id" is NULL) THEN NEW."Id" = GEN_ID(GEN_BI_178_ID, 1);
END!!
SET TERM ; !!

SET TERM !! ;
CREATE OR ALTER TRIGGER "BI_ISSUE178_UPDATEDAT"
ACTIVE BEFORE INSERT OR UPDATE ON "BugInvestigation_ISSUE178"
AS
BEGIN
NEW."UpdatedAt" = CURRENT_TIMESTAMP;
END!!
SET TERM ; !!

-- Stored procedures

SET TERM !! ;
Expand Down
12 changes: 12 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/MSAccessBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,15 @@ CREATE TABLE BugInvestigation_5TN5C4U4 (
[ColumnA] TEXT(20),
[Column2] TEXT(20)
);

DROP TABLE [BugInvestigation_ISSUE178];

CREATE TABLE BugInvestigation_ISSUE178 (
[Id] AUTOINCREMENT PRIMARY KEY,
[PersonId] TEXT(36) NOT NULL,
[PoNumber] TEXT(15) NOT NULL,
[OrderStatus] INTEGER NOT NULL,
[CreatedOn] DATETIME NOT NULL,
[CreatedBy] TEXT(255) NOT NULL,
[UpdatedAt] DATETIME
);
26 changes: 26 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/MariaDBBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,32 @@ CREATE TABLE `BugInvestigation_5TN5C4U4` (
`Column2` VARCHAR(20)
) ENGINE=INNODB;

DROP TABLE IF EXISTS BugInvestigation_ISSUE178;

CREATE TABLE BugInvestigation_ISSUE178 (
`Id` INT AUTO_INCREMENT PRIMARY KEY,
`PersonId` CHAR(36) NOT NULL,
`PoNumber` VARCHAR(15) NOT NULL,
`OrderStatus` INT NOT NULL,
`CreatedOn` DATETIME NOT NULL,
`CreatedBy` VARCHAR(255) NOT NULL,
`UpdatedAt` DATETIME NULL
) ENGINE=INNODB;

CREATE TRIGGER Trigger_BugInvestigation_ISSUE178_UpdatedAt
BEFORE UPDATE ON BugInvestigation_ISSUE178
FOR EACH ROW
BEGIN
SET NEW.UpdatedAt = NOW();
END;

CREATE TRIGGER Trigger_BugInvestigation_ISSUE178_UpdatedAtInsert
BEFORE INSERT ON BugInvestigation_ISSUE178
FOR EACH ROW
BEGIN
SET NEW.UpdatedAt = NOW();
END;

-- Stored Procedures

DROP PROCEDURE IF EXISTS `SelectPeople`;
Expand Down
12 changes: 12 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/MySqlBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ CREATE TABLE `BugInvestigation_5TN5C4U4` (
`Column2` VARCHAR(20)
) ENGINE=INNODB;

DROP TABLE IF EXISTS `BugInvestigation_ISSUE178`;

CREATE TABLE `BugInvestigation_ISSUE178` (
`Id` INT AUTO_INCREMENT PRIMARY KEY,
`PersonId` CHAR(36) NOT NULL,
`PoNumber` VARCHAR(15) NOT NULL,
`OrderStatus` INT NOT NULL,
`CreatedOn` DATETIME(6) NOT NULL,
`CreatedBy` VARCHAR(255) NOT NULL,
`UpdatedAt` DATETIME(6) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6)
) ENGINE=INNODB;

-- Stored Procedures

DROP PROCEDURE IF EXISTS `SelectPeople`;
Expand Down
25 changes: 25 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/PostgresBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,31 @@ CREATE TABLE "BugInvestigation_5TN5C4U4" (
"Column2" VARCHAR(20)
);

DROP TABLE IF EXISTS "BugInvestigation_ISSUE178";

CREATE TABLE "BugInvestigation_ISSUE178" (
"Id" SERIAL PRIMARY KEY,
"PersonId" UUID NOT NULL,
"PoNumber" VARCHAR(15) NOT NULL,
"OrderStatus" INTEGER NOT NULL,
"CreatedOn" TIMESTAMP NOT NULL,
"CreatedBy" VARCHAR(255) NOT NULL,
"UpdatedAt" TIMESTAMP NULL
);

CREATE OR REPLACE FUNCTION update_buginvestigation_issue178_updatedat()
RETURNS TRIGGER AS $$
BEGIN
NEW."UpdatedAt" := NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_buginvestigation_issue178_updatedat
BEFORE INSERT OR UPDATE ON "BugInvestigation_ISSUE178"
FOR EACH ROW
EXECUTE FUNCTION update_buginvestigation_issue178_updatedat();

-- Stored Procedures

CREATE FUNCTION SelectPeople()
Expand Down
28 changes: 28 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/SQLiteBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,31 @@ CREATE TABLE BugInvestigation_5TN5C4U4 (
[ColumnA] TEXT,
[Column2] TEXT
);

DROP TABLE IF EXISTS BugInvestigation_ISSUE178;

CREATE TABLE BugInvestigation_ISSUE178 (
[Id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[PersonId] TEXT NOT NULL,
[PoNumber] TEXT NOT NULL,
[OrderStatus] INTEGER NOT NULL,
[CreatedOn] INTEGER NOT NULL,
[CreatedBy] TEXT NOT NULL,
[UpdatedAt] DATETIME
);

CREATE TRIGGER Trigger_BugInvestigation_ISSUE178_UpdatedAt
AFTER INSERT ON BugInvestigation_ISSUE178
BEGIN
UPDATE BugInvestigation_ISSUE178
SET UpdatedAt = CURRENT_TIMESTAMP
WHERE Id = NEW.Id;
END;

CREATE TRIGGER Trigger_BugInvestigation_ISSUE178_UpdatedAt_Update
AFTER UPDATE ON BugInvestigation_ISSUE178
BEGIN
UPDATE BugInvestigation_ISSUE178
SET UpdatedAt = CURRENT_TIMESTAMP
WHERE Id = NEW.Id;
END;
26 changes: 26 additions & 0 deletions PetaPoco.Tests.Integration/Scripts/SqlServerBuildDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,32 @@ CREATE TABLE dbo.[BugInvestigation_5TN5C4U4] (
)
GO

IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES t WHERE t.TABLE_SCHEMA = 'dbo' AND t.TABLE_NAME = 'BugInvestigation_ISSUE178')
DROP TABLE dbo.[BugInvestigation_ISSUE178]

CREATE TABLE dbo.[BugInvestigation_ISSUE178] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[PersonId] UNIQUEIDENTIFIER NOT NULL,
[PoNumber] NVARCHAR(15) NOT NULL,
[OrderStatus] INT NOT NULL,
[CreatedOn] DATETIME2 NOT NULL,
[CreatedBy] NVARCHAR(255) NOT NULL,
[UpdatedAt] DATETIME NULL
);
GO

CREATE TRIGGER Trigger_BugInvestigation_ISSUE178_UpdatedAt
ON dbo.[BugInvestigation_ISSUE178]
AFTER INSERT, UPDATE
AS
BEGIN
UPDATE dbo.[BugInvestigation_ISSUE178]
SET dbo.[BugInvestigation_ISSUE178].[UpdatedAt] = GETDATE()
FROM dbo.[BugInvestigation_ISSUE178]
INNER JOIN inserted i ON dbo.[BugInvestigation_ISSUE178].[Id] = i.[Id];
END;
GO

-- Stored procedures

IF EXISTS (SELECT * FROM sys.objects o WHERE o.type = 'P' AND o.NAME = 'SelectPeople')
Expand Down
6 changes: 6 additions & 0 deletions PetaPoco/Core/DatabaseProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ public virtual string BuildPageQuery(long skip, long take, SQLParts parts, ref o

/// <inheritdoc/>
public virtual string GetInsertOutputClause(string primaryKeyName) => string.Empty;

/// <inheritdoc/>
public virtual string GetInsertPreamble(string primaryKeyName) => string.Empty;

/// <inheritdoc/>
public virtual string GetInsertPostScript(string primaryKeyName) => string.Empty;

/// <inheritdoc/>
public virtual object ExecuteInsert(Database db, IDbCommand cmd, string primaryKeyName)
Expand Down
18 changes: 18 additions & 0 deletions PetaPoco/Core/IProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ public interface IProvider
/// <param name="primaryKeyName">The primary key column name of the row being inserted.</param>
/// <returns>An expression describing how to return the new primary key value.</returns>
string GetInsertOutputClause(string primaryKeyName);

/// <summary>
/// Return an SQL expression that can be used with <seealso cref="GetInsertPostScript(string)"/>
/// and <seealso cref="GetInsertOutputClause(string)"/> to return a provider-generated value from an INSERT; typically an IDENTITY
/// column in Microsoft SQL Server.
/// </summary>
/// <param name="primaryKeyName"></param>
/// <returns></returns>
string GetInsertPreamble(string primaryKeyName);

/// <summary>
/// Return an SQL expression that can be used with <seealso cref="GetInsertPreamble(string)"/>
/// and <seealso cref="GetInsertOutputClause(string)"/> to return a provider-generated value from an INSERT; typically an IDENTITY
/// column in Microsoft SQL Server.
/// </summary>
/// <param name="primaryKeyName"></param>
/// <returns></returns>
string GetInsertPostScript(string primaryKeyName);

/// <summary>
/// Returns the prefix used to delimit parameters in SQL query strings.
Expand Down
8 changes: 7 additions & 1 deletion PetaPoco/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2094,11 +2094,17 @@ private void PrepareExecuteInsert(string tableName, string primaryKeyName, bool
}

var outputClause = string.Empty;
var insertPreamble = string.Empty;
var insertPostScript = string.Empty;
if (autoIncrement)
{
insertPreamble = _provider.GetInsertPreamble(primaryKeyName);
outputClause = _provider.GetInsertOutputClause(primaryKeyName);
insertPostScript = _provider.GetInsertPostScript(primaryKeyName);
}

cmd.CommandText =
$"INSERT INTO {_provider.EscapeTableName(tableName)} ({string.Join(",", names.ToArray())}){outputClause} VALUES ({string.Join(",", values.ToArray())})";
$"{insertPreamble}INSERT INTO {_provider.EscapeTableName(tableName)} ({string.Join(",", names.ToArray())}){outputClause} VALUES ({string.Join(",", values.ToArray())}){insertPostScript}";
}

/// <inheritdoc cref="IAlterPoco.Insert(string, string, bool, object)"/>
Expand Down
10 changes: 9 additions & 1 deletion PetaPoco/Providers/SqlServerDatabaseProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ public override string GetExistsSql()

/// <inheritdoc/>
public override string GetInsertOutputClause(string primaryKeyName)
=> $" OUTPUT INSERTED.[{primaryKeyName}]";
=> $" OUTPUT INSERTED.[{primaryKeyName}] into @result({primaryKeyName})";

/// <inheritdoc/>
public override string GetInsertPreamble(string primaryKeyName)
=> $"DECLARE @result TABLE({primaryKeyName} sql_variant); ";

/// <inheritdoc/>
public override string GetInsertPostScript(string primaryKeyName)
=> $"; SELECT {primaryKeyName} FROM @result; ";
}
}