Skip to content

Commit 1e23ba5

Browse files
JaBistDuNarrischJaBistDuNarrisch
authored andcommitted
Postgre Identity => GENERATED
1 parent 364bcb4 commit 1e23ba5

File tree

8 files changed

+527
-268
lines changed

8 files changed

+527
-268
lines changed

src/Migrator/Framework/ColumnProperty.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ public enum ColumnProperty
6262
/// <summary>
6363
/// Primary key with identity. This is shorthand for <see cref="PrimaryKey"/> and <see cref="Identity"/>
6464
/// </summary>
65-
PrimaryKeyWithIdentity = 1 << 9 | PrimaryKey | Identity,
65+
PrimaryKeyWithIdentity = PrimaryKey | Identity,
6666

6767
/// <summary>
68-
/// Primary key non clustered.
68+
/// Primary key non clustered.
6969
/// </summary>
7070
PrimaryKeyNonClustered = 1 << 10 | PrimaryKey
7171
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Collections.Generic;
2+
using DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Models;
3+
4+
namespace DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Data.Interfaces;
5+
6+
public interface IPostgreSQLSystemDataLoader
7+
{
8+
/// <summary>
9+
/// Gets column infos.
10+
/// </summary>
11+
/// <param name="tableName"></param>
12+
/// <param name="schemaName"></param>
13+
/// <returns></returns>
14+
List<ColumnInfo> GetColumnInfos(string tableName, string schemaName = "public");
15+
16+
/// <summary>
17+
/// Gets table constraints.
18+
/// </summary>
19+
/// <param name="tableName"></param>
20+
/// <param name="schemaName"></param>
21+
/// <returns></returns>
22+
List<TableConstraint> GetTableConstraints(string tableName, string schemaName = "public");
23+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System.Collections.Generic;
2+
using DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Data.Interfaces;
3+
using DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Interfaces;
4+
using DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Models;
5+
6+
namespace DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Data;
7+
8+
public class PostgreSQLSystemDataLoader(IPostgreSQLTransformationProvider postgreTransformationProvider) : IPostgreSQLSystemDataLoader
9+
{
10+
private readonly IPostgreSQLTransformationProvider _postgreSQLTransformationProvider = postgreTransformationProvider;
11+
12+
public List<TableConstraint> GetTableConstraints(string tableName, string schemaName = "public")
13+
{
14+
var quotedTableName = _postgreSQLTransformationProvider.QuoteTableNameIfRequired(tableName);
15+
16+
var sql = $@"
17+
SELECT
18+
tc.TABLE_SCHEMA,
19+
tc.TABLE_NAME,
20+
tc.CONSTRAINT_NAME,
21+
tc.CONSTRAINT_TYPE,
22+
kcu.COLUMN_NAME
23+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
24+
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
25+
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
26+
AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA
27+
AND tc.TABLE_NAME = kcu.TABLE_NAME
28+
WHERE
29+
LOWER(tc.table_name) = '{quotedTableName.ToLowerInvariant()}'
30+
AND tc.TABLE_SCHEMA = '{schemaName}'
31+
";
32+
33+
List<TableConstraint> tableConstraints = [];
34+
35+
using var cmd = _postgreSQLTransformationProvider.CreateCommand();
36+
using var reader = _postgreSQLTransformationProvider.ExecuteQuery(cmd, sql);
37+
38+
while (reader.Read())
39+
{
40+
var constraintNameOrdinal = reader.GetOrdinal("CONSTRAINT_NAME");
41+
var constraintTypeOrdinal = reader.GetOrdinal("CONSTRAINT_TYPE");
42+
var columnNameOrdinal = reader.GetOrdinal("COLUMN_NAME");
43+
var tableNameOrdinal = reader.GetOrdinal("TABLE_NAME");
44+
var tableSchemaOrdinal = reader.GetOrdinal("TABLE_SCHEMA");
45+
46+
var tableConstraint = new TableConstraint
47+
{
48+
ConstraintName = !reader.IsDBNull(constraintNameOrdinal) ? reader.GetString(constraintNameOrdinal) : null,
49+
ConstraintType = !reader.IsDBNull(constraintTypeOrdinal) ? reader.GetString(constraintTypeOrdinal) : null,
50+
ColumnName = reader.GetString(columnNameOrdinal),
51+
TableName = reader.GetString(tableNameOrdinal),
52+
TableSchema = reader.GetString(tableSchemaOrdinal),
53+
};
54+
55+
tableConstraints.Add(tableConstraint);
56+
}
57+
58+
return tableConstraints;
59+
}
60+
61+
public List<ColumnInfo> GetColumnInfos(string tableName, string schemaName = "public")
62+
{
63+
var quotedTableName = _postgreSQLTransformationProvider.QuoteTableNameIfRequired(tableName);
64+
65+
var sql = $@"
66+
SELECT
67+
c.CHARACTER_MAXIMUM_LENGTH,
68+
c.COLUMN_DEFAULT,
69+
c.COLUMN_NAME,
70+
c.DATA_TYPE,
71+
c.DATETIME_PRECISION,
72+
c.IDENTITY_GENERATION,
73+
c.IS_IDENTITY,
74+
c.IS_NULLABLE,
75+
c.NUMERIC_PRECISION,
76+
c.NUMERIC_SCALE,
77+
c.ORDINAL_POSITION,
78+
c.TABLE_SCHEMA,
79+
c.TABLE_NAME
80+
FROM information_schema.columns c
81+
WHERE
82+
LOWER(c.table_name) = '{quotedTableName.ToLowerInvariant()}' AND
83+
c.TABLE_SCHEMA = '{schemaName}'
84+
";
85+
86+
List<ColumnInfo> columns = [];
87+
88+
using var cmd = _postgreSQLTransformationProvider.CreateCommand();
89+
using var reader = _postgreSQLTransformationProvider.ExecuteQuery(cmd, sql);
90+
91+
while (reader.Read())
92+
{
93+
var characterMaximumLength = reader.GetOrdinal("CHARACTER_MAXIMUM_LENGTH");
94+
var columnDefaultOrdinal = reader.GetOrdinal("COLUMN_DEFAULT");
95+
var columnNameOrdinal = reader.GetOrdinal("COLUMN_NAME");
96+
var dataTypeOrdinal = reader.GetOrdinal("DATA_TYPE");
97+
var dateTimePrecision = reader.GetOrdinal("DATETIME_PRECISION");
98+
var identityGenerationOrdinal = reader.GetOrdinal("IDENTITY_GENERATION");
99+
var isIdentityOrdinal = reader.GetOrdinal("IS_IDENTITY");
100+
var isNullableOrdinal = reader.GetOrdinal("IS_NULLABLE");
101+
var numericPrecisionOrdinal = reader.GetOrdinal("NUMERIC_PRECISION");
102+
var numericScaleOrdinal = reader.GetOrdinal("NUMERIC_SCALE");
103+
var ordinalPositionOrdinal = reader.GetOrdinal("ORDINAL_POSITION");
104+
var tableNameOrdinal = reader.GetOrdinal("TABLE_NAME");
105+
var tableSchemaOrdinal = reader.GetOrdinal("TABLE_SCHEMA");
106+
107+
var columnInfo = new ColumnInfo
108+
{
109+
CharacterMaximumLength = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetInt32(characterMaximumLength) : null,
110+
ColumnDefault = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetString(columnDefaultOrdinal) : null,
111+
ColumnName = reader.GetString(columnNameOrdinal),
112+
DataType = reader.GetString(dataTypeOrdinal),
113+
DateTimePrecision = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetInt32(dateTimePrecision) : null,
114+
IdentityGeneration = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetString(identityGenerationOrdinal) : null,
115+
IsIdentity = reader.GetString(isIdentityOrdinal),
116+
IsNullable = reader.GetString(isNullableOrdinal),
117+
NumericPrecision = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetInt32(numericPrecisionOrdinal) : null,
118+
NumericScale = !reader.IsDBNull(columnDefaultOrdinal) ? reader.GetInt32(numericScaleOrdinal) : null,
119+
OrdinalPosition = reader.GetInt32(ordinalPositionOrdinal),
120+
TableName = reader.GetString(tableNameOrdinal),
121+
TableSchema = reader.GetString(tableSchemaOrdinal),
122+
};
123+
124+
columns.Add(columnInfo);
125+
}
126+
127+
return columns;
128+
}
129+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using DotNetProjects.Migrator.Framework;
2+
3+
namespace DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Interfaces;
4+
5+
public interface IPostgreSQLTransformationProvider : ITransformationProvider
6+
{
7+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
namespace DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Models;
2+
3+
/// <summary>
4+
/// Represents the INFORMATIONSCHEMA.COLUMNS
5+
/// </summary>
6+
public class ColumnInfo
7+
{
8+
/// <summary>
9+
/// Gets or sets the date time precision.
10+
/// </summary>
11+
public int? DateTimePrecision { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets the character maximum length.
15+
/// If data_type identifies a character or bit string type, the declared maximum length; null for all other data types or if no maximum length was declared.
16+
/// </summary>
17+
public int? CharacterMaximumLength { get; set; }
18+
19+
/// <summary>
20+
/// Gets or sets the schema name.
21+
/// </summary>
22+
public string TableSchema { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets the table name.
26+
/// </summary>
27+
public string TableName { get; set; }
28+
29+
/// <summary>
30+
/// Gets or sets the column name.
31+
/// </summary>
32+
public string ColumnName { get; set; }
33+
34+
/// <summary>
35+
/// Gets or sets the data type. Data type of the column, if it is a built-in type, or ARRAY if it is some array (in that case, see the view element_types), else USER-DEFINED (in that case, the type is identified in udt_name and associated columns). If the column is based on a domain, this column refers to the type underlying the domain (and the domain is identified in domain_name and associated columns).
36+
/// </summary>
37+
public string DataType { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets the is nullable string.
41+
/// </summary>
42+
public string IsNullable { get; set; }
43+
44+
/// <summary>
45+
/// Gets or sets the column default.
46+
/// </summary>
47+
public string ColumnDefault { get; set; }
48+
49+
/// <summary>
50+
/// Gets or sets the is identity string. YES or NO.
51+
/// </summary>
52+
public string IsIdentity { get; set; }
53+
54+
/// <summary>
55+
/// Gets or sets the identity generation.
56+
/// </summary>
57+
public string IdentityGeneration { get; set; }
58+
59+
/// <summary>
60+
/// Gets or sets the ordinal position
61+
/// </summary>
62+
public int OrdinalPosition { get; set; }
63+
64+
/// <summary>
65+
/// Gets or sets th numeric scale.
66+
/// </summary>
67+
public int? NumericScale { get; set; }
68+
69+
/// <summary>
70+
/// Gets or sets the numeric precision.
71+
/// </summary>
72+
public int? NumericPrecision { get; set; }
73+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace DotNetProjects.Migrator.Providers.Impl.PostgreSQL.Models;
2+
3+
public class TableConstraint
4+
{
5+
/// <summary>
6+
/// Gets or sets the schema name.
7+
/// </summary>
8+
public string TableSchema { get; set; }
9+
10+
/// <summary>
11+
/// Gets or sets the table name.
12+
/// </summary>
13+
public string TableName { get; set; }
14+
15+
/// <summary>
16+
/// Gets or sets the column name.
17+
/// </summary>
18+
public string ColumnName { get; set; }
19+
20+
/// <summary>
21+
/// Gets or sets the constraint name.
22+
/// </summary>
23+
public string ConstraintName { get; set; }
24+
25+
/// <summary>
26+
/// Gets or sets the constraint type.
27+
/// </summary>
28+
public string ConstraintType { get; set; }
29+
}

src/Migrator/Providers/Impl/PostgreSQL/PostgreSQLDialect.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,11 @@ public PostgreSQLDialect()
8888
"WITHOUT", "WORK", "WRITE", "XMAX", "XMIN", "YEAR", "ZONE");
8989
}
9090

91-
public override bool TableNameNeedsQuote
92-
{
93-
get { return false; }
94-
}
91+
public override bool TableNameNeedsQuote => false;
9592

96-
public override bool ConstraintNameNeedsQuote
97-
{
98-
get { return false; }
99-
}
93+
public override bool ConstraintNameNeedsQuote => false;
10094

101-
//public override bool IdentityNeedsType
102-
//{
103-
// get { return false; }
104-
//}
95+
public override bool IdentityNeedsType => false;
10596

10697
public override ITransformationProvider GetTransformationProvider(Dialect dialect, string connectionString, string defaultSchema, string scope, string providerName)
10798
{
@@ -113,6 +104,18 @@ public override ITransformationProvider GetTransformationProvider(Dialect dialec
113104
return new PostgreSQLTransformationProvider(dialect, connection, defaultSchema, scope, providerName);
114105
}
115106

107+
public override ColumnPropertiesMapper GetColumnMapper(Column column)
108+
{
109+
var type = column.Size > 0 ? GetTypeName(column.Type, column.Size) : GetTypeName(column.Type);
110+
111+
if (column.Precision.HasValue || column.Scale.HasValue)
112+
{
113+
type = GetTypeNameParametrized(column.Type, column.Size, column.Precision ?? 0, column.Scale ?? 0);
114+
}
115+
116+
return new ColumnPropertiesMapper(this, type);
117+
}
118+
116119
public override string Default(object defaultValue)
117120
{
118121
if (defaultValue is TimeSpan timeSpan)

0 commit comments

Comments
 (0)