Skip to content

Commit

Permalink
Merge pull request #30 from ArveH/29-error-reset-auto-generation-for
Browse files Browse the repository at this point in the history
29 error reset auto generation for
  • Loading branch information
ArveH committed Apr 17, 2024
2 parents acefc2c + 520c7b7 commit 5ac0641
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 10 deletions.
28 changes: 25 additions & 3 deletions src/ABulkCopy.APostgres/PgSystemTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,41 @@ public class PgSystemTables : IPgSystemTables
public async Task<uint?> GetIdentityOidAsync(
string tableName, string columnName, CancellationToken ct)
{
var seqName = $"{tableName}_{columnName}_seq";

var seqName = await GetOwnedSequenceNameAsync(tableName, columnName, ct).ConfigureAwait(false);
if (seqName == null)
{
return null;
}
await using var cmd = _pgContext.DataSource.CreateCommand(
$"select oid from pg_class where relkind = 'S' and relname = '{_identifier.AdjustForSystemTable(seqName)}'");
$"select oid from pg_class where relkind = 'S' and " +
$"relname = '{_identifier.AdjustForSystemTable(seqName.TrimSchema())}'");
var oid = await cmd.ExecuteScalarAsync(ct).ConfigureAwait(false);
if (oid == null || oid == DBNull.Value)
{
_logger.Error("Can't get oid for sequence '{SequenceName}'", seqName);
return null;
}

return (uint?)oid;
}

public async Task<string?> GetOwnedSequenceNameAsync(
string tableName, string columnName, CancellationToken ct)
{
await using var cmd = _pgContext.DataSource.CreateCommand(
$"select pg_get_serial_sequence('{_identifier.AdjustForSystemTable(tableName)}', '{_identifier.AdjustForSystemTable(columnName)}')");

var seqName = await cmd.ExecuteScalarAsync(ct).ConfigureAwait(false);
if (seqName == null || seqName == DBNull.Value)
{
_logger.Error("Can't get sequence name for '{TableName}'.'{ColumnName}'",
tableName, columnName);
return null;
}

return (string?)seqName;
}

private async Task<List<(string child, string parent)>> GetForeignKeyColumnsAsync(
string constraintName,
CancellationToken ct)
Expand Down
6 changes: 6 additions & 0 deletions src/ABulkCopy.Common/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public static string Quote(this string str)
return Constants.Quote + str + Constants.Quote;
}

public static string TrimSchema(this string str)
{
var parts = str.Split('.');
return parts.Length == 2 ? parts[1] : str;
}

public static string TrimParentheses(this string str)
{
var offset = str.TakeWhile(c => c == '(').Count();
Expand Down
10 changes: 10 additions & 0 deletions src/CrossRDBMS.Tests/CopyFromMssToPg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public async Task CopyInt()
// Arrange
var tableName = GetName(nameof(CopyFromMssToPg));
DeleteFiles(tableName);
await DropTableAsync(tableName);
await CreateTableAsync(tableName, "int");
var mssServices = CopyProg.GetServices(
CopyDirection.Out, Rdbms.Mss, _fixture.MssConnectionString, tableName);
Expand All @@ -41,6 +42,15 @@ public async Task CopyInt()
await ValidateTypeInfoAsync(tableName, "integer", null, 32, 0);
}

private async Task DropTableAsync(string tableName)
{
await using var conn = new SqlConnection(_fixture.MssConnectionString);
await using var cmd = conn.CreateCommand();
cmd.CommandText = $"DROP TABLE IF EXISTS {tableName}";
await conn.OpenAsync();
await cmd.ExecuteNonQueryAsync();
}

private async Task CreateTableAsync(string tableName, string colType)
{
await using var conn = new SqlConnection(_fixture.MssConnectionString);
Expand Down
3 changes: 1 addition & 2 deletions src/Postgres.Tests/DatabaseFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ public async Task InitializeAsync()
"ed7ee99b-0e84-4e9a-9eb5-985d610aeb8b",
new()
{
{ Constants.Config.AddQuotes, "true" },
{ Constants.Config.UseContainer, "true" }
{ Constants.Config.AddQuotes, "true" }
});
if (Configuration.UseContainer())
{
Expand Down
57 changes: 52 additions & 5 deletions src/Postgres.Tests/PgCmd/PgCmdTests.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,61 @@
namespace Postgres.Tests.PgCmd;

[Collection(nameof(DatabaseCollection))]
public class PgCmdTests : PgTestBase
public class PgCmdTests(
DatabaseFixture dbFixture, ITestOutputHelper output)
: PgTestBase(dbFixture, output)
{
private readonly Mock<IQueryBuilderFactory> _qbFactoryMock = new();
private readonly Mock<IPgSystemTables> _systemTablesMock = new();

public PgCmdTests(DatabaseFixture dbFixture, ITestOutputHelper output)
: base(dbFixture, output)
[Theory]
[InlineData(20, 20)]
[InlineData(64, 20)]
[InlineData(20, 64)]
[InlineData(64, 64)]
public async Task TestResetIdentityColumn(int tableNameLength, int colNameLength)
{
var tableName = "tbl".PadRight(tableNameLength - 3, 'z');
var colName = "col".PadRight(colNameLength - 3, 'z');
try
{
// Arrange
var pgCmd = GetPgCmd();
await CreateTableWithIdentityColumn(tableName, colName, 100);
await DbFixture.ExecuteNonQuery($"insert into \"{tableName}\" (\"Name\") values ('Arve3')");

// Act
await pgCmd.ResetIdentityAsync(tableName, colName, CancellationToken.None);

// Assert
var identityValues = (await DbFixture.SelectColumn<long>(tableName, colName)).ToList();
identityValues.Count.Should().Be(3);
identityValues.Should().Contain(120);
}
finally
{
await DbFixture.DropTable(tableName);
}
}

private async Task CreateTableWithIdentityColumn(
string tableName, string colName, int seed)
{
var inputDefinition = PgTestData.GetEmpty(tableName);
inputDefinition.Header.Identity = new Identity
{
Increment = 10,
Seed = seed
};
var identityCol = new PostgresBigInt(1, colName, false)
{
Identity = inputDefinition.Header.Identity
};
inputDefinition.Columns.Add(identityCol);
inputDefinition.Columns.Add(new PostgresVarChar(2, "Name", true, 100));
await DbFixture.DropTable(tableName);
await DbFixture.CreateTable(inputDefinition);
await DbFixture.ExecuteNonQuery($"insert into \"{tableName}\" (\"Name\") values ('Arve1')");
await DbFixture.ExecuteNonQuery($"insert into \"{tableName}\" (\"Name\") values ('Arve2')");
}

[Fact]
Expand Down Expand Up @@ -370,7 +417,7 @@ private IPgCmd GetPgCmd(Dictionary<string, string?>? appSettings=null)
return new ABulkCopy.APostgres.PgCmd(
DbFixture.PgContext,
_qbFactoryMock.Object,
_systemTablesMock.Object,
GetPgSystemTables(appSettings),
TestLogger);
}
}

0 comments on commit 5ac0641

Please sign in to comment.