Skip to content

Commit

Permalink
Target table (#61)
Browse files Browse the repository at this point in the history
* Issue #60 TargetTable Initial Commit

* Issue #60 Add GetFullQualifiedTableName

* Issue #60 Add Test for scenario no schema set

* Issue #60 Cleanup

The TargetTable / TargetColumn setters are now protected for internal
use only. The Columns are now a IReadOnlyList, so they cannot be changed
in further control flows.

* Issue #60 Add ClrType to TargetTable

* Issue #60 Rename to GetFullQualified... to GetFullyQualified

* Issue #60 Update to 2.6.3

* Add Changelog

* Issue #60 Add nupg Binaries

* Update Changelog for 2.6.2 Release Notes
  • Loading branch information
bytefish committed Dec 12, 2019
1 parent 6018bb2 commit 51b433f
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 12 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,21 @@
# CHANGELOG #

## 2.6.3 ##

* [See Changes](https://github.com/PostgreSQLCopyHelper/PostgreSQLCopyHelper/compare/2.6.2...2.6.3)

#### This release:

- Adds the Property ``TargetTable`` and associated classes to get the Table and Column mapping

## 2.6.2 ##

* [See Changes](https://github.com/PostgreSQLCopyHelper/PostgreSQLCopyHelper/compare/2.6.1...2.6.2)

### This release:

- Adds a dependency to ``Microsoft.Bcl.AsyncInterfaces`` to enable ``IAsyncEnumerable`` for .NET 4.6.1 and netstandard 2.0

## 2.6.1 ##

* [See Changes](https://github.com/PostgreSQLCopyHelper/PostgreSQLCopyHelper/compare/2.6.0...2.6.1)
Expand Down
Binary file added artifacts/PostgreSQLCopyHelper.2.6.3.nupkg
Binary file not shown.
Binary file not shown.
101 changes: 101 additions & 0 deletions src/PostgreSQLCopyHelper.Test/Issues/Issue60_TargetTableTest.cs
@@ -0,0 +1,101 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using NpgsqlTypes;
using NUnit.Framework;

namespace PostgreSQLCopyHelper.Test.Issues
{
[TestFixture]
public class Issue60_TargetTableTest
{
private class User
{
public int Id { get; set; }

public string Name { get; set; }
}

[Test]
public void Test_TargetTable_ColumnsEmpty()
{
var subject = new PostgreSQLCopyHelper<User>("sample", "TestUsers");

var targetTable = subject.TargetTable;

Assert.AreEqual("sample", targetTable.SchemaName);
Assert.AreEqual("TestUsers", targetTable.TableName);

Assert.AreEqual(0, targetTable.Columns.Count);
}

[Test]
public void Test_TargetTable_SchemaEmpty_ColumnsEmpty()
{
var subject = new PostgreSQLCopyHelper<User>("TestUsers");

var targetTable = subject.TargetTable;

Assert.AreEqual(string.Empty, targetTable.SchemaName);
Assert.AreEqual("TestUsers", targetTable.TableName);

Assert.AreEqual(0, targetTable.Columns.Count);
}

[Test]
public void Test_TargetTable_NotEmpty()
{
var subject = new PostgreSQLCopyHelper<User>("sample", "TestUsers")
.MapInteger("Id", x => x.Id)
.MapText("Name", x => x.Name);

var targetTable = subject.TargetTable;

Assert.AreEqual("sample", targetTable.SchemaName);
Assert.AreEqual("TestUsers", targetTable.TableName);

Assert.AreEqual(2, targetTable.Columns.Count);

Assert.AreEqual("Id", targetTable.Columns[0].ColumnName);
Assert.AreEqual(typeof(int), targetTable.Columns[0].ClrType);
Assert.AreEqual(NpgsqlDbType.Integer, targetTable.Columns[0].DbType);

Assert.AreEqual("Name", targetTable.Columns[1].ColumnName);
Assert.AreEqual(typeof(string), targetTable.Columns[1].ClrType);
Assert.AreEqual(NpgsqlDbType.Text, targetTable.Columns[1].DbType);
}

[Test]
public void Test_TargetTable_FullQualifiedTableName_NoPostgresQuoting()
{
var subject = new PostgreSQLCopyHelper<User>("sample", "TestUsers")
.UsePostgresQuoting(false);

var targetTable = subject.TargetTable;

Assert.AreEqual("sample.TestUsers", targetTable.GetFullyQualifiedTableName());
}

[Test]
public void Test_TargetTable_FullQualifiedTableName_WithPostgresQuoting()
{
var subject = new PostgreSQLCopyHelper<User>("Sample", "TestUsers")
.UsePostgresQuoting();

var targetTable = subject.TargetTable;

Assert.AreEqual("\"Sample\".\"TestUsers\"", targetTable.GetFullyQualifiedTableName());
}


[Test]
public void Test_TargetTable_FullQualifiedTableName_WithPostgresQuoting_NoSchema()
{
var subject = new PostgreSQLCopyHelper<User>("TestUsers")
.UsePostgresQuoting();

var targetTable = subject.TargetTable;

Assert.AreEqual("\"TestUsers\"", targetTable.GetFullyQualifiedTableName());
}
}
}
5 changes: 5 additions & 0 deletions src/PostgreSQLCopyHelper/Model/ColumnDefinition.cs
Expand Up @@ -4,13 +4,18 @@
using System.Threading;
using System.Threading.Tasks;
using Npgsql;
using NpgsqlTypes;

namespace PostgreSQLCopyHelper.Model
{
internal class ColumnDefinition<TEntity>
{
public string ColumnName { get; set; }

public Type ClrType { get; set; }

public NpgsqlDbType DbType { get; set; }

public Func<NpgsqlBinaryImporter, TEntity, CancellationToken, Task> WriteAsync { get; set; }

public override string ToString()
Expand Down
6 changes: 2 additions & 4 deletions src/PostgreSQLCopyHelper/Model/TableDefinition.cs
Expand Up @@ -10,11 +10,9 @@ internal class TableDefinition

public string TableName { get; set; }

public string GetFullQualifiedTableName(bool usePostgresQuoting)
public string GetFullyQualifiedTableName(bool usePostgresQuoting)
{
return string.IsNullOrWhiteSpace(Schema)
? TableName.GetIdentifier(usePostgresQuoting)
: $"{Schema.GetIdentifier(usePostgresQuoting)}.{TableName.GetIdentifier(usePostgresQuoting)}";
return NpgsqlUtils.GetFullyQualifiedTableName(Schema, TableName, usePostgresQuoting);
}

public override string ToString()
Expand Down
16 changes: 16 additions & 0 deletions src/PostgreSQLCopyHelper/Model/TargetColumn.cs
@@ -0,0 +1,16 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using NpgsqlTypes;

namespace PostgreSQLCopyHelper.Model
{
public class TargetColumn
{
public string ColumnName { get; internal set; }

public Type ClrType { get; internal set; }

public NpgsqlDbType DbType { get; internal set; }
}
}
23 changes: 23 additions & 0 deletions src/PostgreSQLCopyHelper/Model/TargetTable.cs
@@ -0,0 +1,23 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;
using PostgreSQLCopyHelper.Utils;

namespace PostgreSQLCopyHelper.Model
{
public class TargetTable
{
public string SchemaName { get; internal set; }

public string TableName { get; internal set; }

public bool UsePostgresQuoting { get; internal set; }

public IReadOnlyList<TargetColumn> Columns { get; internal set; }

public string GetFullyQualifiedTableName()
{
return NpgsqlUtils.GetFullyQualifiedTableName(SchemaName, TableName, UsePostgresQuoting);
}
}
}
34 changes: 27 additions & 7 deletions src/PostgreSQLCopyHelper/PostgreSQLCopyHelper.cs
Expand Up @@ -38,6 +38,22 @@ public PostgreSQLCopyHelper(string schemaName, string tableName)
_columns = new List<ColumnDefinition<TEntity>>();
}

public TargetTable TargetTable
{
get
{
return new TargetTable
{
SchemaName = _table.Schema,
TableName = _table.TableName,
UsePostgresQuoting = _usePostgresQuoting,
Columns = _columns
.Select(x => new TargetColumn { ColumnName = x.ColumnName, DbType = x.DbType, ClrType = x.ClrType })
.ToList()
};
}
}

public ulong SaveAll(NpgsqlConnection connection, IEnumerable<TEntity> entities)
{
using (NoSynchronizationContextScope.Enter())
Expand Down Expand Up @@ -95,12 +111,12 @@ public PostgreSQLCopyHelper<TEntity> UsePostgresQuoting(bool enabled = true)
return this;
}

public PostgreSQLCopyHelper<TEntity> Map<TProperty>(string columnName, Func<TEntity, TProperty> propertyGetter, NpgsqlDbType type)
public PostgreSQLCopyHelper<TEntity> Map<TProperty>(string columnName, Func<TEntity, TProperty> propertyGetter, NpgsqlDbType dbType)
{
return AddColumn(columnName, (writer, entity, cancellationToken) => writer.WriteAsync(propertyGetter(entity), type, cancellationToken));
return AddColumn(columnName, (writer, entity, cancellationToken) => writer.WriteAsync(propertyGetter(entity), dbType, cancellationToken), dbType, typeof(TProperty));
}

public PostgreSQLCopyHelper<TEntity> MapNullable<TProperty>(string columnName, Func<TEntity, TProperty?> propertyGetter, NpgsqlDbType type)
public PostgreSQLCopyHelper<TEntity> MapNullable<TProperty>(string columnName, Func<TEntity, TProperty?> propertyGetter, NpgsqlDbType dbType)
where TProperty : struct
{
return AddColumn(columnName, async (writer, entity, cancellationToken) =>
Expand All @@ -113,9 +129,9 @@ public PostgreSQLCopyHelper<TEntity> MapNullable<TProperty>(string columnName, F
}
else
{
await writer.WriteAsync(val.Value, type, cancellationToken);
await writer.WriteAsync(val.Value, dbType, cancellationToken);
}
});
}, dbType, typeof(TProperty));
}

private async Task WriteToStreamAsync(NpgsqlBinaryImporter writer, IEnumerable<TEntity> entities, CancellationToken cancellationToken)
Expand Down Expand Up @@ -144,11 +160,13 @@ private async Task WriteToStreamAsync(NpgsqlBinaryImporter writer, TEntity entit
}
}

private PostgreSQLCopyHelper<TEntity> AddColumn(string columnName, Func<NpgsqlBinaryImporter, TEntity, CancellationToken, Task> action)
private PostgreSQLCopyHelper<TEntity> AddColumn(string columnName, Func<NpgsqlBinaryImporter, TEntity, CancellationToken, Task> action, NpgsqlDbType dbType, Type clrType)
{
_columns.Add(new ColumnDefinition<TEntity>
{
ColumnName = columnName,
DbType = dbType,
ClrType = clrType,
WriteAsync = action
});

Expand All @@ -159,7 +177,9 @@ private string GetCopyCommand()
{
var commaSeparatedColumns = string.Join(", ", _columns.Select(x => x.ColumnName.GetIdentifier(_usePostgresQuoting)));

return $"COPY {_table.GetFullQualifiedTableName(_usePostgresQuoting)}({commaSeparatedColumns}) FROM STDIN BINARY;";
return $"COPY {_table.GetFullyQualifiedTableName(_usePostgresQuoting)}({commaSeparatedColumns}) FROM STDIN BINARY;";
}


}
}
2 changes: 1 addition & 1 deletion src/PostgreSQLCopyHelper/PostgreSQLCopyHelper.csproj
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<Version>2.6.2</Version>
<Version>2.6.3</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
7 changes: 7 additions & 0 deletions src/PostgreSQLCopyHelper/Utils/NpgsqlUtils.cs
Expand Up @@ -15,6 +15,13 @@ public static string QuoteIdentifier(string identifier)
: identifier;
}

public static string GetFullyQualifiedTableName(string schemaName, string tableName, bool usePostgresQuoting)
{
return string.IsNullOrWhiteSpace(schemaName)
? tableName.GetIdentifier(usePostgresQuoting)
: $"{schemaName.GetIdentifier(usePostgresQuoting)}.{tableName.GetIdentifier(usePostgresQuoting)}";
}

/// <summary>
/// Determines, if an identifier required quoting according to the ANSI Standard.
///
Expand Down

0 comments on commit 51b433f

Please sign in to comment.