From cdfa61b11dfaa672a748a36441cf130e0d1e4d05 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 21:21:45 +0300 Subject: [PATCH 01/60] Bump version to 3.1.1-ci --- src/CommonAssemblyInfo.cs | 6 +++--- src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec | 2 +- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec | 2 +- teamcity_set_version.cmd | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs index 1a7f45e..ebd5a78 100644 --- a/src/CommonAssemblyInfo.cs +++ b/src/CommonAssemblyInfo.cs @@ -16,6 +16,6 @@ [assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.MainAssembly)] // The following version attributes get rewritten by GitVersion as part of the build -[assembly: AssemblyVersion("3.1.0")] -[assembly: AssemblyFileVersion("3.1.0")] -[assembly: AssemblyInformationalVersion("3.1.0")] +[assembly: AssemblyVersion("3.1.1")] +[assembly: AssemblyFileVersion("3.1.1")] +[assembly: AssemblyInformationalVersion("3.1.1-ci")] diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec index 07f54f7..2135c9e 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec @@ -3,7 +3,7 @@ EntityFramework5.Npgsql Npgsql for Entity Framework 5 - 3.1.0 + $version$ Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index a3aaaf4..2e493ab 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -3,7 +3,7 @@ EntityFramework6.Npgsql Npgsql for Entity Framework 6 - 3.1.0 + $version$ Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt diff --git a/teamcity_set_version.cmd b/teamcity_set_version.cmd index f0f2e36..1744dc4 100644 --- a/teamcity_set_version.cmd +++ b/teamcity_set_version.cmd @@ -1 +1 @@ -echo ##teamcity[buildNumber '3.1.0-%1'] +echo ##teamcity[buildNumber '3.1.1-ci-%1'] From 043f767a0baf7a5deb4c323536fa35c79fa587ea Mon Sep 17 00:00:00 2001 From: roji Date: Mon, 23 May 2016 13:28:55 -0500 Subject: [PATCH 02/60] TeamCity change in 'EntityFramework6.Npgsql' project: runners of 'Build' build configuration were updated --- .../buildTypes/EntityFramework6Npgsql_Build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml b/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml index 80b1396..3ae11b0 100644 --- a/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml +++ b/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml @@ -107,6 +107,7 @@ + From 7689c806279b17a182b944840e2db12c364f3c01 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 25 May 2016 21:22:54 +0300 Subject: [PATCH 03/60] General cleanup/cosmetics C# 6 and so on --- .../EntityFramework5.Npgsql.csproj | 3 +- .../NpgsqlMigrationSqlGenerator.cs | 513 +++--- .../NpgsqlProviderManifest.cs | 508 +++--- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 89 +- .../SqlGenerators/PendingProjectsNode.cs | 14 +- .../SqlGenerators/SqlBaseGenerator.cs | 1542 ++++++++--------- .../SqlGenerators/SqlDeleteGenerator.cs | 11 +- .../SqlGenerators/SqlInsertGenerator.cs | 16 +- .../SqlGenerators/SqlSelectGenerator.cs | 45 +- .../SqlGenerators/SqlUpdateGenerator.cs | 15 +- .../SqlGenerators/StringPair.cs | 25 +- .../SqlGenerators/VisitedExpression.cs | 680 +++----- 12 files changed, 1551 insertions(+), 1910 deletions(-) diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj index df94040..e351766 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj @@ -15,7 +15,6 @@ true v4.5 - 5 true @@ -80,4 +79,4 @@ - \ No newline at end of file + diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs index e00aa01..5cb03d4 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -30,6 +30,7 @@ using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Spatial; using System.Linq; +using JetBrains.Annotations; namespace Npgsql { @@ -38,10 +39,10 @@ namespace Npgsql /// public class NpgsqlMigrationSqlGenerator : MigrationSqlGenerator { - List migrationStatments; - private List addedSchemas; - private List addedExtensions; - private Version serverVersion; + List _migrationStatments; + List _addedSchemas; + List _addedExtensions; + Version _serverVersion; /// /// Generates the migration sql. @@ -49,117 +50,76 @@ public class NpgsqlMigrationSqlGenerator : MigrationSqlGenerator /// The operations in the migration /// The provider manifest token used for server versioning. public override IEnumerable Generate( - IEnumerable migrationOperations, string providerManifestToken) + [NotNull] IEnumerable migrationOperations, + [NotNull] string providerManifestToken) { - migrationStatments = new List(); - addedSchemas = new List(); - addedExtensions = new List(); - serverVersion = new Version(providerManifestToken); + _migrationStatments = new List(); + _addedSchemas = new List(); + _addedExtensions = new List(); + _serverVersion = new Version(providerManifestToken); Convert(migrationOperations); - return migrationStatments; + return _migrationStatments; } #region MigrationOperation to MigrationStatement converters #region General - protected virtual void Convert(IEnumerable operations) + protected virtual void Convert([NotNull] IEnumerable operations) { foreach (var migrationOperation in operations) { if (migrationOperation is AddColumnOperation) - { Convert(migrationOperation as AddColumnOperation); - } else if (migrationOperation is AlterColumnOperation) - { Convert(migrationOperation as AlterColumnOperation); - } else if (migrationOperation is CreateTableOperation) - { Convert(migrationOperation as CreateTableOperation); - } else if (migrationOperation is DropForeignKeyOperation) - { Convert(migrationOperation as DropForeignKeyOperation); - } else if (migrationOperation is DropTableOperation) - { Convert(migrationOperation as DropTableOperation); - } else if (migrationOperation is MoveTableOperation) - { Convert(migrationOperation as MoveTableOperation); - } else if (migrationOperation is RenameTableOperation) - { Convert(migrationOperation as RenameTableOperation); - } else if (migrationOperation is AddForeignKeyOperation) - { Convert(migrationOperation as AddForeignKeyOperation); - } else if (migrationOperation is DropIndexOperation) - { Convert(migrationOperation as DropIndexOperation); - } else if (migrationOperation is SqlOperation) - { AddStatment((migrationOperation as SqlOperation).Sql, (migrationOperation as SqlOperation).SuppressTransaction); - } else if (migrationOperation is AddPrimaryKeyOperation) - { Convert(migrationOperation as AddPrimaryKeyOperation); - } else if (migrationOperation is CreateIndexOperation) - { Convert(migrationOperation as CreateIndexOperation); - } else if (migrationOperation is RenameIndexOperation) - { Convert(migrationOperation as RenameIndexOperation); - } else if (migrationOperation is DropColumnOperation) - { Convert(migrationOperation as DropColumnOperation); - } else if (migrationOperation is DropPrimaryKeyOperation) - { Convert(migrationOperation as DropPrimaryKeyOperation); - } else if (migrationOperation is HistoryOperation) - { Convert(migrationOperation as HistoryOperation); - } else if (migrationOperation is RenameColumnOperation) - { Convert(migrationOperation as RenameColumnOperation); - } else if (migrationOperation is UpdateDatabaseOperation) - { Convert((migrationOperation as UpdateDatabaseOperation).Migrations as IEnumerable); - } else - { throw new NotImplementedException("Unhandled MigrationOperation " + migrationOperation.GetType().Name + " in " + GetType().Name); - } } } - private void AddStatment(string sql, bool suppressTransacion = false) - { - migrationStatments.Add(new MigrationStatement - { - Sql = sql, - SuppressTransaction = suppressTransacion, - BatchTerminator = ";" - }); - } + void AddStatment(string sql, bool suppressTransacion = false) + => _migrationStatments.Add(new MigrationStatement + { + Sql = sql, + SuppressTransaction = suppressTransacion, + BatchTerminator = ";" + }); - private void AddStatment(StringBuilder sql, bool suppressTransacion = false) - { - AddStatment(sql.ToString(), suppressTransacion); - } + void AddStatment(StringBuilder sql, bool suppressTransacion = false) + => AddStatment(sql.ToString(), suppressTransacion); #endregion @@ -170,7 +130,7 @@ protected virtual void Convert(HistoryOperation historyOperation) foreach (var command in historyOperation.CommandTrees) { var npgsqlCommand = new NpgsqlCommand(); - NpgsqlServices.Instance.TranslateCommandTree(serverVersion, command, npgsqlCommand, false); + NpgsqlServices.Instance.TranslateCommandTree(_serverVersion, command, npgsqlCommand, false); AddStatment(npgsqlCommand.CommandText); } } @@ -181,12 +141,10 @@ protected virtual void Convert(HistoryOperation historyOperation) protected virtual void Convert(CreateTableOperation createTableOperation) { - StringBuilder sql = new StringBuilder(); - int dotIndex = createTableOperation.Name.IndexOf('.'); + var sql = new StringBuilder(); + var dotIndex = createTableOperation.Name.IndexOf('.'); if (dotIndex != -1) - { CreateSchema(createTableOperation.Name.Remove(dotIndex)); - } sql.Append("CREATE TABLE "); AppendTableName(createTableOperation.Name, sql); @@ -222,7 +180,7 @@ protected virtual void Convert(CreateTableOperation createTableOperation) protected virtual void Convert(DropTableOperation dropTableOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("DROP TABLE "); AppendTableName(dropTableOperation.Name, sql); AddStatment(sql); @@ -230,7 +188,7 @@ protected virtual void Convert(DropTableOperation dropTableOperation) protected virtual void Convert(RenameTableOperation renameTableOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(renameTableOperation.Name, sql); sql.Append(" RENAME TO "); @@ -238,15 +196,13 @@ protected virtual void Convert(RenameTableOperation renameTableOperation) AddStatment(sql); } - private void CreateSchema(string schemaName) + void CreateSchema(string schemaName) { - if (schemaName == "public" || addedSchemas.Contains(schemaName)) + if (schemaName == "public" || _addedSchemas.Contains(schemaName)) return; - addedSchemas.Add(schemaName); - if (serverVersion.Major > 9 || (serverVersion.Major == 9 && serverVersion.Minor >= 3)) - { + _addedSchemas.Add(schemaName); + if (_serverVersion.Major > 9 || (_serverVersion.Major == 9 && _serverVersion.Minor >= 3)) AddStatment("CREATE SCHEMA IF NOT EXISTS " + schemaName); - } else { //TODO: CREATE PROCEDURE that checks if schema already exists on servers < 9.3 @@ -254,7 +210,7 @@ private void CreateSchema(string schemaName) } } - //private void CreateExtension(string exensionName) + //void CreateExtension(string exensionName) //{ // //This is compatible only with server 9.1+ // if (serverVersion.Major > 9 || (serverVersion.Major == 9 && serverVersion.Minor >= 1)) @@ -268,7 +224,7 @@ private void CreateSchema(string schemaName) protected virtual void Convert(MoveTableOperation moveTableOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); var newSchema = moveTableOperation.NewSchema ?? "dbo"; CreateSchema(newSchema); sql.Append("ALTER TABLE "); @@ -283,7 +239,7 @@ protected virtual void Convert(MoveTableOperation moveTableOperation) #region Columns protected virtual void Convert(AddColumnOperation addColumnOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(addColumnOperation.Table, sql); sql.Append(" ADD "); @@ -293,7 +249,7 @@ protected virtual void Convert(AddColumnOperation addColumnOperation) protected virtual void Convert(DropColumnOperation dropColumnOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(dropColumnOperation.Table, sql); sql.Append(" DROP COLUMN \""); @@ -304,7 +260,7 @@ protected virtual void Convert(DropColumnOperation dropColumnOperation) protected virtual void Convert(AlterColumnOperation alterColumnOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); //TYPE AppendAlterColumn(alterColumnOperation, sql); @@ -359,13 +315,11 @@ protected virtual void Convert(AlterColumnOperation alterColumnOperation) } } else - { sql.Append(" DROP DEFAULT"); - } AddStatment(sql); } - private void AppendAlterColumn(AlterColumnOperation alterColumnOperation, StringBuilder sql) + void AppendAlterColumn(AlterColumnOperation alterColumnOperation, StringBuilder sql) { sql.Append("ALTER TABLE "); AppendTableName(alterColumnOperation.Table, sql); @@ -376,7 +330,7 @@ private void AppendAlterColumn(AlterColumnOperation alterColumnOperation, String protected virtual void Convert(RenameColumnOperation renameColumnOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(renameColumnOperation.Table, sql); sql.Append(" RENAME COLUMN \""); @@ -393,7 +347,7 @@ protected virtual void Convert(RenameColumnOperation renameColumnOperation) protected virtual void Convert(AddForeignKeyOperation addForeignKeyOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(addForeignKeyOperation.DependentTable, sql); sql.Append(" ADD CONSTRAINT \""); @@ -419,21 +373,19 @@ protected virtual void Convert(AddForeignKeyOperation addForeignKeyOperation) sql.Append(")"); if (addForeignKeyOperation.CascadeDelete) - { sql.Append(" ON DELETE CASCADE"); - } AddStatment(sql); } protected virtual void Convert(DropForeignKeyOperation dropForeignKeyOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(dropForeignKeyOperation.DependentTable, sql); - if (serverVersion.Major < 9) - sql.Append(" DROP CONSTRAINT \"");//TODO: http://piecesformthewhole.blogspot.com/2011/04/dropping-foreign-key-if-it-exists-in.html ? - else - sql.Append(" DROP CONSTRAINT IF EXISTS \""); + sql.Append(_serverVersion.Major < 9 + ? " DROP CONSTRAINT \"" //TODO: http://piecesformthewhole.blogspot.com/2011/04/dropping-foreign-key-if-it-exists-in.html ? + : " DROP CONSTRAINT IF EXISTS \"" + ); sql.Append(dropForeignKeyOperation.Name); sql.Append('"'); AddStatment(sql); @@ -441,7 +393,7 @@ protected virtual void Convert(DropForeignKeyOperation dropForeignKeyOperation) protected virtual void Convert(CreateIndexOperation createIndexOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("CREATE "); if (createIndexOperation.IsUnique) @@ -465,16 +417,11 @@ protected virtual void Convert(CreateIndexOperation createIndexOperation) protected virtual void Convert(RenameIndexOperation renameIndexOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); - if (serverVersion.Major > 9 || (serverVersion.Major == 9 && serverVersion.Minor >= 2)) - { - sql.Append("ALTER INDEX IF EXISTS "); - } - else - { - sql.Append("ALTER INDEX "); - } + sql.Append(_serverVersion.Major > 9 || (_serverVersion.Major == 9 && _serverVersion.Minor >= 2) + ? "ALTER INDEX IF EXISTS " + : "ALTER INDEX "); sql.Append(GetSchemaNameFromFullTableName(renameIndexOperation.Table)); sql.Append(".\""); @@ -485,13 +432,11 @@ protected virtual void Convert(RenameIndexOperation renameIndexOperation) AddStatment(sql); } - private string GetSchemaNameFromFullTableName(string tableFullName) + string GetSchemaNameFromFullTableName(string tableFullName) { - int dotIndex = tableFullName.IndexOf('.'); - if (dotIndex != -1) - return tableFullName.Remove(dotIndex); - else - return "dto";//TODO: Check always setting dto schema if no schema in table name is not bug + var dotIndex = tableFullName.IndexOf('.'); + return dotIndex != -1 ? tableFullName.Remove(dotIndex) : "dto"; + //TODO: Check always setting dto schema if no schema in table name is not bug } /// @@ -499,18 +444,15 @@ private string GetSchemaNameFromFullTableName(string tableFullName) /// /// /// - private string GetTableNameFromFullTableName(string tableName) + string GetTableNameFromFullTableName(string tableName) { - int dotIndex = tableName.IndexOf('.'); - if (dotIndex != -1) - return tableName.Substring(dotIndex + 1); - else - return tableName; + var dotIndex = tableName.IndexOf('.'); + return dotIndex != -1 ? tableName.Substring(dotIndex + 1) : tableName; } protected virtual void Convert(DropIndexOperation dropIndexOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("DROP INDEX IF EXISTS "); sql.Append(GetSchemaNameFromFullTableName(dropIndexOperation.Table)); sql.Append(".\""); @@ -521,7 +463,7 @@ protected virtual void Convert(DropIndexOperation dropIndexOperation) protected virtual void Convert(AddPrimaryKeyOperation addPrimaryKeyOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(addPrimaryKeyOperation.Table, sql); sql.Append(" ADD CONSTRAINT \""); @@ -542,7 +484,7 @@ protected virtual void Convert(AddPrimaryKeyOperation addPrimaryKeyOperation) protected virtual void Convert(DropPrimaryKeyOperation dropPrimaryKeyOperation) { - StringBuilder sql = new StringBuilder(); + var sql = new StringBuilder(); sql.Append("ALTER TABLE "); AppendTableName(dropPrimaryKeyOperation.Table, sql); sql.Append(" DROP CONSTRAINT \""); @@ -557,7 +499,7 @@ protected virtual void Convert(DropPrimaryKeyOperation dropPrimaryKeyOperation) #region Misc functions - private void AppendColumn(ColumnModel column, StringBuilder sql) + void AppendColumn(ColumnModel column, StringBuilder sql) { sql.Append('"'); sql.Append(column.Name); @@ -581,19 +523,19 @@ private void AppendColumn(ColumnModel column, StringBuilder sql) { switch (column.Type) { - case PrimitiveTypeKind.Guid: - //CreateExtension("uuid-ossp"); - //If uuid-ossp is not enabled migrations throw exception - AddStatment("select * from uuid_generate_v4()"); - sql.Append(" DEFAULT uuid_generate_v4()"); - break; - case PrimitiveTypeKind.Byte: - case PrimitiveTypeKind.SByte: - case PrimitiveTypeKind.Int16: - case PrimitiveTypeKind.Int32: - case PrimitiveTypeKind.Int64: - //TODO: Add support for setting "SERIAL" - break; + case PrimitiveTypeKind.Guid: + //CreateExtension("uuid-ossp"); + //If uuid-ossp is not enabled migrations throw exception + AddStatment("select * from uuid_generate_v4()"); + sql.Append(" DEFAULT uuid_generate_v4()"); + break; + case PrimitiveTypeKind.Byte: + case PrimitiveTypeKind.SByte: + case PrimitiveTypeKind.Int16: + case PrimitiveTypeKind.Int32: + case PrimitiveTypeKind.Int64: + //TODO: Add support for setting "SERIAL" + break; } } else if (column.IsNullable != null @@ -606,152 +548,145 @@ private void AppendColumn(ColumnModel column, StringBuilder sql) } } - private void AppendColumnType(ColumnModel column, StringBuilder sql, bool setSerial) + void AppendColumnType(ColumnModel column, StringBuilder sql, bool setSerial) { if (column.StoreType != null) { sql.Append(column.StoreType); return; } + switch (column.Type) { - case PrimitiveTypeKind.Binary: - sql.Append("bytea"); - break; - case PrimitiveTypeKind.Boolean: - sql.Append("boolean"); - break; - case PrimitiveTypeKind.DateTime: - if (column.Precision != null) - sql.Append("timestamp(" + column.Precision + ")"); - else - sql.Append("timestamp"); - break; - case PrimitiveTypeKind.Decimal: - //TODO: Check if inside min/max - if (column.Precision == null && column.Scale == null) - { - sql.Append("numeric"); - } - else - { - sql.Append("numeric("); - sql.Append(column.Precision ?? 19); - sql.Append(','); - sql.Append(column.Scale ?? 4); - sql.Append(')'); - } - break; - case PrimitiveTypeKind.Double: - sql.Append("float8"); - break; - case PrimitiveTypeKind.Guid: - sql.Append("uuid"); - break; - case PrimitiveTypeKind.Single: - sql.Append("float4"); - break; - case PrimitiveTypeKind.Byte://postgres doesn't support sbyte :( - case PrimitiveTypeKind.SByte://postgres doesn't support sbyte :( - case PrimitiveTypeKind.Int16: - if (setSerial) - sql.Append(column.IsIdentity ? "serial2" : "int2"); - else - sql.Append("int2"); - break; - case PrimitiveTypeKind.Int32: - if (setSerial) - sql.Append(column.IsIdentity ? "serial4" : "int4"); - else - sql.Append("int4"); - break; - case PrimitiveTypeKind.Int64: - if (setSerial) - sql.Append(column.IsIdentity ? "serial8" : "int8"); - else - sql.Append("int8"); - break; - case PrimitiveTypeKind.String: - if (column.IsFixedLength.HasValue && - column.IsFixedLength.Value && - column.MaxLength.HasValue) - { - sql.AppendFormat("char({0})",column.MaxLength.Value); - } - else if (column.MaxLength.HasValue) - { - sql.AppendFormat("varchar({0})", column.MaxLength); - } - else - { - sql.Append("text"); - } - break; - case PrimitiveTypeKind.Time: - if (column.Precision != null) - { - sql.Append("interval("); - sql.Append(column.Precision); - sql.Append(')'); - } - else - { - sql.Append("interval"); - } - break; - case PrimitiveTypeKind.DateTimeOffset: - if (column.Precision != null) - { - sql.Append("timestamptz("); - sql.Append(column.Precision); - sql.Append(')'); - } - else - { - sql.Append("timestamptz"); - } - break; - case PrimitiveTypeKind.Geometry: - sql.Append("point"); - break; - //case PrimitiveTypeKind.Geography: - // break; - //case PrimitiveTypeKind.GeometryPoint: - // break; - //case PrimitiveTypeKind.GeometryLineString: - // break; - //case PrimitiveTypeKind.GeometryPolygon: - // break; - //case PrimitiveTypeKind.GeometryMultiPoint: - // break; - //case PrimitiveTypeKind.GeometryMultiLineString: - // break; - //case PrimitiveTypeKind.GeometryMultiPolygon: - // break; - //case PrimitiveTypeKind.GeometryCollection: - // break; - //case PrimitiveTypeKind.GeographyPoint: - // break; - //case PrimitiveTypeKind.GeographyLineString: - // break; - //case PrimitiveTypeKind.GeographyPolygon: - // break; - //case PrimitiveTypeKind.GeographyMultiPoint: - // break; - //case PrimitiveTypeKind.GeographyMultiLineString: - // break; - //case PrimitiveTypeKind.GeographyMultiPolygon: - // break; - //case PrimitiveTypeKind.GeographyCollection: - // break; - default: - throw new ArgumentException("Unhandled column type:" + column.Type); - } - } - - private void AppendTableName(string tableName, StringBuilder sql) - { - int dotIndex = tableName.IndexOf('.'); + case PrimitiveTypeKind.Binary: + sql.Append("bytea"); + break; + case PrimitiveTypeKind.Boolean: + sql.Append("boolean"); + break; + case PrimitiveTypeKind.DateTime: + sql.Append(column.Precision != null + ? $"timestamp({column.Precision})" + : "timestamp" + ); + break; + case PrimitiveTypeKind.Decimal: + //TODO: Check if inside min/max + if (column.Precision == null && column.Scale == null) + sql.Append("numeric"); + else + { + sql.Append("numeric("); + sql.Append(column.Precision ?? 19); + sql.Append(','); + sql.Append(column.Scale ?? 4); + sql.Append(')'); + } + break; + case PrimitiveTypeKind.Double: + sql.Append("float8"); + break; + case PrimitiveTypeKind.Guid: + sql.Append("uuid"); + break; + case PrimitiveTypeKind.Single: + sql.Append("float4"); + break; + case PrimitiveTypeKind.Byte://postgres doesn't support sbyte :( + case PrimitiveTypeKind.SByte://postgres doesn't support sbyte :( + case PrimitiveTypeKind.Int16: + sql.Append(setSerial + ? column.IsIdentity ? "serial2" : "int2" + : "int2" + ); + break; + case PrimitiveTypeKind.Int32: + sql.Append(setSerial + ? column.IsIdentity ? "serial4" : "int4" + : "int4" + ); + break; + case PrimitiveTypeKind.Int64: + sql.Append(setSerial + ? column.IsIdentity ? "serial8" : "int8" + : "int8" + ); + break; + case PrimitiveTypeKind.String: + if (column.IsFixedLength.HasValue && + column.IsFixedLength.Value && + column.MaxLength.HasValue) + { + sql.Append($"char({column.MaxLength.Value})"); + } + else if (column.MaxLength.HasValue) + sql.Append($"varchar({column.MaxLength})"); + else + sql.Append("text"); + break; + case PrimitiveTypeKind.Time: + if (column.Precision != null) + { + sql.Append("interval("); + sql.Append(column.Precision); + sql.Append(')'); + } + else + sql.Append("interval"); + break; + case PrimitiveTypeKind.DateTimeOffset: + if (column.Precision != null) + { + sql.Append("timestamptz("); + sql.Append(column.Precision); + sql.Append(')'); + } + else + { + sql.Append("timestamptz"); + } + break; + case PrimitiveTypeKind.Geometry: + sql.Append("point"); + break; + //case PrimitiveTypeKind.Geography: + // break; + //case PrimitiveTypeKind.GeometryPoint: + // break; + //case PrimitiveTypeKind.GeometryLineString: + // break; + //case PrimitiveTypeKind.GeometryPolygon: + // break; + //case PrimitiveTypeKind.GeometryMultiPoint: + // break; + //case PrimitiveTypeKind.GeometryMultiLineString: + // break; + //case PrimitiveTypeKind.GeometryMultiPolygon: + // break; + //case PrimitiveTypeKind.GeometryCollection: + // break; + //case PrimitiveTypeKind.GeographyPoint: + // break; + //case PrimitiveTypeKind.GeographyLineString: + // break; + //case PrimitiveTypeKind.GeographyPolygon: + // break; + //case PrimitiveTypeKind.GeographyMultiPoint: + // break; + //case PrimitiveTypeKind.GeographyMultiLineString: + // break; + //case PrimitiveTypeKind.GeographyMultiPolygon: + // break; + //case PrimitiveTypeKind.GeographyCollection: + // break; + default: + throw new ArgumentException("Unhandled column type:" + column.Type); + } + } + + void AppendTableName(string tableName, StringBuilder sql) + { + var dotIndex = tableName.IndexOf('.'); if (dotIndex == -1) { sql.Append('"'); @@ -772,12 +707,10 @@ private void AppendTableName(string tableName, StringBuilder sql) #region Value appenders - private void AppendValue(byte[] values, StringBuilder sql) + void AppendValue(byte[] values, StringBuilder sql) { if (values.Length == 0) - { sql.Append("''"); - } else { sql.Append("E'\\\\"); @@ -787,91 +720,73 @@ private void AppendValue(byte[] values, StringBuilder sql) } } - private void AppendValue(bool value, StringBuilder sql) + void AppendValue(bool value, StringBuilder sql) { sql.Append(value ? "TRUE" : "FALSE"); } - private void AppendValue(DateTime value, StringBuilder sql) + void AppendValue(DateTime value, StringBuilder sql) { sql.Append("'"); sql.Append(new NpgsqlTypes.NpgsqlDateTime(value)); sql.Append("'"); } - private void AppendValue(DateTimeOffset value, StringBuilder sql) + void AppendValue(DateTimeOffset value, StringBuilder sql) { sql.Append("'"); sql.Append(new NpgsqlTypes.NpgsqlDateTime(value.UtcDateTime)); sql.Append("'"); } - private void AppendValue(Guid value, StringBuilder sql) + void AppendValue(Guid value, StringBuilder sql) { sql.Append("'"); sql.Append(value); sql.Append("'"); } - private void AppendValue(string value, StringBuilder sql) + void AppendValue(string value, StringBuilder sql) { sql.Append("'"); sql.Append(value); sql.Append("'"); } - private void AppendValue(TimeSpan value, StringBuilder sql) + void AppendValue(TimeSpan value, StringBuilder sql) { sql.Append("'"); - sql.Append(new NpgsqlTypes.NpgsqlTimeSpan(value).ToString()); + sql.Append(new NpgsqlTypes.NpgsqlTimeSpan(value)); sql.Append("'"); } - private void AppendValue(DbGeometry value, StringBuilder sql) + void AppendValue(DbGeometry value, StringBuilder sql) { sql.Append("'"); sql.Append(value); sql.Append("'"); } - private void AppendValue(object value, StringBuilder sql) + void AppendValue(object value, StringBuilder sql) { if (value is byte[]) - { AppendValue((byte[])value, sql); - } else if (value is bool) - { AppendValue((bool)value, sql); - } else if (value is DateTime) - { AppendValue((DateTime)value, sql); - } else if (value is DateTimeOffset) - { AppendValue((DateTimeOffset)value, sql); - } else if (value is Guid) - { AppendValue((Guid)value, sql); - } else if (value is string) - { AppendValue((string)value, sql); - } else if (value is TimeSpan) - { AppendValue((TimeSpan)value, sql); - } else if (value is DbGeometry) - { AppendValue((DbGeometry)value, sql); - } else - { sql.Append(string.Format(CultureInfo.InvariantCulture, "{0}", value)); - } } #endregion diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index b990f72..3dfa842 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -37,321 +37,306 @@ #endif using System.Xml; using System.Data; +using JetBrains.Annotations; using NpgsqlTypes; namespace Npgsql { internal class NpgsqlProviderManifest : DbXmlEnabledProviderManifest { - private Version _version; - - public Version Version { get { return _version; } } + public Version Version { get; } public NpgsqlProviderManifest(string serverVersion) : base(CreateXmlReaderForResource("Npgsql.NpgsqlProviderManifest.Manifest.xml")) { - if (!Version.TryParse(serverVersion, out _version)) - { - _version = new Version(9, 5); - } + Version version; + Version = Version.TryParse(serverVersion, out version) + ? version + : new Version(9, 5); } - protected override XmlReader GetDbInformation(string informationType) + protected override XmlReader GetDbInformation([NotNull] string informationType) { - XmlReader xmlReader = null; - if (informationType == StoreSchemaDefinition) - { - xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.ssdl"); - } -#if !NET40 - else if (informationType == StoreSchemaDefinitionVersion3) - { - xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchemaV3.ssdl"); - } -#endif - else if (informationType == StoreSchemaMapping) - { - xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.msl"); - } - - if (xmlReader == null) - throw new ArgumentOutOfRangeException("informationType"); + return CreateXmlReaderForResource("Npgsql.NpgsqlSchema.ssdl"); + if (informationType == StoreSchemaDefinitionVersion3) + return CreateXmlReaderForResource("Npgsql.NpgsqlSchemaV3.ssdl"); + if (informationType == StoreSchemaMapping) + return CreateXmlReaderForResource("Npgsql.NpgsqlSchema.msl"); - return xmlReader; + throw new ArgumentOutOfRangeException(nameof(informationType)); } - private const string MaxLengthFacet = "MaxLength"; - private const string ScaleFacet = "Scale"; - private const string PrecisionFacet = "Precision"; - private const string FixedLengthFacet = "FixedLength"; + const string MaxLengthFacet = "MaxLength"; + const string ScaleFacet = "Scale"; + const string PrecisionFacet = "Precision"; + const string FixedLengthFacet = "FixedLength"; - internal static NpgsqlDbType GetNpgsqlDbType(PrimitiveTypeKind _primitiveType) + internal static NpgsqlDbType GetNpgsqlDbType(PrimitiveTypeKind primitiveType) { - switch (_primitiveType) + switch (primitiveType) { - case PrimitiveTypeKind.Binary: - return NpgsqlDbType.Bytea; - case PrimitiveTypeKind.Boolean: - return NpgsqlDbType.Boolean; - case PrimitiveTypeKind.Byte: - case PrimitiveTypeKind.SByte: - case PrimitiveTypeKind.Int16: - return NpgsqlDbType.Smallint; - case PrimitiveTypeKind.DateTime: - return NpgsqlDbType.Timestamp; - case PrimitiveTypeKind.DateTimeOffset: - return NpgsqlDbType.TimestampTZ; - case PrimitiveTypeKind.Decimal: - return NpgsqlDbType.Numeric; - case PrimitiveTypeKind.Double: - return NpgsqlDbType.Double; - case PrimitiveTypeKind.Int32: - return NpgsqlDbType.Integer; - case PrimitiveTypeKind.Int64: - return NpgsqlDbType.Bigint; - case PrimitiveTypeKind.Single: - return NpgsqlDbType.Real; - case PrimitiveTypeKind.Time: - return NpgsqlDbType.Interval; - case PrimitiveTypeKind.Guid: - return NpgsqlDbType.Uuid; - case PrimitiveTypeKind.String: - // Send strings as unknowns to be compatible with other datatypes than text - return NpgsqlDbType.Unknown; - default: - return NpgsqlDbType.Unknown; + case PrimitiveTypeKind.Binary: + return NpgsqlDbType.Bytea; + case PrimitiveTypeKind.Boolean: + return NpgsqlDbType.Boolean; + case PrimitiveTypeKind.Byte: + case PrimitiveTypeKind.SByte: + case PrimitiveTypeKind.Int16: + return NpgsqlDbType.Smallint; + case PrimitiveTypeKind.DateTime: + return NpgsqlDbType.Timestamp; + case PrimitiveTypeKind.DateTimeOffset: + return NpgsqlDbType.TimestampTZ; + case PrimitiveTypeKind.Decimal: + return NpgsqlDbType.Numeric; + case PrimitiveTypeKind.Double: + return NpgsqlDbType.Double; + case PrimitiveTypeKind.Int32: + return NpgsqlDbType.Integer; + case PrimitiveTypeKind.Int64: + return NpgsqlDbType.Bigint; + case PrimitiveTypeKind.Single: + return NpgsqlDbType.Real; + case PrimitiveTypeKind.Time: + return NpgsqlDbType.Interval; + case PrimitiveTypeKind.Guid: + return NpgsqlDbType.Uuid; + case PrimitiveTypeKind.String: + // Send strings as unknowns to be compatible with other datatypes than text + return NpgsqlDbType.Unknown; + default: + return NpgsqlDbType.Unknown; } } - public override TypeUsage GetEdmType(TypeUsage storeType) + public override TypeUsage GetEdmType([NotNull] TypeUsage storeType) { if (storeType == null) - throw new ArgumentNullException("storeType"); + throw new ArgumentNullException(nameof(storeType)); - string storeTypeName = storeType.EdmType.Name; - PrimitiveType primitiveType = StoreTypeNameToEdmPrimitiveType[storeTypeName]; + var storeTypeName = storeType.EdmType.Name; + var primitiveType = StoreTypeNameToEdmPrimitiveType[storeTypeName]; // TODO: come up with way to determin if unicode is used - bool isUnicode = true; + var isUnicode = true; Facet facet; switch (storeTypeName) { - case "bool": - case "int2": - case "int4": - case "int8": - case "float4": - case "float8": - case "uuid": - return TypeUsage.CreateDefaultTypeUsage(primitiveType); - case "numeric": + case "bool": + case "int2": + case "int4": + case "int8": + case "float4": + case "float8": + case "uuid": + return TypeUsage.CreateDefaultTypeUsage(primitiveType); + case "numeric": + { + byte scale; + byte precision; + if (storeType.Facets.TryGetValue(ScaleFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) { - byte scale; - byte precision; - if (storeType.Facets.TryGetValue(ScaleFacet, false, out facet) && + scale = (byte)facet.Value; + if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - scale = (byte)facet.Value; - if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - precision = (byte)facet.Value; - return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale); - } + precision = (byte)facet.Value; + return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale); } - return TypeUsage.CreateDecimalTypeUsage(primitiveType); } - case "bpchar": - if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true, (int)facet.Value); - else - return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true); - case "varchar": - if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false, (int)facet.Value); - else - return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false); - case "text": - case "xml": + return TypeUsage.CreateDecimalTypeUsage(primitiveType); + } + case "bpchar": + if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true, (int)facet.Value); + else + return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true); + case "varchar": + if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false, (int)facet.Value); + else return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false); - case "timestamp": - // TODO: make sure the arguments are correct here - if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateDateTimeTypeUsage(primitiveType, (byte)facet.Value); - } - else - { - return TypeUsage.CreateDateTimeTypeUsage(primitiveType, null); - } - case "date": - return TypeUsage.CreateDateTimeTypeUsage(primitiveType, 0); - case "timestamptz": - if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, (byte)facet.Value); - } - else - { - return TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, null); - } - case "time": - case "interval": - if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + case "text": + case "xml": + return TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false); + case "timestamp": + // TODO: make sure the arguments are correct here + if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateDateTimeTypeUsage(primitiveType, (byte)facet.Value); + } + else + { + return TypeUsage.CreateDateTimeTypeUsage(primitiveType, null); + } + case "date": + return TypeUsage.CreateDateTimeTypeUsage(primitiveType, 0); + case "timestamptz": + if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, (byte)facet.Value); + } + else + { + return TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, null); + } + case "time": + case "interval": + if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateTimeTypeUsage(primitiveType, (byte)facet.Value); + } + else + { + return TypeUsage.CreateTimeTypeUsage(primitiveType, null); + } + case "bytea": + { + if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - return TypeUsage.CreateTimeTypeUsage(primitiveType, (byte)facet.Value); - } - else - { - return TypeUsage.CreateTimeTypeUsage(primitiveType, null); - } - case "bytea": - { - if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateBinaryTypeUsage(primitiveType, false, (int)facet.Value); - } - return TypeUsage.CreateBinaryTypeUsage(primitiveType, false); - } - case "rowversion": - { - return TypeUsage.CreateBinaryTypeUsage(primitiveType, true, 8); + return TypeUsage.CreateBinaryTypeUsage(primitiveType, false, (int)facet.Value); } - //TypeUsage.CreateBinaryTypeUsage - //TypeUsage.CreateDateTimeTypeUsage - //TypeUsage.CreateDecimalTypeUsage - //TypeUsage.CreateStringTypeUsage + return TypeUsage.CreateBinaryTypeUsage(primitiveType, false); + } + case "rowversion": + { + return TypeUsage.CreateBinaryTypeUsage(primitiveType, true, 8); + } + //TypeUsage.CreateBinaryTypeUsage + //TypeUsage.CreateDateTimeTypeUsage + //TypeUsage.CreateDecimalTypeUsage + //TypeUsage.CreateStringTypeUsage } + throw new NotSupportedException("Not supported store type: " + storeTypeName); } - public override TypeUsage GetStoreType(TypeUsage edmType) + public override TypeUsage GetStoreType([NotNull] TypeUsage edmType) { if (edmType == null) - throw new ArgumentNullException("edmType"); + throw new ArgumentNullException(nameof(edmType)); - PrimitiveType primitiveType = edmType.EdmType as PrimitiveType; + var primitiveType = edmType.EdmType as PrimitiveType; if (primitiveType == null) throw new ArgumentException("Store does not support specified edm type"); // TODO: come up with way to determin if unicode is used - bool isUnicode = true; + var isUnicode = true; Facet facet; switch (primitiveType.PrimitiveTypeKind) { - case PrimitiveTypeKind.Boolean: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bool"]); - case PrimitiveTypeKind.Int16: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"]); - case PrimitiveTypeKind.Int32: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int4"]); - case PrimitiveTypeKind.Int64: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int8"]); - case PrimitiveTypeKind.Single: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float4"]); - case PrimitiveTypeKind.Double: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float8"]); - case PrimitiveTypeKind.Decimal: + case PrimitiveTypeKind.Boolean: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bool"]); + case PrimitiveTypeKind.Int16: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"]); + case PrimitiveTypeKind.Int32: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int4"]); + case PrimitiveTypeKind.Int64: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int8"]); + case PrimitiveTypeKind.Single: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float4"]); + case PrimitiveTypeKind.Double: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float8"]); + case PrimitiveTypeKind.Decimal: + { + byte scale; + byte precision; + if (edmType.Facets.TryGetValue(ScaleFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) { - byte scale; - byte precision; - if (edmType.Facets.TryGetValue(ScaleFacet, false, out facet) && + scale = (byte)facet.Value; + if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - scale = (byte)facet.Value; - if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - precision = (byte)facet.Value; - return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"], precision, scale); - } + precision = (byte)facet.Value; + return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"], precision, scale); } - return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"]); } - case PrimitiveTypeKind.String: + return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"]); + } + case PrimitiveTypeKind.String: + { + // TODO: could get character, character varying, text + if (edmType.Facets.TryGetValue(FixedLengthFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null && (bool)facet.Value) { - // TODO: could get character, character varying, text - if (edmType.Facets.TryGetValue(FixedLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null && (bool)facet.Value) - { - PrimitiveType characterPrimitive = StoreTypeNameToStorePrimitiveType["bpchar"]; - if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true, (int)facet.Value); - } - // this may not work well - return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true); - } + PrimitiveType characterPrimitive = StoreTypeNameToStorePrimitiveType["bpchar"]; if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], isUnicode, false, (int)facet.Value); + return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true, (int)facet.Value); } - // assume text since it is not fixed length and has no max length - return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["text"], isUnicode, false); - } - case PrimitiveTypeKind.DateTime: - if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], (byte)facet.Value); - } - else - { - return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], null); + // this may not work well + return TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true); } - case PrimitiveTypeKind.DateTimeOffset: - if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - return TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], (byte)facet.Value); - } - else - { - return TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], null); + return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], isUnicode, false, (int)facet.Value); } - case PrimitiveTypeKind.Time: - if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + // assume text since it is not fixed length and has no max length + return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["text"], isUnicode, false); + } + case PrimitiveTypeKind.DateTime: + if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], (byte)facet.Value); + } + else + { + return TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], null); + } + case PrimitiveTypeKind.DateTimeOffset: + if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], (byte)facet.Value); + } + else + { + return TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], null); + } + case PrimitiveTypeKind.Time: + if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], (byte)facet.Value); + } + else + { + return TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], null); + } + case PrimitiveTypeKind.Binary: + { + if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - return TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], (byte)facet.Value); - } - else - { - return TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], null); + return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false, (int)facet.Value); } - case PrimitiveTypeKind.Binary: - { - if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && - !facet.IsUnbounded && facet.Value != null) - { - return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false, (int)facet.Value); - } - return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false); - } - case PrimitiveTypeKind.Guid: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uuid"]); - case PrimitiveTypeKind.Byte: - case PrimitiveTypeKind.SByte: - return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"]); + return TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false); + } + case PrimitiveTypeKind.Guid: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uuid"]); + case PrimitiveTypeKind.Byte: + case PrimitiveTypeKind.SByte: + return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"]); } throw new NotSupportedException("Not supported edm type: " + edmType); } - private static XmlReader CreateXmlReaderForResource(string resourceName) - { - return XmlReader.Create(System.Reflection.Assembly.GetAssembly(typeof(NpgsqlProviderManifest)).GetManifestResourceStream(resourceName)); - } + static XmlReader CreateXmlReaderForResource(string resourceName) + => XmlReader.Create(System.Reflection.Assembly.GetAssembly(typeof(NpgsqlProviderManifest)).GetManifestResourceStream(resourceName)); public override bool SupportsEscapingLikeArgument(out char escapeCharacter) { @@ -359,35 +344,27 @@ public override bool SupportsEscapingLikeArgument(out char escapeCharacter) return true; } - public override string EscapeLikeArgument(string argument) - { - return argument.Replace("\\","\\\\").Replace("%", "\\%").Replace("_", "\\_"); - } + public override string EscapeLikeArgument([NotNull] string argument) + => argument.Replace("\\","\\\\").Replace("%", "\\%").Replace("_", "\\_"); #if ENTITIES6 - public override bool SupportsInExpression() - { - return true; - } + public override bool SupportsInExpression() => true; public override ReadOnlyCollection GetStoreFunctions() - { - var functions = new List(); - - functions.AddRange( - typeof(NpgsqlTextFunctions).GetTypeInfo() - .GetMethods(BindingFlags.Public | BindingFlags.Static) - .Select(x => new { Method = x, DbFunction = x.GetCustomAttribute() }) - .Where(x => x.DbFunction != null) - .Select(x => CreateFullTextEdmFunction(x.Method, x.DbFunction))); + => typeof(NpgsqlTextFunctions).GetTypeInfo() + .GetMethods(BindingFlags.Public | BindingFlags.Static) + .Select(x => new { Method = x, DbFunction = x.GetCustomAttribute() }) + .Where(x => x.DbFunction != null) + .Select(x => CreateFullTextEdmFunction(x.Method, x.DbFunction)) + .ToList() + .AsReadOnly(); - return functions.AsReadOnly(); - } - - private static EdmFunction CreateFullTextEdmFunction(MethodInfo method, DbFunctionAttribute dbFunctionInfo) + static EdmFunction CreateFullTextEdmFunction([NotNull] MethodInfo method, [NotNull] DbFunctionAttribute dbFunctionInfo) { - if (method == null) throw new ArgumentNullException("method"); - if (dbFunctionInfo == null) throw new ArgumentNullException("dbFunctionInfo"); + if (method == null) + throw new ArgumentNullException(nameof(method)); + if (dbFunctionInfo == null) + throw new ArgumentNullException(nameof(dbFunctionInfo)); return EdmFunction.Create( dbFunctionInfo.FunctionName, @@ -418,24 +395,19 @@ private static EdmFunction CreateFullTextEdmFunction(MethodInfo method, DbFuncti new List()); } - private static EdmType MapTypeToEdmType(Type type) + static EdmType MapTypeToEdmType(Type type) { var fromClrType = PrimitiveType .GetEdmPrimitiveTypes() .FirstOrDefault(t => t.ClrEquivalentType == type); if (fromClrType != null) - { return fromClrType; - } if (type.IsEnum) - { return MapTypeToEdmType(Enum.GetUnderlyingType(type)); - } - throw new NotSupportedException( - string.Format("Unsupported type for mapping to EdmType: {0}", type.FullName)); + throw new NotSupportedException($"Unsupported type for mapping to EdmType: {type.FullName}"); } #endif } diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index 9fe793d..cebda62 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -22,8 +22,8 @@ #endregion using System; -using System.Collections.Generic; using System.Text; +using JetBrains.Annotations; #if ENTITIES6 using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Common.CommandTrees; @@ -39,6 +39,8 @@ using DbConnection = System.Data.Common.DbConnection; using DbCommand = System.Data.Common.DbCommand; +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + namespace Npgsql { #if ENTITIES6 @@ -47,38 +49,33 @@ public class NpgsqlServices : DbProviderServices internal class NpgsqlServices : DbProviderServices #endif { - private static readonly NpgsqlServices _instance = new NpgsqlServices(); + public static NpgsqlServices Instance { get; } = new NpgsqlServices(); #if ENTITIES6 public NpgsqlServices() { AddDependencyResolver(new SingletonDependencyResolver>( - () => new NpgsqlMigrationSqlGenerator(), "Npgsql")); + () => new NpgsqlMigrationSqlGenerator(), nameof(Npgsql))); } #endif - public static NpgsqlServices Instance - { - get { return _instance; } - } - - protected override DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree) - { - return CreateCommandDefinition(CreateDbCommand(((NpgsqlProviderManifest)providerManifest).Version, commandTree)); - } + protected override DbCommandDefinition CreateDbCommandDefinition([NotNull] DbProviderManifest providerManifest, [NotNull] DbCommandTree commandTree) + => CreateCommandDefinition(CreateDbCommand(((NpgsqlProviderManifest)providerManifest).Version, commandTree)); internal DbCommand CreateDbCommand(Version serverVersion, DbCommandTree commandTree) { if (commandTree == null) - throw new ArgumentNullException("commandTree"); + throw new ArgumentNullException(nameof(commandTree)); - NpgsqlCommand command = new NpgsqlCommand(); + var command = new NpgsqlCommand(); - foreach (KeyValuePair parameter in commandTree.Parameters) + foreach (var parameter in commandTree.Parameters) { - NpgsqlParameter dbParameter = new NpgsqlParameter(); - dbParameter.ParameterName = parameter.Key; - dbParameter.NpgsqlDbType = NpgsqlProviderManifest.GetNpgsqlDbType(((PrimitiveType)parameter.Value.EdmType).PrimitiveTypeKind); + var dbParameter = new NpgsqlParameter + { + ParameterName = parameter.Key, + NpgsqlDbType = NpgsqlProviderManifest.GetNpgsqlDbType(((PrimitiveType)parameter.Value.EdmType).PrimitiveTypeKind) + }; command.Parameters.Add(dbParameter); } @@ -89,76 +86,66 @@ internal DbCommand CreateDbCommand(Version serverVersion, DbCommandTree commandT internal void TranslateCommandTree(Version serverVersion, DbCommandTree commandTree, DbCommand command, bool createParametersForNonSelect = true) { - SqlBaseGenerator sqlGenerator = null; + SqlBaseGenerator sqlGenerator; DbQueryCommandTree select; DbInsertCommandTree insert; DbUpdateCommandTree update; DbDeleteCommandTree delete; if ((select = commandTree as DbQueryCommandTree) != null) - { sqlGenerator = new SqlSelectGenerator(select); - } else if ((insert = commandTree as DbInsertCommandTree) != null) - { sqlGenerator = new SqlInsertGenerator(insert); - } else if ((update = commandTree as DbUpdateCommandTree) != null) - { sqlGenerator = new SqlUpdateGenerator(update); - } else if ((delete = commandTree as DbDeleteCommandTree) != null) - { sqlGenerator = new SqlDeleteGenerator(delete); - } else { // TODO: get a message (unsupported DbCommandTree type) throw new ArgumentException(); } - sqlGenerator._createParametersForConstants = select != null ? false : createParametersForNonSelect; - sqlGenerator._command = (NpgsqlCommand)command; + sqlGenerator.CreateParametersForConstants = select == null && createParametersForNonSelect; + sqlGenerator.Command = (NpgsqlCommand)command; sqlGenerator.Version = serverVersion; sqlGenerator.BuildCommand(command); } - protected override string GetDbProviderManifestToken(DbConnection connection) + protected override string GetDbProviderManifestToken([NotNull] DbConnection connection) { if (connection == null) - throw new ArgumentNullException("connection"); - string serverVersion = ""; - UsingPostgresDBConnection((NpgsqlConnection)connection, conn => - { + throw new ArgumentNullException(nameof(connection)); + + var serverVersion = ""; + UsingPostgresDbConnection((NpgsqlConnection)connection, conn => { serverVersion = conn.ServerVersion; }); return serverVersion; } - protected override DbProviderManifest GetDbProviderManifest(string versionHint) + protected override DbProviderManifest GetDbProviderManifest([NotNull] string versionHint) { if (versionHint == null) - throw new ArgumentNullException("versionHint"); + throw new ArgumentNullException(nameof(versionHint)); return new NpgsqlProviderManifest(versionHint); } #if ENTITIES6 - protected override bool DbDatabaseExists(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection) + protected override bool DbDatabaseExists([NotNull] DbConnection connection, int? commandTimeout, [NotNull] StoreItemCollection storeItemCollection) { - bool exists = false; - UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + var exists = false; + UsingPostgresDbConnection((NpgsqlConnection)connection, conn => { - using (NpgsqlCommand command = new NpgsqlCommand("select count(*) from pg_catalog.pg_database where datname = '" + connection.Database + "';", conn)) - { + using (var command = new NpgsqlCommand("select count(*) from pg_catalog.pg_database where datname = '" + connection.Database + "';", conn)) exists = Convert.ToInt32(command.ExecuteScalar()) > 0; - } }); return exists; } - protected override void DbCreateDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection) + protected override void DbCreateDatabase([NotNull] DbConnection connection, int? commandTimeout, [NotNull] StoreItemCollection storeItemCollection) { - UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + UsingPostgresDbConnection((NpgsqlConnection)connection, conn => { var sb = new StringBuilder(); sb.Append("CREATE DATABASE \""); @@ -171,28 +158,24 @@ protected override void DbCreateDatabase(DbConnection connection, int? commandTi sb.Append("\""); } - using (NpgsqlCommand command = new NpgsqlCommand(sb.ToString(), conn)) - { + using (var command = new NpgsqlCommand(sb.ToString(), conn)) command.ExecuteNonQuery(); - } }); } - protected override void DbDeleteDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection) + protected override void DbDeleteDatabase([NotNull] DbConnection connection, int? commandTimeout, [NotNull] StoreItemCollection storeItemCollection) { - UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + UsingPostgresDbConnection((NpgsqlConnection)connection, conn => { //Close all connections in pool or exception "database used by another user appears" NpgsqlConnection.ClearAllPools(); - using (NpgsqlCommand command = new NpgsqlCommand("DROP DATABASE \"" + connection.Database + "\";", conn)) - { + using (var command = new NpgsqlCommand("DROP DATABASE \"" + connection.Database + "\";", conn)) command.ExecuteNonQuery(); - } }); } #endif - private static void UsingPostgresDBConnection(NpgsqlConnection connection, Action action) + static void UsingPostgresDbConnection(NpgsqlConnection connection, Action action) { var connectionBuilder = new NpgsqlConnectionStringBuilder(connection.ConnectionString) { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs index 9f5bbc4..646fba6 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs @@ -21,10 +21,7 @@ // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #endregion -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Npgsql.SqlGenerators { @@ -51,23 +48,18 @@ internal class PendingProjectsNode { public readonly List Selects = new List(); public PendingProjectsNode JoinParent { get; set; } - public string TopName - { - get - { - return Selects[0].AsName; - } - } + public string TopName => Selects[0].AsName; public PendingProjectsNode(string asName, InputExpression exp) { Selects.Add(new NameAndInputExpression(asName, exp)); } + public void Add(string asName, InputExpression exp) { Selects.Add(new NameAndInputExpression(asName, exp)); } - public NameAndInputExpression Last { get { return Selects[Selects.Count - 1]; } } + public NameAndInputExpression Last => Selects[Selects.Count - 1]; } } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index dd6435e..0dbccdd 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -24,6 +24,7 @@ using System; using System.Collections.Generic; using System.Data.Common; +using System.Diagnostics; #if ENTITIES6 using System.Globalization; using System.Data.Entity.Core.Common.CommandTrees; @@ -33,25 +34,33 @@ using System.Data.Metadata.Edm; #endif using System.Linq; -using Npgsql; -using NpgsqlTypes; +using JetBrains.Annotations; namespace Npgsql.SqlGenerators { internal abstract class SqlBaseGenerator : DbExpressionVisitor { - internal NpgsqlCommand _command; - internal bool _createParametersForConstants; - private Version _version; - internal Version Version { get { return _version; } set { _version = value; _useNewPrecedences = value >= new Version(9, 5); } } - private bool _useNewPrecedences; - - protected Dictionary _refToNode = new Dictionary(); - protected HashSet _currentExpressions = new HashSet(); - protected uint _aliasCounter = 0; - protected uint _parameterCount = 0; - - private static Dictionary AggregateFunctionNames = new Dictionary() + internal NpgsqlCommand Command; + internal bool CreateParametersForConstants; + bool _useNewPrecedences; + + protected Dictionary RefToNode = new Dictionary(); + protected HashSet CurrentExpressions = new HashSet(); + protected uint AliasCounter; + protected uint ParameterCount; + + internal Version Version + { + get { return _version; } + set + { + _version = value; + _useNewPrecedences = value >= new Version(9, 5); + } + } + Version _version; + + static readonly Dictionary AggregateFunctionNames = new Dictionary() { {"Avg","avg"}, {"Count","count"}, @@ -66,7 +75,7 @@ internal abstract class SqlBaseGenerator : DbExpressionVisitor BinaryOperatorFunctionNames = new Dictionary() + static readonly Dictionary BinaryOperatorFunctionNames = new Dictionary() { {"@@",Operator.QueryMatch}, {"operator_tsquery_and",Operator.QueryAnd}, @@ -76,363 +85,335 @@ internal abstract class SqlBaseGenerator : DbExpressionVisitor CurrentExpressions.Add(n.Last.Exp); + void LeaveExpression(PendingProjectsNode n) => CurrentExpressions.Remove(n.Last.Exp); - protected string NextAlias() - { - return "Alias" + _aliasCounter++; - } + protected string NextAlias() => "Alias" + AliasCounter++; - private bool IsCompatible(InputExpression child, DbExpressionKind parentKind) + bool IsCompatible(InputExpression child, DbExpressionKind parentKind) { switch (parentKind) { - case DbExpressionKind.Filter: - return - child.Projection == null && - child.GroupBy == null && - child.Skip == null && - child.Limit == null; - case DbExpressionKind.GroupBy: - return - child.Projection == null && - child.GroupBy == null && - child.Distinct == false && - child.OrderBy == null && - child.Skip == null && - child.Limit == null; - case DbExpressionKind.Distinct: - return - child.OrderBy == null && - child.Skip == null && - child.Limit == null; - case DbExpressionKind.Sort: - return - child.Projection == null && - child.GroupBy == null && - child.Skip == null && - child.Limit == null; - case DbExpressionKind.Skip: - return - child.Projection == null && - child.Skip == null && - child.Limit == null; - case DbExpressionKind.Project: - return - child.Projection == null && - child.Distinct == false; - // Limit and NewInstance are always true - default: - throw new ArgumentException("Unexpected parent expression kind"); + case DbExpressionKind.Filter: + return + child.Projection == null && + child.GroupBy == null && + child.Skip == null && + child.Limit == null; + case DbExpressionKind.GroupBy: + return + child.Projection == null && + child.GroupBy == null && + child.Distinct == false && + child.OrderBy == null && + child.Skip == null && + child.Limit == null; + case DbExpressionKind.Distinct: + return + child.OrderBy == null && + child.Skip == null && + child.Limit == null; + case DbExpressionKind.Sort: + return + child.Projection == null && + child.GroupBy == null && + child.Skip == null && + child.Limit == null; + case DbExpressionKind.Skip: + return + child.Projection == null && + child.Skip == null && + child.Limit == null; + case DbExpressionKind.Project: + return + child.Projection == null && + child.Distinct == false; + // Limit and NewInstance are always true + default: + throw new ArgumentException("Unexpected parent expression kind"); } } - private PendingProjectsNode GetInput(DbExpression expression, string childBindingName, string parentBindingName, DbExpressionKind parentKind) + PendingProjectsNode GetInput(DbExpression expression, string childBindingName, string parentBindingName, DbExpressionKind parentKind) { - PendingProjectsNode n = VisitInputWithBinding(expression, childBindingName); + var n = VisitInputWithBinding(expression, childBindingName); if (!IsCompatible(n.Last.Exp, parentKind)) - { n.Selects.Add(new NameAndInputExpression(parentBindingName, new InputExpression(n.Last.Exp, n.Last.AsName))); - } return n; } - private PendingProjectsNode VisitInputWithBinding(DbExpression expression, string bindingName) + PendingProjectsNode VisitInputWithBinding(DbExpression expression, string bindingName) { PendingProjectsNode n; switch (expression.ExpressionKind) { - case DbExpressionKind.Scan: - { - ScanExpression scan = (ScanExpression)expression.Accept(this); - InputExpression input = new InputExpression(scan, bindingName); - n = new PendingProjectsNode(bindingName, input); + case DbExpressionKind.Scan: + { + var scan = (ScanExpression)expression.Accept(this); + var input = new InputExpression(scan, bindingName); + n = new PendingProjectsNode(bindingName, input); - break; - } - case DbExpressionKind.Filter: - { - DbFilterExpression exp = (DbFilterExpression)expression; - n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); - EnterExpression(n); - VisitedExpression pred = exp.Predicate.Accept(this); - if (n.Last.Exp.Where == null) - n.Last.Exp.Where = new WhereExpression(pred); - else - n.Last.Exp.Where.And(pred); - LeaveExpression(n); - - break; - } - case DbExpressionKind.Sort: - { - DbSortExpression exp = (DbSortExpression)expression; - n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); - EnterExpression(n); - n.Last.Exp.OrderBy = new OrderByExpression(); - foreach (var order in exp.SortOrder) - { - n.Last.Exp.OrderBy.AppendSort(order.Expression.Accept(this), order.Ascending); - } - LeaveExpression(n); - - break; - } - case DbExpressionKind.Skip: - { - DbSkipExpression exp = (DbSkipExpression)expression; - n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); - EnterExpression(n); - n.Last.Exp.OrderBy = new OrderByExpression(); - foreach (var order in exp.SortOrder) - { - n.Last.Exp.OrderBy.AppendSort(order.Expression.Accept(this), order.Ascending); - } - n.Last.Exp.Skip = new SkipExpression(exp.Count.Accept(this)); - LeaveExpression(n); - break; - } - case DbExpressionKind.Distinct: - { - DbDistinctExpression exp = (DbDistinctExpression)expression; - string childBindingName = NextAlias(); - - n = VisitInputWithBinding(exp.Argument, childBindingName); - if (!IsCompatible(n.Last.Exp, expression.ExpressionKind)) - { - InputExpression prev = n.Last.Exp; - string prevName = n.Last.AsName; - InputExpression input = new InputExpression(prev, prevName); - n.Selects.Add(new NameAndInputExpression(bindingName, input)); - - // We need to copy all the projected columns so the DISTINCT keyword will work on the correct columns - // A parent project expression is never compatible with this new expression, - // so these are the columns that finally will be projected, as wanted - foreach (ColumnExpression col in prev.Projection.Arguments) - { - input.ColumnsToProject.Add(new StringPair(prevName, col.Name), col.Name); - input.ProjectNewNames.Add(col.Name); - } - } - n.Last.Exp.Distinct = true; - break; - } - case DbExpressionKind.Limit: - { - DbLimitExpression exp = (DbLimitExpression)expression; - n = VisitInputWithBinding(exp.Argument, NextAlias()); - if (n.Last.Exp.Limit != null) - { - FunctionExpression least = new FunctionExpression("LEAST"); - least.AddArgument(n.Last.Exp.Limit.Arg); - least.AddArgument(exp.Limit.Accept(this)); - n.Last.Exp.Limit.Arg = least; - } - else - { - n.Last.Exp.Limit = new LimitExpression(exp.Limit.Accept(this)); - } - break; - } - case DbExpressionKind.NewInstance: + break; + } + case DbExpressionKind.Filter: + { + var exp = (DbFilterExpression)expression; + n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); + EnterExpression(n); + var pred = exp.Predicate.Accept(this); + if (n.Last.Exp.Where == null) + n.Last.Exp.Where = new WhereExpression(pred); + else + n.Last.Exp.Where.And(pred); + LeaveExpression(n); + + break; + } + case DbExpressionKind.Sort: + { + var exp = (DbSortExpression)expression; + n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); + EnterExpression(n); + n.Last.Exp.OrderBy = new OrderByExpression(); + foreach (var order in exp.SortOrder) + n.Last.Exp.OrderBy.AppendSort(order.Expression.Accept(this), order.Ascending); + LeaveExpression(n); + + break; + } + case DbExpressionKind.Skip: + { + var exp = (DbSkipExpression)expression; + n = GetInput(exp.Input.Expression, exp.Input.VariableName, bindingName, expression.ExpressionKind); + EnterExpression(n); + n.Last.Exp.OrderBy = new OrderByExpression(); + foreach (var order in exp.SortOrder) + n.Last.Exp.OrderBy.AppendSort(order.Expression.Accept(this), order.Ascending); + n.Last.Exp.Skip = new SkipExpression(exp.Count.Accept(this)); + LeaveExpression(n); + break; + } + case DbExpressionKind.Distinct: + { + var exp = (DbDistinctExpression)expression; + var childBindingName = NextAlias(); + + n = VisitInputWithBinding(exp.Argument, childBindingName); + if (!IsCompatible(n.Last.Exp, expression.ExpressionKind)) + { + var prev = n.Last.Exp; + var prevName = n.Last.AsName; + var input = new InputExpression(prev, prevName); + n.Selects.Add(new NameAndInputExpression(bindingName, input)); + + // We need to copy all the projected columns so the DISTINCT keyword will work on the correct columns + // A parent project expression is never compatible with this new expression, + // so these are the columns that finally will be projected, as wanted + foreach (ColumnExpression col in prev.Projection.Arguments) { - DbNewInstanceExpression exp = (DbNewInstanceExpression)expression; - if (exp.Arguments.Count == 1 && exp.Arguments[0].ExpressionKind == DbExpressionKind.Element) - { - n = VisitInputWithBinding(((DbElementExpression)exp.Arguments[0]).Argument, NextAlias()); - if (n.Last.Exp.Limit != null) - { - FunctionExpression least = new FunctionExpression("LEAST"); - least.AddArgument(n.Last.Exp.Limit.Arg); - least.AddArgument(new LiteralExpression("1")); - n.Last.Exp.Limit.Arg = least; - } - else - { - n.Last.Exp.Limit = new LimitExpression(new LiteralExpression("1")); - } - } - else if (exp.Arguments.Count >= 1) - { - LiteralExpression result = new LiteralExpression("("); - for (int i = 0; i < exp.Arguments.Count; ++i) - { - DbExpression arg = exp.Arguments[i]; - var visitedColumn = arg.Accept(this); - if (!(visitedColumn is ColumnExpression)) - visitedColumn = new ColumnExpression(visitedColumn, "C", arg.ResultType); - - result.Append(i == 0 ? "SELECT " : " UNION ALL SELECT "); - result.Append(visitedColumn); - } - result.Append(")"); - n = new PendingProjectsNode(bindingName, new InputExpression(result, bindingName)); - } - else - { - TypeUsage type = ((CollectionType)exp.ResultType.EdmType).TypeUsage; - LiteralExpression result = new LiteralExpression("(SELECT "); - result.Append(new CastExpression(new LiteralExpression("NULL"), GetDbType(type.EdmType))); - result.Append(" LIMIT 0)"); - n = new PendingProjectsNode(bindingName, new InputExpression(result, bindingName)); - } - break; + input.ColumnsToProject.Add(new StringPair(prevName, col.Name), col.Name); + input.ProjectNewNames.Add(col.Name); } - case DbExpressionKind.UnionAll: - case DbExpressionKind.Intersect: - case DbExpressionKind.Except: + } + n.Last.Exp.Distinct = true; + break; + } + case DbExpressionKind.Limit: + { + var exp = (DbLimitExpression)expression; + n = VisitInputWithBinding(exp.Argument, NextAlias()); + if (n.Last.Exp.Limit != null) + { + var least = new FunctionExpression("LEAST"); + least.AddArgument(n.Last.Exp.Limit.Arg); + least.AddArgument(exp.Limit.Accept(this)); + n.Last.Exp.Limit.Arg = least; + } + else + n.Last.Exp.Limit = new LimitExpression(exp.Limit.Accept(this)); + break; + } + case DbExpressionKind.NewInstance: + { + var exp = (DbNewInstanceExpression)expression; + if (exp.Arguments.Count == 1 && exp.Arguments[0].ExpressionKind == DbExpressionKind.Element) + { + n = VisitInputWithBinding(((DbElementExpression)exp.Arguments[0]).Argument, NextAlias()); + if (n.Last.Exp.Limit != null) { - DbBinaryExpression exp = (DbBinaryExpression)expression; - DbExpressionKind expKind = exp.ExpressionKind; - List list = new List(); - Action func = null; - func = e => - { - if (e.ExpressionKind == expKind && e.ExpressionKind != DbExpressionKind.Except) - { - DbBinaryExpression binaryExp = (DbBinaryExpression)e; - func(binaryExp.Left); - func(binaryExp.Right); - } - else - { - list.Add(VisitInputWithBinding(e, bindingName + "_" + list.Count).Last.Exp); - } - }; - func(exp.Left); - func(exp.Right); - InputExpression input = new InputExpression(new CombinedProjectionExpression(expression.ExpressionKind, list), bindingName); - n = new PendingProjectsNode(bindingName, input); - break; + var least = new FunctionExpression("LEAST"); + least.AddArgument(n.Last.Exp.Limit.Arg); + least.AddArgument(new LiteralExpression("1")); + n.Last.Exp.Limit.Arg = least; } - case DbExpressionKind.Project: + else + n.Last.Exp.Limit = new LimitExpression(new LiteralExpression("1")); + } + else if (exp.Arguments.Count >= 1) + { + var result = new LiteralExpression("("); + for (var i = 0; i < exp.Arguments.Count; ++i) { - DbProjectExpression exp = (DbProjectExpression)expression; - PendingProjectsNode child = VisitInputWithBinding(exp.Input.Expression, exp.Input.VariableName); - InputExpression input = child.Last.Exp; - bool enterScope = false; - if (!IsCompatible(input, expression.ExpressionKind)) - { - input = new InputExpression(input, child.Last.AsName); - } - else enterScope = true; - - if (enterScope) EnterExpression(child); - - input.Projection = new CommaSeparatedExpression(); - - DbNewInstanceExpression projection = (DbNewInstanceExpression)exp.Projection; - RowType rowType = projection.ResultType.EdmType as RowType; - for (int i = 0; i < rowType.Properties.Count && i < projection.Arguments.Count; ++i) - { - EdmProperty prop = rowType.Properties[i]; - input.Projection.Arguments.Add(new ColumnExpression(projection.Arguments[i].Accept(this), prop.Name, prop.TypeUsage)); - } - - if (enterScope) LeaveExpression(child); - - n = new PendingProjectsNode(bindingName, input); - break; + var arg = exp.Arguments[i]; + var visitedColumn = arg.Accept(this); + if (!(visitedColumn is ColumnExpression)) + visitedColumn = new ColumnExpression(visitedColumn, "C", arg.ResultType); + + result.Append(i == 0 ? "SELECT " : " UNION ALL SELECT "); + result.Append(visitedColumn); } - case DbExpressionKind.GroupBy: + result.Append(")"); + n = new PendingProjectsNode(bindingName, new InputExpression(result, bindingName)); + } + else + { + var type = ((CollectionType)exp.ResultType.EdmType).TypeUsage; + var result = new LiteralExpression("(SELECT "); + result.Append(new CastExpression(new LiteralExpression("NULL"), GetDbType(type.EdmType))); + result.Append(" LIMIT 0)"); + n = new PendingProjectsNode(bindingName, new InputExpression(result, bindingName)); + } + break; + } + case DbExpressionKind.UnionAll: + case DbExpressionKind.Intersect: + case DbExpressionKind.Except: + { + var exp = (DbBinaryExpression)expression; + var expKind = exp.ExpressionKind; + var list = new List(); + Action func = null; + func = e => + { + if (e.ExpressionKind == expKind && e.ExpressionKind != DbExpressionKind.Except) { - DbGroupByExpression exp = (DbGroupByExpression)expression; - PendingProjectsNode child = VisitInputWithBinding(exp.Input.Expression, exp.Input.VariableName); - - // I don't know why the input for GroupBy in EF have two names - _refToNode[exp.Input.GroupVariableName] = child; - - InputExpression input = child.Last.Exp; - bool enterScope = false; - if (!IsCompatible(input, expression.ExpressionKind)) - { - input = new InputExpression(input, child.Last.AsName); - } - else enterScope = true; - - if (enterScope) EnterExpression(child); - - input.Projection = new CommaSeparatedExpression(); - - input.GroupBy = new GroupByExpression(); - RowType rowType = ((CollectionType)(exp.ResultType.EdmType)).TypeUsage.EdmType as RowType; - int columnIndex = 0; - foreach (var key in exp.Keys) - { - VisitedExpression keyColumnExpression = key.Accept(this); - var prop = rowType.Properties[columnIndex]; - input.Projection.Arguments.Add(new ColumnExpression(keyColumnExpression, prop.Name, prop.TypeUsage)); - // have no idea why EF is generating a group by with a constant expression, - // but postgresql doesn't need it. - if (!(key is DbConstantExpression)) - { - input.GroupBy.AppendGroupingKey(keyColumnExpression); - } - ++columnIndex; - } - foreach (var ag in exp.Aggregates) - { - DbFunctionAggregate function = (DbFunctionAggregate)ag; - VisitedExpression functionExpression = VisitFunction(function); - var prop = rowType.Properties[columnIndex]; - input.Projection.Arguments.Add(new ColumnExpression(functionExpression, prop.Name, prop.TypeUsage)); - ++columnIndex; - } - - if (enterScope) LeaveExpression(child); - - n = new PendingProjectsNode(bindingName, input); - break; + var binaryExp = (DbBinaryExpression)e; + func(binaryExp.Left); + func(binaryExp.Right); } - case DbExpressionKind.CrossJoin: - case DbExpressionKind.FullOuterJoin: - case DbExpressionKind.InnerJoin: - case DbExpressionKind.LeftOuterJoin: - case DbExpressionKind.CrossApply: - case DbExpressionKind.OuterApply: - { - InputExpression input = new InputExpression(); - n = new PendingProjectsNode(bindingName, input); + else + list.Add(VisitInputWithBinding(e, bindingName + "_" + list.Count).Last.Exp); + }; + func(exp.Left); + func(exp.Right); + var input = new InputExpression(new CombinedProjectionExpression(expression.ExpressionKind, list), bindingName); + n = new PendingProjectsNode(bindingName, input); + break; + } + case DbExpressionKind.Project: + { + var exp = (DbProjectExpression)expression; + var child = VisitInputWithBinding(exp.Input.Expression, exp.Input.VariableName); + var input = child.Last.Exp; + var enterScope = false; + if (!IsCompatible(input, expression.ExpressionKind)) + input = new InputExpression(input, child.Last.AsName); + else + enterScope = true; - JoinExpression from = VisitJoinChildren(expression, input, n); + if (enterScope) EnterExpression(child); - input.From = from; + input.Projection = new CommaSeparatedExpression(); - break; - } - default: throw new NotImplementedException(); + var projection = (DbNewInstanceExpression)exp.Projection; + var rowType = (RowType)projection.ResultType.EdmType; + for (var i = 0; i < rowType.Properties.Count && i < projection.Arguments.Count; ++i) + { + var prop = rowType.Properties[i]; + input.Projection.Arguments.Add(new ColumnExpression(projection.Arguments[i].Accept(this), prop.Name, prop.TypeUsage)); + } + + if (enterScope) LeaveExpression(child); + + n = new PendingProjectsNode(bindingName, input); + break; + } + case DbExpressionKind.GroupBy: + { + var exp = (DbGroupByExpression)expression; + var child = VisitInputWithBinding(exp.Input.Expression, exp.Input.VariableName); + + // I don't know why the input for GroupBy in EF have two names + RefToNode[exp.Input.GroupVariableName] = child; + + var input = child.Last.Exp; + var enterScope = false; + if (!IsCompatible(input, expression.ExpressionKind)) + input = new InputExpression(input, child.Last.AsName); + else enterScope = true; + + if (enterScope) EnterExpression(child); + + input.Projection = new CommaSeparatedExpression(); + + input.GroupBy = new GroupByExpression(); + var rowType = (RowType)((CollectionType)exp.ResultType.EdmType).TypeUsage.EdmType; + var columnIndex = 0; + foreach (var key in exp.Keys) + { + var keyColumnExpression = key.Accept(this); + var prop = rowType.Properties[columnIndex]; + input.Projection.Arguments.Add(new ColumnExpression(keyColumnExpression, prop.Name, prop.TypeUsage)); + // have no idea why EF is generating a group by with a constant expression, + // but postgresql doesn't need it. + if (!(key is DbConstantExpression)) + input.GroupBy.AppendGroupingKey(keyColumnExpression); + ++columnIndex; + } + foreach (var ag in exp.Aggregates) + { + var function = (DbFunctionAggregate)ag; + var functionExpression = VisitFunction(function); + var prop = rowType.Properties[columnIndex]; + input.Projection.Arguments.Add(new ColumnExpression(functionExpression, prop.Name, prop.TypeUsage)); + ++columnIndex; + } + + if (enterScope) LeaveExpression(child); + + n = new PendingProjectsNode(bindingName, input); + break; + } + case DbExpressionKind.CrossJoin: + case DbExpressionKind.FullOuterJoin: + case DbExpressionKind.InnerJoin: + case DbExpressionKind.LeftOuterJoin: + case DbExpressionKind.CrossApply: + case DbExpressionKind.OuterApply: + { + var input = new InputExpression(); + n = new PendingProjectsNode(bindingName, input); + + var from = VisitJoinChildren(expression, input, n); + + input.From = from; + + break; + } + default: + throw new NotImplementedException(); } - _refToNode[bindingName] = n; + + RefToNode[bindingName] = n; return n; } - private bool IsJoin(DbExpressionKind kind) + bool IsJoin(DbExpressionKind kind) { switch (kind) { - case DbExpressionKind.CrossJoin: - case DbExpressionKind.FullOuterJoin: - case DbExpressionKind.InnerJoin: - case DbExpressionKind.LeftOuterJoin: - case DbExpressionKind.CrossApply: - case DbExpressionKind.OuterApply: - return true; + case DbExpressionKind.CrossJoin: + case DbExpressionKind.FullOuterJoin: + case DbExpressionKind.InnerJoin: + case DbExpressionKind.LeftOuterJoin: + case DbExpressionKind.CrossApply: + case DbExpressionKind.OuterApply: + return true; } return false; } - private JoinExpression VisitJoinChildren(DbExpression expression, InputExpression input, PendingProjectsNode n) + JoinExpression VisitJoinChildren(DbExpression expression, InputExpression input, PendingProjectsNode n) { DbExpressionBinding left, right; DbExpression condition = null; @@ -460,18 +441,16 @@ private JoinExpression VisitJoinChildren(DbExpression expression, InputExpressio return VisitJoinChildren(left.Expression, left.VariableName, right.Expression, right.VariableName, expression.ExpressionKind, condition, input, n); } - private JoinExpression VisitJoinChildren(DbExpression left, string leftName, DbExpression right, string rightName, DbExpressionKind joinType, DbExpression condition, InputExpression input, PendingProjectsNode n) + + JoinExpression VisitJoinChildren(DbExpression left, string leftName, DbExpression right, string rightName, DbExpressionKind joinType, [CanBeNull] DbExpression condition, InputExpression input, PendingProjectsNode n) { - JoinExpression join = new JoinExpression(); - join.JoinType = joinType; + var join = new JoinExpression { JoinType = joinType }; if (IsJoin(left.ExpressionKind)) - { join.Left = VisitJoinChildren(left, input, n); - } else { - PendingProjectsNode l = VisitInputWithBinding(left, leftName); + var l = VisitInputWithBinding(left, leftName); l.JoinParent = n; join.Left = new FromExpression(l.Last.Exp, l.Last.AsName); } @@ -479,7 +458,7 @@ private JoinExpression VisitJoinChildren(DbExpression left, string leftName, DbE if (joinType == DbExpressionKind.OuterApply || joinType == DbExpressionKind.CrossApply) { EnterExpression(n); - PendingProjectsNode r = VisitInputWithBinding(right, rightName); + var r = VisitInputWithBinding(right, rightName); LeaveExpression(n); r.JoinParent = n; join.Right = new FromExpression(r.Last.Exp, r.Last.AsName) { ForceSubquery = true }; @@ -487,12 +466,10 @@ private JoinExpression VisitJoinChildren(DbExpression left, string leftName, DbE else { if (IsJoin(right.ExpressionKind)) - { join.Right = VisitJoinChildren(right, input, n); - } else { - PendingProjectsNode r = VisitInputWithBinding(right, rightName); + var r = VisitInputWithBinding(right, rightName); r.JoinParent = n; join.Right = new FromExpression(r.Last.Exp, r.Last.AsName); } @@ -507,91 +484,77 @@ private JoinExpression VisitJoinChildren(DbExpression left, string leftName, DbE return join; } - public override VisitedExpression Visit(DbVariableReferenceExpression expression) + public override VisitedExpression Visit([NotNull] DbVariableReferenceExpression expression) { //return new VariableReferenceExpression(expression.VariableName, _variableSubstitution); throw new NotImplementedException(); } - public override VisitedExpression Visit(DbUnionAllExpression expression) + public override VisitedExpression Visit([NotNull] DbUnionAllExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbTreatExpression expression) + public override VisitedExpression Visit([NotNull] DbTreatExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbSkipExpression expression) + public override VisitedExpression Visit([NotNull] DbSkipExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbSortExpression expression) + public override VisitedExpression Visit([NotNull] DbSortExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbScanExpression expression) + public override VisitedExpression Visit([NotNull] DbScanExpression expression) { MetadataProperty metadata; string tableName; - string overrideTable = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Name"; + var overrideTable = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Name"; if (expression.Target.MetadataProperties.TryGetValue(overrideTable, false, out metadata) && metadata.Value != null) - { tableName = metadata.Value.ToString(); - } else if (expression.Target.MetadataProperties.TryGetValue("Table", false, out metadata) && metadata.Value != null) - { tableName = metadata.Value.ToString(); - } else - { tableName = expression.Target.Name; - } if (expression.Target.MetadataProperties.Contains("DefiningQuery")) { - MetadataProperty definingQuery = expression.Target.MetadataProperties.GetValue("DefiningQuery", false); + var definingQuery = expression.Target.MetadataProperties.GetValue("DefiningQuery", false); if (definingQuery.Value != null) - { return new ScanExpression("(" + definingQuery.Value + ")", expression.Target); - } } ScanExpression scan; - string overrideSchema = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Schema"; + var overrideSchema = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Schema"; if (expression.Target.MetadataProperties.TryGetValue(overrideSchema, false, out metadata) && metadata.Value != null) - { scan = new ScanExpression(QuoteIdentifier(metadata.Value.ToString()) + "." + QuoteIdentifier(tableName), expression.Target); - } else if (expression.Target.MetadataProperties.TryGetValue("Schema", false, out metadata) && metadata.Value != null) - { scan = new ScanExpression(QuoteIdentifier(metadata.Value.ToString()) + "." + QuoteIdentifier(tableName), expression.Target); - } else - { scan = new ScanExpression(QuoteIdentifier(expression.Target.EntityContainer.Name) + "." + QuoteIdentifier(tableName), expression.Target); - } return scan; } - public override VisitedExpression Visit(DbRelationshipNavigationExpression expression) + public override VisitedExpression Visit([NotNull] DbRelationshipNavigationExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbRefExpression expression) + public override VisitedExpression Visit([NotNull] DbRefExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbQuantifierExpression expression) + public override VisitedExpression Visit([NotNull] DbQuantifierExpression expression) { // TODO: EXISTS or NOT EXISTS depending on expression.ExpressionKind // comes with it's built in test (subselect for EXISTS) @@ -599,49 +562,38 @@ public override VisitedExpression Visit(DbQuantifierExpression expression) throw new NotImplementedException(); } - public override VisitedExpression Visit(DbProjectExpression expression) - { - return VisitInputWithBinding(expression, NextAlias()).Last.Exp; - } + public override VisitedExpression Visit([NotNull] DbProjectExpression expression) + => VisitInputWithBinding(expression, NextAlias()).Last.Exp; - public override VisitedExpression Visit(DbParameterReferenceExpression expression) - { - // use parameter in sql - return new LiteralExpression("@" + expression.ParameterName); - } + // use parameter in sql + public override VisitedExpression Visit([NotNull] DbParameterReferenceExpression expression) + => new LiteralExpression("@" + expression.ParameterName); - public override VisitedExpression Visit(DbOrExpression expression) - { - return OperatorExpression.Build(Operator.Or, _useNewPrecedences, expression.Left.Accept(this), expression.Right.Accept(this)); - } + public override VisitedExpression Visit([NotNull] DbOrExpression expression) + => OperatorExpression.Build(Operator.Or, _useNewPrecedences, expression.Left.Accept(this), expression.Right.Accept(this)); - public override VisitedExpression Visit(DbOfTypeExpression expression) + public override VisitedExpression Visit([NotNull] DbOfTypeExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbNullExpression expression) - { - // select does something different here. But insert, update, delete, and functions can just use - // a NULL literal. - return new LiteralExpression("NULL"); - } + // select does something different here. But insert, update, delete, and functions can just use + // a NULL literal. + public override VisitedExpression Visit([NotNull] DbNullExpression expression) + => new LiteralExpression("NULL"); - public override VisitedExpression Visit(DbNotExpression expression) - { - // argument can be a "NOT EXISTS" or similar operator that can be negated. - // Convert the not if that's the case - VisitedExpression argument = expression.Argument.Accept(this); - return OperatorExpression.Negate(argument, _useNewPrecedences); - } + // argument can be a "NOT EXISTS" or similar operator that can be negated. + // Convert the not if that's the case + public override VisitedExpression Visit([NotNull] DbNotExpression expression) + => OperatorExpression.Negate(expression.Argument.Accept(this), _useNewPrecedences); - public override VisitedExpression Visit(DbNewInstanceExpression expression) + // Handled by VisitInputWithBinding + public override VisitedExpression Visit([NotNull] DbNewInstanceExpression expression) { - // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbLimitExpression expression) + public override VisitedExpression Visit([NotNull] DbLimitExpression expression) { // Normally handled by VisitInputWithBinding @@ -649,7 +601,7 @@ public override VisitedExpression Visit(DbLimitExpression expression) // in which case the child of this expression might be a DbProjectExpression, // then the correct columns will be projected since Limit is compatible with the result of a DbProjectExpression, // which will result in having a Projection on the node after visiting it. - PendingProjectsNode node = VisitInputWithBinding(expression, NextAlias()); + var node = VisitInputWithBinding(expression, NextAlias()); if (node.Last.Exp.Projection == null) { // This DbLimitExpression is (probably) a child of DbElementExpression @@ -661,204 +613,191 @@ public override VisitedExpression Visit(DbLimitExpression expression) // Since this is (probably) a child of DbElementExpression, we want the first column, // so make sure it is propagated from the nearest explicit projection. - CommaSeparatedExpression projection = node.Selects[0].Exp.Projection; - for (int i = 1; i < node.Selects.Count; i++) + var projection = node.Selects[0].Exp.Projection; + for (var i = 1; i < node.Selects.Count; i++) { - ColumnExpression column = (ColumnExpression)projection.Arguments[0]; - + var column = (ColumnExpression)projection.Arguments[0]; node.Selects[i].Exp.ColumnsToProject[new StringPair(node.Selects[i - 1].AsName, column.Name)] = column.Name; } } return node.Last.Exp; } - public override VisitedExpression Visit(DbLikeExpression expression) - { - // LIKE keyword - return OperatorExpression.Build(Operator.Like, _useNewPrecedences, expression.Argument.Accept(this), expression.Pattern.Accept(this)); - } + // LIKE keyword + public override VisitedExpression Visit([NotNull] DbLikeExpression expression) + => OperatorExpression.Build(Operator.Like, _useNewPrecedences, expression.Argument.Accept(this), expression.Pattern.Accept(this)); - public override VisitedExpression Visit(DbJoinExpression expression) + public override VisitedExpression Visit([NotNull] DbJoinExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbIsOfExpression expression) + public override VisitedExpression Visit([NotNull] DbIsOfExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbIsNullExpression expression) - { - return OperatorExpression.Build(Operator.IsNull, _useNewPrecedences, expression.Argument.Accept(this)); - } + public override VisitedExpression Visit([NotNull] DbIsNullExpression expression) + => OperatorExpression.Build(Operator.IsNull, _useNewPrecedences, expression.Argument.Accept(this)); - public override VisitedExpression Visit(DbIsEmptyExpression expression) - { - // NOT EXISTS - return OperatorExpression.Negate(new ExistsExpression(expression.Argument.Accept(this)), _useNewPrecedences); - } + // NOT EXISTS + public override VisitedExpression Visit([NotNull] DbIsEmptyExpression expression) + => OperatorExpression.Negate(new ExistsExpression(expression.Argument.Accept(this)), _useNewPrecedences); - public override VisitedExpression Visit(DbIntersectExpression expression) + public override VisitedExpression Visit([NotNull] DbIntersectExpression expression) { // INTERSECT keyword // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbGroupByExpression expression) - { - // Normally handled by VisitInputWithBinding - - // Otherwise, it is (probably) a child of a DbElementExpression. - // Group by always projects the correct columns. - return VisitInputWithBinding(expression, NextAlias()).Last.Exp; - } + // Normally handled by VisitInputWithBinding + // Otherwise, it is (probably) a child of a DbElementExpression. + // Group by always projects the correct columns. + public override VisitedExpression Visit([NotNull] DbGroupByExpression expression) + => VisitInputWithBinding(expression, NextAlias()).Last.Exp; - public override VisitedExpression Visit(DbRefKeyExpression expression) + public override VisitedExpression Visit([NotNull] DbRefKeyExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbEntityRefExpression expression) + public override VisitedExpression Visit([NotNull] DbEntityRefExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbFunctionExpression expression) - { - // a function call - // may be built in, canonical, or user defined - return VisitFunction(expression.Function, expression.Arguments, expression.ResultType); - } + // a function call + // may be built in, canonical, or user defined + public override VisitedExpression Visit([NotNull] DbFunctionExpression expression) + => VisitFunction(expression.Function, expression.Arguments, expression.ResultType); - public override VisitedExpression Visit(DbFilterExpression expression) + public override VisitedExpression Visit([NotNull] DbFilterExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbExceptExpression expression) + public override VisitedExpression Visit([NotNull] DbExceptExpression expression) { // EXCEPT keyword // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbElementExpression expression) + public override VisitedExpression Visit([NotNull] DbElementExpression expression) { // If child of DbNewInstanceExpression, this is handled in VisitInputWithBinding // a scalar expression (ie ExecuteScalar) // so it will likely be translated into a select //throw new NotImplementedException(); - LiteralExpression scalar = new LiteralExpression("("); + var scalar = new LiteralExpression("("); scalar.Append(expression.Argument.Accept(this)); scalar.Append(")"); return scalar; } - public override VisitedExpression Visit(DbDistinctExpression expression) + public override VisitedExpression Visit([NotNull] DbDistinctExpression expression) { // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbDerefExpression expression) + public override VisitedExpression Visit([NotNull] DbDerefExpression expression) { throw new NotImplementedException(); } - public override VisitedExpression Visit(DbCrossJoinExpression expression) + public override VisitedExpression Visit([NotNull] DbCrossJoinExpression expression) { // join without ON // Handled by VisitInputWithBinding throw new NotImplementedException(); } - public override VisitedExpression Visit(DbConstantExpression expression) + public override VisitedExpression Visit([NotNull] DbConstantExpression expression) { - if (_createParametersForConstants) + if (CreateParametersForConstants) { - NpgsqlParameter parameter = new NpgsqlParameter(); - parameter.ParameterName = "p_" + _parameterCount++; - parameter.NpgsqlDbType = NpgsqlProviderManifest.GetNpgsqlDbType(((PrimitiveType)expression.ResultType.EdmType).PrimitiveTypeKind); - parameter.Value = expression.Value; - _command.Parameters.Add(parameter); + var parameter = new NpgsqlParameter + { + ParameterName = "p_" + ParameterCount++, + NpgsqlDbType = NpgsqlProviderManifest.GetNpgsqlDbType(((PrimitiveType)expression.ResultType.EdmType).PrimitiveTypeKind), + Value = expression.Value + }; + Command.Parameters.Add(parameter); return new LiteralExpression("@" + parameter.ParameterName); } - else - { - return new ConstantExpression(expression.Value, expression.ResultType); - } + + return new ConstantExpression(expression.Value, expression.ResultType); } - public override VisitedExpression Visit(DbComparisonExpression expression) + public override VisitedExpression Visit([NotNull] DbComparisonExpression expression) { Operator comparisonOperator; switch (expression.ExpressionKind) { - case DbExpressionKind.Equals: comparisonOperator = Operator.Equals; break; - case DbExpressionKind.GreaterThan: comparisonOperator = Operator.GreaterThan; break; - case DbExpressionKind.GreaterThanOrEquals: comparisonOperator = Operator.GreaterThanOrEquals; break; - case DbExpressionKind.LessThan: comparisonOperator = Operator.LessThan; break; - case DbExpressionKind.LessThanOrEquals: comparisonOperator = Operator.LessThanOrEquals; break; - case DbExpressionKind.Like: comparisonOperator = Operator.Like; break; - case DbExpressionKind.NotEquals: comparisonOperator = Operator.NotEquals; break; - default: throw new NotSupportedException(); + case DbExpressionKind.Equals: comparisonOperator = Operator.Equals; break; + case DbExpressionKind.GreaterThan: comparisonOperator = Operator.GreaterThan; break; + case DbExpressionKind.GreaterThanOrEquals: comparisonOperator = Operator.GreaterThanOrEquals; break; + case DbExpressionKind.LessThan: comparisonOperator = Operator.LessThan; break; + case DbExpressionKind.LessThanOrEquals: comparisonOperator = Operator.LessThanOrEquals; break; + case DbExpressionKind.Like: comparisonOperator = Operator.Like; break; + case DbExpressionKind.NotEquals: comparisonOperator = Operator.NotEquals; break; + default: throw new NotSupportedException(); } return OperatorExpression.Build(comparisonOperator, _useNewPrecedences, expression.Left.Accept(this), expression.Right.Accept(this)); } - public override VisitedExpression Visit(DbCastExpression expression) - { - return new CastExpression(expression.Argument.Accept(this), GetDbType(expression.ResultType.EdmType)); - } + public override VisitedExpression Visit([NotNull] DbCastExpression expression) + => new CastExpression(expression.Argument.Accept(this), GetDbType(expression.ResultType.EdmType)); protected string GetDbType(EdmType edmType) { - PrimitiveType primitiveType = edmType as PrimitiveType; + var primitiveType = edmType as PrimitiveType; if (primitiveType == null) throw new NotSupportedException(); + switch (primitiveType.PrimitiveTypeKind) { - case PrimitiveTypeKind.Boolean: - return "bool"; - case PrimitiveTypeKind.SByte: - case PrimitiveTypeKind.Byte: - case PrimitiveTypeKind.Int16: - return "int2"; - case PrimitiveTypeKind.Int32: - return "int4"; - case PrimitiveTypeKind.Int64: - return "int8"; - case PrimitiveTypeKind.String: - return "text"; - case PrimitiveTypeKind.Decimal: - return "numeric"; - case PrimitiveTypeKind.Single: - return "float4"; - case PrimitiveTypeKind.Double: - return "float8"; - case PrimitiveTypeKind.DateTime: - return "timestamp"; - case PrimitiveTypeKind.DateTimeOffset: - return "timestamptz"; - case PrimitiveTypeKind.Time: - return "interval"; - case PrimitiveTypeKind.Binary: - return "bytea"; - case PrimitiveTypeKind.Guid: - return "uuid"; + case PrimitiveTypeKind.Boolean: + return "bool"; + case PrimitiveTypeKind.SByte: + case PrimitiveTypeKind.Byte: + case PrimitiveTypeKind.Int16: + return "int2"; + case PrimitiveTypeKind.Int32: + return "int4"; + case PrimitiveTypeKind.Int64: + return "int8"; + case PrimitiveTypeKind.String: + return "text"; + case PrimitiveTypeKind.Decimal: + return "numeric"; + case PrimitiveTypeKind.Single: + return "float4"; + case PrimitiveTypeKind.Double: + return "float8"; + case PrimitiveTypeKind.DateTime: + return "timestamp"; + case PrimitiveTypeKind.DateTimeOffset: + return "timestamptz"; + case PrimitiveTypeKind.Time: + return "interval"; + case PrimitiveTypeKind.Binary: + return "bytea"; + case PrimitiveTypeKind.Guid: + return "uuid"; } throw new NotSupportedException(); } - public override VisitedExpression Visit(DbCaseExpression expression) + public override VisitedExpression Visit([NotNull] DbCaseExpression expression) { - LiteralExpression caseExpression = new LiteralExpression(" CASE "); - for (int i = 0; i < expression.When.Count && i < expression.Then.Count; ++i) + var caseExpression = new LiteralExpression(" CASE "); + for (var i = 0; i < expression.When.Count && i < expression.Then.Count; ++i) { caseExpression.Append(" WHEN ("); caseExpression.Append(expression.When[i].Accept(this)); @@ -866,60 +805,58 @@ public override VisitedExpression Visit(DbCaseExpression expression) caseExpression.Append(expression.Then[i].Accept(this)); caseExpression.Append(")"); } + if (expression.Else is DbNullExpression) - { caseExpression.Append(" END "); - } else { caseExpression.Append(" ELSE ("); caseExpression.Append(expression.Else.Accept(this)); caseExpression.Append(") END "); } + return caseExpression; } - public override VisitedExpression Visit(DbArithmeticExpression expression) + public override VisitedExpression Visit([NotNull] DbArithmeticExpression expression) { Operator arithmeticOperator; switch (expression.ExpressionKind) { - case DbExpressionKind.Divide: - arithmeticOperator = Operator.Div; - break; - case DbExpressionKind.Minus: - arithmeticOperator = Operator.Sub; - break; - case DbExpressionKind.Modulo: - arithmeticOperator = Operator.Mod; - break; - case DbExpressionKind.Multiply: - arithmeticOperator = Operator.Mul; - break; - case DbExpressionKind.Plus: - arithmeticOperator = Operator.Add; - break; - case DbExpressionKind.UnaryMinus: - arithmeticOperator = Operator.UnaryMinus; - break; - default: - throw new NotSupportedException(); + case DbExpressionKind.Divide: + arithmeticOperator = Operator.Div; + break; + case DbExpressionKind.Minus: + arithmeticOperator = Operator.Sub; + break; + case DbExpressionKind.Modulo: + arithmeticOperator = Operator.Mod; + break; + case DbExpressionKind.Multiply: + arithmeticOperator = Operator.Mul; + break; + case DbExpressionKind.Plus: + arithmeticOperator = Operator.Add; + break; + case DbExpressionKind.UnaryMinus: + arithmeticOperator = Operator.UnaryMinus; + break; + default: + throw new NotSupportedException(); } if (expression.ExpressionKind == DbExpressionKind.UnaryMinus) { - System.Diagnostics.Debug.Assert(expression.Arguments.Count == 1); + Debug.Assert(expression.Arguments.Count == 1); return OperatorExpression.Build(arithmeticOperator, _useNewPrecedences, expression.Arguments[0].Accept(this)); } - else - { - System.Diagnostics.Debug.Assert(expression.Arguments.Count == 2); - return OperatorExpression.Build(arithmeticOperator, _useNewPrecedences, expression.Arguments[0].Accept(this), expression.Arguments[1].Accept(this)); - } + + Debug.Assert(expression.Arguments.Count == 2); + return OperatorExpression.Build(arithmeticOperator, _useNewPrecedences, expression.Arguments[0].Accept(this), expression.Arguments[1].Accept(this)); } - public override VisitedExpression Visit(DbApplyExpression expression) + public override VisitedExpression Visit([NotNull] DbApplyExpression expression) { // like a join, but used when the right hand side (the Apply part) is a function. // it lets you return the results of a function call given values from the @@ -930,12 +867,10 @@ public override VisitedExpression Visit(DbApplyExpression expression) throw new NotImplementedException(); } - public override VisitedExpression Visit(DbAndExpression expression) - { - return OperatorExpression.Build(Operator.And, _useNewPrecedences, expression.Left.Accept(this), expression.Right.Accept(this)); - } + public override VisitedExpression Visit([NotNull] DbAndExpression expression) + => OperatorExpression.Build(Operator.And, _useNewPrecedences, expression.Left.Accept(this), expression.Right.Accept(this)); - public override VisitedExpression Visit(DbExpression expression) + public override VisitedExpression Visit([NotNull] DbExpression expression) { // only concrete types visited throw new NotSupportedException(); @@ -944,11 +879,9 @@ public override VisitedExpression Visit(DbExpression expression) public abstract void BuildCommand(DbCommand command); internal static string QuoteIdentifier(string identifier) - { - return "\"" + identifier.Replace("\"", "\"\"") + "\""; - } + => "\"" + identifier.Replace("\"", "\"\"") + "\""; - private VisitedExpression VisitFunction(DbFunctionAggregate functionAggregate) + VisitedExpression VisitFunction(DbFunctionAggregate functionAggregate) { if (functionAggregate.Function.NamespaceName == "Edm") { @@ -956,11 +889,12 @@ private VisitedExpression VisitFunction(DbFunctionAggregate functionAggregate) try { aggregate = new FunctionExpression(AggregateFunctionNames[functionAggregate.Function.Name]); - } catch (KeyNotFoundException) + } + catch (KeyNotFoundException) { throw new NotSupportedException(); } - System.Diagnostics.Debug.Assert(functionAggregate.Arguments.Count == 1); + Debug.Assert(functionAggregate.Arguments.Count == 1); VisitedExpression aggregateArg; if (functionAggregate.Distinct) { @@ -977,159 +911,159 @@ private VisitedExpression VisitFunction(DbFunctionAggregate functionAggregate) throw new NotSupportedException(); } - private VisitedExpression VisitFunction(EdmFunction function, IList args, TypeUsage resultType) + VisitedExpression VisitFunction(EdmFunction function, IList args, TypeUsage resultType) { if (function.NamespaceName == "Edm") { VisitedExpression arg; switch (function.Name) { - // string functions - case "Concat": - System.Diagnostics.Debug.Assert(args.Count == 2); - return OperatorExpression.Build(Operator.Concat, _useNewPrecedences, args[0].Accept(this), args[1].Accept(this)); - case "Contains": - System.Diagnostics.Debug.Assert(args.Count == 2); - FunctionExpression contains = new FunctionExpression("position"); - arg = args[1].Accept(this); - arg.Append(" in "); - arg.Append(args[0].Accept(this)); - contains.AddArgument(arg); - // if position returns zero, then contains is false - return OperatorExpression.Build(Operator.GreaterThan, _useNewPrecedences, contains, new LiteralExpression("0")); - // case "EndsWith": - depends on a reverse function to be able to implement with parameterized queries - case "IndexOf": - System.Diagnostics.Debug.Assert(args.Count == 2); - FunctionExpression indexOf = new FunctionExpression("position"); - arg = args[0].Accept(this); - arg.Append(" in "); - arg.Append(args[1].Accept(this)); - indexOf.AddArgument(arg); - return indexOf; - case "Left": - System.Diagnostics.Debug.Assert(args.Count == 2); - return Substring(args[0].Accept(this), new LiteralExpression(" 1 "), args[1].Accept(this)); - case "Length": - FunctionExpression length = new FunctionExpression("char_length"); - System.Diagnostics.Debug.Assert(args.Count == 1); - length.AddArgument(args[0].Accept(this)); - return new CastExpression(length, GetDbType(resultType.EdmType)); - case "LTrim": - return StringModifier("ltrim", args); - case "Replace": - FunctionExpression replace = new FunctionExpression("replace"); - System.Diagnostics.Debug.Assert(args.Count == 3); - replace.AddArgument(args[0].Accept(this)); - replace.AddArgument(args[1].Accept(this)); - replace.AddArgument(args[2].Accept(this)); - return replace; - // case "Reverse": - case "Right": - System.Diagnostics.Debug.Assert(args.Count == 2); - { - var arg0 = args[0].Accept(this); - var arg1 = args[1].Accept(this); - var start = new FunctionExpression("char_length"); - start.AddArgument(arg0); - // add one before subtracting count since strings are 1 based in postgresql - return Substring(arg0, OperatorExpression.Build(Operator.Sub, _useNewPrecedences, OperatorExpression.Build(Operator.Add, _useNewPrecedences, start, new LiteralExpression("1")), arg1)); - } - case "RTrim": - return StringModifier("rtrim", args); - case "Substring": - System.Diagnostics.Debug.Assert(args.Count == 3); - return Substring(args[0].Accept(this), args[1].Accept(this), args[2].Accept(this)); - case "StartsWith": - System.Diagnostics.Debug.Assert(args.Count == 2); - FunctionExpression startsWith = new FunctionExpression("position"); - arg = args[1].Accept(this); - arg.Append(" in "); - arg.Append(args[0].Accept(this)); - startsWith.AddArgument(arg); - return OperatorExpression.Build(Operator.Equals, _useNewPrecedences, startsWith, new LiteralExpression("1")); - case "ToLower": - return StringModifier("lower", args); - case "ToUpper": - return StringModifier("upper", args); - case "Trim": - return StringModifier("btrim", args); - - // date functions - // date functions - case "AddDays": - case "AddHours": - case "AddMicroseconds": - case "AddMilliseconds": - case "AddMinutes": - case "AddMonths": - case "AddNanoseconds": - case "AddSeconds": - case "AddYears": - return DateAdd(function.Name, args); - case "DiffDays": - case "DiffHours": - case "DiffMicroseconds": - case "DiffMilliseconds": - case "DiffMinutes": - case "DiffMonths": - case "DiffNanoseconds": - case "DiffSeconds": - case "DiffYears": - System.Diagnostics.Debug.Assert(args.Count == 2); - return DateDiff(function.Name, args[0].Accept(this), args[1].Accept(this)); - case "Day": - case "Hour": - case "Minute": - case "Month": - case "Second": - case "Year": - return DatePart(function.Name, args); - case "Millisecond": - return DatePart("milliseconds", args); - case "GetTotalOffsetMinutes": - VisitedExpression timezone = DatePart("timezone", args); - return OperatorExpression.Build(Operator.Div, _useNewPrecedences, timezone, new LiteralExpression("60")); - case "CurrentDateTime": - return new LiteralExpression("LOCALTIMESTAMP"); - case "CurrentUtcDateTime": - LiteralExpression utcNow = new LiteralExpression("CURRENT_TIMESTAMP"); - utcNow.Append(" AT TIME ZONE 'UTC'"); - return utcNow; - case "CurrentDateTimeOffset": - // TODO: this doesn't work yet because the reader - // doesn't return DateTimeOffset. - return new LiteralExpression("CURRENT_TIMESTAMP"); - - // bitwise operators - case "BitwiseAnd": - return BitwiseOperator(args, Operator.BitwiseAnd); - case "BitwiseOr": - return BitwiseOperator(args, Operator.BitwiseOr); - case "BitwiseXor": - return BitwiseOperator(args, Operator.BitwiseXor); - case "BitwiseNot": - System.Diagnostics.Debug.Assert(args.Count == 1); - return OperatorExpression.Build(Operator.BitwiseNot, _useNewPrecedences, args[0].Accept(this)); - - // math operators - case "Abs": - case "Ceiling": - case "Floor": - return UnaryMath(function.Name, args); - case "Round": - return (args.Count == 1) ? UnaryMath(function.Name, args) : BinaryMath(function.Name, args); - case "Power": - return BinaryMath(function.Name, args); - case "Truncate": - return BinaryMath("trunc", args); - - case "NewGuid": - return new FunctionExpression("uuid_generate_v4"); - case "TruncateTime": - return new TruncateTimeExpression("day", args[0].Accept(this)); - - default: - throw new NotSupportedException("NotSupported " + function.Name); + // string functions + case "Concat": + Debug.Assert(args.Count == 2); + return OperatorExpression.Build(Operator.Concat, _useNewPrecedences, args[0].Accept(this), args[1].Accept(this)); + case "Contains": + Debug.Assert(args.Count == 2); + var contains = new FunctionExpression("position"); + arg = args[1].Accept(this); + arg.Append(" in "); + arg.Append(args[0].Accept(this)); + contains.AddArgument(arg); + // if position returns zero, then contains is false + return OperatorExpression.Build(Operator.GreaterThan, _useNewPrecedences, contains, new LiteralExpression("0")); + // case "EndsWith": - depends on a reverse function to be able to implement with parameterized queries + case "IndexOf": + Debug.Assert(args.Count == 2); + var indexOf = new FunctionExpression("position"); + arg = args[0].Accept(this); + arg.Append(" in "); + arg.Append(args[1].Accept(this)); + indexOf.AddArgument(arg); + return indexOf; + case "Left": + Debug.Assert(args.Count == 2); + return Substring(args[0].Accept(this), new LiteralExpression(" 1 "), args[1].Accept(this)); + case "Length": + var length = new FunctionExpression("char_length"); + Debug.Assert(args.Count == 1); + length.AddArgument(args[0].Accept(this)); + return new CastExpression(length, GetDbType(resultType.EdmType)); + case "LTrim": + return StringModifier("ltrim", args); + case "Replace": + var replace = new FunctionExpression("replace"); + Debug.Assert(args.Count == 3); + replace.AddArgument(args[0].Accept(this)); + replace.AddArgument(args[1].Accept(this)); + replace.AddArgument(args[2].Accept(this)); + return replace; + // case "Reverse": + case "Right": + Debug.Assert(args.Count == 2); + { + var arg0 = args[0].Accept(this); + var arg1 = args[1].Accept(this); + var start = new FunctionExpression("char_length"); + start.AddArgument(arg0); + // add one before subtracting count since strings are 1 based in postgresql + return Substring(arg0, OperatorExpression.Build(Operator.Sub, _useNewPrecedences, OperatorExpression.Build(Operator.Add, _useNewPrecedences, start, new LiteralExpression("1")), arg1)); + } + case "RTrim": + return StringModifier("rtrim", args); + case "Substring": + Debug.Assert(args.Count == 3); + return Substring(args[0].Accept(this), args[1].Accept(this), args[2].Accept(this)); + case "StartsWith": + Debug.Assert(args.Count == 2); + var startsWith = new FunctionExpression("position"); + arg = args[1].Accept(this); + arg.Append(" in "); + arg.Append(args[0].Accept(this)); + startsWith.AddArgument(arg); + return OperatorExpression.Build(Operator.Equals, _useNewPrecedences, startsWith, new LiteralExpression("1")); + case "ToLower": + return StringModifier("lower", args); + case "ToUpper": + return StringModifier("upper", args); + case "Trim": + return StringModifier("btrim", args); + + // date functions + // date functions + case "AddDays": + case "AddHours": + case "AddMicroseconds": + case "AddMilliseconds": + case "AddMinutes": + case "AddMonths": + case "AddNanoseconds": + case "AddSeconds": + case "AddYears": + return DateAdd(function.Name, args); + case "DiffDays": + case "DiffHours": + case "DiffMicroseconds": + case "DiffMilliseconds": + case "DiffMinutes": + case "DiffMonths": + case "DiffNanoseconds": + case "DiffSeconds": + case "DiffYears": + Debug.Assert(args.Count == 2); + return DateDiff(function.Name, args[0].Accept(this), args[1].Accept(this)); + case "Day": + case "Hour": + case "Minute": + case "Month": + case "Second": + case "Year": + return DatePart(function.Name, args); + case "Millisecond": + return DatePart("milliseconds", args); + case "GetTotalOffsetMinutes": + var timezone = DatePart("timezone", args); + return OperatorExpression.Build(Operator.Div, _useNewPrecedences, timezone, new LiteralExpression("60")); + case "CurrentDateTime": + return new LiteralExpression("LOCALTIMESTAMP"); + case "CurrentUtcDateTime": + var utcNow = new LiteralExpression("CURRENT_TIMESTAMP"); + utcNow.Append(" AT TIME ZONE 'UTC'"); + return utcNow; + case "CurrentDateTimeOffset": + // TODO: this doesn't work yet because the reader + // doesn't return DateTimeOffset. + return new LiteralExpression("CURRENT_TIMESTAMP"); + + // bitwise operators + case "BitwiseAnd": + return BitwiseOperator(args, Operator.BitwiseAnd); + case "BitwiseOr": + return BitwiseOperator(args, Operator.BitwiseOr); + case "BitwiseXor": + return BitwiseOperator(args, Operator.BitwiseXor); + case "BitwiseNot": + Debug.Assert(args.Count == 1); + return OperatorExpression.Build(Operator.BitwiseNot, _useNewPrecedences, args[0].Accept(this)); + + // math operators + case "Abs": + case "Ceiling": + case "Floor": + return UnaryMath(function.Name, args); + case "Round": + return args.Count == 1 ? UnaryMath(function.Name, args) : BinaryMath(function.Name, args); + case "Power": + return BinaryMath(function.Name, args); + case "Truncate": + return BinaryMath("trunc", args); + + case "NewGuid": + return new FunctionExpression("uuid_generate_v4"); + case "TruncateTime": + return new TruncateTimeExpression("day", args[0].Accept(this)); + + default: + throw new NotSupportedException("NotSupported " + function.Name); } } @@ -1226,59 +1160,58 @@ private VisitedExpression VisitFunction(EdmFunction function, IList args) + VisitedExpression UnaryMath(string funcName, IList args) { - FunctionExpression mathFunction = new FunctionExpression(funcName); - System.Diagnostics.Debug.Assert(args.Count == 1); + var mathFunction = new FunctionExpression(funcName); + Debug.Assert(args.Count == 1); mathFunction.AddArgument(args[0].Accept(this)); return mathFunction; } - private VisitedExpression BinaryMath(string funcName, IList args) + VisitedExpression BinaryMath(string funcName, IList args) { - FunctionExpression mathFunction = new FunctionExpression(funcName); - System.Diagnostics.Debug.Assert(args.Count == 2); + var mathFunction = new FunctionExpression(funcName); + Debug.Assert(args.Count == 2); mathFunction.AddArgument(args[0].Accept(this)); mathFunction.AddArgument(args[1].Accept(this)); return mathFunction; } - private VisitedExpression StringModifier(string modifier, IList args) + VisitedExpression StringModifier(string modifier, IList args) { - FunctionExpression modifierFunction = new FunctionExpression(modifier); - System.Diagnostics.Debug.Assert(args.Count == 1); + var modifierFunction = new FunctionExpression(modifier); + Debug.Assert(args.Count == 1); modifierFunction.AddArgument(args[0].Accept(this)); return modifierFunction; } - private VisitedExpression DatePart(string partName, IList args) + VisitedExpression DatePart(string partName, IList args) { - - FunctionExpression extract_date = new FunctionExpression("cast(extract"); - System.Diagnostics.Debug.Assert(args.Count == 1); + var extractDate = new FunctionExpression("cast(extract"); + Debug.Assert(args.Count == 1); VisitedExpression arg = new LiteralExpression(partName + " FROM "); arg.Append(args[0].Accept(this)); - extract_date.AddArgument(arg); + extractDate.AddArgument(arg); // need to convert to Int32 to match cononical function - extract_date.Append(" as int4)"); - return extract_date; + extractDate.Append(" as int4)"); + return extractDate; } /// @@ -1292,10 +1225,10 @@ private VisitedExpression DatePart(string partName, IList args) /// /// /// - private VisitedExpression DateAdd(string functionName, IList args) + VisitedExpression DateAdd(string functionName, IList args) { - bool nano = false; - string part = functionName.Substring(3); + var nano = false; + var part = functionName.Substring(3); if (part == "Nanoseconds") { @@ -1303,125 +1236,124 @@ private VisitedExpression DateAdd(string functionName, IList args) part = "Microseconds"; } - System.Diagnostics.Debug.Assert(args.Count == 2); - VisitedExpression time = args[0].Accept(this); - VisitedExpression mulLeft = args[1].Accept(this); + Debug.Assert(args.Count == 2); + var time = args[0].Accept(this); + var mulLeft = args[1].Accept(this); if (nano) mulLeft = OperatorExpression.Build(Operator.Div, _useNewPrecedences, mulLeft, new LiteralExpression("1000")); - LiteralExpression mulRight = new LiteralExpression(String.Format("INTERVAL '1 {0}'", part)); + var mulRight = new LiteralExpression($"INTERVAL '1 {part}'"); return OperatorExpression.Build(Operator.Add, _useNewPrecedences, time, OperatorExpression.Build(Operator.Mul, _useNewPrecedences, mulLeft, mulRight)); } - private VisitedExpression DateDiff(string functionName, VisitedExpression start, VisitedExpression end) + VisitedExpression DateDiff(string functionName, VisitedExpression start, VisitedExpression end) { switch (functionName) { - case "DiffDays": - start = new FunctionExpression("date_trunc").AddArgument("'day'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'day'").AddArgument(end); - return new FunctionExpression("date_part").AddArgument("'day'").AddArgument( - OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start) - ).Append("::int4"); - case "DiffHours": - { - start = new FunctionExpression("date_trunc").AddArgument("'hour'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'hour'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return OperatorExpression.Build(Operator.Div, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch).Append("::int4"), new LiteralExpression("3600")); - } - case "DiffMicroseconds": - { - start = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000000")), "int4"); - } - case "DiffMilliseconds": - { - start = new FunctionExpression("date_trunc").AddArgument("'milliseconds'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'milliseconds'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000")), "int4"); - } - case "DiffMinutes": - { - start = new FunctionExpression("date_trunc").AddArgument("'minute'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'minute'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return OperatorExpression.Build(Operator.Div, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch).Append("::int4"), new LiteralExpression("60")); - } - case "DiffMonths": - { - start = new FunctionExpression("date_trunc").AddArgument("'month'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'month'").AddArgument(end); - VisitedExpression age = new FunctionExpression("age").AddArgument(end).AddArgument(start); - - // A month is 30 days and a year is 365.25 days after conversion from interval to seconds. - // After rounding and casting, the result will contain the correct number of months as an int4. - FunctionExpression seconds = new FunctionExpression("extract").AddArgument(new LiteralExpression("epoch from ").Append(age)); - VisitedExpression months = OperatorExpression.Build(Operator.Div, _useNewPrecedences, seconds, new LiteralExpression("2629800.0")); - return new FunctionExpression("round").AddArgument(months).Append("::int4"); - } - case "DiffNanoseconds": - { - // PostgreSQL only supports microseconds precision, so the value will be a multiple of 1000 - // This date_trunc will make sure start and end are of type timestamp, e.g. if the arguments is of type date - start = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000000000")), "int4"); - } - case "DiffSeconds": - { - start = new FunctionExpression("date_trunc").AddArgument("'second'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'second'").AddArgument(end); - LiteralExpression epoch = new LiteralExpression("epoch from "); - OperatorExpression diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); - epoch.Append(diff); - return new FunctionExpression("extract").AddArgument(epoch).Append("::int4"); - } - case "DiffYears": - { - start = new FunctionExpression("date_trunc").AddArgument("'year'").AddArgument(start); - end = new FunctionExpression("date_trunc").AddArgument("'year'").AddArgument(end); - VisitedExpression age = new FunctionExpression("age").AddArgument(end).AddArgument(start); - return new FunctionExpression("date_part").AddArgument("'year'").AddArgument(age).Append("::int4"); - } - default: throw new NotSupportedException("Internal error: unknown function name " + functionName); + case "DiffDays": + start = new FunctionExpression("date_trunc").AddArgument("'day'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'day'").AddArgument(end); + return new FunctionExpression("date_part").AddArgument("'day'").AddArgument( + OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start) + ).Append("::int4"); + case "DiffHours": + { + start = new FunctionExpression("date_trunc").AddArgument("'hour'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'hour'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return OperatorExpression.Build(Operator.Div, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch).Append("::int4"), new LiteralExpression("3600")); + } + case "DiffMicroseconds": + { + start = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000000")), "int4"); + } + case "DiffMilliseconds": + { + start = new FunctionExpression("date_trunc").AddArgument("'milliseconds'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'milliseconds'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000")), "int4"); + } + case "DiffMinutes": + { + start = new FunctionExpression("date_trunc").AddArgument("'minute'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'minute'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return OperatorExpression.Build(Operator.Div, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch).Append("::int4"), new LiteralExpression("60")); + } + case "DiffMonths": + { + start = new FunctionExpression("date_trunc").AddArgument("'month'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'month'").AddArgument(end); + var age = new FunctionExpression("age").AddArgument(end).AddArgument(start); + + // A month is 30 days and a year is 365.25 days after conversion from interval to seconds. + // After rounding and casting, the result will contain the correct number of months as an int4. + var seconds = new FunctionExpression("extract").AddArgument(new LiteralExpression("epoch from ").Append(age)); + var months = OperatorExpression.Build(Operator.Div, _useNewPrecedences, seconds, new LiteralExpression("2629800.0")); + return new FunctionExpression("round").AddArgument(months).Append("::int4"); + } + case "DiffNanoseconds": + { + // PostgreSQL only supports microseconds precision, so the value will be a multiple of 1000 + // This date_trunc will make sure start and end are of type timestamp, e.g. if the arguments is of type date + start = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'microseconds'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return new CastExpression(OperatorExpression.Build(Operator.Mul, _useNewPrecedences, new FunctionExpression("extract").AddArgument(epoch), new LiteralExpression("1000000000")), "int4"); + } + case "DiffSeconds": + { + start = new FunctionExpression("date_trunc").AddArgument("'second'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'second'").AddArgument(end); + var epoch = new LiteralExpression("epoch from "); + var diff = OperatorExpression.Build(Operator.Sub, _useNewPrecedences, end, start); + epoch.Append(diff); + return new FunctionExpression("extract").AddArgument(epoch).Append("::int4"); + } + case "DiffYears": + { + start = new FunctionExpression("date_trunc").AddArgument("'year'").AddArgument(start); + end = new FunctionExpression("date_trunc").AddArgument("'year'").AddArgument(end); + var age = new FunctionExpression("age").AddArgument(end).AddArgument(start); + return new FunctionExpression("date_part").AddArgument("'year'").AddArgument(age).Append("::int4"); + } + default: + throw new NotSupportedException("Internal error: unknown function name " + functionName); } } - private VisitedExpression BitwiseOperator(IList args, Operator oper) + VisitedExpression BitwiseOperator(IList args, Operator oper) { - System.Diagnostics.Debug.Assert(args.Count == 2); + Debug.Assert(args.Count == 2); return OperatorExpression.Build(oper, _useNewPrecedences, args[0].Accept(this), args[1].Accept(this)); } #if ENTITIES6 - public override VisitedExpression Visit(DbInExpression expression) + public override VisitedExpression Visit([NotNull] DbInExpression expression) { - VisitedExpression item = expression.Item.Accept(this); + var item = expression.Item.Accept(this); - ConstantExpression[] elements = new ConstantExpression[expression.List.Count]; - for (int i = 0; i < expression.List.Count; i++) - { + var elements = new ConstantExpression[expression.List.Count]; + for (var i = 0; i < expression.List.Count; i++) elements[i] = (ConstantExpression)expression.List[i].Accept(this); - } return OperatorExpression.Build(Operator.In, _useNewPrecedences, item, new ConstantListExpression(elements)); } - public override VisitedExpression Visit(DbPropertyExpression expression) + public override VisitedExpression Visit([NotNull] DbPropertyExpression expression) { // This is overridden in the other visitors throw new NotImplementedException("New in Entity Framework 6"); diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs index a0cc522..a1ae978 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs @@ -22,7 +22,6 @@ #endregion using System; -using System.Collections.Generic; using System.Data.Common; #if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; @@ -34,8 +33,8 @@ namespace Npgsql.SqlGenerators { internal class SqlDeleteGenerator : SqlBaseGenerator { - private DbDeleteCommandTree _commandTree; - private string _tableName; + readonly DbDeleteCommandTree _commandTree; + string _tableName; public SqlDeleteGenerator(DbDeleteCommandTree commandTree) { @@ -44,7 +43,7 @@ public SqlDeleteGenerator(DbDeleteCommandTree commandTree) public override VisitedExpression Visit(DbPropertyExpression expression) { - DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + var variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _tableName) throw new NotSupportedException(); return new PropertyExpression(expression.Property); @@ -53,13 +52,11 @@ public override VisitedExpression Visit(DbPropertyExpression expression) public override void BuildCommand(DbCommand command) { // TODO: handle _commandTree.Returning and _commandTree.Parameters - DeleteExpression delete = new DeleteExpression(); + var delete = new DeleteExpression(); _tableName = _commandTree.Target.VariableName; delete.AppendFrom(_commandTree.Target.Expression.Accept(this)); if (_commandTree.Predicate != null) - { delete.AppendWhere(_commandTree.Predicate.Accept(this)); - } _tableName = null; command.CommandText = delete.ToString(); } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs index b018bca..80da4b8 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs @@ -34,8 +34,8 @@ namespace Npgsql.SqlGenerators { internal class SqlInsertGenerator : SqlBaseGenerator { - private DbInsertCommandTree _commandTree; - private string _tableName; + readonly DbInsertCommandTree _commandTree; + string _tableName; public SqlInsertGenerator(DbInsertCommandTree commandTree) { @@ -44,7 +44,7 @@ public SqlInsertGenerator(DbInsertCommandTree commandTree) public override VisitedExpression Visit(DbPropertyExpression expression) { - DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + var variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _tableName) throw new NotSupportedException(); return new PropertyExpression(expression.Property); @@ -53,11 +53,11 @@ public override VisitedExpression Visit(DbPropertyExpression expression) public override void BuildCommand(DbCommand command) { // TODO: handle_commandTree.Parameters - InsertExpression insert = new InsertExpression(); + var insert = new InsertExpression(); _tableName = _commandTree.Target.VariableName; insert.AppendTarget(_commandTree.Target.Expression.Accept(this)); - List columns = new List(); - List values = new List(); + var columns = new List(); + var values = new List(); foreach (DbSetClause clause in _commandTree.SetClauses) { columns.Add(clause.Property.Accept(this)); @@ -66,9 +66,7 @@ public override void BuildCommand(DbCommand command) insert.AppendColumns(columns); insert.AppendValues(values); if (_commandTree.Returning != null) - { - insert.AppendReturning(_commandTree.Returning as DbNewInstanceExpression); - } + insert.AppendReturning((DbNewInstanceExpression)_commandTree.Returning); _tableName = null; command.CommandText = insert.ToString(); } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs index ef4e8ba..ffecf5b 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs @@ -23,8 +23,8 @@ using System; using System.Linq; -using System.Collections.Generic; using System.Data.Common; +using System.Diagnostics; #if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Core.Metadata.Edm; @@ -37,7 +37,7 @@ namespace Npgsql.SqlGenerators { internal class SqlSelectGenerator : SqlBaseGenerator { - private DbQueryCommandTree _commandTree; + readonly DbQueryCommandTree _commandTree; public SqlSelectGenerator(DbQueryCommandTree commandTree) { @@ -74,18 +74,18 @@ public override VisitedExpression Visit(DbPropertyExpression expression) * The new name is then propagated down to the root. */ - string name = expression.Property.Name; - string from = (expression.Instance.ExpressionKind == DbExpressionKind.Property) + var name = expression.Property.Name; + var from = expression.Instance.ExpressionKind == DbExpressionKind.Property ? ((DbPropertyExpression)expression.Instance).Property.Name : ((DbVariableReferenceExpression)expression.Instance).VariableName; - PendingProjectsNode node = _refToNode[from]; + var node = RefToNode[from]; from = node.TopName; while (node != null) { foreach (var item in node.Selects) { - if (_currentExpressions.Contains(item.Exp)) + if (CurrentExpressions.Contains(item.Exp)) continue; var use = new StringPair(from, name); @@ -99,9 +99,7 @@ public override VisitedExpression Visit(DbPropertyExpression expression) item.Exp.ProjectNewNames.Add(name); } else - { name = item.Exp.ColumnsToProject[use]; - } from = item.AsName; } node = node.JoinParent; @@ -109,20 +107,18 @@ public override VisitedExpression Visit(DbPropertyExpression expression) return new ColumnReferenceExpression { Variable = from, Name = name }; } + // must provide a NULL of the correct type + // this is necessary for certain types of union queries. public override VisitedExpression Visit(DbNullExpression expression) - { - // must provide a NULL of the correct type - // this is necessary for certain types of union queries. - return new CastExpression(new LiteralExpression("NULL"), GetDbType(expression.ResultType.EdmType)); - } + => new CastExpression(new LiteralExpression("NULL"), GetDbType(expression.ResultType.EdmType)); public override void BuildCommand(DbCommand command) { - System.Diagnostics.Debug.Assert(command is NpgsqlCommand); - System.Diagnostics.Debug.Assert(_commandTree.Query is DbProjectExpression); - VisitedExpression ve = _commandTree.Query.Accept(this); - System.Diagnostics.Debug.Assert(ve is InputExpression); - InputExpression pe = (InputExpression)ve; + Debug.Assert(command is NpgsqlCommand); + Debug.Assert(_commandTree.Query is DbProjectExpression); + var ve = _commandTree.Query.Accept(this); + Debug.Assert(ve is InputExpression); + var pe = (InputExpression)ve; command.CommandText = pe.ToString(); // We retrieve all strings as unknowns in text format in the case the data types aren't really texts @@ -134,17 +130,18 @@ public override void BuildCommand(DbCommand command) return kind == PrimitiveTypeKind.SByte || kind == PrimitiveTypeKind.DateTimeOffset; })) { - ((NpgsqlCommand)command).ObjectResultTypes = pe.Projection.Arguments.Select(a => { + ((NpgsqlCommand)command).ObjectResultTypes = pe.Projection.Arguments.Select(a => + { var kind = ((PrimitiveType)((ColumnExpression)a).ColumnType.EdmType).PrimitiveTypeKind; - if (kind == PrimitiveTypeKind.SByte) + switch (kind) { + case PrimitiveTypeKind.SByte: return typeof(sbyte); - } - else if (kind == PrimitiveTypeKind.DateTimeOffset) - { + case PrimitiveTypeKind.DateTimeOffset: return typeof(DateTimeOffset); + default: + return null; } - return null; }).ToArray(); } } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs index 9912e4e..c109282 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs @@ -22,7 +22,6 @@ #endregion using System; -using System.Collections.Generic; using System.Data.Common; #if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; @@ -34,8 +33,8 @@ namespace Npgsql.SqlGenerators { class SqlUpdateGenerator : SqlBaseGenerator { - private DbUpdateCommandTree _commandTree; - private string _tableName; + readonly DbUpdateCommandTree _commandTree; + string _tableName; public SqlUpdateGenerator(DbUpdateCommandTree commandTree) { @@ -44,7 +43,7 @@ public SqlUpdateGenerator(DbUpdateCommandTree commandTree) public override VisitedExpression Visit(DbPropertyExpression expression) { - DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + var variable = expression.Instance as DbVariableReferenceExpression; if (variable == null || variable.VariableName != _tableName) throw new NotSupportedException(); return new PropertyExpression(expression.Property); @@ -53,21 +52,15 @@ public override VisitedExpression Visit(DbPropertyExpression expression) public override void BuildCommand(DbCommand command) { // TODO: handle _commandTree.Parameters - UpdateExpression update = new UpdateExpression(); + var update = new UpdateExpression(); _tableName = _commandTree.Target.VariableName; update.AppendTarget(_commandTree.Target.Expression.Accept(this)); foreach (DbSetClause clause in _commandTree.SetClauses) - { update.AppendSet(clause.Property.Accept(this), clause.Value.Accept(this)); - } if (_commandTree.Predicate != null) - { update.AppendWhere(_commandTree.Predicate.Accept(this)); - } if (_commandTree.Returning != null) - { update.AppendReturning((DbNewInstanceExpression)_commandTree.Returning); - } _tableName = null; command.CommandText = update.ToString(); } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs b/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs index 7cd6779..c605574 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs @@ -25,6 +25,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using JetBrains.Annotations; namespace Npgsql.SqlGenerators { @@ -33,33 +34,25 @@ namespace Npgsql.SqlGenerators /// internal class StringPair { - private string _item1; - private string _item2; - - public string Item1 { get { return _item1; } } - public string Item2 { get { return _item2; } } + public string Item1 { get; } + public string Item2 { get; } public StringPair(string s1, string s2) { - _item1 = s1; - _item2 = s2; + Item1 = s1; + Item2 = s2; } - public override bool Equals(object obj) + public override bool Equals([CanBeNull] object obj) { - if (obj == null) - return false; - - StringPair o = obj as StringPair; + var o = obj as StringPair; if (o == null) return false; - return _item1 == o._item1 && _item2 == o._item2; + return Item1 == o.Item1 && Item2 == o.Item2; } public override int GetHashCode() - { - return (_item1 + "." + _item2).GetHashCode(); - } + => (Item1 + "." + Item2).GetHashCode(); } } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs index 0f468d0..f8963cb 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -33,8 +33,8 @@ using System.Data.Common.CommandTrees; #endif using NpgsqlTypes; -using System.Data; using System.Globalization; +using JetBrains.Annotations; namespace Npgsql.SqlGenerators { @@ -59,25 +59,23 @@ public VisitedExpression Append(string literal) public override string ToString() { - StringBuilder sqlText = new StringBuilder(); + var sqlText = new StringBuilder(); WriteSql(sqlText); return sqlText.ToString(); } - protected List ExpressionList { get; private set; } + protected List ExpressionList { get; } internal virtual void WriteSql(StringBuilder sqlText) { - foreach (VisitedExpression expression in ExpressionList) - { + foreach (var expression in ExpressionList) expression.WriteSql(sqlText); - } } } internal class LiteralExpression : VisitedExpression { - private string _literal; + readonly string _literal; public LiteralExpression(string literal) { @@ -108,7 +106,7 @@ internal class CommaSeparatedExpression : VisitedExpression internal override void WriteSql(StringBuilder sqlText) { - for (int i = 0; i < Arguments.Count; ++i) + for (var i = 0; i < Arguments.Count; ++i) { if (i != 0) sqlText.Append(", "); @@ -120,15 +118,15 @@ internal override void WriteSql(StringBuilder sqlText) internal class ConstantExpression : VisitedExpression { - private PrimitiveTypeKind _primitiveType; - private object _value; + readonly PrimitiveTypeKind _primitiveType; + readonly object _value; public ConstantExpression(object value, TypeUsage edmType) { if (edmType == null) - throw new ArgumentNullException("edmType"); + throw new ArgumentNullException(nameof(edmType)); if (edmType.EdmType == null || edmType.EdmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) - throw new ArgumentException("Require primitive EdmType", "edmType"); + throw new ArgumentException("Require primitive EdmType", nameof(edmType)); _primitiveType = ((PrimitiveType)edmType.EdmType).PrimitiveTypeKind; _value = value; } @@ -136,120 +134,88 @@ public ConstantExpression(object value, TypeUsage edmType) internal override void WriteSql(StringBuilder sqlText) { var ni = CultureInfo.InvariantCulture.NumberFormat; - object value = _value; + var value = _value; switch (_primitiveType) { - case PrimitiveTypeKind.Binary: - { - sqlText.AppendFormat("decode('{0}', 'base64')", Convert.ToBase64String((byte[])_value)); - } - break; - case PrimitiveTypeKind.DateTime: - sqlText.AppendFormat(ni, "TIMESTAMP '{0:o}'", _value); - break; - case PrimitiveTypeKind.DateTimeOffset: - sqlText.AppendFormat(ni, "TIMESTAMP WITH TIME ZONE '{0:o}'", _value); - break; - case PrimitiveTypeKind.Decimal: - if ((decimal)_value < 0) - { - sqlText.AppendFormat(ni, "({0})::numeric", _value); - } - else - { - sqlText.AppendFormat(ni, "{0}::numeric", _value); - } - break; - case PrimitiveTypeKind.Double: - if (double.IsNaN((double)_value)) - { - sqlText.AppendFormat("'NaN'::float8"); - } - else if (double.IsPositiveInfinity((double)_value)) - { - sqlText.AppendFormat("'Infinity'::float8"); - } - else if (double.IsNegativeInfinity((double)_value)) - { - sqlText.AppendFormat("'-Infinity'::float8"); - } - else if ((double)_value < 0) - { - sqlText.AppendFormat(ni, "({0:r})::float8", _value); - } - else - { - sqlText.AppendFormat(ni, "{0:r}::float8", _value); - } - break; - // PostgreSQL has no support for bytes. int2 is used instead in Npgsql. - case PrimitiveTypeKind.Byte: - value = (short)(byte)_value; - goto case PrimitiveTypeKind.Int16; - case PrimitiveTypeKind.SByte: - value = (short)(sbyte)_value; - goto case PrimitiveTypeKind.Int16; - case PrimitiveTypeKind.Int16: - if ((short)value < 0) - { - sqlText.AppendFormat(ni, "({0})::int2", _value); - } - else - { - sqlText.AppendFormat(ni, "{0}::int2", _value); - } - break; - case PrimitiveTypeKind.Int32: - sqlText.AppendFormat(ni, "{0}", _value); - break; - case PrimitiveTypeKind.Int64: - if ((long)_value < 0) - { - sqlText.AppendFormat(ni, "({0})::int8", _value); - } - else - { - sqlText.AppendFormat(ni, "{0}::int8", _value); - } - break; - case PrimitiveTypeKind.Single: - if (float.IsNaN((float)_value)) - { - sqlText.AppendFormat("'NaN'::float4"); - } - else if (float.IsPositiveInfinity((float)_value)) - { - sqlText.AppendFormat("'Infinity'::float4"); - } - else if (float.IsNegativeInfinity((float)_value)) - { - sqlText.AppendFormat("'-Infinity'::float4"); - } - else if ((float)_value < 0) - { - sqlText.AppendFormat(ni, "({0:r})::float4", _value); - } - else - { - sqlText.AppendFormat(ni, "{0:r}::float4", _value); - } - break; - case PrimitiveTypeKind.Boolean: - sqlText.Append(((bool)_value) ? "TRUE" : "FALSE"); - break; - case PrimitiveTypeKind.Guid: - sqlText.Append('\'').Append((Guid)_value).Append('\''); - sqlText.Append("::uuid"); - break; - case PrimitiveTypeKind.String: - sqlText.Append("E'").Append(((string)_value).Replace(@"\", @"\\").Replace("'", @"\'")).Append("'"); - break; - case PrimitiveTypeKind.Time: - sqlText.AppendFormat(ni, "INTERVAL '{0}'", (NpgsqlTimeSpan)(TimeSpan)_value); - break; - default: - // TODO: must support more constant value types. - throw new NotSupportedException(string.Format("NotSupported: {0} {1}", _primitiveType, _value)); + case PrimitiveTypeKind.Binary: + { + sqlText.Append($"decode('{Convert.ToBase64String((byte[])_value)}', 'base64')"); + } + break; + case PrimitiveTypeKind.DateTime: + sqlText.AppendFormat(ni, "TIMESTAMP '{0:o}'", _value); + break; + case PrimitiveTypeKind.DateTimeOffset: + sqlText.AppendFormat(ni, "TIMESTAMP WITH TIME ZONE '{0:o}'", _value); + break; + case PrimitiveTypeKind.Decimal: + sqlText.AppendFormat(ni, (decimal)_value < 0 + ? "({0})::numeric" + : "{0}::numeric", _value + ); + break; + case PrimitiveTypeKind.Double: + if (double.IsNaN((double)_value)) + sqlText.Append("'NaN'::float8"); + else if (double.IsPositiveInfinity((double)_value)) + sqlText.Append("'Infinity'::float8"); + else if (double.IsNegativeInfinity((double)_value)) + sqlText.Append("'-Infinity'::float8"); + else if ((double)_value < 0) + sqlText.AppendFormat(ni, "({0:r})::float8", _value); + else + sqlText.AppendFormat(ni, "{0:r}::float8", _value); + break; + // PostgreSQL has no support for bytes. int2 is used instead in Npgsql. + case PrimitiveTypeKind.Byte: + value = (short)(byte)_value; + goto case PrimitiveTypeKind.Int16; + case PrimitiveTypeKind.SByte: + value = (short)(sbyte)_value; + goto case PrimitiveTypeKind.Int16; + case PrimitiveTypeKind.Int16: + sqlText.AppendFormat(ni, (short)value < 0 + ? "({0})::int2" + : "{0}::int2", _value + ); + break; + case PrimitiveTypeKind.Int32: + sqlText.AppendFormat(ni, "{0}", _value); + break; + case PrimitiveTypeKind.Int64: + sqlText.AppendFormat(ni, (long)_value < 0 + ? "({0})::int8" + : "{0}::int8", _value + ); + break; + case PrimitiveTypeKind.Single: + if (float.IsNaN((float)_value)) + sqlText.Append("'NaN'::float4"); + else if (float.IsPositiveInfinity((float)_value)) + sqlText.Append("'Infinity'::float4"); + else if (float.IsNegativeInfinity((float)_value)) + sqlText.Append("'-Infinity'::float4"); + else if ((float)_value < 0) + sqlText.AppendFormat(ni, "({0:r})::float4", _value); + else + sqlText.AppendFormat(ni, "{0:r}::float4", _value); + break; + case PrimitiveTypeKind.Boolean: + sqlText.Append((bool)_value ? "TRUE" : "FALSE"); + break; + case PrimitiveTypeKind.Guid: + sqlText.Append('\'').Append((Guid)_value).Append('\''); + sqlText.Append("::uuid"); + break; + case PrimitiveTypeKind.String: + sqlText.Append("E'").Append(((string)_value).Replace(@"\", @"\\").Replace("'", @"\'")).Append("'"); + break; + case PrimitiveTypeKind.Time: + sqlText.AppendFormat(ni, "INTERVAL '{0}'", (NpgsqlTimeSpan)(TimeSpan)_value); + break; + default: + // TODO: must support more constant value types. + throw new NotSupportedException($"NotSupported: {_primitiveType} {_value}"); } base.WriteSql(sqlText); } @@ -268,8 +234,8 @@ public void AppendColumns(IEnumerable columns) return; Append("("); - bool first = true; - foreach (VisitedExpression expression in columns) + var first = true; + foreach (var expression in columns) { if (!first) Append(","); @@ -285,7 +251,7 @@ public void AppendValues(IEnumerable columns) { Append(" VALUES ("); bool first = true; - foreach (VisitedExpression expression in columns) + foreach (var expression in columns) { if (!first) Append(","); @@ -295,20 +261,18 @@ public void AppendValues(IEnumerable columns) Append(")"); } else - { Append(" DEFAULT VALUES"); - } } internal void AppendReturning(DbNewInstanceExpression expression) { Append(" RETURNING ");//Don't put () around columns it will probably have unwanted effect - bool first = true; + var first = true; foreach (var returingProperty in expression.Arguments) { if (!first) Append(","); - Append(SqlBaseGenerator.QuoteIdentifier((returingProperty as DbPropertyExpression).Property.Name)); + Append(SqlBaseGenerator.QuoteIdentifier(((DbPropertyExpression)returingProperty).Property.Name)); first = false; } } @@ -322,7 +286,7 @@ internal override void WriteSql(StringBuilder sqlText) internal class UpdateExpression : VisitedExpression { - private bool _setSeperatorRequired; + bool _setSeperatorRequired; public void AppendTarget(VisitedExpression target) { @@ -331,10 +295,7 @@ public void AppendTarget(VisitedExpression target) public void AppendSet(VisitedExpression property, VisitedExpression value) { - if (_setSeperatorRequired) - Append(","); - else - Append(" SET "); + Append(_setSeperatorRequired ? "," : " SET "); Append(property); Append("="); Append(value); @@ -356,12 +317,12 @@ internal override void WriteSql(StringBuilder sqlText) internal void AppendReturning(DbNewInstanceExpression expression) { Append(" RETURNING ");//Don't put () around columns it will probably have unwanted effect - bool first = true; + var first = true; foreach (var returingProperty in expression.Arguments) { if (!first) Append(","); - Append(SqlBaseGenerator.QuoteIdentifier((returingProperty as DbPropertyExpression).Property.Name)); + Append(SqlBaseGenerator.QuoteIdentifier(((DbPropertyExpression)returingProperty).Property.Name)); first = false; } } @@ -389,31 +350,23 @@ internal override void WriteSql(StringBuilder sqlText) internal class ColumnExpression : VisitedExpression { - private VisitedExpression _column; - private string _columnName; - private TypeUsage _columnType; + internal string Name { get; } + internal TypeUsage ColumnType { get; } + readonly VisitedExpression _column; public ColumnExpression(VisitedExpression column, string columnName, TypeUsage columnType) { _column = column; - _columnName = columnName; - _columnType = columnType; + Name = columnName; + ColumnType = columnType; } - public string Name { get { return _columnName; } } - internal TypeUsage ColumnType { get { return _columnType; ;} } - - public Type CLRType + public Type ClrType { get { - if (_columnType == null) - return null; - PrimitiveType pt = _columnType.EdmType as PrimitiveType; - if (pt != null) - return pt.ClrEquivalentType; - else - return null; + var pt = ColumnType?.EdmType as PrimitiveType; + return pt?.ClrEquivalentType; } } @@ -421,11 +374,11 @@ internal override void WriteSql(StringBuilder sqlText) { _column.WriteSql(sqlText); - ColumnReferenceExpression column = _column as ColumnReferenceExpression; - if (column == null || column.Name != _columnName) + var column = _column as ColumnReferenceExpression; + if (column == null || column.Name != Name) { sqlText.Append(" AS "); - sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_columnName)); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(Name)); } base.WriteSql(sqlText); @@ -451,17 +404,15 @@ internal override void WriteSql(StringBuilder sqlText) internal class ScanExpression : VisitedExpression { - private string _scanString; - private EntitySetBase _target; + readonly string _scanString; + internal EntitySetBase Target { get; } public ScanExpression(string scanString, EntitySetBase target) { _scanString = scanString; - _target = target; + Target = target; } - internal EntitySetBase Target { get { return _target; } } - internal override void WriteSql(StringBuilder sqlText) { sqlText.Append(_scanString); @@ -480,55 +431,11 @@ internal class InputExpression : VisitedExpression // Either FromExpression or JoinExpression public VisitedExpression From { get; set; } - - private WhereExpression _where; - - public WhereExpression Where - { - get { return _where; } - set - { - _where = value; - } - } - - private GroupByExpression _groupBy; - - public GroupByExpression GroupBy - { - get { return _groupBy; } - set - { - _groupBy = value; - } - } - - private OrderByExpression _orderBy; - - public OrderByExpression OrderBy - { - get { return _orderBy; } - set { _orderBy = value; } - } - - private SkipExpression _skip; - - public SkipExpression Skip - { - get { return _skip; } - set { _skip = value; } - } - - private LimitExpression _limit; - - public LimitExpression Limit - { - get { return _limit; } - set - { - _limit = value; - } - } + public WhereExpression Where { get; set; } + public GroupByExpression GroupBy { get; set; } + public OrderByExpression OrderBy { get; set; } + public SkipExpression Skip { get; set; } + public LimitExpression Limit { get; set; } public InputExpression() { } @@ -540,21 +447,22 @@ public InputExpression(VisitedExpression from, string asName) internal override void WriteSql(StringBuilder sqlText) { sqlText.Append("SELECT "); - if (Distinct) sqlText.Append("DISTINCT "); - if (Projection != null) Projection.WriteSql(sqlText); + if (Distinct) + sqlText.Append("DISTINCT "); + if (Projection != null) + Projection.WriteSql(sqlText); else { if (ColumnsToProject.Count == 0) sqlText.Append("1"); // Could be arbitrary, let's pick 1 else { - bool first = true; + var first = true; foreach (var column in ColumnsToProject) { if (!first) - { sqlText.Append(", "); - } - else first = false; + else + first = false; sqlText.Append(SqlBaseGenerator.QuoteIdentifier(column.Key.Item1)); sqlText.Append("."); sqlText.Append(SqlBaseGenerator.QuoteIdentifier(column.Key.Item2)); @@ -568,38 +476,34 @@ internal override void WriteSql(StringBuilder sqlText) } sqlText.Append(" FROM "); From.WriteSql(sqlText); - if (Where != null) Where.WriteSql(sqlText); - if (GroupBy != null) GroupBy.WriteSql(sqlText); - if (OrderBy != null) OrderBy.WriteSql(sqlText); - if (Skip != null) Skip.WriteSql(sqlText); - if (Limit != null) Limit.WriteSql(sqlText); + Where?.WriteSql(sqlText); + GroupBy?.WriteSql(sqlText); + OrderBy?.WriteSql(sqlText); + Skip?.WriteSql(sqlText); + Limit?.WriteSql(sqlText); base.WriteSql(sqlText); } } internal class FromExpression : VisitedExpression { - private VisitedExpression _from; - private string _name; + readonly VisitedExpression _from; + internal string Name { get; } public FromExpression(VisitedExpression from, string name) { _from = from; - _name = name; - } - - public string Name - { - get { return _name; } + Name = name; } public bool ForceSubquery { get; set; } internal override void WriteSql(StringBuilder sqlText) { - if (_from is InputExpression) + var from = _from as InputExpression; + if (from != null) { - InputExpression input = (InputExpression)_from; + var input = from; if (!ForceSubquery && input.Projection == null && input.Where == null && input.Distinct == false && input.OrderBy == null && input.Skip == null && input.Limit == null) { @@ -617,19 +521,19 @@ internal override void WriteSql(StringBuilder sqlText) sqlText.Append("("); input.WriteSql(sqlText); sqlText.Append(") AS "); - sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_name)); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(Name)); } } else { - bool wrap = !(_from is LiteralExpression || _from is ScanExpression); + var wrap = !(_from is LiteralExpression || _from is ScanExpression); if (wrap) sqlText.Append("("); _from.WriteSql(sqlText); if (wrap) sqlText.Append(")"); sqlText.Append(" AS "); - sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_name)); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(Name)); } base.WriteSql(sqlText); } @@ -637,64 +541,54 @@ internal override void WriteSql(StringBuilder sqlText) internal class JoinExpression : VisitedExpression { - private VisitedExpression _left; - private DbExpressionKind _joinType; - private VisitedExpression _right; - private VisitedExpression _condition; + internal VisitedExpression Left { get; set; } + internal DbExpressionKind JoinType { get; set; } + internal VisitedExpression Right { get; set; } + internal VisitedExpression Condition { get; set; } public JoinExpression() { } public JoinExpression(InputExpression left, DbExpressionKind joinType, InputExpression right, VisitedExpression condition) { - _left = left; - _joinType = joinType; - _right = right; - _condition = condition; - } - - public VisitedExpression Left { get { return _left; } set { _left = value; } } - public DbExpressionKind JoinType { get { return _joinType; } set { _joinType = value; } } - public VisitedExpression Right { get { return _right; } set { _right = value; } } - - public VisitedExpression Condition - { - get { return _condition; } - set { _condition = value; } + Left = left; + JoinType = joinType; + Right = right; + Condition = condition; } internal override void WriteSql(StringBuilder sqlText) { - _left.WriteSql(sqlText); - switch (_joinType) + Left.WriteSql(sqlText); + switch (JoinType) { - case DbExpressionKind.InnerJoin: - sqlText.Append(" INNER JOIN "); - break; - case DbExpressionKind.LeftOuterJoin: - sqlText.Append(" LEFT OUTER JOIN "); - break; - case DbExpressionKind.FullOuterJoin: - sqlText.Append(" FULL OUTER JOIN "); - break; - case DbExpressionKind.CrossJoin: - sqlText.Append(" CROSS JOIN "); - break; - case DbExpressionKind.CrossApply: - sqlText.Append(" CROSS JOIN LATERAL "); - break; - case DbExpressionKind.OuterApply: - sqlText.Append(" LEFT OUTER JOIN LATERAL "); - break; - default: - throw new NotSupportedException(); + case DbExpressionKind.InnerJoin: + sqlText.Append(" INNER JOIN "); + break; + case DbExpressionKind.LeftOuterJoin: + sqlText.Append(" LEFT OUTER JOIN "); + break; + case DbExpressionKind.FullOuterJoin: + sqlText.Append(" FULL OUTER JOIN "); + break; + case DbExpressionKind.CrossJoin: + sqlText.Append(" CROSS JOIN "); + break; + case DbExpressionKind.CrossApply: + sqlText.Append(" CROSS JOIN LATERAL "); + break; + case DbExpressionKind.OuterApply: + sqlText.Append(" LEFT OUTER JOIN LATERAL "); + break; + default: + throw new NotSupportedException(); } - _right.WriteSql(sqlText); - if (_joinType == DbExpressionKind.OuterApply) + Right.WriteSql(sqlText); + if (JoinType == DbExpressionKind.OuterApply) sqlText.Append(" ON TRUE"); - else if (_joinType != DbExpressionKind.CrossJoin && _joinType != DbExpressionKind.CrossApply) + else if (JoinType != DbExpressionKind.CrossJoin && JoinType != DbExpressionKind.CrossApply) { sqlText.Append(" ON "); - _condition.WriteSql(sqlText); + Condition.WriteSql(sqlText); } base.WriteSql(sqlText); } @@ -702,7 +596,7 @@ internal override void WriteSql(StringBuilder sqlText) internal class WhereExpression : VisitedExpression { - private VisitedExpression _where; + VisitedExpression _where; public WhereExpression(VisitedExpression where) { @@ -725,7 +619,9 @@ internal void And(VisitedExpression andAlso) internal class PropertyExpression : VisitedExpression { - private EdmMember _property; + readonly EdmMember _property; + public string Name => _property.Name; + public TypeUsage PropertyType => _property.TypeUsage; // used for inserts or updates where the column is not qualified public PropertyExpression(EdmMember property) @@ -733,10 +629,6 @@ public PropertyExpression(EdmMember property) _property = property; } - public string Name { get { return _property.Name; } } - - public TypeUsage PropertyType { get { return _property.TypeUsage; } } - internal override void WriteSql(StringBuilder sqlText) { sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_property.Name)); @@ -745,16 +637,13 @@ internal override void WriteSql(StringBuilder sqlText) // override ToString since we don't want variable substitution or identifier quoting // until writing out the SQL. - public override string ToString() - { - return _property.Name; - } + public override string ToString() => Name; } internal class FunctionExpression : VisitedExpression { - private string _name; - private List _args = new List(); + readonly string _name; + readonly List _args = new List(); public FunctionExpression(string name) { @@ -792,8 +681,8 @@ internal override void WriteSql(StringBuilder sqlText) internal class CastExpression : VisitedExpression { - private VisitedExpression _value; - private string _type; + readonly VisitedExpression _value; + readonly string _type; public CastExpression(VisitedExpression value, string type) { @@ -812,7 +701,7 @@ internal override void WriteSql(StringBuilder sqlText) internal class GroupByExpression : VisitedExpression { - private bool _requiresGroupSeperator; + bool _requiresGroupSeperator; public void AppendGroupingKey(VisitedExpression key) { @@ -832,26 +721,24 @@ internal override void WriteSql(StringBuilder sqlText) internal class LimitExpression : VisitedExpression { - private VisitedExpression _arg; - - public VisitedExpression Arg { get { return _arg; } set { _arg = value; } } + internal VisitedExpression Arg { get; set; } public LimitExpression(VisitedExpression arg) { - _arg = arg; + Arg = arg; } internal override void WriteSql(StringBuilder sqlText) { sqlText.Append(" LIMIT "); - _arg.WriteSql(sqlText); + Arg.WriteSql(sqlText); base.WriteSql(sqlText); } } internal class SkipExpression : VisitedExpression { - private VisitedExpression _arg; + readonly VisitedExpression _arg; public SkipExpression(VisitedExpression arg) { @@ -868,19 +755,13 @@ internal override void WriteSql(StringBuilder sqlText) internal class Operator { - private string op; - private int leftPrecedence; - private int rightPrecedence; - private int newPrecedence; // Since PostgreSQL 9.5, the operator precedence was changed - private UnaryTypes unaryType; - private bool rightAssoc; - - public string Op { get { return op; } } - public int LeftPrecedence { get { return leftPrecedence; } } - public int RightPrecedence { get { return rightPrecedence; } } - public int NewPrecedence { get { return newPrecedence; } } - public UnaryTypes UnaryType { get { return unaryType; } } - public bool RightAssoc { get { return rightAssoc; } } + internal string Op { get; } + internal int LeftPrecedence { get; } + internal int RightPrecedence { get; } + // Since PostgreSQL 9.5, the operator precedence was changed + internal int NewPrecedence { get; } + internal UnaryTypes UnaryType { get; } + internal bool RightAssoc { get; } internal enum UnaryTypes { Binary, @@ -888,32 +769,32 @@ internal enum UnaryTypes { Postfix } - private Operator(string op, int precedence, int newPrecedence) + Operator(string op, int precedence, int newPrecedence) { - this.op = ' ' + op + ' '; - this.leftPrecedence = precedence; - this.rightPrecedence = precedence; - this.newPrecedence = newPrecedence; - this.unaryType = UnaryTypes.Binary; + Op = ' ' + op + ' '; + LeftPrecedence = precedence; + RightPrecedence = precedence; + NewPrecedence = newPrecedence; + UnaryType = UnaryTypes.Binary; } - private Operator(string op, int leftPrecedence, int rightPrecedence, int newPrecedence) + Operator(string op, int leftPrecedence, int rightPrecedence, int newPrecedence) { - this.op = ' ' + op + ' '; - this.leftPrecedence = leftPrecedence; - this.rightPrecedence = rightPrecedence; - this.newPrecedence = newPrecedence; - this.unaryType = UnaryTypes.Binary; + Op = ' ' + op + ' '; + LeftPrecedence = leftPrecedence; + RightPrecedence = rightPrecedence; + NewPrecedence = newPrecedence; + UnaryType = UnaryTypes.Binary; } - private Operator(string op, int precedence, int newPrecedence, UnaryTypes unaryType, bool rightAssoc) + Operator(string op, int precedence, int newPrecedence, UnaryTypes unaryType, bool rightAssoc) { - this.op = unaryType == UnaryTypes.Binary ? ' ' + op + ' ' : unaryType == UnaryTypes.Prefix ? op + ' ' : ' ' + op; - this.leftPrecedence = precedence; - this.rightPrecedence = precedence; - this.newPrecedence = newPrecedence; - this.unaryType = unaryType; - this.rightAssoc = rightAssoc; + Op = unaryType == UnaryTypes.Binary ? ' ' + op + ' ' : unaryType == UnaryTypes.Prefix ? op + ' ' : ' ' + op; + LeftPrecedence = precedence; + RightPrecedence = precedence; + NewPrecedence = newPrecedence; + UnaryType = unaryType; + RightAssoc = rightAssoc; } /* @@ -952,7 +833,7 @@ private Operator(string op, int precedence, int newPrecedence, UnaryTypes unaryT public static readonly Operator NotLike = new Operator("NOT LIKE", 3, 6, 6); public static readonly Operator LessThan = new Operator("<", 5, 5); public static readonly Operator GreaterThan = new Operator(">", 5, 5); - public static readonly new Operator Equals = new Operator("=", 4, 5, UnaryTypes.Binary, true); + public new static readonly Operator Equals = new Operator("=", 4, 5, UnaryTypes.Binary, true); public static readonly Operator Not = new Operator("NOT", 3, 3, UnaryTypes.Prefix, true); public static readonly Operator And = new Operator("AND", 2, 2); public static readonly Operator Or = new Operator("OR", 1, 1); @@ -970,61 +851,53 @@ static Operator() { NegateDict = new Dictionary() { - {IsNull, IsNotNull}, - {IsNotNull, IsNull}, - {LessThanOrEquals, GreaterThan}, - {GreaterThanOrEquals, LessThan}, - {NotEquals, Equals}, - {In, NotIn}, - {NotIn, In}, - {Like, NotLike}, - {NotLike, Like}, - {LessThan, GreaterThanOrEquals}, - {GreaterThan, LessThanOrEquals}, - {Equals, NotEquals} + { IsNull, IsNotNull }, + { IsNotNull, IsNull }, + { LessThanOrEquals, GreaterThan }, + { GreaterThanOrEquals, LessThan }, + { NotEquals, Equals }, + { In, NotIn }, + { NotIn, In }, + { Like, NotLike }, + { NotLike, Like }, + { LessThan, GreaterThanOrEquals }, + { GreaterThan, LessThanOrEquals }, + { Equals, NotEquals } }; } } internal class OperatorExpression : VisitedExpression { - private Operator op; - private bool useNewPrecedences; - private VisitedExpression left; - private VisitedExpression right; + Operator _op; + readonly bool _useNewPrecedences; + readonly VisitedExpression _left; + readonly VisitedExpression _right; - private OperatorExpression(Operator op, bool useNewPrecedences, VisitedExpression left, VisitedExpression right) + OperatorExpression(Operator op, bool useNewPrecedences, [CanBeNull] VisitedExpression left, [CanBeNull] VisitedExpression right) { - this.op = op; - this.useNewPrecedences = useNewPrecedences; - this.left = left; - this.right = right; + _op = op; + _useNewPrecedences = useNewPrecedences; + _left = left; + _right = right; } public static OperatorExpression Build(Operator op, bool useNewPrecedences, VisitedExpression left, VisitedExpression right) { if (op.UnaryType == Operator.UnaryTypes.Binary) - { return new OperatorExpression(op, useNewPrecedences, left, right); - } - else - { - throw new InvalidOperationException("Unary operator with two operands"); - } + throw new InvalidOperationException("Unary operator with two operands"); } public static OperatorExpression Build(Operator op, bool useNewPrecedences, VisitedExpression exp) { - if (op.UnaryType == Operator.UnaryTypes.Prefix) + switch (op.UnaryType) { + case Operator.UnaryTypes.Prefix: return new OperatorExpression(op, useNewPrecedences, null, exp); - } - else if (op.UnaryType == Operator.UnaryTypes.Postfix) - { + case Operator.UnaryTypes.Postfix: return new OperatorExpression(op, useNewPrecedences, exp, null); - } - else - { + default: throw new InvalidOperationException("Binary operator with one operand"); } } @@ -1036,23 +909,21 @@ public static OperatorExpression Build(Operator op, bool useNewPrecedences, Visi /// public static VisitedExpression Negate(VisitedExpression exp, bool useNewPrecedences) { - OperatorExpression expOp = exp as OperatorExpression; + var expOp = exp as OperatorExpression; if (expOp != null) { - Operator op = expOp.op; - Operator newOp = null; + var op = expOp._op; + Operator newOp; if (Operator.NegateDict.TryGetValue(op, out newOp)) { - expOp.op = newOp; + expOp._op = newOp; return expOp; } - if (expOp.op == Operator.Not) - { - return expOp.right; - } + if (expOp._op == Operator.Not) + return expOp._right; } - return OperatorExpression.Build(Operator.Not, useNewPrecedences, exp); + return Build(Operator.Not, useNewPrecedences, exp); } internal override void WriteSql(StringBuilder sqlText) @@ -1060,60 +931,60 @@ internal override void WriteSql(StringBuilder sqlText) WriteSql(sqlText, null); } - private void WriteSql(StringBuilder sqlText, OperatorExpression rightParent) + void WriteSql(StringBuilder sqlText, [CanBeNull] OperatorExpression rightParent) { - OperatorExpression leftOp = left as OperatorExpression; - OperatorExpression rightOp = right as OperatorExpression; + var leftOp = _left as OperatorExpression; + var rightOp = _right as OperatorExpression; bool wrapLeft, wrapRight; - if (!useNewPrecedences) + if (!_useNewPrecedences) { - wrapLeft = leftOp != null && (op.RightAssoc ? leftOp.op.RightPrecedence <= op.LeftPrecedence : leftOp.op.RightPrecedence < op.LeftPrecedence); - wrapRight = rightOp != null && (!op.RightAssoc ? rightOp.op.LeftPrecedence <= op.RightPrecedence : rightOp.op.LeftPrecedence < op.RightPrecedence); + wrapLeft = leftOp != null && (_op.RightAssoc ? leftOp._op.RightPrecedence <= _op.LeftPrecedence : leftOp._op.RightPrecedence < _op.LeftPrecedence); + wrapRight = rightOp != null && (!_op.RightAssoc ? rightOp._op.LeftPrecedence <= _op.RightPrecedence : rightOp._op.LeftPrecedence < _op.RightPrecedence); } else { - wrapLeft = leftOp != null && (op.RightAssoc ? leftOp.op.NewPrecedence <= op.NewPrecedence : leftOp.op.NewPrecedence < op.NewPrecedence); - wrapRight = rightOp != null && (!op.RightAssoc ? rightOp.op.NewPrecedence <= op.NewPrecedence : rightOp.op.NewPrecedence < op.NewPrecedence); + wrapLeft = leftOp != null && (_op.RightAssoc ? leftOp._op.NewPrecedence <= _op.NewPrecedence : leftOp._op.NewPrecedence < _op.NewPrecedence); + wrapRight = rightOp != null && (!_op.RightAssoc ? rightOp._op.NewPrecedence <= _op.NewPrecedence : rightOp._op.NewPrecedence < _op.NewPrecedence); } // Avoid parentheses for prefix operators if possible, // e.g. BitwiseNot: (a & (~ b)) & c is written as a & ~ b & c // but (a + (~ b)) + c must be written as a + (~ b) + c - if (!useNewPrecedences) + if (!_useNewPrecedences) { - if (wrapRight && rightOp.left == null && (rightParent == null || (!rightParent.op.RightAssoc ? rightOp.op.RightPrecedence >= rightParent.op.LeftPrecedence : rightOp.op.RightPrecedence > rightParent.op.LeftPrecedence))) + if (wrapRight && rightOp._left == null && (rightParent == null || (!rightParent._op.RightAssoc ? rightOp._op.RightPrecedence >= rightParent._op.LeftPrecedence : rightOp._op.RightPrecedence > rightParent._op.LeftPrecedence))) wrapRight = false; } else { - if (wrapRight && rightOp.left == null && (rightParent == null || (!rightParent.op.RightAssoc ? rightOp.op.NewPrecedence >= rightParent.op.NewPrecedence : rightOp.op.NewPrecedence > rightParent.op.NewPrecedence))) + if (wrapRight && rightOp._left == null && (rightParent == null || (!rightParent._op.RightAssoc ? rightOp._op.NewPrecedence >= rightParent._op.NewPrecedence : rightOp._op.NewPrecedence > rightParent._op.NewPrecedence))) wrapRight = false; } - if (left != null) + if (_left != null) { if (wrapLeft) sqlText.Append("("); if (leftOp != null && !wrapLeft) leftOp.WriteSql(sqlText, this); else - left.WriteSql(sqlText); + _left.WriteSql(sqlText); if (wrapLeft) sqlText.Append(")"); } - sqlText.Append(op.Op); + sqlText.Append(_op.Op); - if (right != null) + if (_right != null) { if (wrapRight) sqlText.Append("("); if (rightOp != null && !wrapRight) rightOp.WriteSql(sqlText, rightParent); else - right.WriteSql(sqlText); + _right.WriteSql(sqlText); if (wrapRight) sqlText.Append(")"); } @@ -1124,7 +995,7 @@ private void WriteSql(StringBuilder sqlText, OperatorExpression rightParent) internal class ConstantListExpression : VisitedExpression { - private IEnumerable _list; + readonly IEnumerable _list; public ConstantListExpression(IEnumerable list) { @@ -1134,7 +1005,7 @@ public ConstantListExpression(IEnumerable list) internal override void WriteSql(StringBuilder sqlText) { sqlText.Append("("); - bool first = true; + var first = true; foreach (var constant in _list) { if (!first) @@ -1149,12 +1020,16 @@ internal override void WriteSql(StringBuilder sqlText) internal class CombinedProjectionExpression : VisitedExpression { - private List _list; - private string _setOperator; + readonly List _list; + readonly string _setOperator; public CombinedProjectionExpression(DbExpressionKind setOperator, List list) { - _setOperator = setOperator == DbExpressionKind.UnionAll ? "UNION ALL" : setOperator == DbExpressionKind.Except ? "EXCEPT" : "INTERSECT"; + _setOperator = setOperator == DbExpressionKind.UnionAll + ? "UNION ALL" + : setOperator == DbExpressionKind.Except + ? "EXCEPT" + : "INTERSECT"; _list = list; } @@ -1163,9 +1038,7 @@ internal override void WriteSql(StringBuilder sqlText) for (var i = 0; i < _list.Count; i++) { if (i != 0) - { sqlText.Append(' ').Append(_setOperator).Append(' '); - } sqlText.Append('('); _list[i].WriteSql(sqlText); sqlText.Append(')'); @@ -1177,7 +1050,7 @@ internal override void WriteSql(StringBuilder sqlText) internal class ExistsExpression : VisitedExpression { - private VisitedExpression _argument; + readonly VisitedExpression _argument; public ExistsExpression(VisitedExpression argument) { @@ -1195,17 +1068,14 @@ internal override void WriteSql(StringBuilder sqlText) class OrderByExpression : VisitedExpression { - private bool _requiresOrderSeperator; + bool _requiresOrderSeperator; public void AppendSort(VisitedExpression sort, bool ascending) { if (_requiresOrderSeperator) Append(","); Append(sort); - if (ascending) - Append(" ASC "); - else - Append(" DESC "); + Append(ascending ? " ASC " : " DESC "); _requiresOrderSeperator = true; } From 4214de4326406c83df35cc2894537f14d11c4fc3 Mon Sep 17 00:00:00 2001 From: PSeON Date: Tue, 5 Jul 2016 15:17:40 +0300 Subject: [PATCH 04/60] POSIX regular expressions operators --- .../NpgsqlTextFunctions.cs | 29 +++- .../SqlGenerators/SqlBaseGenerator.cs | 76 ++++++++ .../SqlGenerators/VisitedExpression.cs | 1 + .../EntityFramework6.Npgsql.Tests.csproj | 1 + .../PatternMatchingTests.cs | 164 ++++++++++++++++++ 5 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs index d31a7a5..c468716 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs @@ -1,6 +1,7 @@ using System; using System.Data.Entity; using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; namespace Npgsql { @@ -368,5 +369,31 @@ public static string TsRewrite(string query, string target, string substitute) { throw new NotSupportedException(); } - } + + /// + /// Matches regular expression. Generates the "~" operator. + /// http://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP + /// This method follows the semantics of + /// and it is translated to the equivalent PostgreSQL expression when executed. + /// + [DbFunction("Npgsql", "match_regex")] + public static bool MatchRegex(string input, string pattern) + { + throw new NotSupportedException(); + } + + /// + /// Matches regular expression. Generates the "~" operator. + /// http://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP + /// This method follows the semantics of + /// and it is translated to the equivalent PostgreSQL expression when executed. + /// Options and + /// are not supported. + /// + [DbFunction("Npgsql", "match_regex")] + public static bool MatchRegex(string input, string pattern, RegexOptions options) + { + throw new NotSupportedException(); + } + } } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 0dbccdd..dc3555c 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -35,6 +35,8 @@ #endif using System.Linq; using JetBrains.Annotations; +using System.Text.RegularExpressions; +using System.Text; namespace Npgsql.SqlGenerators { @@ -1144,6 +1146,10 @@ VisitedExpression VisitFunction(EdmFunction function, IList args, return new CastExpression(args[0].Accept(this), "tsquery"); } + else if (functionName == "match_regex") + { + return VisitMatchRegex(function, args, resultType); + } } var customFuncCall = new FunctionExpression( @@ -1160,6 +1166,76 @@ VisitedExpression VisitFunction(EdmFunction function, IList args, #endif } +#if ENTITIES6 + VisitedExpression VisitMatchRegex(EdmFunction function, IList args, TypeUsage resultType) + { + if (args.Count != 2 && args.Count != 3) + throw new ArgumentException("Invalid number of arguments. Expected 2 or 3.", nameof(args)); + + var options = RegexOptions.None; + + if (args.Count == 3) + { + var optionsExpression = args[2] as DbConstantExpression; + if (optionsExpression == null) + throw new NotSupportedException("Options must be constant expression."); + + options = (RegexOptions)optionsExpression.Value; + } + + if (options.HasFlag(RegexOptions.RightToLeft) || options.HasFlag(RegexOptions.ECMAScript)) + { + throw new NotSupportedException("Options RightToLeft and ECMAScript are not supported."); + } + + if (options == RegexOptions.Singleline) + { + return OperatorExpression.Build( + Operator.RegexMatch, + _useNewPrecedences, + args[0].Accept(this), + args[1].Accept(this)); + } + + var flags = new StringBuilder("(?"); + + if (options.HasFlag(RegexOptions.IgnoreCase)) + { + flags.Append('i'); + } + + if (options.HasFlag(RegexOptions.Multiline)) + { + flags.Append('n'); + } + else if (!options.HasFlag(RegexOptions.Singleline)) + { + // In .NET's default mode, . doesn't match newlines but PostgreSQL it does. + flags.Append('p'); + } + + if (options.HasFlag(RegexOptions.IgnorePatternWhitespace)) + { + flags.Append('x'); + } + + flags.Append(')'); + + var primitiveType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String); + var newRegexExpression = OperatorExpression.Build( + Operator.Concat, + _useNewPrecedences, + new ConstantExpression(flags.ToString(), TypeUsage.CreateStringTypeUsage(primitiveType, true, false)), + args[1].Accept(this)); + + return OperatorExpression.Build( + Operator.RegexMatch, + _useNewPrecedences, + args[0].Accept(this), + newRegexExpression); + } +#endif + VisitedExpression Substring(VisitedExpression source, VisitedExpression start, VisitedExpression count) { var substring = new FunctionExpression("substr"); diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs index f8963cb..04ff22f 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -844,6 +844,7 @@ internal enum UnaryTypes { public static readonly Operator QueryNegate = new Operator("!!", 10, 8, UnaryTypes.Prefix, true); public static readonly Operator QueryContains = new Operator("@>", 10, 8); public static readonly Operator QueryIsContained = new Operator("<@", 10, 8); + public static readonly Operator RegexMatch = new Operator("~", 10, 8); public static readonly Dictionary NegateDict; diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 1d15360..573642b 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -72,6 +72,7 @@ + diff --git a/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs b/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs new file mode 100644 index 0000000..6260b90 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs @@ -0,0 +1,164 @@ +#region License +// The PostgreSQL License +// +// Copyright (C) 2016 The Npgsql Development Team +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose, without fee, and without a written +// agreement is hereby granted, provided that the above copyright notice +// and this paragraph and the following two paragraphs appear in all copies. +// +// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY +// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// +// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS +// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +#endregion + +using Npgsql; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Data.Entity; +using System.Linq; +using System.Text; +using System.ComponentModel.DataAnnotations.Schema; +using System.Data.Entity.Core.Metadata.Edm; +using System.Data.Entity.Core.Objects; +using System.Data.Entity.Infrastructure; +using NpgsqlTypes; +using System.Text.RegularExpressions; + +namespace EntityFramework6.Npgsql.Tests +{ + class PatternMatchingTests : EntityFrameworkTestBase + { + [Test] + [TestCase("blog", "blog", "BLOG", TestName = "Case-sensitive")] + [TestCase("^blog$", "blog", "some \nblog\n name", TestName = "^ and $ match beginning and end")] + [TestCase("some .* name", "some blog name", "some \n name", TestName = ". matches all except \\n")] + [TestCase("some blog name", "some blog name", "someblogname", TestName = "Whitespace not ignored in pattern")] + public void MatchRegex(string pattern, string matchingInput, string mismatchingInput) + { + // Arrange + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog() { Name = matchingInput }); + context.Blogs.Add(new Blog() { Name = mismatchingInput }); + context.SaveChanges(); + } + + // Act + // Ensure correctness of a test case + var netMatchResult = Regex.IsMatch(matchingInput, pattern); + var netMismatchResult = Regex.IsMatch(mismatchingInput, pattern); + + List pgMatchResults; + List pgMismatchResults; + List pgMatchWithOptionsResults; + List pgMismatchWithOptionsResults; + using (var context = new BloggingContext(ConnectionString)) + { + pgMatchResults = (from b in context.Blogs + where NpgsqlTextFunctions.MatchRegex(b.Name, pattern) + select b.Name).ToList(); + + pgMismatchResults = (from b in context.Blogs + where !NpgsqlTextFunctions.MatchRegex(b.Name, pattern) + select b.Name).ToList(); + + pgMatchWithOptionsResults = (from b in context.Blogs + where NpgsqlTextFunctions.MatchRegex(b.Name, pattern, RegexOptions.None) + select b.Name).ToList(); + + pgMismatchWithOptionsResults = (from b in context.Blogs + where !NpgsqlTextFunctions.MatchRegex(b.Name, pattern, RegexOptions.None) + select b.Name).ToList(); + } + + // Assert + Assert.That(netMatchResult, Is.True); + Assert.That(netMismatchResult, Is.False); + + Assert.That(pgMatchResults.Count, Is.EqualTo(1)); + Assert.That(pgMatchResults[0], Is.EqualTo(matchingInput)); + Assert.That(pgMismatchResults.Count, Is.EqualTo(1)); + Assert.That(pgMismatchResults[0], Is.EqualTo(mismatchingInput)); + + Assert.That(pgMatchWithOptionsResults.Count, Is.EqualTo(1)); + Assert.That(pgMatchWithOptionsResults[0], Is.EqualTo(matchingInput)); + Assert.That(pgMismatchWithOptionsResults.Count, Is.EqualTo(1)); + Assert.That(pgMismatchWithOptionsResults[0], Is.EqualTo(mismatchingInput)); + } + + [Test] + [TestCase(RegexOptions.IgnoreCase, "some", "SOME", "placeholder", TestName = "IgnoreCase")] + [TestCase(RegexOptions.IgnorePatternWhitespace, "s o m e", "some", "s o m e", TestName = "IgnorePatternWhitespace")] + [TestCase(RegexOptions.Multiline, "^blog$", "some \nblog\n name", "placeholder", TestName = "Multiline")] + [TestCase(RegexOptions.Singleline, "some .* name", "some \n name", "placeholder", TestName = "Singleline")] + public void MatchRegexOptions(RegexOptions options, string pattern, string matchingInput, string mismatchingInput) + { + // Arrange + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog() { Name = matchingInput }); + context.Blogs.Add(new Blog() { Name = mismatchingInput }); + context.SaveChanges(); + } + + // Act + // Ensure correctness of a test case + var netMatchResult = Regex.IsMatch(matchingInput, pattern, options); + var netMismatchResult = Regex.IsMatch(mismatchingInput, pattern, options); + + List pgMatchResults; + List pgMismatchResults; + using (var context = new BloggingContext(ConnectionString)) + { + pgMatchResults = (from b in context.Blogs + where NpgsqlTextFunctions.MatchRegex(b.Name, pattern, options) + select b.Name).ToList(); + + pgMismatchResults = (from b in context.Blogs + where !NpgsqlTextFunctions.MatchRegex(b.Name, pattern, options) + select b.Name).ToList(); + } + + // Assert + Assert.That(netMatchResult, Is.True); + Assert.That(netMismatchResult, Is.False); + + Assert.That(pgMatchResults.Count, Is.EqualTo(1)); + Assert.That(pgMatchResults[0], Is.EqualTo(matchingInput)); + Assert.That(pgMismatchResults.Count, Is.EqualTo(1)); + Assert.That(pgMismatchResults[0], Is.EqualTo(mismatchingInput)); + } + + [Test] + [TestCase(RegexOptions.RightToLeft)] + [TestCase(RegexOptions.ECMAScript)] + public void MatchRegex_NotSupportedOption(RegexOptions options) + { + using (var context = new BloggingContext(ConnectionString)) + { + Assert.That(() => + { + var results = (from b in context.Blogs + where NpgsqlTextFunctions.MatchRegex(b.Name, "Some pattern", options) + select b.Name).ToList(); + }, Throws.InnerException.TypeOf()); + } + } + } +} From e1689b94b8b83e94023f5bfb751b6345349d550c Mon Sep 17 00:00:00 2001 From: rwasef1830 Date: Tue, 31 May 2016 18:13:51 +0200 Subject: [PATCH 05/60] Fix #27 by casting literal strings in projection lists + explicit cast function + tests. --- .../EntityFramework6.Npgsql.csproj | 1 + .../NpgsqlProviderManifest.cs | 8 +-- .../NpgsqlTypeFunctions.cs | 20 ++++++ .../SqlGenerators/SqlBaseGenerator.cs | 20 +++++- .../EntityFrameworkBasicTests.cs | 69 +++++++++++++++++++ .../Support/EntityFrameworkTestBase.cs | 20 ++++++ 6 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index 1d7fb7c..c5b375b 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -69,6 +69,7 @@ + diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index 3dfa842..f7d4d21 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -351,15 +351,15 @@ public override string EscapeLikeArgument([NotNull] string argument) public override bool SupportsInExpression() => true; public override ReadOnlyCollection GetStoreFunctions() - => typeof(NpgsqlTextFunctions).GetTypeInfo() - .GetMethods(BindingFlags.Public | BindingFlags.Static) + => new[] { typeof(NpgsqlTextFunctions).GetTypeInfo(), typeof(NpgsqlTypeFunctions) } + .SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.Static)) .Select(x => new { Method = x, DbFunction = x.GetCustomAttribute() }) .Where(x => x.DbFunction != null) - .Select(x => CreateFullTextEdmFunction(x.Method, x.DbFunction)) + .Select(x => CreateComposableEdmFunction(x.Method, x.DbFunction)) .ToList() .AsReadOnly(); - static EdmFunction CreateFullTextEdmFunction([NotNull] MethodInfo method, [NotNull] DbFunctionAttribute dbFunctionInfo) + static EdmFunction CreateComposableEdmFunction([NotNull] MethodInfo method, [NotNull] DbFunctionAttribute dbFunctionInfo) { if (method == null) throw new ArgumentNullException(nameof(method)); diff --git a/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs new file mode 100644 index 0000000..b567668 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs @@ -0,0 +1,20 @@ +using System; +using System.Data.Entity; + +namespace Npgsql +{ + /// + /// Use this class in LINQ queries to emit type manipulation SQL fragments. + /// + public static class NpgsqlTypeFunctions + { + /// + /// Emits an explicit cast for unknown types sent as strings to their correct postgresql type. + /// + [DbFunction("Npgsql", "cast")] + public static string Cast(string unknownTypeValue, string postgresTypeName) + { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index dc3555c..0cf543c 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -322,7 +322,14 @@ PendingProjectsNode VisitInputWithBinding(DbExpression expression, string bindin for (var i = 0; i < rowType.Properties.Count && i < projection.Arguments.Count; ++i) { var prop = rowType.Properties[i]; - input.Projection.Arguments.Add(new ColumnExpression(projection.Arguments[i].Accept(this), prop.Name, prop.TypeUsage)); + var argument = projection.Arguments[i].Accept(this); + var constantArgument = projection.Arguments[i] as DbConstantExpression; + if (constantArgument != null && constantArgument.Value is string) + { + argument = new CastExpression(argument, "varchar"); + } + + input.Projection.Arguments.Add(new ColumnExpression(argument, prop.Name, prop.TypeUsage)); } if (enterScope) LeaveExpression(child); @@ -1150,6 +1157,17 @@ VisitedExpression VisitFunction(EdmFunction function, IList args, { return VisitMatchRegex(function, args, resultType); } + else if (functionName == "cast") + { + if (args.Count != 2) + throw new ArgumentException("Invalid number of arguments. Expected 2.", "args"); + + var typeNameExpression = args[1] as DbConstantExpression; + if (typeNameExpression == null) + throw new NotSupportedException("cast type name argument must be a constant expression."); + + return new CastExpression(args[0].Accept(this), typeNameExpression.Value.ToString()); + } } var customFuncCall = new FunctionExpression( diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index e1e30fc..2ff87fb 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -650,5 +650,74 @@ public void TestScalarValuedStoredFunctions_with_null_StoreFunctionName() Assert.That(echo, Is.EqualTo(1337)); } } + + [Test] + public void TestCastFunction() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + var varbitVal = "10011"; + + var blog = new Blog + { + Name = "_", + Posts = new List + { + new Post + { + Content = "Some post content", + Rating = 1, + Title = "Some post Title", + VarbitColumn = varbitVal + } + } + }; + context.Blogs.Add(blog); + context.SaveChanges(); + + Assert.IsTrue( + context.Posts.Select( + p => NpgsqlTypeFunctions.Cast(p.VarbitColumn, "varbit") == varbitVal).First()); + + Assert.IsTrue( + context.Posts.Select( + p => NpgsqlTypeFunctions.Cast(p.VarbitColumn, "varbit") == "10011").First()); + } + } + + [Test] + public void Test_issue_27_select_ef_generated_literals_from_inner_select() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog = new Blog { Name = "Hello" }; + context.Users.Add(new Administrator { Blogs = new List { blog } }); + context.Users.Add(new Editor()); + context.SaveChanges(); + + var administrator = context.Users + .Where(x => x is Administrator) // Removing this changes the query to using a UNION which doesn't fail. + .Select( + x => new + { + // causes entity framework to emit a literal discriminator + Computed = x is Administrator + ? "I administrate" + : x is Editor + ? "I edit" + : "Unknown", + // causes an inner select to be emitted thus showing the issue + HasBlog = x.Blogs.Any() + }) + .First(); + + Assert.That(administrator.Computed, Is.EqualTo("I administrate")); + Assert.That(administrator.HasBlog, Is.True); + } + } } } diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index 366a02f..1fcc3ad 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -104,6 +104,20 @@ public class NoColumnsEntity public int Id { get; set; } } + [Table("Users")] + public abstract class User + { + public int Id { get; set; } + + public IList Blogs { get; set; } + } + + [Table("Editors")] + public class Editor : User { } + + [Table("Administrators")] + public class Administrator : User { } + public class BloggingContext : DbContext { public BloggingContext(string connection) @@ -114,6 +128,9 @@ public BloggingContext(string connection) public DbSet Blogs { get; set; } public DbSet Posts { get; set; } public DbSet NoColumnsEntities { get; set; } + public DbSet Users { get; set; } + public DbSet Editors { get; set; } + public DbSet Administrators { get; set; } [DbFunction("BloggingContext", "ClrStoredAddFunction")] public static int StoredAddFunction(int val1, int val2) @@ -135,6 +152,9 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) dbModelBuilder.Entity(); dbModelBuilder.Entity(); dbModelBuilder.Entity(); + dbModelBuilder.Entity(); + dbModelBuilder.Entity(); + dbModelBuilder.Entity(); // Import function var dbModel = dbModelBuilder.Build(connection); From 890f3dd573d85214ac1a3cfcc9a948f2016fc192 Mon Sep 17 00:00:00 2001 From: Anton Shkuratov Date: Fri, 10 Jun 2016 00:03:49 +0700 Subject: [PATCH 06/60] Adds table valued functions support --- .../SqlGenerators/SqlBaseGenerator.cs | 9 ++ .../SqlGenerators/VisitedExpression.cs | 2 +- .../EntityFrameworkBasicTests.cs | 38 ++++++++ .../Support/EntityFrameworkTestBase.cs | 92 +++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 0cf543c..723def2 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -399,6 +399,15 @@ PendingProjectsNode VisitInputWithBinding(DbExpression expression, string bindin break; } + case DbExpressionKind.Function: + { + var function = (DbFunctionExpression)expression; + var input = new InputExpression( + VisitFunction(function.Function, function.Arguments, function.ResultType), bindingName); + + n = new PendingProjectsNode(bindingName, input); + break; + } default: throw new NotImplementedException(); } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs index 04ff22f..d1e94b2 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -526,7 +526,7 @@ internal override void WriteSql(StringBuilder sqlText) } else { - var wrap = !(_from is LiteralExpression || _from is ScanExpression); + var wrap = !(_from is LiteralExpression || _from is ScanExpression || _from is FunctionExpression); if (wrap) sqlText.Append("("); _from.WriteSql(sqlText); diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 2ff87fb..dc39dc0 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -719,5 +719,43 @@ public void Test_issue_27_select_ef_generated_literals_from_inner_select() Assert.That(administrator.HasBlog, Is.True); } } + + [Test] + public void TestTableValuedStoredFunctions() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + // Add some data and query it back using Stored Function + context.Blogs.Add(new Blog + { + Name = "Some blog1 name", + Posts = new List() + }); + context.Blogs.Add(new Blog + { + Name = "Some blog2 name", + Posts = new List() + }); + context.SaveChanges(); + + // Query back + var query = from b in context.GetBlogsByName("blog1") + select b; + var list = query.ToList(); + + Assert.AreEqual(1, list.Count); + Assert.AreEqual("Some blog1 name", list[0].Name); + + // Query with projection + var query2 = from b in context.GetBlogsByName("blog1") + select new { b.Name, Something = 1 }; + var list2 = query2.ToList(); + Assert.AreEqual(1, list2.Count); + Assert.AreEqual("Some blog1 name", list2[0].Name); + Assert.AreEqual(1, list2[0].Something); + } + } } } diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index 1fcc3ad..e26dbc6 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -30,6 +30,7 @@ using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations.Schema; +using System.Data.Entity.Core.Mapping; using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; @@ -58,6 +59,7 @@ public abstract class EntityFrameworkTestBase : TestBase createSequenceConn.ExecuteNonQuery("alter table \"dbo\".\"Posts\" alter column \"VarbitColumn\" type varbit using null"); createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"StoredAddFunction\"(integer, integer) RETURNS integer AS $$ SELECT $1 + $2; $$ LANGUAGE SQL;"); createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"StoredEchoFunction\"(integer) RETURNS integer AS $$ SELECT $1; $$ LANGUAGE SQL;"); + createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"GetBlogsByName\"(text) RETURNS TABLE(\"BlogId\" int, \"Name\" text, \"IntComputedValue\" int) as $$ select \"BlogId\", \"Name\", \"IntComputedValue\" from \"dbo\".\"Blogs\" where \"Name\" ilike '%' || $1 || '%' $$ LANGUAGE SQL;"); } } @@ -144,6 +146,15 @@ public static int StoredEchoFunction(int value) throw new NotSupportedException(); } + [DbFunction("BloggingContext", "GetBlogsByName")] + public IQueryable GetBlogsByName(string name) + { + ObjectParameter nameParameter = new ObjectParameter("Name", name); + + return ((IObjectContextAdapter)this).ObjectContext.CreateQuery( + $"[GetBlogsByName](@Name)", nameParameter); + } + private static DbCompiledModel CreateModel(NpgsqlConnection connection) { var dbModelBuilder = new DbModelBuilder(DbModelBuilderVersion.Latest); @@ -213,6 +224,87 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) null); dbModel.StoreModel.AddItem(echoFunc); + var stringStoreType = dbModel.ProviderManifest.GetStoreTypes().First(x => x.ClrEquivalentType == typeof(string)); + var modelBlogStoreType = dbModel.StoreModel.EntityTypes.First(x => x.Name == typeof(Blog).Name); + var rowType = RowType.Create( + modelBlogStoreType.Properties.Select(x => + { + var clone = EdmProperty.Create(x.Name, x.TypeUsage); + clone.CollectionKind = x.CollectionKind; + clone.ConcurrencyMode = x.ConcurrencyMode; + clone.IsFixedLength = x.IsFixedLength; + clone.IsMaxLength = x.IsMaxLength; + clone.IsUnicode = x.IsUnicode; + clone.MaxLength = x.MaxLength; + clone.Precision = x.Precision; + clone.Scale = x.Scale; + clone.StoreGeneratedPattern = x.StoreGeneratedPattern; + clone.SetMetadataProperties(x + .MetadataProperties + .Where(metadataProerty => !clone + .MetadataProperties + .Any(cloneMetadataProperty => cloneMetadataProperty.Name.Equals(metadataProerty.Name)))); + return clone; + }), + null); + + var getBlogsFunc = EdmFunction.Create( + "StoredGetBlogsFunction", + "BloggingContext", + DataSpace.SSpace, + new EdmFunctionPayload + { + ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, + Schema = "dbo", + IsComposable = true, + IsNiladic = false, + IsBuiltIn = false, + IsAggregate = false, + StoreFunctionName = "GetBlogsByName", + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType1", rowType.GetCollectionType(), ParameterMode.ReturnValue) + }, + Parameters = new[] + { + FunctionParameter.Create("Name", stringStoreType, ParameterMode.In) + } + }, + null); + dbModel.StoreModel.AddItem(getBlogsFunc); + + var stringPrimitiveType = PrimitiveType.GetEdmPrimitiveTypes().First(x => x.ClrEquivalentType == typeof(string)); + var modelBlogConceptualType = dbModel.ConceptualModel.EntityTypes.First(x => x.Name == typeof(Blog).Name); + EdmFunction getBlogsFuncModel = EdmFunction.Create( + "GetBlogsByName", + dbModel.ConceptualModel.Container.Name, + DataSpace.CSpace, + new EdmFunctionPayload + { + IsFunctionImport = true, + IsComposable = true, + Parameters = new[] + { + FunctionParameter.Create("Name", stringPrimitiveType, ParameterMode.In) + }, + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType1", modelBlogConceptualType.GetCollectionType(), ParameterMode.ReturnValue) + }, + EntitySets = new[] + { + dbModel.ConceptualModel.Container.EntitySets.First(x => x.ElementType == modelBlogConceptualType) + } + }, + null); + dbModel.ConceptualModel.Container.AddFunctionImport(getBlogsFuncModel); + + dbModel.ConceptualToStoreMapping.AddFunctionImportMapping(new FunctionImportMappingComposable( + getBlogsFuncModel, + getBlogsFunc, + new FunctionImportResultMapping(), + dbModel.ConceptualToStoreMapping)); + var compiledModel = dbModel.Compile(); return compiledModel; } From 13b535b54c2626268e59ce0b0d1abc37ced614f3 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 14 Jul 2016 22:59:25 +0000 Subject: [PATCH 07/60] Depend on EF 6.1.0 Otherwise we get: Could not load type 'System.Data.Entity.Migrations.Model.RenameIndexOperation' Fixes #44 --- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index 2e493ab..b88c9de 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -17,7 +17,7 @@ npgsql postgresql postgres data database entity framework ef orm - + From c6702ce2da03368c6586ca42740dee9a3a2b23a9 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 20 Nov 2016 16:47:08 +0200 Subject: [PATCH 08/60] Add docfx conceptual docs (cherry picked from commit ccf3aa84e833bc707b8cd2da635ef84ecd7527b1) --- doc/index.md | 34 ++++++++++++++++++++++++++++++++++ doc/toc.md | 1 + 2 files changed, 35 insertions(+) create mode 100644 doc/index.md create mode 100644 doc/toc.md diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 0000000..e3387c8 --- /dev/null +++ b/doc/index.md @@ -0,0 +1,34 @@ +--- +layout: doc +title: Entity Framework 6 +--- + +Npgsql has an Entity Framework 6 provider. You can use it by installing the +[EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget. + +## Guid Support ## + +Npgsql EF migrations support uses `uuid_generate_v4()` function to generate guids. +In order to have access to this function, you have to install the extension uuid-ossp through the following command: + +```sql +create extension "uuid-ossp"; +``` + +If you don't have this extension installed, when you run Npgsql migrations you will get the following error message: + +``` +ERROR: function uuid_generate_v4() does not exist +``` + +If the database is being created by Npgsql Migrations, you will need to +[run the `create extension` command in the `template1` database](http://stackoverflow.com/a/11584751). +This way, when the new database is created, the extension will be installed already. + +## Template Database ## + +When the Entity Framework 6 provider creates a database, it issues a simple `CREATE DATABASE` command. +In PostgreSQL, this implicitly uses `template1` as the template - anything existing in `template1` will +be copied to your new database. If you wish to change the database used as a template, you can specify +the `EF Template Database` connection string parameter. For more info see the +[PostgreSQL docs](https://www.postgresql.org/docs/current/static/sql-createdatabase.html). diff --git a/doc/toc.md b/doc/toc.md new file mode 100644 index 0000000..0d45642 --- /dev/null +++ b/doc/toc.md @@ -0,0 +1 @@ +# [Getting Started](index.md) From 767f11fa50c0fa2290d1add058a4b090664aadf6 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 12 Dec 2016 17:03:56 +0000 Subject: [PATCH 09/60] Fix SSL/Certificate authentication See ticket #59 --- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index cebda62..c422a86 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -183,7 +183,7 @@ static void UsingPostgresDbConnection(NpgsqlConnection connection, Action Date: Fri, 20 Jan 2017 22:01:52 +0200 Subject: [PATCH 10/60] Access conn properties via settings We were accessing 2 EF6-specific connection string params via properties on NpgsqlConnection. Access them via the connection's settings instead. --- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index c422a86..1e7c29e 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -151,10 +151,10 @@ protected override void DbCreateDatabase([NotNull] DbConnection connection, int? sb.Append("CREATE DATABASE \""); sb.Append(connection.Database); sb.Append("\""); - if (conn.EntityTemplateDatabase != null) + if (conn.Settings.EntityTemplateDatabase != null) { sb.Append(" TEMPLATE \""); - sb.Append(conn.EntityTemplateDatabase); + sb.Append(conn.Settings.EntityTemplateDatabase); sb.Append("\""); } @@ -179,7 +179,7 @@ static void UsingPostgresDbConnection(NpgsqlConnection connection, Action Date: Thu, 16 Feb 2017 08:03:08 +0200 Subject: [PATCH 11/60] Document the possibility of using EF6 interceptors. --- doc/index.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/doc/index.md b/doc/index.md index e3387c8..0a73365 100644 --- a/doc/index.md +++ b/doc/index.md @@ -32,3 +32,61 @@ In PostgreSQL, this implicitly uses `template1` as the template - anything exist be copied to your new database. If you wish to change the database used as a template, you can specify the `EF Template Database` connection string parameter. For more info see the [PostgreSQL docs](https://www.postgresql.org/docs/current/static/sql-createdatabase.html). + +## Customizing DataReader Behavior ## + +You can use [an Entity Framework 6 IDbCommandInterceptor](https://msdn.microsoft.com/en-us/library/dn469464(v=vs.113).aspx) to wrap the `DataReader` instance returned by Npgsql when Entity Framework executes queries. This is possible using a ```DbConfiguration``` class. + +Example use cases: +- Forcing all returned ```DateTime``` and ```DateTimeOffset``` values to be in the UTC timezone. +- Preventing accidental insertion of DateTime values having ```DateTimeKind.Unspecified```. +- Forcing all postgres date/time types to be returned to Entity Framework as ```DateTimeOffset```. + +```c# +[DbConfigurationType(typeof(AppDbContextConfiguration))] +public class AppDbContext : DbContext +{ + // ... +} + +public class AppDbContextConfiguration : DbConfiguration +{ + public AppDbContextConfiguration() + { + this.AddInterceptor(new MyEntityFrameworkInterceptor()); + } +} + +class MyEntityFrameworkInterceptor : DbCommandInterceptor +{ + public override void ReaderExecuted( + DbCommand command, + DbCommandInterceptionContext interceptionContext) + { + if (interceptionContext.Result == null) return; + interceptionContext.Result = new WrappingDbDataReader(interceptionContext.Result); + } + + public override void ScalarExecuted( + DbCommand command, + DbCommandInterceptionContext interceptionContext) + { + interceptionContext.Result = ModifyReturnValues(interceptionContext.Result); + } + + static object ModifyReturnValues(object result) + { + // Transform and then + return result; + } +} + +class WrappingDbDataReader : DbDataReader, IDataReader +{ + // Wrap an existing DbDataReader, proxy all calls to the underlying instance, + // modify return values and/or parameters as needed... + public WrappingDbDataReader(DbDataReader reader) + { + } +} +``` From 877222893e94504df07dcc7a33c77aa4330dd45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sun, 10 Sep 2017 16:12:02 +0200 Subject: [PATCH 12/60] Add quotes to schema and table names (#74) * Fixes #72 --- .../NpgsqlMigrationSqlGenerator.cs | 65 +++++++++++++++---- .../EntityFrameworkMigrationTests.cs | 44 ++++++++++--- 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs index 5cb03d4..e590bf2 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -202,11 +202,11 @@ void CreateSchema(string schemaName) return; _addedSchemas.Add(schemaName); if (_serverVersion.Major > 9 || (_serverVersion.Major == 9 && _serverVersion.Minor >= 3)) - AddStatment("CREATE SCHEMA IF NOT EXISTS " + schemaName); + AddStatment("CREATE SCHEMA IF NOT EXISTS " + QuoteIdentifier(schemaName)); else { //TODO: CREATE PROCEDURE that checks if schema already exists on servers < 9.3 - AddStatment("CREATE SCHEMA " + schemaName); + AddStatment("CREATE SCHEMA " + QuoteIdentifier(schemaName)); } } @@ -230,7 +230,7 @@ protected virtual void Convert(MoveTableOperation moveTableOperation) sql.Append("ALTER TABLE "); AppendTableName(moveTableOperation.Name, sql); sql.Append(" SET SCHEMA "); - sql.Append(newSchema); + AppendQuotedIdentifier(newSchema, sql); AddStatment(sql); } @@ -499,6 +499,53 @@ protected virtual void Convert(DropPrimaryKeyOperation dropPrimaryKeyOperation) #region Misc functions + /// + /// Quotes an identifier for Postgres SQL and appends it to a + /// + /// The identifier to be quoted. + /// The used for building the query. + /// The quoted identifier. + void AppendQuotedIdentifier(string identifier, StringBuilder builder) + { + if (String.IsNullOrEmpty(identifier)) + { + throw new ArgumentException("Value cannot be null or empty", nameof(identifier)); + } + + if (identifier[identifier.Length - 1] == '"' && identifier[0] == '"') + { + builder.Append(identifier); + } + else + { + builder.Append('"'); + builder.Append(identifier); + builder.Append('"'); + } + } + + /// + /// Quotes an identifier for Postgres SQL + /// + /// The identifier to be quoted. + /// The quoted identifier. + string QuoteIdentifier(string identifier) + { + if (String.IsNullOrEmpty(identifier)) + { + throw new ArgumentException("Value cannot be null or empty", nameof(identifier)); + } + + if (identifier[identifier.Length - 1] == '"' && identifier[0] == '"') + { + return identifier; + } + else + { + return '"' + identifier + '"'; + } + } + void AppendColumn(ColumnModel column, StringBuilder sql) { sql.Append('"'); @@ -689,17 +736,13 @@ void AppendTableName(string tableName, StringBuilder sql) var dotIndex = tableName.IndexOf('.'); if (dotIndex == -1) { - sql.Append('"'); - sql.Append(tableName); - sql.Append('"'); + AppendQuotedIdentifier(tableName, sql); } else { - sql.Append('"'); - sql.Append(tableName.Remove(dotIndex)); - sql.Append("\".\""); - sql.Append(tableName.Substring(dotIndex + 1)); - sql.Append('"'); + AppendQuotedIdentifier(tableName.Remove(dotIndex), sql); + sql.Append('.'); + AppendQuotedIdentifier(tableName.Substring(dotIndex + 1), sql); } } diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs index a0b768c..f32a035 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs @@ -355,9 +355,9 @@ public void CreateTableOperation() var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); Assert.AreEqual(2, statments.Count()); if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor > 2)) - Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS someSchema", statments.ElementAt(0).Sql); + Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"someSchema\"", statments.ElementAt(0).Sql); else - Assert.AreEqual("CREATE SCHEMA someSchema", statments.ElementAt(0).Sql); + Assert.AreEqual("CREATE SCHEMA \"someSchema\"", statments.ElementAt(0).Sql); Assert.AreEqual("CREATE TABLE \"someSchema\".\"someTable\"(\"SomeString\" varchar(233) NOT NULL DEFAULT '',\"AnotherString\" text,\"SomeBytes\" bytea,\"SomeLong\" serial8,\"SomeDateTime\" timestamp)", statments.ElementAt(1).Sql); } @@ -503,10 +503,10 @@ public void MoveTableOperation() var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); Assert.AreEqual(2, statments.Count()); if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor > 2)) - Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS someNewSchema", statments.ElementAt(0).Sql); + Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"someNewSchema\"", statments.ElementAt(0).Sql); else - Assert.AreEqual("CREATE SCHEMA someNewSchema", statments.ElementAt(0).Sql); - Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA someNewSchema", statments.ElementAt(1).Sql); + Assert.AreEqual("CREATE SCHEMA \"someNewSchema\"", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA \"someNewSchema\"", statments.ElementAt(1).Sql); } [Test] @@ -517,10 +517,38 @@ public void MoveTableOperationNewSchemaIsNull() var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); Assert.AreEqual(2, statments.Count()); if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor > 2)) - Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS dbo", statments.ElementAt(0).Sql); + Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"dbo\"", statments.ElementAt(0).Sql); else - Assert.AreEqual("CREATE SCHEMA dbo", statments.ElementAt(0).Sql); - Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA dbo", statments.ElementAt(1).Sql); + Assert.AreEqual("CREATE SCHEMA \"dbo\"", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA \"dbo\"", statments.ElementAt(1).Sql); + } + + [Test] + public void MoveTableOperationPrequotedNewSchema() + { + var operations = new List(); + operations.Add(new MoveTableOperation("someOldSchema.someTable", "\"prequotedNewSchema\"")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(2, statments.Count()); + if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor > 2)) + Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"prequotedNewSchema\"", statments.ElementAt(0).Sql); + else + Assert.AreEqual("CREATE SCHEMA \"prequotedNewSchema\"", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA \"prequotedNewSchema\"", statments.ElementAt(1).Sql); + } + + [Test] + public void MoveTableOperationPrequotedOldSchema() + { + var operations = new List(); + operations.Add(new MoveTableOperation("\"prequotedOldSchema\".\"someTable\"", "newSchema")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(2, statments.Count()); + if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor > 2)) + Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"newSchema\"", statments.ElementAt(0).Sql); + else + Assert.AreEqual("CREATE SCHEMA \"newSchema\"", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"prequotedOldSchema\".\"someTable\" SET SCHEMA \"newSchema\"", statments.ElementAt(1).Sql); } [Test] From 42393c13f02ae4c3b2b936dda99ce1f3e6806da0 Mon Sep 17 00:00:00 2001 From: superfuego Date: Wed, 19 Jul 2017 21:53:41 +0200 Subject: [PATCH 13/60] Ignore empty schema string. Fixes #72. (original pull request: #75). --- .../SqlGenerators/SqlBaseGenerator.cs | 23 ++++++++++++++--- .../EntityFrameworkBasicTests.cs | 25 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 723def2..b35586f 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -553,12 +553,27 @@ public override VisitedExpression Visit([NotNull] DbScanExpression expression) ScanExpression scan; var overrideSchema = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator:Schema"; if (expression.Target.MetadataProperties.TryGetValue(overrideSchema, false, out metadata) && metadata.Value != null) - scan = new ScanExpression(QuoteIdentifier(metadata.Value.ToString()) + "." + QuoteIdentifier(tableName), expression.Target); + { + var schema = metadata.Value.ToString(); + scan = string.IsNullOrEmpty(schema) + ? new ScanExpression(QuoteIdentifier(tableName), expression.Target) + : new ScanExpression(QuoteIdentifier(schema) + "." + QuoteIdentifier(tableName), expression.Target); + } else if (expression.Target.MetadataProperties.TryGetValue("Schema", false, out metadata) && metadata.Value != null) - scan = new ScanExpression(QuoteIdentifier(metadata.Value.ToString()) + "." + QuoteIdentifier(tableName), expression.Target); + { + var schema = metadata.Value.ToString(); + scan = string.IsNullOrEmpty(schema) + ? new ScanExpression(QuoteIdentifier(tableName), expression.Target) + : new ScanExpression(QuoteIdentifier(schema) + "." + QuoteIdentifier(tableName), expression.Target); + } else - scan = new ScanExpression(QuoteIdentifier(expression.Target.EntityContainer.Name) + "." + QuoteIdentifier(tableName), expression.Target); - + { + var schema = expression.Target.EntityContainer.Name; + scan = string.IsNullOrEmpty(schema) + ? new ScanExpression(QuoteIdentifier(tableName), expression.Target) + : new ScanExpression(QuoteIdentifier(schema) + "." + QuoteIdentifier(tableName), expression.Target); + } + return scan; } diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index dc39dc0..783fc7e 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -82,6 +82,27 @@ public void InsertAndSelect() } } + [Test] + public void InsertAndSelectSchemaless() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Delete(); + context.Database.Create(); + } + + using (var context = new BloggingContext(ConnectionString)) + { + context.NoColumnsEntities.Add(new NoColumnsEntity()); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionString)) + { + Assert.AreEqual(1, context.NoColumnsEntities.Count()); + } + } + [Test] public void SelectWithWhere() { @@ -621,8 +642,8 @@ public void TestScalarValuedStoredFunctions() CollectionAssert.AreEqual(localChangedIds, remoteChangedIds); } } - - [Test] + + [Test] public void TestScalarValuedStoredFunctions_with_null_StoreFunctionName() { using (var context = new BloggingContext(ConnectionString)) From 0845a5eb92cceda2a1a65362cbe88d8e37e8d34d Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 17 Sep 2017 16:33:11 +0300 Subject: [PATCH 14/60] Depend on Npgsql 3.2.5 --- .../EntityFramework5.Npgsql.csproj | 10 ++++++---- src/EntityFramework5.Npgsql/packages.config | 5 +++-- .../EntityFramework6.Npgsql.csproj | 8 +++++--- src/EntityFramework6.Npgsql/packages.config | 5 +++-- .../EntityFramework6.Npgsql.Tests.csproj | 8 +++++--- test/EntityFramework6.Npgsql.Tests/packages.config | 5 +++-- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj index e351766..682357c 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj @@ -36,14 +36,16 @@ bin\Release\EntityFramework5.Npgsql.xml - - ..\..\packages\Npgsql.3.1.2\lib\net45\Npgsql.dll - True + + ..\..\packages\Npgsql.3.2.5\lib\net45\Npgsql.dll + + ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + @@ -79,4 +81,4 @@ - + \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/packages.config b/src/EntityFramework5.Npgsql/packages.config index a55205e..4e61629 100644 --- a/src/EntityFramework5.Npgsql/packages.config +++ b/src/EntityFramework5.Npgsql/packages.config @@ -1,4 +1,5 @@  - - \ No newline at end of file + + + diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index c5b375b..ecfa056 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -44,13 +44,15 @@ ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll True - - ..\..\packages\Npgsql.3.1.2\lib\net45\Npgsql.dll - True + + ..\..\packages\Npgsql.3.2.5\lib\net45\Npgsql.dll + + ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + diff --git a/src/EntityFramework6.Npgsql/packages.config b/src/EntityFramework6.Npgsql/packages.config index ef18161..824d02f 100644 --- a/src/EntityFramework6.Npgsql/packages.config +++ b/src/EntityFramework6.Npgsql/packages.config @@ -1,5 +1,6 @@  - - \ No newline at end of file + + + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 573642b..fbc8651 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -47,9 +47,8 @@ ..\..\packages\NLog.4.3.3\lib\net45\NLog.dll True - - ..\..\packages\Npgsql.3.1.2\lib\net451\Npgsql.dll - True + + ..\..\packages\Npgsql.3.2.5\lib\net451\Npgsql.dll ..\..\packages\NUnit.3.2.1\lib\net45\nunit.framework.dll @@ -64,6 +63,9 @@ 3.0 + + ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config index 7c2a037..83be5fc 100644 --- a/test/EntityFramework6.Npgsql.Tests/packages.config +++ b/test/EntityFramework6.Npgsql.Tests/packages.config @@ -2,6 +2,7 @@ - + - \ No newline at end of file + + From 3b82c96e89ea4421f698f3eb582a5dda661d8391 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 17 Sep 2017 15:07:25 +0300 Subject: [PATCH 15/60] Depend on NUnit 3.8.1 --- .../EntityFramework6.Npgsql.Tests.csproj | 4 ++-- test/EntityFramework6.Npgsql.Tests/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index fbc8651..0631769 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -50,8 +50,8 @@ ..\..\packages\Npgsql.3.2.5\lib\net451\Npgsql.dll - - ..\..\packages\NUnit.3.2.1\lib\net45\nunit.framework.dll + + ..\..\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config index 83be5fc..c7aab02 100644 --- a/test/EntityFramework6.Npgsql.Tests/packages.config +++ b/test/EntityFramework6.Npgsql.Tests/packages.config @@ -3,6 +3,6 @@ - + From 483523f179ce3866ef54eedd6d06c51c636349cd Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 17 Sep 2017 16:23:51 +0300 Subject: [PATCH 16/60] Depend on NLog 4.4.12 --- .../EntityFramework6.Npgsql.Tests.csproj | 2 +- test/EntityFramework6.Npgsql.Tests/packages.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 0631769..097e553 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -44,7 +44,7 @@ True - ..\..\packages\NLog.4.3.3\lib\net45\NLog.dll + ..\..\packages\NLog.4.4.12\lib\net45\NLog.dll True diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config index c7aab02..2efc253 100644 --- a/test/EntityFramework6.Npgsql.Tests/packages.config +++ b/test/EntityFramework6.Npgsql.Tests/packages.config @@ -1,7 +1,7 @@  - + From 91492ec5c7edf9d3715e0b3561cd14b2120515a5 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 17 Sep 2017 15:09:48 +0300 Subject: [PATCH 17/60] Fix whitespace --- src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs | 2 +- test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index b35586f..1d078d6 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -573,7 +573,7 @@ public override VisitedExpression Visit([NotNull] DbScanExpression expression) ? new ScanExpression(QuoteIdentifier(tableName), expression.Target) : new ScanExpression(QuoteIdentifier(schema) + "." + QuoteIdentifier(tableName), expression.Target); } - + return scan; } diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 783fc7e..082a0f3 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -642,7 +642,7 @@ public void TestScalarValuedStoredFunctions() CollectionAssert.AreEqual(localChangedIds, remoteChangedIds); } } - + [Test] public void TestScalarValuedStoredFunctions_with_null_StoreFunctionName() { From 62803384d93a0bb64088dac7f178ba6156b666dc Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 17 Sep 2017 16:50:24 +0300 Subject: [PATCH 18/60] Bump version to 3.2.0 --- src/CommonAssemblyInfo.cs | 6 +++--- src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec | 2 +- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec | 2 +- teamcity_set_version.cmd | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs index ebd5a78..4ff278f 100644 --- a/src/CommonAssemblyInfo.cs +++ b/src/CommonAssemblyInfo.cs @@ -16,6 +16,6 @@ [assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.MainAssembly)] // The following version attributes get rewritten by GitVersion as part of the build -[assembly: AssemblyVersion("3.1.1")] -[assembly: AssemblyFileVersion("3.1.1")] -[assembly: AssemblyInformationalVersion("3.1.1-ci")] +[assembly: AssemblyVersion("3.2.0")] +[assembly: AssemblyFileVersion("3.2.0")] +[assembly: AssemblyInformationalVersion("3.2.0")] diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec index 2135c9e..9d92bfe 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec @@ -3,7 +3,7 @@ EntityFramework5.Npgsql Npgsql for Entity Framework 5 - $version$ + 3.2.0 Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index b88c9de..a28fec4 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -3,7 +3,7 @@ EntityFramework6.Npgsql Npgsql for Entity Framework 6 - $version$ + 3.2.0 Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt diff --git a/teamcity_set_version.cmd b/teamcity_set_version.cmd index 1744dc4..866a662 100644 --- a/teamcity_set_version.cmd +++ b/teamcity_set_version.cmd @@ -1 +1 @@ -echo ##teamcity[buildNumber '3.1.1-ci-%1'] +echo ##teamcity[buildNumber '3.2.0-%1'] From e1a7c4860442fcd6fa60722ab8fc0927535d31bf Mon Sep 17 00:00:00 2001 From: rwasef1830 Date: Mon, 18 Sep 2017 23:39:33 +0200 Subject: [PATCH 19/60] Fix test regression due to #77. --- .../EntityFrameworkBasicTests.cs | 6 ------ .../Support/EntityFrameworkTestBase.cs | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 082a0f3..1fbb22e 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -85,12 +85,6 @@ public void InsertAndSelect() [Test] public void InsertAndSelectSchemaless() { - using (var context = new BloggingContext(ConnectionString)) - { - context.Database.Delete(); - context.Database.Create(); - } - using (var context = new BloggingContext(ConnectionString)) { context.NoColumnsEntities.Add(new NoColumnsEntity()); diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index e26dbc6..d00f6ca 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -73,6 +73,7 @@ protected void SetUp() { context.Blogs.RemoveRange(context.Blogs); context.Posts.RemoveRange(context.Posts); + context.NoColumnsEntities.RemoveRange(context.NoColumnsEntities); context.SaveChanges(); } } From c1cf25518173944a9f5044af611c8eccd3af4cd7 Mon Sep 17 00:00:00 2001 From: Pavel Krasikov Date: Thu, 7 Sep 2017 18:00:41 +0300 Subject: [PATCH 20/60] Remove explicit default value for not nullable columns # Conflicts: # test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs --- .../NpgsqlMigrationSqlGenerator.cs | 8 -------- .../EntityFrameworkMigrationTests.cs | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs index e590bf2..f116d64 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -585,14 +585,6 @@ void AppendColumn(ColumnModel column, StringBuilder sql) break; } } - else if (column.IsNullable != null - && !column.IsNullable.Value - && (column.StoreType == null || - (column.StoreType.IndexOf("rowversion", StringComparison.OrdinalIgnoreCase) == -1))) - { - sql.Append(" DEFAULT "); - AppendValue(column.ClrDefaultValue, sql); - } } void AppendColumnType(ColumnModel column, StringBuilder sql, bool setSerial) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs index f32a035..dccc6fd 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs @@ -151,13 +151,13 @@ public void CreateBloggingContext() expectedColumns.Remove((string)reader[0]); Assert.AreEqual("integer", (string)reader[1]); Assert.AreEqual("NO", (string)reader[2]); - Assert.AreEqual("0", (string)reader[3]); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); break; case "UniqueId": expectedColumns.Remove((string)reader[0]); Assert.AreEqual("uuid", (string)reader[1]); Assert.AreEqual("NO", (string)reader[2]); - Assert.AreEqual("'00000000-0000-0000-0000-000000000000'::uuid", reader[3] as string); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); //Assert.AreEqual("uuid_generate_v4()", reader[3] as string); break; case "Rating": @@ -358,7 +358,7 @@ public void CreateTableOperation() Assert.AreEqual("CREATE SCHEMA IF NOT EXISTS \"someSchema\"", statments.ElementAt(0).Sql); else Assert.AreEqual("CREATE SCHEMA \"someSchema\"", statments.ElementAt(0).Sql); - Assert.AreEqual("CREATE TABLE \"someSchema\".\"someTable\"(\"SomeString\" varchar(233) NOT NULL DEFAULT '',\"AnotherString\" text,\"SomeBytes\" bytea,\"SomeLong\" serial8,\"SomeDateTime\" timestamp)", statments.ElementAt(1).Sql); + Assert.AreEqual("CREATE TABLE \"someSchema\".\"someTable\"(\"SomeString\" varchar(233) NOT NULL,\"AnotherString\" text,\"SomeBytes\" bytea,\"SomeLong\" serial8,\"SomeDateTime\" timestamp)", statments.ElementAt(1).Sql); } [Test] From 11f1cbdd843c5424352267e87c078c87bbea93d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Be=C3=B1at=20Gurmendi?= Date: Thu, 3 May 2018 17:03:34 +0200 Subject: [PATCH 21/60] Translate 'case when X is null...' to 'coalesce(X,...)'. --- .../SqlGenerators/SqlBaseGenerator.cs | 17 +++++ .../EntityFrameworkBasicTests.cs | 75 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 1d078d6..32212c2 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -829,6 +829,23 @@ protected string GetDbType(EdmType edmType) public override VisitedExpression Visit([NotNull] DbCaseExpression expression) { + // Check for COALESCE like CASE + if (expression.When.Count == 1 && + expression.When[0].ExpressionKind == DbExpressionKind.IsNull) + { + var isNullExpression = (DbIsNullExpression)expression.When[0]; + if (isNullExpression.Argument.Equals(expression.Else)) + { + var coalesceExpression = new LiteralExpression("COALESCE("); + coalesceExpression.Append(expression.Else.Accept(this)); + coalesceExpression.Append(","); + coalesceExpression.Append(expression.Then[0].Accept(this)); + coalesceExpression.Append(")"); + return coalesceExpression; + } + } + + // General CASE var caseExpression = new LiteralExpression(" CASE "); for (var i = 0; i < expression.When.Count && i < expression.Then.Count; ++i) { diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 1fbb22e..cc7d85f 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -33,6 +33,7 @@ using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; +using System.Diagnostics.CodeAnalysis; using NpgsqlTypes; namespace EntityFramework6.Npgsql.Tests @@ -772,5 +773,79 @@ public void TestTableValuedStoredFunctions() Assert.AreEqual(1, list2[0].Something); } } + + [Test] + public void Test_string_type_inference_in_coalesce_statements() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue = "string_value"; + var query = context.Blogs.Select(b => stringValue + "_postfix"); + var blogTitle = query.First(); + Assert.That(blogTitle, Is.EqualTo("string_value_postfix")); + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase( + "SELECT COALESCE(@p__linq__0,E'') || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", + query.ToString()); + } + } + + [Test] + [SuppressMessage("ReSharper", "ConstantNullCoalescingCondition")] + public void Test_string_null_propagation() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue = "string_value"; + var query = context.Blogs.Select(b => (stringValue ?? "default_value") + "_postfix"); + var blog_title = query.First(); + Assert.That(blog_title, Is.EqualTo("string_value_postfix")); + + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase( + "SELECT CASE WHEN (COALESCE(@p__linq__0,E'default_value') IS NULL) THEN (E'')" + + " WHEN (@p__linq__0 IS NULL) THEN (E'default_value') ELSE (@p__linq__0) END ||" + + " E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", + query.ToString()); + } + } + + [Test] + [SuppressMessage("ReSharper", "ConstantNullCoalescingCondition")] + public void Test_string_multiple_null_propagation() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue1 = "string_value1"; + string stringValue2 = "string_value2"; + string stringValue3 = "string_value3"; + + var query = context.Blogs.Select(b => (stringValue1 ?? stringValue2 ?? stringValue3) + "_postfix"); + var blog_title = query.First(); + Assert.That(blog_title, Is.EqualTo("string_value1_postfix")); + + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase( + "SELECT CASE WHEN (COALESCE(@p__linq__0,COALESCE(@p__linq__1,@p__linq__2)) IS NULL)" + + " THEN (E'') WHEN (@p__linq__0 IS NULL) THEN (COALESCE(@p__linq__1,@p__linq__2)) ELSE" + + " (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", + query.ToString()); + } + } } } From 796da4456053d08a1fdd3e0d7e1a4254d2687ce7 Mon Sep 17 00:00:00 2001 From: rwasef1830 Date: Wed, 2 May 2018 17:34:58 +0200 Subject: [PATCH 22/60] Add support for tsquery_phrase which was added in PostgreSQL 9.6 --- .../NpgsqlTextFunctions.cs | 23 ++++++++++++++++ .../FullTextSearchTests.cs | 26 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs index c468716..117b214 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs @@ -370,6 +370,29 @@ public static string TsRewrite(string query, string target, string substitute) throw new NotSupportedException(); } + /// + /// Returns a tsquery that searches for a match to followed by a match + /// to . + /// https://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY + /// + [DbFunction("Npgsql", "tsquery_phrase")] + public static string TsQueryPhrase(string query1, string query2) + { + throw new NotSupportedException(); + } + + /// + /// Returns a tsquery that searches for a match to followed by a match + /// to at a distance of lexemes using + /// the <N> tsquery operator + /// https://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY + /// + [DbFunction("Npgsql", "tsquery_phrase")] + public static string TsQueryPhrase(string query1, string query2, int distance) + { + throw new NotSupportedException(); + } + /// /// Matches regular expression. Generates the "~" operator. /// http://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP diff --git a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs index e293da7..101e8b3 100644 --- a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs @@ -602,5 +602,31 @@ public void TsRewrite() Is.EqualTo(NpgsqlTsQuery.Parse("'b' & ( 'foo' | 'bar' )").ToString())); } } + + [Test] + public void TsQueryPhrase() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "_" + }; + context.Blogs.Add(blog1); + context.SaveChanges(); + + var newQuery = context + .Blogs.Select(x => NpgsqlTextFunctions.TsQueryPhrase("b", "c")) + .FirstOrDefault(); + Assert.That(newQuery, Is.EqualTo("'b' <-> 'c'")); + + newQuery = context + .Blogs.Select(x => NpgsqlTextFunctions.TsQueryPhrase("b", "c", 10)) + .FirstOrDefault(); + Assert.That(newQuery, Is.EqualTo("'b' <10> 'c'")); + } + } } } From 0bf9deb079b3e2e17cd7963a8ab82dfbc308fcc6 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 28 Jun 2018 07:26:50 +0100 Subject: [PATCH 23/60] Tweak license file To make github recognize it --- LICENSE | 17 +++++++++++++++++ LICENSE.txt | 7 ------- 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 LICENSE delete mode 100644 LICENSE.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..edaca74 --- /dev/null +++ b/LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2002-2018, Npgsql + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL NPGSQL BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +Npgsql HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +NPGSQL SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND Npgsql +HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, +OR MODIFICATIONS. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 0a45364..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2002-2016, The Npgsql Development Team - -Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. From 0f179c4f632b6c133eaa9d3e33d6f6fdc54d1738 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 17:14:28 +0100 Subject: [PATCH 24/60] Add .vs to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9a262f9..adc05e9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ artifacts/ *.lock.json .build TestResult.xml +.vs/ From 9a737da4eb2ce7a7e905b47372fb1fc98d02329c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 17:49:35 +0100 Subject: [PATCH 25/60] Switch to new csproj, drop EF5 Closes #102, #101 --- EntityFramework6.Npgsql.sln | 19 ++- EntityFramework6.Npgsql.sln.DotSettings | 6 + bump.sh | 43 ------- src/CommonAssemblyInfo.cs | 21 ---- src/EntityFramework5.Npgsql/App.config | 17 --- .../EntityFramework5.Npgsql.csproj | 84 ------------- .../EntityFramework5.Npgsql.nuspec | 29 ----- src/EntityFramework5.Npgsql/packages.config | 5 - .../EntityFramework6.Npgsql.csproj | 112 +++++------------- .../EntityFramework6.Npgsql.nuspec | 30 ----- .../NpgsqlProviderManifest.cs | 25 ++-- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 15 +-- .../Properties/AssemblyInfo.cs | 12 +- .../PublisherPolicy.config | 13 -- .../PublisherPolicyLegacy.config | 13 -- .../NpgsqlProviderManifest.Manifest.xml | 0 .../{ => Resources}/NpgsqlSchema.msl | 0 .../{ => Resources}/NpgsqlSchema.ssdl | 0 .../{ => Resources}/NpgsqlSchemaV3.ssdl | 0 .../Spatial/PostgisDataReader.cs | 58 --------- .../Spatial/PostgisServices.cs | 4 - .../SqlGenerators/SqlBaseGenerator.cs | 15 --- .../SqlGenerators/SqlDeleteGenerator.cs | 4 - .../SqlGenerators/SqlInsertGenerator.cs | 4 - .../SqlGenerators/SqlSelectGenerator.cs | 5 - .../SqlGenerators/SqlUpdateGenerator.cs | 4 - .../SqlGenerators/VisitedExpression.cs | 5 - src/EntityFramework6.Npgsql/packages.config | 6 - teamcity_set_version.cmd | 1 - test/EntityFramework6.Npgsql.Tests/App.config | 18 +-- .../EntityFramework6.Npgsql.Tests.csproj | 108 ++--------------- test/EntityFramework6.Npgsql.Tests/Program.cs | 22 ---- .../Properties/AssemblyInfo.cs | 54 --------- .../packages.config | 8 -- 34 files changed, 67 insertions(+), 693 deletions(-) delete mode 100644 bump.sh delete mode 100644 src/CommonAssemblyInfo.cs delete mode 100644 src/EntityFramework5.Npgsql/App.config delete mode 100644 src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj delete mode 100644 src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec delete mode 100644 src/EntityFramework5.Npgsql/packages.config delete mode 100644 src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec delete mode 100644 src/EntityFramework6.Npgsql/PublisherPolicy.config delete mode 100644 src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config rename src/EntityFramework6.Npgsql/{ => Resources}/NpgsqlProviderManifest.Manifest.xml (100%) rename src/EntityFramework6.Npgsql/{ => Resources}/NpgsqlSchema.msl (100%) rename src/EntityFramework6.Npgsql/{ => Resources}/NpgsqlSchema.ssdl (100%) rename src/EntityFramework6.Npgsql/{ => Resources}/NpgsqlSchemaV3.ssdl (100%) delete mode 100644 src/EntityFramework6.Npgsql/packages.config delete mode 100644 teamcity_set_version.cmd delete mode 100644 test/EntityFramework6.Npgsql.Tests/Program.cs delete mode 100644 test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs delete mode 100644 test/EntityFramework6.Npgsql.Tests/packages.config diff --git a/EntityFramework6.Npgsql.sln b/EntityFramework6.Npgsql.sln index f4ccf6f..54bf88e 100644 --- a/EntityFramework6.Npgsql.sln +++ b/EntityFramework6.Npgsql.sln @@ -1,11 +1,10 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A5A60DD-41B6-40BF-B677-227A921ECCC8}" ProjectSection(SolutionItems) = preProject - CommonAssemblyInfo.cs = CommonAssemblyInfo.cs Npgsql.snk = Npgsql.snk EndProjectSection EndProject @@ -13,11 +12,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8537E50E-CF7 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{ED612DB1-AB32-4603-95E7-891BACA71C39}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework6.Npgsql", "src\EntityFramework6.Npgsql\EntityFramework6.Npgsql.csproj", "{3EC85CBA-5B79-11E3-8104-0022198AB089}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework6.Npgsql", "src\EntityFramework6.Npgsql\EntityFramework6.Npgsql.csproj", "{3EC85CBA-5B79-11E3-8104-0022198AB089}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework5.Npgsql", "src\EntityFramework5.Npgsql\EntityFramework5.Npgsql.csproj", "{100998C4-5B85-11E3-911C-0022198AB089}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework6.Npgsql.Tests", "test\EntityFramework6.Npgsql.Tests\EntityFramework6.Npgsql.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework6.Npgsql.Tests", "test\EntityFramework6.Npgsql.Tests\EntityFramework6.Npgsql.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -29,10 +26,6 @@ Global {3EC85CBA-5B79-11E3-8104-0022198AB089}.Debug|Any CPU.Build.0 = Debug|Any CPU {3EC85CBA-5B79-11E3-8104-0022198AB089}.Release|Any CPU.ActiveCfg = Release|Any CPU {3EC85CBA-5B79-11E3-8104-0022198AB089}.Release|Any CPU.Build.0 = Release|Any CPU - {100998C4-5B85-11E3-911C-0022198AB089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {100998C4-5B85-11E3-911C-0022198AB089}.Debug|Any CPU.Build.0 = Debug|Any CPU - {100998C4-5B85-11E3-911C-0022198AB089}.Release|Any CPU.ActiveCfg = Release|Any CPU - {100998C4-5B85-11E3-911C-0022198AB089}.Release|Any CPU.Build.0 = Release|Any CPU {4A0A42DE-C8B8-11E4-8EC9-005056A163A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4A0A42DE-C8B8-11E4-8EC9-005056A163A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A0A42DE-C8B8-11E4-8EC9-005056A163A4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -43,9 +36,11 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {3EC85CBA-5B79-11E3-8104-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} - {100998C4-5B85-11E3-911C-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} = {ED612DB1-AB32-4603-95E7-891BACA71C39} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {84B4C9EA-ED4F-4E87-8809-297958315622} + EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Npgsql.csproj EndGlobalSection diff --git a/EntityFramework6.Npgsql.sln.DotSettings b/EntityFramework6.Npgsql.sln.DotSettings index db04052..78c61b1 100644 --- a/EntityFramework6.Npgsql.sln.DotSettings +++ b/EntityFramework6.Npgsql.sln.DotSettings @@ -2,6 +2,7 @@ True Implicit False + NEVER False True GSS @@ -53,6 +54,11 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True + True True + True True True \ No newline at end of file diff --git a/bump.sh b/bump.sh deleted file mode 100644 index 3a46822..0000000 --- a/bump.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -if [ "$#" -ne 1 ]; then - echo "usage: bump.sh " - exit 1 -fi - -v=$1 -if [[ $v == *"-" ]]; then - echo "Version must not end with -" - exit 1 -fi - -echo "echo ##teamcity[buildNumber '$v-%1']" > teamcity_set_version.cmd - -if [[ $v == *"-"* ]]; then - # Prerelease version - - without_prerelease=`echo $v | cut -d- -f1` - - sed -i 's/^\(\s*\)[^<]*<\/version>/\1$version$<\/version>/' src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec - sed -i 's/^\(\s*\)[^<]*<\/version>/\1$version$<\/version>/' src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec - - sed -i 's/AssemblyVersion("[^"]*")/AssemblyVersion("'$without_prerelease'")/' src/CommonAssemblyInfo.cs - sed -i 's/AssemblyFileVersion("[^"]*")/AssemblyFileVersion("'$without_prerelease'")/' src/CommonAssemblyInfo.cs - sed -i 's/AssemblyInformationalVersion("[^"]*")/AssemblyInformationalVersion("'$v'")/' src/CommonAssemblyInfo.cs -else - # Release version - - sed -i 's/^\(\s*\)[^<]*<\/version>/\1'$v'<\/version>/' src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec - sed -i 's/^\(\s*\)[^<]*<\/version>/\1'$v'<\/version>/' src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec - - sed -i 's/AssemblyVersion("[^"]*")/AssemblyVersion("'$v'")/' src/CommonAssemblyInfo.cs - sed -i 's/AssemblyFileVersion("[^"]*")/AssemblyFileVersion("'$v'")/' src/CommonAssemblyInfo.cs - sed -i 's/AssemblyInformationalVersion("[^"]*")/AssemblyInformationalVersion("'$v'")/' src/CommonAssemblyInfo.cs -fi - -git add teamcity_set_version.cmd -git add src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec -git add src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec -git add src/CommonAssemblyInfo.cs - -git commit -m "Bump version to $v" diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs deleted file mode 100644 index 4ff278f..0000000 --- a/src/CommonAssemblyInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Security; -using System.Reflection; -using System.Resources; - -// Contains assembly attributes shared by all Npgsql projects - -[assembly: CLSCompliant(false)] -[assembly: AllowPartiallyTrustedCallers()] -[assembly: SecurityRules(SecurityRuleSet.Level1)] -[assembly: AssemblyCompany("Npgsql Development Team")] -[assembly: AssemblyProduct("Npgsql")] -[assembly: AssemblyCopyright("Copyright © 2002 - 2016 Npgsql Development Team")] -[assembly: AssemblyTrademark("")] -[assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.MainAssembly)] - -// The following version attributes get rewritten by GitVersion as part of the build -[assembly: AssemblyVersion("3.2.0")] -[assembly: AssemblyFileVersion("3.2.0")] -[assembly: AssemblyInformationalVersion("3.2.0")] diff --git a/src/EntityFramework5.Npgsql/App.config b/src/EntityFramework5.Npgsql/App.config deleted file mode 100644 index 0c119f7..0000000 --- a/src/EntityFramework5.Npgsql/App.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - -
- - - - - - - - - - - - \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj deleted file mode 100644 index 682357c..0000000 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - Debug - AnyCPU - {100998C4-5B85-11E3-911C-0022198AB089} - Library - Properties - EntityFramework5.Npgsql - Npgsql - 512 - true - ..\..\Npgsql.snk - ..\ - true - - v4.5 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45 - prompt - 4 - bin\Debug\EntityFramework5.Npgsql.xml - - - pdbonly - true - bin\Release\ - TRACE;NET45 - prompt - 4 - bin\Release\EntityFramework5.Npgsql.xml - - - - ..\..\packages\Npgsql.3.2.5\lib\net45\Npgsql.dll - - - - - - - ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - Properties\CommonAssemblyInfo.cs - Code - - - - - - - - \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec deleted file mode 100644 index 9d92bfe..0000000 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec +++ /dev/null @@ -1,29 +0,0 @@ - - - - EntityFramework5.Npgsql - Npgsql for Entity Framework 5 - 3.2.0 - Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito - Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno - https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt - http://www.npgsql.org - http://www.npgsql.org/img/postgresql.gif - Copyright 2002 - 2016 Npgsql Development Team - false - PostgreSQL provider for Entity Framework 5 - PostgreSQL provider for Entity Framework 5 - en-US - npgsql postgresql postgres data database entity framework ef orm - - - - - - - - - - - - diff --git a/src/EntityFramework5.Npgsql/packages.config b/src/EntityFramework5.Npgsql/packages.config deleted file mode 100644 index 4e61629..0000000 --- a/src/EntityFramework5.Npgsql/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index ecfa056..ce61dab 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -1,97 +1,45 @@ - - + - Debug - AnyCPU - {3EC85CBA-5B79-11E3-8104-0022198AB089} - Library - Properties - EntityFramework6.Npgsql + PostgreSQL provider for Entity Framework 6 + Shay Rojansky;Emil Lenngren;Francisco Figueiredo Jr.;Kenji Uno + Copyright 2018 © The Npgsql Development Team + Npgsql + npgsql postgresql postgres data database entity framework ef orm + 3.2.0 + latest + net45 + true + CS1591 + true Npgsql - 512 + true + ../../Npgsql.snk true - ..\..\Npgsql.snk - ..\ - true - - v4.5 - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NET45;ENTITIES6 - prompt - 4 - bin\Debug\EntityFramework6.Npgsql.xml - - - pdbonly - true - bin\Release\ - TRACE;NET45;ENTITIES6 - prompt - 4 - bin\Release\EntityFramework6.Npgsql.xml + true + http://www.npgsql.org + http://www.npgsql.org/img/postgresql.gif + https://raw.githubusercontent.com/npgsql/npgsql/master/LICENSE.txt + git + git://github.com/npgsql/EntityFramework6.Npgsql + true - - ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll - True - - - ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll - True - - - ..\..\packages\Npgsql.3.2.5\lib\net45\Npgsql.dll - + + + + + + - - ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - Properties\CommonAssemblyInfo.cs - Code - - - - - + + - - \ No newline at end of file + diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec deleted file mode 100644 index a28fec4..0000000 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - EntityFramework6.Npgsql - Npgsql for Entity Framework 6 - 3.2.0 - Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno, Jon Asher, John Cooley, Federico Di Gregorio, Jon Hanna, Chris Morgan, Dave Page, Glen Parker, Brar Piening, Hiroshi Saito - Shay Rojansky, Emil Lenngren, Francisco Figueiredo Jr., Kenji Uno - https://github.com/npgsql/EntityFramework6.Npgsql/blob/dev/LICENSE.txt - http://www.npgsql.org - http://www.npgsql.org/img/postgresql.gif - Copyright 2002 - 2016 Npgsql Development Team - false - PostgreSQL provider for Entity Framework 6 - PostgreSQL provider for Entity Framework 6 - en-US - npgsql postgresql postgres data database entity framework ef orm - - - - - - - - - - - - - diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index f7d4d21..706d887 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -24,17 +24,12 @@ using System; using System.Collections.Generic; using System.Text; -#if ENTITIES6 using System.Data.Entity; using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Metadata.Edm; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; -#else -using System.Data.Common; -using System.Data.Metadata.Edm; -#endif using System.Xml; using System.Data; using JetBrains.Annotations; @@ -47,10 +42,9 @@ internal class NpgsqlProviderManifest : DbXmlEnabledProviderManifest public Version Version { get; } public NpgsqlProviderManifest(string serverVersion) - : base(CreateXmlReaderForResource("Npgsql.NpgsqlProviderManifest.Manifest.xml")) + : base(CreateXmlReaderForResource("Npgsql.Resources.NpgsqlProviderManifest.Manifest.xml")) { - Version version; - Version = Version.TryParse(serverVersion, out version) + Version = Version.TryParse(serverVersion, out var version) ? version : new Version(9, 5); } @@ -58,11 +52,11 @@ public NpgsqlProviderManifest(string serverVersion) protected override XmlReader GetDbInformation([NotNull] string informationType) { if (informationType == StoreSchemaDefinition) - return CreateXmlReaderForResource("Npgsql.NpgsqlSchema.ssdl"); + return CreateXmlReaderForResource("Npgsql.Resources.NpgsqlSchema.ssdl"); if (informationType == StoreSchemaDefinitionVersion3) - return CreateXmlReaderForResource("Npgsql.NpgsqlSchemaV3.ssdl"); + return CreateXmlReaderForResource("Npgsql.Resources.NpgsqlSchemaV3.ssdl"); if (informationType == StoreSchemaMapping) - return CreateXmlReaderForResource("Npgsql.NpgsqlSchema.msl"); + return CreateXmlReaderForResource("Npgsql.Resources.NpgsqlSchema.msl"); throw new ArgumentOutOfRangeException(nameof(informationType)); } @@ -336,7 +330,12 @@ public override TypeUsage GetStoreType([NotNull] TypeUsage edmType) } static XmlReader CreateXmlReaderForResource(string resourceName) - => XmlReader.Create(System.Reflection.Assembly.GetAssembly(typeof(NpgsqlProviderManifest)).GetManifestResourceStream(resourceName)); + { + var stream = Assembly.GetAssembly(typeof(NpgsqlProviderManifest)).GetManifestResourceStream(resourceName); + if (stream == null) + throw new InvalidOperationException($"Could not find resource {resourceName} in assembly, please report issue"); + return XmlReader.Create(stream); + } public override bool SupportsEscapingLikeArgument(out char escapeCharacter) { @@ -347,7 +346,6 @@ public override bool SupportsEscapingLikeArgument(out char escapeCharacter) public override string EscapeLikeArgument([NotNull] string argument) => argument.Replace("\\","\\\\").Replace("%", "\\%").Replace("_", "\\_"); -#if ENTITIES6 public override bool SupportsInExpression() => true; public override ReadOnlyCollection GetStoreFunctions() @@ -409,6 +407,5 @@ static EdmType MapTypeToEdmType(Type type) throw new NotSupportedException($"Unsupported type for mapping to EdmType: {type.FullName}"); } -#endif } } diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index 1e7c29e..a7f1abd 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -24,17 +24,11 @@ using System; using System.Text; using JetBrains.Annotations; -#if ENTITIES6 using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Migrations.Sql; using System.Data.Entity.Infrastructure.DependencyResolution; -#else -using System.Data.Common; -using System.Data.Common.CommandTrees; -using System.Data.Metadata.Edm; -#endif using Npgsql.SqlGenerators; using DbConnection = System.Data.Common.DbConnection; using DbCommand = System.Data.Common.DbCommand; @@ -43,21 +37,16 @@ namespace Npgsql { -#if ENTITIES6 + [PublicAPI] public class NpgsqlServices : DbProviderServices -#else - internal class NpgsqlServices : DbProviderServices -#endif { public static NpgsqlServices Instance { get; } = new NpgsqlServices(); -#if ENTITIES6 public NpgsqlServices() { AddDependencyResolver(new SingletonDependencyResolver>( () => new NpgsqlMigrationSqlGenerator(), nameof(Npgsql))); } -#endif protected override DbCommandDefinition CreateDbCommandDefinition([NotNull] DbProviderManifest providerManifest, [NotNull] DbCommandTree commandTree) => CreateCommandDefinition(CreateDbCommand(((NpgsqlProviderManifest)providerManifest).Version, commandTree)); @@ -131,7 +120,6 @@ protected override DbProviderManifest GetDbProviderManifest([NotNull] string ver return new NpgsqlProviderManifest(versionHint); } -#if ENTITIES6 protected override bool DbDatabaseExists([NotNull] DbConnection connection, int? commandTimeout, [NotNull] StoreItemCollection storeItemCollection) { var exists = false; @@ -173,7 +161,6 @@ protected override void DbDeleteDatabase([NotNull] DbConnection connection, int? command.ExecuteNonQuery(); }); } -#endif static void UsingPostgresDbConnection(NpgsqlConnection connection, Action action) { diff --git a/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs b/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs index aeb1aee..2caf9c9 100644 --- a/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs +++ b/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs @@ -5,11 +5,7 @@ using System.Resources; // Additional assembly attributes are defined in GlobalAssemblyInfo.cs - -#if ENTITIES6 -[assembly: AssemblyTitleAttribute("EntityFramework6.Npgsql")] -[assembly: AssemblyDescriptionAttribute("PostgreSQL provider for Entity Framework 6")] -#else -[assembly: AssemblyTitleAttribute("EntityFramework5.Npgsql")] -[assembly: AssemblyDescriptionAttribute("PostgreSQL provider for Entity Framework 5")] -#endif +[assembly: CLSCompliant(false)] +[assembly: AllowPartiallyTrustedCallers()] +[assembly: SecurityRules(SecurityRuleSet.Level1)] +[assembly: NeutralResourcesLanguage("en", UltimateResourceFallbackLocation.MainAssembly)] diff --git a/src/EntityFramework6.Npgsql/PublisherPolicy.config b/src/EntityFramework6.Npgsql/PublisherPolicy.config deleted file mode 100644 index bbfd05c..0000000 --- a/src/EntityFramework6.Npgsql/PublisherPolicy.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - diff --git a/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config b/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config deleted file mode 100644 index db8b53f..0000000 --- a/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.Manifest.xml b/src/EntityFramework6.Npgsql/Resources/NpgsqlProviderManifest.Manifest.xml similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlProviderManifest.Manifest.xml rename to src/EntityFramework6.Npgsql/Resources/NpgsqlProviderManifest.Manifest.xml diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchema.msl b/src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.msl similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlSchema.msl rename to src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.msl diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl b/src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.ssdl similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl rename to src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.ssdl diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl b/src/EntityFramework6.Npgsql/Resources/NpgsqlSchemaV3.ssdl similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl rename to src/EntityFramework6.Npgsql/Resources/NpgsqlSchemaV3.ssdl diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs index 63a9c53..730cd22 100644 --- a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs @@ -1,11 +1,6 @@ using System; using System.Data; - -#if ENTITIES6 using System.Data.Entity.Spatial; -#else -using System.Data.Spatial; -#endif namespace Npgsql.Spatial { @@ -65,11 +60,7 @@ public override DbGeometry GetGeometry(int ordinal) ///
/// /// -#if ENTITIES6 public override bool IsGeometryColumn(int ordinal) -#else - public bool IsGeometryColumn(int ordinal) -#endif { return _rdr[ordinal] is NpgsqlTypes.PostgisGeometry; } @@ -79,11 +70,7 @@ public bool IsGeometryColumn(int ordinal) /// /// /// -#if ENTITIES6 public override bool IsGeographyColumn(int ordinal) -#else - public bool IsGeographyColumn(int ordinal) -#endif { throw new NotImplementedException(); } @@ -205,8 +192,6 @@ public void Dispose() /// /// Gets the name of a column, given a zero based ordinal. /// - /// - /// public string GetName(int i) { return _rdr.GetName(i); @@ -215,30 +200,22 @@ public string GetName(int i) /// /// Gets the data type name of a column, given a zero based ordinal. /// - /// - /// public string GetDataTypeName(int i) { return _rdr.GetDataTypeName(i); } - /// /// Gets the System.Type of a column, given a zero based ordinal. /// - /// - /// public Type GetFieldType(int i) { return _rdr.GetFieldType(i); } - /// /// Gets the value of a column, given a zero based ordinal. /// - /// - /// public object GetValue(int i) { return _rdr.GetValue(i); @@ -247,8 +224,6 @@ public object GetValue(int i) /// /// Populates an array of objects with the values of the current row. /// - /// - /// public int GetValues(object[] values) { return _rdr.GetValues(values); @@ -257,19 +232,14 @@ public int GetValues(object[] values) /// /// Gets the column ordinal given the column name. /// - /// - /// public int GetOrdinal(string name) { return _rdr.GetOrdinal(name); } - /// /// Get the value of a column as a boolean, given its zero-based ordinal. /// - /// - /// public bool GetBoolean(int i) { return _rdr.GetBoolean(i); @@ -278,8 +248,6 @@ public bool GetBoolean(int i) /// /// Get the value of a column as a byte, given its zero-based ordinal. /// - /// - /// public byte GetByte(int i) { return _rdr.GetByte(i); @@ -288,8 +256,6 @@ public byte GetByte(int i) /// /// Populates a byte array with the value of a column, given its zero-based ordinal. /// - /// - /// public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) { return _rdr.GetBytes(i, fieldOffset, buffer, bufferoffset, length); @@ -298,8 +264,6 @@ public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, i /// /// Get the value of a column as a char, given its zero-based ordinal. /// - /// - /// public char GetChar(int i) { return _rdr.GetChar(i); @@ -313,8 +277,6 @@ public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, i /// /// Get the value of a column as a GUID, given its zero-based ordinal. /// - /// - /// public Guid GetGuid(int i) { return _rdr.GetGuid(i); @@ -323,8 +285,6 @@ public Guid GetGuid(int i) /// /// Get the value of a column as an int16, given its zero-based ordinal. /// - /// - /// public short GetInt16(int i) { return _rdr.GetInt16(i); @@ -333,8 +293,6 @@ public short GetInt16(int i) /// /// Get the value of a column as an int32, given its zero-based ordinal. /// - /// - /// public int GetInt32(int i) { return _rdr.GetInt32(i); @@ -343,8 +301,6 @@ public int GetInt32(int i) /// /// Get the value of a column as an int64, given its zero-based ordinal. /// - /// - /// public long GetInt64(int i) { return _rdr.GetInt64(i); @@ -353,8 +309,6 @@ public long GetInt64(int i) /// /// Get the value of a column as a float, given its zero-based ordinal. /// - /// - /// public float GetFloat(int i) { return _rdr.GetFloat(i); @@ -363,8 +317,6 @@ public float GetFloat(int i) /// /// Get the value of a column as a double, given its zero-based ordinal. /// - /// - /// public double GetDouble(int i) { return _rdr.GetDouble(i); @@ -373,8 +325,6 @@ public double GetDouble(int i) /// /// Get the value of a column as a string, given its zero-based ordinal. /// - /// - /// public string GetString(int i) { return _rdr.GetString(i); @@ -383,8 +333,6 @@ public string GetString(int i) /// /// Get the value of a column as a decimal, given its zero-based ordinal. /// - /// - /// public decimal GetDecimal(int i) { return _rdr.GetDecimal(i); @@ -393,8 +341,6 @@ public decimal GetDecimal(int i) /// /// Get the value of a column as a datetime, given its zero-based ordinal. /// - /// - /// public DateTime GetDateTime(int i) { return _rdr.GetDateTime(i); @@ -403,8 +349,6 @@ public DateTime GetDateTime(int i) /// /// Returns a DbDataReader of a column, given its zero-based ordinal. /// - /// - /// public IDataReader GetData(int i) { return _rdr.GetData(i); @@ -413,8 +357,6 @@ public IDataReader GetData(int i) /// /// Get the value indicating wether the column contains non-existent or missing value, given its zero-based ordinal. /// - /// - /// public bool IsDBNull(int i) { return _rdr.IsDBNull(i); diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs b/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs index 232b683..7bc6771 100644 --- a/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs @@ -1,9 +1,5 @@ using System; -#if ENTITIES6 using System.Data.Entity.Spatial; -#else -using System.Data.Spatial; -#endif namespace Npgsql.Spatial { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 32212c2..c2247fc 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -25,14 +25,9 @@ using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; -#if ENTITIES6 using System.Globalization; using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Core.Metadata.Edm; -#else -using System.Data.Common.CommandTrees; -using System.Data.Metadata.Edm; -#endif using System.Linq; using JetBrains.Annotations; using System.Text.RegularExpressions; @@ -76,7 +71,6 @@ internal Version Version {"VarP","var_pop"}, }; -#if ENTITIES6 static readonly Dictionary BinaryOperatorFunctionNames = new Dictionary() { {"@@",Operator.QueryMatch}, @@ -85,7 +79,6 @@ internal Version Version {"operator_tsquery_contains",Operator.QueryContains}, {"operator_tsquery_is_contained",Operator.QueryIsContained} }; -#endif void EnterExpression(PendingProjectsNode n) => CurrentExpressions.Add(n.Last.Exp); void LeaveExpression(PendingProjectsNode n) => CurrentExpressions.Remove(n.Last.Exp); @@ -1117,7 +1110,6 @@ VisitedExpression VisitFunction(EdmFunction function, IList args, } } -#if ENTITIES6 var functionName = function.StoreFunctionNameAttribute ?? function.Name; if (function.NamespaceName == "Npgsql") { @@ -1220,12 +1212,8 @@ VisitedExpression VisitFunction(EdmFunction function, IList args, foreach (var a in args) customFuncCall.AddArgument(a.Accept(this)); return customFuncCall; -#else - throw new NotSupportedException(); -#endif } -#if ENTITIES6 VisitedExpression VisitMatchRegex(EdmFunction function, IList args, TypeUsage resultType) { if (args.Count != 2 && args.Count != 3) @@ -1293,7 +1281,6 @@ VisitedExpression VisitMatchRegex(EdmFunction function, IList args args[0].Accept(this), newRegexExpression); } -#endif VisitedExpression Substring(VisitedExpression source, VisitedExpression start, VisitedExpression count) { @@ -1476,7 +1463,6 @@ VisitedExpression BitwiseOperator(IList args, Operator oper) return OperatorExpression.Build(oper, _useNewPrecedences, args[0].Accept(this), args[1].Accept(this)); } -#if ENTITIES6 public override VisitedExpression Visit([NotNull] DbInExpression expression) { var item = expression.Item.Accept(this); @@ -1493,6 +1479,5 @@ public override VisitedExpression Visit([NotNull] DbPropertyExpression expressio // This is overridden in the other visitors throw new NotImplementedException("New in Entity Framework 6"); } -#endif } } diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs index a1ae978..0766ac0 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs @@ -23,11 +23,7 @@ using System; using System.Data.Common; -#if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; -#else -using System.Data.Common.CommandTrees; -#endif namespace Npgsql.SqlGenerators { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs index 80da4b8..0e0fe5a 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs @@ -24,11 +24,7 @@ using System; using System.Collections.Generic; using System.Data.Common; -#if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; -#else -using System.Data.Common.CommandTrees; -#endif namespace Npgsql.SqlGenerators { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs index ffecf5b..22d22e6 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs @@ -25,13 +25,8 @@ using System.Linq; using System.Data.Common; using System.Diagnostics; -#if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Core.Metadata.Edm; -#else -using System.Data.Common.CommandTrees; -using System.Data.Metadata.Edm; -#endif namespace Npgsql.SqlGenerators { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs index c109282..fde7c7a 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs @@ -23,11 +23,7 @@ using System; using System.Data.Common; -#if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; -#else -using System.Data.Common.CommandTrees; -#endif namespace Npgsql.SqlGenerators { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs index d1e94b2..2621c74 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -25,13 +25,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; -#if ENTITIES6 using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Core.Metadata.Edm; -#else -using System.Data.Metadata.Edm; -using System.Data.Common.CommandTrees; -#endif using NpgsqlTypes; using System.Globalization; using JetBrains.Annotations; diff --git a/src/EntityFramework6.Npgsql/packages.config b/src/EntityFramework6.Npgsql/packages.config deleted file mode 100644 index 824d02f..0000000 --- a/src/EntityFramework6.Npgsql/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/teamcity_set_version.cmd b/teamcity_set_version.cmd deleted file mode 100644 index 866a662..0000000 --- a/teamcity_set_version.cmd +++ /dev/null @@ -1 +0,0 @@ -echo ##teamcity[buildNumber '3.2.0-%1'] diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/test/EntityFramework6.Npgsql.Tests/App.config index 79c8fa4..119bb22 100644 --- a/test/EntityFramework6.Npgsql.Tests/App.config +++ b/test/EntityFramework6.Npgsql.Tests/App.config @@ -25,20 +25,4 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 097e553..6dce1a5 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -1,107 +1,13 @@ - - + - {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} - EntityFramework6.Npgsql.Tests - Debug - AnyCPU - true - ..\..\Npgsql.snk - Library - EntityFramework6.Npgsql.Tests - ..\..\ - true - - v4.6 + latest + net45 - - bin\Debug\ - true - full - false - - - true - 4 - TRACE;DEBUG;NET46 - - - bin\Release\ - - - true - true - 4 - TRACE;NET46 - - - - ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll - True - - - ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll - True - - - ..\..\packages\NLog.4.4.12\lib\net45\NLog.dll - True - - - ..\..\packages\Npgsql.3.2.5\lib\net451\Npgsql.dll - - - ..\..\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll - True - - - - 3.5 - - - - - 3.0 - - - ..\..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - + - - {3ec85cba-5b79-11e3-8104-0022198ab089} - EntityFramework6.Npgsql - + + - - \ No newline at end of file + diff --git a/test/EntityFramework6.Npgsql.Tests/Program.cs b/test/EntityFramework6.Npgsql.Tests/Program.cs deleted file mode 100644 index 87168b4..0000000 --- a/test/EntityFramework6.Npgsql.Tests/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using NUnitLite; - -// Exists as a temporary test runner for dotnet cli -// (see https://github.com/nunit/nunit/issues/1371) -namespace Npgsql.Tests -{ - public class Program - { - public static int Main(string[] args) - { -#if DNXCORE50 - return new AutoRun().Execute(typeof(Program).GetTypeInfo().Assembly, Console.Out, Console.In, args); -#else - return new AutoRun().Execute(args); -#endif - } - } -} diff --git a/test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs b/test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index fac0285..0000000 --- a/test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Author: -// Francisco Figueiredo Jr. -// -// Copyright (C) 2002 The Npgsql Development Team -// npgsql-general@gborg.postgresql.org -// http://gborg.postgresql.org/project/npgsql/projdisplay.php -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following -// attributes. -// -// change them to the information which is associated with the assembly -// you compile. - -[assembly: AssemblyTitle("")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has following format : -// -// Major.Minor.Build.Revision -// -// You can specify all values by your own or you can build default build and revision -// numbers with the '*' character (the default): - -[assembly: AssemblyVersion("1.0.0.0")] - -// The following attributes specify the key for the sign of your assembly. See the -// .NET Framework documentation for more information about signing. -// This is not required, if you don't want signing let these attributes like they're. -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile("")] diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config deleted file mode 100644 index 2efc253..0000000 --- a/test/EntityFramework6.Npgsql.Tests/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From b63d0035d2480c777f82b61b1b5fb9d11bc8d2d0 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 18:45:58 +0100 Subject: [PATCH 26/60] Code quality improvements C# 7 etc. --- .../NpgsqlMigrationSqlGenerator.cs | 131 +- .../NpgsqlProviderManifest.cs | 14 +- .../NpgsqlTextFunctions.cs | 171 +-- .../NpgsqlTypeFunctions.cs | 8 +- .../Spatial/PostgisDataReader.cs | 199 +-- .../Spatial/PostgisServices.cs | 1129 +++++------------ 6 files changed, 433 insertions(+), 1219 deletions(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs index f116d64..cf8f413 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -69,42 +69,42 @@ protected virtual void Convert([NotNull] IEnumerable operati { foreach (var migrationOperation in operations) { - if (migrationOperation is AddColumnOperation) - Convert(migrationOperation as AddColumnOperation); - else if (migrationOperation is AlterColumnOperation) - Convert(migrationOperation as AlterColumnOperation); - else if (migrationOperation is CreateTableOperation) - Convert(migrationOperation as CreateTableOperation); - else if (migrationOperation is DropForeignKeyOperation) - Convert(migrationOperation as DropForeignKeyOperation); - else if (migrationOperation is DropTableOperation) - Convert(migrationOperation as DropTableOperation); - else if (migrationOperation is MoveTableOperation) - Convert(migrationOperation as MoveTableOperation); - else if (migrationOperation is RenameTableOperation) - Convert(migrationOperation as RenameTableOperation); - else if (migrationOperation is AddForeignKeyOperation) - Convert(migrationOperation as AddForeignKeyOperation); - else if (migrationOperation is DropIndexOperation) - Convert(migrationOperation as DropIndexOperation); - else if (migrationOperation is SqlOperation) - AddStatment((migrationOperation as SqlOperation).Sql, (migrationOperation as SqlOperation).SuppressTransaction); - else if (migrationOperation is AddPrimaryKeyOperation) - Convert(migrationOperation as AddPrimaryKeyOperation); - else if (migrationOperation is CreateIndexOperation) - Convert(migrationOperation as CreateIndexOperation); - else if (migrationOperation is RenameIndexOperation) - Convert(migrationOperation as RenameIndexOperation); - else if (migrationOperation is DropColumnOperation) - Convert(migrationOperation as DropColumnOperation); - else if (migrationOperation is DropPrimaryKeyOperation) - Convert(migrationOperation as DropPrimaryKeyOperation); - else if (migrationOperation is HistoryOperation) - Convert(migrationOperation as HistoryOperation); - else if (migrationOperation is RenameColumnOperation) - Convert(migrationOperation as RenameColumnOperation); - else if (migrationOperation is UpdateDatabaseOperation) - Convert((migrationOperation as UpdateDatabaseOperation).Migrations as IEnumerable); + if (migrationOperation is AddColumnOperation operation) + Convert(operation); + else if (migrationOperation is AlterColumnOperation columnOperation) + Convert(columnOperation); + else if (migrationOperation is CreateTableOperation tableOperation) + Convert(tableOperation); + else if (migrationOperation is DropForeignKeyOperation keyOperation) + Convert(keyOperation); + else if (migrationOperation is DropTableOperation dropTableOperation) + Convert(dropTableOperation); + else if (migrationOperation is MoveTableOperation moveTableOperation) + Convert(moveTableOperation); + else if (migrationOperation is RenameTableOperation renameTableOperation) + Convert(renameTableOperation); + else if (migrationOperation is AddForeignKeyOperation foreignKeyOperation) + Convert(foreignKeyOperation); + else if (migrationOperation is DropIndexOperation indexOperation) + Convert(indexOperation); + else if (migrationOperation is SqlOperation sqlOperation) + AddStatment(sqlOperation.Sql, sqlOperation.SuppressTransaction); + else if (migrationOperation is AddPrimaryKeyOperation primaryKeyOperation) + Convert(primaryKeyOperation); + else if (migrationOperation is CreateIndexOperation createIndexOperation) + Convert(createIndexOperation); + else if (migrationOperation is RenameIndexOperation renameIndexOperation) + Convert(renameIndexOperation); + else if (migrationOperation is DropColumnOperation dropColumnOperation) + Convert(dropColumnOperation); + else if (migrationOperation is DropPrimaryKeyOperation dropPrimaryKeyOperation) + Convert(dropPrimaryKeyOperation); + else if (migrationOperation is HistoryOperation historyOperation) + Convert(historyOperation); + else if (migrationOperation is RenameColumnOperation renameColumnOperation) + Convert(renameColumnOperation); + else if (migrationOperation is UpdateDatabaseOperation databaseOperation) + Convert(databaseOperation.Migrations as IEnumerable); else throw new NotImplementedException("Unhandled MigrationOperation " + migrationOperation.GetType().Name + " in " + GetType().Name); } @@ -237,6 +237,7 @@ protected virtual void Convert(MoveTableOperation moveTableOperation) #endregion #region Columns + protected virtual void Convert(AddColumnOperation addColumnOperation) { var sql = new StringBuilder(); @@ -507,15 +508,11 @@ protected virtual void Convert(DropPrimaryKeyOperation dropPrimaryKeyOperation) /// The quoted identifier. void AppendQuotedIdentifier(string identifier, StringBuilder builder) { - if (String.IsNullOrEmpty(identifier)) - { + if (string.IsNullOrEmpty(identifier)) throw new ArgumentException("Value cannot be null or empty", nameof(identifier)); - } if (identifier[identifier.Length - 1] == '"' && identifier[0] == '"') - { builder.Append(identifier); - } else { builder.Append('"'); @@ -531,19 +528,11 @@ void AppendQuotedIdentifier(string identifier, StringBuilder builder) /// The quoted identifier. string QuoteIdentifier(string identifier) { - if (String.IsNullOrEmpty(identifier)) - { + if (string.IsNullOrEmpty(identifier)) throw new ArgumentException("Value cannot be null or empty", nameof(identifier)); - } - if (identifier[identifier.Length - 1] == '"' && identifier[0] == '"') - { - return identifier; - } - else - { - return '"' + identifier + '"'; - } + return identifier[identifier.Length - 1] == '"' && identifier[0] == '"' + ? identifier : $"\"{identifier}\""; } void AppendColumn(ColumnModel column, StringBuilder sql) @@ -727,9 +716,7 @@ void AppendTableName(string tableName, StringBuilder sql) { var dotIndex = tableName.IndexOf('.'); if (dotIndex == -1) - { AppendQuotedIdentifier(tableName, sql); - } else { AppendQuotedIdentifier(tableName.Remove(dotIndex), sql); @@ -756,9 +743,7 @@ void AppendValue(byte[] values, StringBuilder sql) } void AppendValue(bool value, StringBuilder sql) - { - sql.Append(value ? "TRUE" : "FALSE"); - } + => sql.Append(value ? "TRUE" : "FALSE"); void AppendValue(DateTime value, StringBuilder sql) { @@ -804,22 +789,22 @@ void AppendValue(DbGeometry value, StringBuilder sql) void AppendValue(object value, StringBuilder sql) { - if (value is byte[]) - AppendValue((byte[])value, sql); - else if (value is bool) - AppendValue((bool)value, sql); - else if (value is DateTime) - AppendValue((DateTime)value, sql); - else if (value is DateTimeOffset) - AppendValue((DateTimeOffset)value, sql); - else if (value is Guid) - AppendValue((Guid)value, sql); - else if (value is string) - AppendValue((string)value, sql); - else if (value is TimeSpan) - AppendValue((TimeSpan)value, sql); - else if (value is DbGeometry) - AppendValue((DbGeometry)value, sql); + if (value is byte[] bytes) + AppendValue(bytes, sql); + else if (value is bool b) + AppendValue(b, sql); + else if (value is DateTime time) + AppendValue(time, sql); + else if (value is DateTimeOffset offset) + AppendValue(offset, sql); + else if (value is Guid guid) + AppendValue(guid, sql); + else if (value is string s) + AppendValue(s, sql); + else if (value is TimeSpan timeSpan) + AppendValue(timeSpan, sql); + else if (value is DbGeometry geometry) + AppendValue(geometry, sql); else sql.Append(string.Format(CultureInfo.InvariantCulture, "{0}", value)); } diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index 706d887..5eb788d 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; -using System.Text; using System.Data.Entity; using System.Data.Entity.Core.Common; using System.Data.Entity.Core.Metadata.Edm; @@ -31,7 +30,6 @@ using System.Linq; using System.Reflection; using System.Xml; -using System.Data; using JetBrains.Annotations; using NpgsqlTypes; @@ -127,16 +125,14 @@ public override TypeUsage GetEdmType([NotNull] TypeUsage storeType) return TypeUsage.CreateDefaultTypeUsage(primitiveType); case "numeric": { - byte scale; - byte precision; if (storeType.Facets.TryGetValue(ScaleFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - scale = (byte)facet.Value; + var scale = (byte)facet.Value; if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - precision = (byte)facet.Value; + var precision = (byte)facet.Value; return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale); } } @@ -242,16 +238,14 @@ public override TypeUsage GetStoreType([NotNull] TypeUsage edmType) return TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float8"]); case PrimitiveTypeKind.Decimal: { - byte scale; - byte precision; if (edmType.Facets.TryGetValue(ScaleFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - scale = (byte)facet.Value; + var scale = (byte)facet.Value; if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { - precision = (byte)facet.Value; + var precision = (byte)facet.Value; return TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"], precision, scale); } } diff --git a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs index 117b214..f3cd584 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs @@ -17,20 +17,14 @@ public static class NpgsqlTextFunctions /// Cast to the tsvector data type. /// [DbFunction("Npgsql", "as_tsvector")] - public static string AsTsVector(string vector) - { - throw new NotSupportedException(); - } + public static string AsTsVector(string vector) => throw new NotSupportedException(); /// /// Reduce to tsvector. /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS /// [DbFunction("Npgsql", "to_tsvector")] - public static string ToTsVector(string document) - { - throw new NotSupportedException(); - } + public static string ToTsVector(string document) => throw new NotSupportedException(); /// /// Reduce to tsvector using the text search configuration specified @@ -38,29 +32,20 @@ public static string ToTsVector(string document) /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS /// [DbFunction("Npgsql", "to_tsvector")] - public static string ToTsVector(string config, string document) - { - throw new NotSupportedException(); - } + public static string ToTsVector(string config, string document) => throw new NotSupportedException(); /// /// Cast to the tsquery data type. /// [DbFunction("Npgsql", "as_tsquery")] - public static string AsTsQuery(string query) - { - throw new NotSupportedException(); - } + public static string AsTsQuery(string query) => throw new NotSupportedException(); /// /// Produce tsquery from ignoring punctuation. /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// [DbFunction("Npgsql", "plainto_tsquery")] - public static string PlainToTsQuery(string query) - { - throw new NotSupportedException(); - } + public static string PlainToTsQuery(string query) => throw new NotSupportedException(); /// /// Produce tsquery from ignoring punctuation and using the text search @@ -68,10 +53,7 @@ public static string PlainToTsQuery(string query) /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// [DbFunction("Npgsql", "plainto_tsquery")] - public static string PlainToTsQuery(string config, string query) - { - throw new NotSupportedException(); - } + public static string PlainToTsQuery(string config, string query) => throw new NotSupportedException(); /// /// Normalize words in and convert to tsquery. If your input @@ -80,10 +62,7 @@ public static string PlainToTsQuery(string config, string query) /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// [DbFunction("Npgsql", "to_tsquery")] - public static string ToTsQuery(string query) - { - throw new NotSupportedException(); - } + public static string ToTsQuery(string query) => throw new NotSupportedException(); /// /// Normalize words in and convert to tsquery using the text search @@ -93,40 +72,28 @@ public static string ToTsQuery(string query) /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// [DbFunction("Npgsql", "to_tsquery")] - public static string ToTsQuery(string config, string query) - { - throw new NotSupportedException(); - } + public static string ToTsQuery(string config, string query) => throw new NotSupportedException(); /// /// AND tsquerys together. Generates the "&&" operator. /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY /// [DbFunction("Npgsql", "operator_tsquery_and")] - public static string QueryAnd(string tsquery1, string tsquery2) - { - throw new NotSupportedException(); - } + public static string QueryAnd(string tsquery1, string tsquery2) => throw new NotSupportedException(); /// /// OR tsquerys together. Generates the "||" operator. /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY /// [DbFunction("Npgsql", "operator_tsquery_or")] - public static string QueryOr(string tsquery1, string tsquery2) - { - throw new NotSupportedException(); - } + public static string QueryOr(string tsquery1, string tsquery2) => throw new NotSupportedException(); /// /// Negate a tsquery. Generates the "!!" operator. /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY /// [DbFunction("Npgsql", "operator_tsquery_negate")] - public static string QueryNot(string tsquery) - { - throw new NotSupportedException(); - } + public static string QueryNot(string tsquery) => throw new NotSupportedException(); /// /// Returns whether contains . @@ -134,10 +101,7 @@ public static string QueryNot(string tsquery) /// http://www.postgresql.org/docs/current/static/functions-textsearch.html /// [DbFunction("Npgsql", "operator_tsquery_contains")] - public static bool QueryContains(string tsquery1, string tsquery2) - { - throw new NotSupportedException(); - } + public static bool QueryContains(string tsquery1, string tsquery2) => throw new NotSupportedException(); /// /// Returns whether is contained within . @@ -145,20 +109,14 @@ public static bool QueryContains(string tsquery1, string tsquery2) /// http://www.postgresql.org/docs/current/static/functions-textsearch.html /// [DbFunction("Npgsql", "operator_tsquery_is_contained")] - public static bool QueryIsContained(string tsquery1, string tsquery2) - { - throw new NotSupportedException(); - } + public static bool QueryIsContained(string tsquery1, string tsquery2) => throw new NotSupportedException(); /// /// This method generates the "@@" match operator. /// http://www.postgresql.org/docs/current/static/textsearch-intro.html#TEXTSEARCH-MATCHING /// [DbFunction("Npgsql", "@@")] - public static bool Match(string tsvector, string tsquery) - { - throw new NotSupportedException(); - } + public static bool Match(string tsvector, string tsquery) => throw new NotSupportedException(); /// /// Assign weight to each element of and return a new @@ -166,30 +124,21 @@ public static bool Match(string tsvector, string tsquery) /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR /// [DbFunction("Npgsql", "setweight")] - public static string SetWeight(string tsvector, NpgsqlWeightLabel label) - { - throw new NotSupportedException(); - } + public static string SetWeight(string tsvector, NpgsqlWeightLabel label) => throw new NotSupportedException(); /// /// Returns the number of lexemes in . /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR /// [DbFunction("Npgsql", "length")] - public static int Length(string tsvector) - { - throw new NotSupportedException(); - } + public static int Length(string tsvector) => throw new NotSupportedException(); /// /// Returns the number of lexemes plus operators in . /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY /// [DbFunction("Npgsql", "numnode")] - public static int NumNode(string tsquery) - { - throw new NotSupportedException(); - } + public static int NumNode(string tsquery) => throw new NotSupportedException(); /// /// Removes weights and positions from and returns @@ -197,20 +146,14 @@ public static int NumNode(string tsquery) /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR /// [DbFunction("Npgsql", "strip")] - public static string Strip(string tsvector) - { - throw new NotSupportedException(); - } + public static string Strip(string tsvector) => throw new NotSupportedException(); /// /// Get indexable part of . /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY /// [DbFunction("Npgsql", "querytree")] - public static string QueryTree(string query) - { - throw new NotSupportedException(); - } + public static string QueryTree(string query) => throw new NotSupportedException(); /// /// Returns a string suitable for display containing a query match. @@ -218,9 +161,7 @@ public static string QueryTree(string query) /// [DbFunction("Npgsql", "ts_headline")] public static string TsHeadline(string document, string tsquery, string options) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Returns a string suitable for display containing a query match using the text @@ -229,21 +170,14 @@ public static string TsHeadline(string document, string tsquery, string options) /// [DbFunction("Npgsql", "ts_headline")] public static string TsHeadline(string config, string document, string tsquery, string options) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Calculates the rank of for . /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING /// [DbFunction("Npgsql", "ts_rank")] - public static float TsRank( - string vector, - string query) - { - throw new NotSupportedException(); - } + public static float TsRank(string vector, string query) => throw new NotSupportedException(); /// /// Calculates the rank of for while normalizing @@ -251,13 +185,8 @@ public static float TsRank( /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING /// [DbFunction("Npgsql", "ts_rank")] - public static float TsRank( - string vector, - string query, - NpgsqlRankingNormalization normalization) - { - throw new NotSupportedException(); - } + public static float TsRank(string vector, string query, NpgsqlRankingNormalization normalization) + => throw new NotSupportedException(); /// /// Calculates the rank of for with custom @@ -272,9 +201,7 @@ public static float TsRank( float weightA, string vector, string query) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Calculates the rank of for while normalizing @@ -291,9 +218,7 @@ public static float TsRank( string vector, string query, NpgsqlRankingNormalization normalization) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Calculates the rank of for using the cover @@ -301,12 +226,7 @@ public static float TsRank( /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING /// [DbFunction("Npgsql", "ts_rank_cd")] - public static float TsRankCd( - string vector, - string query) - { - throw new NotSupportedException(); - } + public static float TsRankCd(string vector, string query) => throw new NotSupportedException(); /// /// Calculates the rank of for using the cover @@ -315,13 +235,8 @@ public static float TsRankCd( /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING /// [DbFunction("Npgsql", "ts_rank_cd")] - public static float TsRankCd( - string vector, - string query, - NpgsqlRankingNormalization normalization) - { - throw new NotSupportedException(); - } + public static float TsRankCd(string vector, string query, NpgsqlRankingNormalization normalization) + => throw new NotSupportedException(); /// /// Calculates the rank of for using the cover @@ -336,9 +251,7 @@ public static float TsRankCd( float weightA, string vector, string query) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Calculates the rank of for using the cover density @@ -355,9 +268,7 @@ public static float TsRankCd( string vector, string query, NpgsqlRankingNormalization normalization) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Searchs for occurrences of , and replaces @@ -366,9 +277,7 @@ public static float TsRankCd( /// [DbFunction("Npgsql", "ts_rewrite")] public static string TsRewrite(string query, string target, string substitute) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Returns a tsquery that searches for a match to followed by a match @@ -377,9 +286,7 @@ public static string TsRewrite(string query, string target, string substitute) /// [DbFunction("Npgsql", "tsquery_phrase")] public static string TsQueryPhrase(string query1, string query2) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Returns a tsquery that searches for a match to followed by a match @@ -389,9 +296,7 @@ public static string TsQueryPhrase(string query1, string query2) /// [DbFunction("Npgsql", "tsquery_phrase")] public static string TsQueryPhrase(string query1, string query2, int distance) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Matches regular expression. Generates the "~" operator. @@ -401,9 +306,7 @@ public static string TsQueryPhrase(string query1, string query2, int distance) /// [DbFunction("Npgsql", "match_regex")] public static bool MatchRegex(string input, string pattern) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); /// /// Matches regular expression. Generates the "~" operator. @@ -415,8 +318,6 @@ public static bool MatchRegex(string input, string pattern) /// [DbFunction("Npgsql", "match_regex")] public static bool MatchRegex(string input, string pattern, RegexOptions options) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); } } diff --git a/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs index b567668..a469d32 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs @@ -1,11 +1,13 @@ using System; using System.Data.Entity; +using System.Diagnostics.CodeAnalysis; namespace Npgsql { /// /// Use this class in LINQ queries to emit type manipulation SQL fragments. /// + [SuppressMessage("ReSharper", "UnusedParameter.Global")] public static class NpgsqlTypeFunctions { /// @@ -13,8 +15,6 @@ public static class NpgsqlTypeFunctions /// [DbFunction("Npgsql", "cast")] public static string Cast(string unknownTypeValue, string postgresTypeName) - { - throw new NotSupportedException(); - } + => throw new NotSupportedException(); } -} \ No newline at end of file +} diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs index 730cd22..60e901d 100644 --- a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs @@ -7,11 +7,10 @@ namespace Npgsql.Spatial /// /// A postgis geometry service API. /// - public class PostgisDataReader - : DbSpatialDataReader, System.Data.IDataReader + public class PostgisDataReader : DbSpatialDataReader, IDataReader { - private PostgisServices _svcs; - private NpgsqlDataReader _rdr; + PostgisServices _svcs; + NpgsqlDataReader _rdr; /// /// Creates a new instance of postgis data reader using a specific instance of PostgisService. @@ -19,7 +18,6 @@ public class PostgisDataReader /// The service provider that DbGeometry instances will use. /// The underlying data reader. public PostgisDataReader(PostgisServices svcs, NpgsqlDataReader rdr) - :base() { _svcs = svcs; _rdr = rdr; @@ -29,298 +27,173 @@ public PostgisDataReader(PostgisServices svcs, NpgsqlDataReader rdr) /// Creates a new instance of postgis data reader. /// /// The underlying data reader. - public PostgisDataReader(NpgsqlDataReader rdr) - :this(new PostgisServices(),rdr) - { - - } + public PostgisDataReader(NpgsqlDataReader rdr) : this(new PostgisServices(),rdr) {} /// /// Get the DbGeography value of a column, given its zero-based ordinal. /// - /// - /// public override DbGeography GetGeography(int ordinal) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the DbGeometry value of a column, given its zero-based ordinal. /// - /// - /// public override DbGeometry GetGeometry(int ordinal) - { - return _svcs.GeometryFromProviderValue(_rdr[ordinal]); - } + => throw new NotImplementedException(); /// /// Get the value indicating wether a column is a Geometry value, given its zero-based ordinal. /// - /// - /// public override bool IsGeometryColumn(int ordinal) - { - return _rdr[ordinal] is NpgsqlTypes.PostgisGeometry; - } + => throw new NotImplementedException(); /// /// Get the value indicating wether a column is a Geography value, given its zero-based ordinal. /// - /// - /// public override bool IsGeographyColumn(int ordinal) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Gets a value indicating the depth of nesting of the current row. Always Zero. /// - public int Depth - { - get - { - return _rdr.Depth; - } - } + public int Depth => _rdr.Depth; /// /// Gets a value indicating wether the data reader is closed. /// - public bool IsClosed - { - get - { - return _rdr.IsClosed; - } - } + public bool IsClosed => _rdr.IsClosed; /// /// Gets the number of row affected by the SQL statement. /// - public int RecordsAffected - { - get - { - return _rdr.RecordsAffected; - } - } + public int RecordsAffected => _rdr.RecordsAffected; /// /// Gets the number of columns in the current row. /// - public int FieldCount - { - get - { - return _rdr.FieldCount; - } - } + public int FieldCount => _rdr.FieldCount; /// /// Gets the value of the specified column name of the current row. /// - /// - /// - public object this[string name] - { - get - { - return _rdr[name]; - } - } + public object this[string name] => _rdr[name]; /// /// Gets the value of the specified column index of the current row. /// - /// - /// - public object this[int i] - { - get - { - return _rdr[i]; - } - } + public object this[int i] => _rdr[i]; /// /// Close the underlying datareader object. /// - public void Close() - { - _rdr.Close(); - } + public void Close() => _rdr.Close(); /// /// Returns a DataTable which contains metadata about the current row. /// - /// - public DataTable GetSchemaTable() - { - return _rdr.GetSchemaTable(); - } + public DataTable GetSchemaTable() => _rdr.GetSchemaTable(); /// /// Advances the reader to the next result when reading data from a batch of statements. /// /// - public bool NextResult() - { - return _rdr.NextResult(); - } + public bool NextResult() => _rdr.NextResult(); /// /// Advances the reader to the next record in a result set. /// /// - public bool Read() - { - return _rdr.Read(); - } + public bool Read() => _rdr.Read(); /// /// Frees the resources hold by the data reader. /// - public void Dispose() - { - _rdr.Dispose(); - } + public void Dispose() => _rdr.Dispose(); /// /// Gets the name of a column, given a zero based ordinal. /// - public string GetName(int i) - { - return _rdr.GetName(i); - } + public string GetName(int i) => _rdr.GetName(i); /// /// Gets the data type name of a column, given a zero based ordinal. /// - public string GetDataTypeName(int i) - { - return _rdr.GetDataTypeName(i); - } + public string GetDataTypeName(int i) => _rdr.GetDataTypeName(i); /// /// Gets the System.Type of a column, given a zero based ordinal. /// - public Type GetFieldType(int i) - { - return _rdr.GetFieldType(i); - } + public Type GetFieldType(int i) => _rdr.GetFieldType(i); /// /// Gets the value of a column, given a zero based ordinal. /// - public object GetValue(int i) - { - return _rdr.GetValue(i); - } + public object GetValue(int i) => _rdr.GetValue(i); /// /// Populates an array of objects with the values of the current row. /// - public int GetValues(object[] values) - { - return _rdr.GetValues(values); - } + public int GetValues(object[] values) => _rdr.GetValues(values); /// /// Gets the column ordinal given the column name. /// - public int GetOrdinal(string name) - { - return _rdr.GetOrdinal(name); - } + public int GetOrdinal(string name) => _rdr.GetOrdinal(name); /// /// Get the value of a column as a boolean, given its zero-based ordinal. /// - public bool GetBoolean(int i) - { - return _rdr.GetBoolean(i); - } + public bool GetBoolean(int i) => _rdr.GetBoolean(i); /// /// Get the value of a column as a byte, given its zero-based ordinal. /// - public byte GetByte(int i) - { - return _rdr.GetByte(i); - } + public byte GetByte(int i) => _rdr.GetByte(i); /// /// Populates a byte array with the value of a column, given its zero-based ordinal. /// public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) - { - return _rdr.GetBytes(i, fieldOffset, buffer, bufferoffset, length); - } + => _rdr.GetBytes(i, fieldOffset, buffer, bufferoffset, length); /// /// Get the value of a column as a char, given its zero-based ordinal. /// - public char GetChar(int i) - { - return _rdr.GetChar(i); - } + public char GetChar(int i) => _rdr.GetChar(i); public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) - { - return _rdr.GetChars(i, fieldoffset, buffer, bufferoffset, length); - } + => _rdr.GetChars(i, fieldoffset, buffer, bufferoffset, length); /// /// Get the value of a column as a GUID, given its zero-based ordinal. /// - public Guid GetGuid(int i) - { - return _rdr.GetGuid(i); - } + public Guid GetGuid(int i) => _rdr.GetGuid(i); /// /// Get the value of a column as an int16, given its zero-based ordinal. /// - public short GetInt16(int i) - { - return _rdr.GetInt16(i); - } + public short GetInt16(int i) => _rdr.GetInt16(i); /// /// Get the value of a column as an int32, given its zero-based ordinal. /// - public int GetInt32(int i) - { - return _rdr.GetInt32(i); - } + public int GetInt32(int i) => _rdr.GetInt32(i); /// /// Get the value of a column as an int64, given its zero-based ordinal. /// - public long GetInt64(int i) - { - return _rdr.GetInt64(i); - } + public long GetInt64(int i) => _rdr.GetInt64(i); /// /// Get the value of a column as a float, given its zero-based ordinal. /// - public float GetFloat(int i) - { - return _rdr.GetFloat(i); - } + public float GetFloat(int i) => _rdr.GetFloat(i); /// /// Get the value of a column as a double, given its zero-based ordinal. /// - public double GetDouble(int i) - { - return _rdr.GetDouble(i); - } + public double GetDouble(int i) => _rdr.GetDouble(i); /// /// Get the value of a column as a string, given its zero-based ordinal. diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs b/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs index 7bc6771..227625c 100644 --- a/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs @@ -1,26 +1,23 @@ using System; using System.Data.Entity.Spatial; +using NpgsqlTypes; namespace Npgsql.Spatial { /// /// A class exposing spatial services. /// - public class PostgisServices - : DbSpatialServices + public class PostgisServices : DbSpatialServices { /// /// Returns the well known binary value of the geometry input. /// - /// - /// public override byte[] AsBinary(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_asbinary(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_AsBinary(:p1)"; return (byte[])cmd.ExecuteScalar(); } } @@ -28,25 +25,18 @@ public override byte[] AsBinary(DbGeometry geometryValue) /// /// Returns the well known binary value of the geography input. /// - /// - /// public override byte[] AsBinary(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the geographical markup language representation of the geometry input. /// - /// - /// public override string AsGml(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_asgml(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_AsGml(:p1)"; return (string)cmd.ExecuteScalar(); } } @@ -54,25 +44,18 @@ public override string AsGml(DbGeometry geometryValue) /// /// Returns the geographical markup language representation of the geography input. /// - /// - /// public override string AsGml(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the well known text representation of the geometry input. /// - /// - /// public override string AsText(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_astext(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_AsText(:p1)"; return (string)cmd.ExecuteScalar(); } } @@ -80,28 +63,20 @@ public override string AsText(DbGeometry geometryValue) /// /// Returns the well known text representation of the geography input. /// - /// - /// public override string AsText(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns a geometry that represents all points whose distance from this Geometry is less than or equal to distance. /// - /// - /// - /// public override DbGeometry Buffer(DbGeometry geometryValue, double distance) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Double, distance); - cmd.CommandText = - "SELECT st_buffer(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Double, distance); + cmd.CommandText = "SELECT ST_Buffer(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } @@ -109,28 +84,19 @@ public override DbGeometry Buffer(DbGeometry geometryValue, double distance) /// Returns a geometry that represents all points whose distance from this Geometry is less than or equal to distance. /// Calculations are in the Spatial Reference System of this Geometry. Uses a planar transform wrapper. /// - /// - /// - /// public override DbGeography Buffer(DbGeography geographyValue, double distance) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns true if and only if no points of B lie in the exterior of A, and at least one point of the interior of B lies in the interior of A /// - /// - /// - /// public override bool Contains(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_contains(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Contains(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -139,77 +105,52 @@ public override bool Contains(DbGeometry geometryValue, DbGeometry otherGeometry } } - /// - /// - /// - /// - /// + /// public override object CreateProviderValue(DbGeometryWellKnownValue wellKnownValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, wellKnownValue.WellKnownBinary); - cmd.CommandText = - "SELECT st_geomfromwkb(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, wellKnownValue.WellKnownBinary); + cmd.CommandText = "SELECT ST_GeomFromWkb(:p1)"; return cmd.ExecuteScalar(); } } - /// - /// - /// - /// - /// + /// public override object CreateProviderValue(DbGeographyWellKnownValue wellKnownValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override DbGeometryWellKnownValue CreateWellKnownValue(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = "SELECT st_astext(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_AsText(:p1)"; var d = new DbGeometryWellKnownValue(); d.WellKnownText = (string)cmd.ExecuteScalar(); - cmd.CommandText = "SELECT st_asbinary(:p1)"; + cmd.CommandText = "SELECT ST_AsBinary(:p1)"; d.WellKnownBinary = (byte[])cmd.ExecuteScalar(); - cmd.CommandText = "SELECT st_srid(:p1)"; + cmd.CommandText = "SELECT ST_SRID(:p1)"; d.CoordinateSystemId = (int)cmd.ExecuteScalar(); return d; } } - /// - /// - /// - /// - /// + /// public override DbGeographyWellKnownValue CreateWellKnownValue(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns TRUE if the supplied geometries have some, but not all, interior points in commo /// - /// - /// - /// public override bool Crosses(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_crosses(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Crosses(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -221,46 +162,33 @@ public override bool Crosses(DbGeometry geometryValue, DbGeometry otherGeometry) /// /// Returns a geometry that represents that part of geometry A that does not intersect with geometry B. /// - /// - /// - /// public override DbGeometry Difference(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_difference(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Difference(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns a geometry that represents that part of geometry A that does not intersect with geometry B. /// - /// - /// - /// public override DbGeography Difference(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns TRUE if the Geometries do not "spatially intersect" - if they do not share any space together. /// - /// - /// - /// public override bool Disjoint(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_disjoint(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Disjoint(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -272,28 +200,19 @@ public override bool Disjoint(DbGeometry geometryValue, DbGeometry otherGeometry /// /// Returns TRUE if the Geometries do not "spatially intersect" - if they do not share any space together. /// - /// - /// - /// public override bool Disjoint(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units. /// - /// - /// - /// public override double Distance(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_distance(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Distance(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -305,569 +224,343 @@ public override double Distance(DbGeometry geometryValue, DbGeometry otherGeomet /// /// Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units. /// - /// - /// - /// public override double Distance(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Given a geometry collection, returns the index-nth geometry. /// - /// - /// - /// public override DbGeometry ElementAt(DbGeometry geometryValue, int index) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, index); - cmd.CommandText = - "SELECT st_geometryn(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, index); + cmd.CommandText = "SELECT ST_GeometryN(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Given a geography collection, returns the index-nth geography. /// - /// - /// - /// public override DbGeography ElementAt(DbGeography geographyValue, int index) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyCollectionFromBinary(byte[] geographyCollectionWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyCollectionFromText(string geographyCollectionWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromBinary(byte[] wellKnownBinary) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromBinary(byte[] wellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromGml(string geographyMarkup) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromGml(string geographyMarkup, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromProviderValue(object providerValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromText(string wellKnownText) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyFromText(string wellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyLineFromBinary(byte[] lineWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyLineFromText(string lineWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiLineFromBinary(byte[] multiLineWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiLineFromText(string multiLineWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiPointFromBinary(byte[] multiPointWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiPointFromText(string multiPointWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiPolygonFromBinary(byte[] multiPolygonWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyMultiPolygonFromText(string multiPolygonWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyPointFromBinary(byte[] pointWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyPointFromText(string pointWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyPolygonFromBinary(byte[] polygonWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// - /// + /// public override DbGeography GeographyPolygonFromText(string polygonWellKnownText, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the geometry collection from a well know binary representation. /// - /// - /// - /// public override DbGeometry GeometryCollectionFromBinary(byte[] geometryCollectionWellKnownBinary, int coordinateSystemId) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the geometry collection from a well know binary representation. /// - /// - /// public override DbGeometry GeometryCollectionFromText(string geometryCollectionWellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, geometryCollectionWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geomcollfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, geometryCollectionWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeomCollFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the geometry from its well known binary representation /// - /// - /// public override DbGeometry GeometryFromBinary(byte[] wellKnownBinary) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, wellKnownBinary); - cmd.CommandText = - "SELECT st_geomfromwkb(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, wellKnownBinary); + cmd.CommandText = "SELECT ST_GeomFromWKB(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the geometry from its well known binary representation /// - /// - /// - /// public override DbGeometry GeometryFromBinary(byte[] wellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, wellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geomfromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, wellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeomFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the geometry from a geometic markup language representation. /// - /// - /// public override DbGeometry GeometryFromGml(string geometryMarkup) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, geometryMarkup); - cmd.CommandText = - "SELECT st_geomfromgml(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, geometryMarkup); + cmd.CommandText = "SELECT ST_GeomFromGML(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the geometry from a geometic markup language representation. /// - /// - /// - /// public override DbGeometry GeometryFromGml(string geometryMarkup, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, geometryMarkup); - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geomfromgml(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, geometryMarkup); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeomFromGML(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Wrap a npgsql geometry in a DbGeometry structure. /// - /// - /// public override DbGeometry GeometryFromProviderValue(object providerValue) - { - return DbSpatialServices.CreateGeometry(this, providerValue); - } + => CreateGeometry(this, providerValue); /// /// Get the geometry from a well known text value. /// - /// - /// public override DbGeometry GeometryFromText(string wellKnownText) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, wellKnownText); - cmd.CommandText = - "SELECT st_geomfromtext(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, wellKnownText); + cmd.CommandText = "SELECT ST_GeomFromText(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the geometry from a well known text value. /// - /// - /// - /// public override DbGeometry GeometryFromText(string wellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, wellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geomfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, wellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeomFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a line from its well known binary value. /// - /// - /// - /// public override DbGeometry GeometryLineFromBinary(byte[] lineWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, lineWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_linefromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, lineWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_LineFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a line from its well known text value. /// - /// - /// - /// public override DbGeometry GeometryLineFromText(string lineWellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, lineWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_linefromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, lineWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_LineFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multiline from its well known binary value. /// - /// - /// - /// public override DbGeometry GeometryMultiLineFromBinary(byte[] multiLineWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, multiLineWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mlinefromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, multiLineWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MLineFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multiline from a well known text value. /// - /// - /// - /// public override DbGeometry GeometryMultiLineFromText(string multiLineWellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, multiLineWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mlinefromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, multiLineWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MLineFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multipoint from its well known binaryrepresentation. /// - /// - /// - /// public override DbGeometry GeometryMultiPointFromBinary(byte[] multiPointWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, multiPointWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mpointfromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, multiPointWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MPointFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multipoint from its well known text representation. /// - /// - /// - /// public override DbGeometry GeometryMultiPointFromText(string multiPointWellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, multiPointWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mpointfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, multiPointWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MPointFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multipolygon from its well known binary value. /// - /// - /// - /// public override DbGeometry GeometryMultiPolygonFromBinary(byte[] multiPolygonWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, multiPolygonWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mpolyfromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, multiPolygonWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MPolyFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a multipolygon from its well known text value. /// - /// - /// - /// public override DbGeometry GeometryMultiPolygonFromText(string multiPolygonKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, multiPolygonKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_mpolyfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, multiPolygonKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_MPolyFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a point from its well known binary value. /// - /// - /// - /// public override DbGeometry GeometryPointFromBinary(byte[] pointWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, pointWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_GeomFromWKB(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, pointWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT st_GeomFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } @@ -881,66 +574,54 @@ public override DbGeometry GeometryPointFromText(string pointWellKnownText, int { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, pointWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_pointfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, pointWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_PointFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a polygon from its well known binary value. /// - /// - /// - /// public override DbGeometry GeometryPolygonFromBinary(byte[] polygonWellKnownBinary, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Bytea, polygonWellKnownBinary); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geomfromwkb(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Bytea, polygonWellKnownBinary); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeomFromWKB(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get a polygon from its well known text value. /// - /// - /// - /// public override DbGeometry GeometryPolygonFromText(string polygonWellKnownText, int coordinateSystemId) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Text, polygonWellKnownText); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, coordinateSystemId); - cmd.CommandText = - "SELECT st_geometryfromtext(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Text, polygonWellKnownText); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, coordinateSystemId); + cmd.CommandText = "SELECT ST_GeometryFromText(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns the area of the surface if it is a polygon or multi-polygon. /// - /// - /// public override double? GetArea(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_area(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Area(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + return rdr.IsDBNull(0) ? new double?() : rdr.GetDouble(0); } } } @@ -948,139 +629,107 @@ public override DbGeometry GeometryPolygonFromText(string polygonWellKnownText, /// /// Returns the area of the surface if it is a polygon or multi-polygon. /// - /// - /// public override double? GetArea(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the closure of the combinatorial boundary of the geometry. /// - /// - /// public override DbGeometry GetBoundary(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_boundary(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Boundary(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns the centroid of the geometry. /// - /// - /// public override DbGeometry GetCentroid(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_centroid(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Centroid(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the convex hull of the geometry. /// - /// - /// public override DbGeometry GetConvexHull(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_convexhull(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_ConvexHull(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the SRID of the geometry. /// - /// - /// public override int GetCoordinateSystemId(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_srid(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_SRID(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); return rdr.GetInt32(0); } - } } /// /// Get the SRID of the geography. /// - /// - /// public override int GetCoordinateSystemId(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the geometry dimension. /// - /// - /// public override int GetDimension(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_dimension(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Dimension(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); return rdr.GetInt32(0); } - } } /// /// Get the geograpy dimension. /// - /// - /// public override int GetDimension(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the element count of the geometry collection. /// - /// - /// public override int? GetElementCount(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_numgeometries(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_NumGeometries(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new int() : new int?(rdr.GetInt32(0)); + return rdr.IsDBNull(0) ? new int() : rdr.GetInt32(0); } } } @@ -1088,103 +737,75 @@ public override int GetDimension(DbGeography geographyValue) /// /// Get the element count of the geometry collection. /// - /// - /// public override int? GetElementCount(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the elevation of the geometry /// - /// - /// public override double? GetElevation(DbGeometry geometryValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the elevation of the geography. /// - /// - /// public override double? GetElevation(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the endpoint of the geometry. /// - /// - /// public override DbGeometry GetEndPoint(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_endpoint(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_EndPoint(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the endpoint of the geography. /// - /// - /// public override DbGeography GetEndPoint(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Get the envelope of the geometry. /// - /// - /// public override DbGeometry GetEnvelope(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_envelope(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Envelope(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the exterior ring of the geometry. /// - /// - /// public override DbGeometry GetExteriorRing(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_exteriorring(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_ExteriorRing(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Get the ring count of the geometry. /// - /// - /// public override int? GetInteriorRingCount(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_numinteriorring(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_NumInteriorRing(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1196,15 +817,12 @@ public override DbGeometry GetExteriorRing(DbGeometry geometryValue) /// /// Check if the geometry is closed. /// - /// - /// public override bool? GetIsClosed(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_isclosed(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_IsClosed(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1216,25 +834,18 @@ public override DbGeometry GetExteriorRing(DbGeometry geometryValue) /// /// Check if the geography is closed; /// - /// - /// public override bool? GetIsClosed(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Chekc if the geometry is empty. /// - /// - /// public override bool GetIsEmpty(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_isempty(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_IsEmpty(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1246,25 +857,18 @@ public override bool GetIsEmpty(DbGeometry geometryValue) /// /// Check if the geography is empty. /// - /// - /// public override bool GetIsEmpty(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Check if the geometry is a linestring, simple and closed. /// - /// - /// public override bool? GetIsRing(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_isring(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_IsRing(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1276,15 +880,12 @@ public override bool GetIsEmpty(DbGeography geographyValue) /// /// Check if the geometry is simple. /// - /// - /// public override bool GetIsSimple(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_issimple(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_IsSimple(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1296,15 +897,12 @@ public override bool GetIsSimple(DbGeometry geometryValue) /// /// Check if the geometry is valid. /// - /// - /// public override bool GetIsValid(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_isvalid(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_IsValid(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1316,29 +914,22 @@ public override bool GetIsValid(DbGeometry geometryValue) /// /// Returns the latitude of the geography. /// - /// - /// public override double? GetLatitude(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the length of the geometry. /// - /// - /// public override double? GetLength(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_length(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Length(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + return rdr.IsDBNull(0) ? new double?() : rdr.GetDouble(0); } } } @@ -1346,59 +937,36 @@ public override bool GetIsValid(DbGeometry geometryValue) /// /// Returns the length of the geography. /// - /// - /// public override double? GetLength(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the longitutde of the geography. /// - /// - /// public override double? GetLongitude(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// / - /// - /// - /// + /// public override double? GetMeasure(DbGeometry geometryValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// - /// - /// - /// + /// public override double? GetMeasure(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the point count of the geometry. /// - /// - /// public override int? GetPointCount(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_npoints(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_NPoints(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new int?() : new int?(rdr.GetInt32(0)); + return rdr.IsDBNull(0) ? new int?() : rdr.GetInt32(0); } } } @@ -1406,41 +974,31 @@ public override bool GetIsValid(DbGeometry geometryValue) /// /// Returns the point count of the geography. /// - /// - /// public override int? GetPointCount(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns a POINT guaranteed to lie on the geometry surface. /// - /// - /// public override DbGeometry GetPointOnSurface(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_pointonsurface(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_PointOnSurface(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// returns the spatial type of the geometry. /// - /// - /// public override string GetSpatialTypeName(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT geometrytype(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT GeometryType(:p1)"; return (string)cmd.ExecuteScalar(); } } @@ -1448,55 +1006,41 @@ public override string GetSpatialTypeName(DbGeometry geometryValue) /// /// Returns the spatial type of the geography. /// - /// - /// public override string GetSpatialTypeName(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns the start point of the geometry. /// - /// - /// public override DbGeometry GetStartPoint(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_startpoint(:p1)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_StartPoint(:p1)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns the start point of the geography. /// - /// - /// public override DbGeography GetStartPoint(DbGeography geographyValue) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns a point X coordinate. /// - /// - /// public override double? GetXCoordinate(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_X(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_X(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + return rdr.IsDBNull(0) ? new double?() : rdr.GetDouble(0); } } } @@ -1504,19 +1048,16 @@ public override DbGeography GetStartPoint(DbGeography geographyValue) /// /// Returns a point Y coordinate. /// - /// - /// public override double? GetYCoordinate(DbGeometry geometryValue) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.CommandText = - "SELECT st_y(:p1)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.CommandText = "SELECT ST_Y(:p1)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); - return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + return rdr.IsDBNull(0) ? new double?() : rdr.GetDouble(0); } } } @@ -1524,64 +1065,47 @@ public override DbGeography GetStartPoint(DbGeography geographyValue) /// /// Returns the index-nth interior ring of the geometry /// - /// - /// - /// public override DbGeometry InteriorRingAt(DbGeometry geometryValue, int index) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Integer, index); - cmd.CommandText = - "SELECT st_interiorringn(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Integer, index); + cmd.CommandText = "SELECT ST_InteriorRingN(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// ///Returns the intersection of two geometries. /// - /// - /// - /// public override DbGeometry Intersection(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_intersection(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Intersection(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns the intersection of two geographies. /// - /// - /// - /// public override DbGeography Intersection(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns TRUE if the Geometries/Geography "spatially intersect in 2D" - (share any portion of space) and FALSE if they don't (they are Disjoint). /// - /// - /// - /// public override bool Intersects(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry); - cmd.CommandText = - "SELECT st_intersects(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry); + cmd.CommandText = "SELECT ST_Intersects(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1594,28 +1118,19 @@ public override bool Intersects(DbGeometry geometryValue, DbGeometry otherGeomet /// Returns TRUE if the Geometries/Geography "spatially intersect in 2D" - (share any portion of space) and FALSE if they don't (they are Disjoint). /// For geography -- tolerance is 0.00001 meters (so any points that close are considered to intersect) /// - /// - /// - /// public override bool Intersects(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns TRUE if the Geometries share space, are of the same dimension, but are not completely contained by each other. /// - /// - /// - /// public override bool Overlaps(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_overlaps(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Overlaps(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1624,45 +1139,26 @@ public override bool Overlaps(DbGeometry geometryValue, DbGeometry otherGeometry } } - /// - /// ??? - /// - /// - /// - /// + /// public override DbGeometry PointAt(DbGeometry geometryValue, int index) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); - /// - /// ??? - /// - /// - /// - /// + /// public override DbGeography PointAt(DbGeography geographyValue, int index) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns true if this Geometry is spatially related to anotherGeometry, /// by testing for intersections between the Interior, Boundary and Exterior of the two geometries /// - /// - /// - /// - /// public override bool Relate(DbGeometry geometryValue, DbGeometry otherGeometry, string matrix) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.Parameters.AddWithValue("p3", NpgsqlTypes.NpgsqlDbType.Text, matrix); - cmd.CommandText = - "SELECT st_relate(:p1,:p2,:p3)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.Parameters.AddWithValue("p3", NpgsqlDbType.Text, matrix); + cmd.CommandText = "SELECT ST_Relate(:p1,:p2,:p3)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1674,17 +1170,13 @@ public override bool Relate(DbGeometry geometryValue, DbGeometry otherGeometry, /// /// Returns true if the given geometries represent the same geometry. Directionality is ignored. /// - /// - /// - /// public override bool SpatialEquals(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_equals(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Equals(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1696,30 +1188,21 @@ public override bool SpatialEquals(DbGeometry geometryValue, DbGeometry otherGeo /// /// Returns true if the given geometries represent the same geometry. Directionality is ignored. /// - /// - /// - /// public override bool SpatialEquals(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// - /// Returns a geometry that represents the portions of A and B that do not intersect. + /// Returns a geometry that represents the portions of A and B that do not intersect. /// It is called a symmetric difference because ST_SymDifference(A,B) = ST_SymDifference(B,A). /// - /// - /// - /// public override DbGeometry SymmetricDifference(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_symdifference(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_SymDifference(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } @@ -1727,28 +1210,19 @@ public override DbGeometry SymmetricDifference(DbGeometry geometryValue, DbGeome /// Returns a geometry that represents the portions of A and B that do not intersect. /// It is called a symmetric difference because ST_SymDifference(A,B) = ST_SymDifference(B,A). /// - /// - /// - /// public override DbGeography SymmetricDifference(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns TRUE if the geometries have at least one point in common, but their interiors do not intersect. /// - /// - /// - /// public override bool Touches(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_touches(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Touches(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1760,46 +1234,33 @@ public override bool Touches(DbGeometry geometryValue, DbGeometry otherGeometry) /// /// Returns a geometry that represents the point set union of the Geometries. /// - /// - /// - /// public override DbGeometry Union(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_union(:p1,:p2)"; - return DbSpatialServices.CreateGeometry(this, cmd.ExecuteScalar()); + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Union(:p1,:p2)"; + return CreateGeometry(this, cmd.ExecuteScalar()); } } /// /// Returns a geometry that represents the point set union of the Geometries. /// - /// - /// - /// public override DbGeography Union(DbGeography geographyValue, DbGeography otherGeography) - { - throw new NotImplementedException(); - } + => throw new NotImplementedException(); /// /// Returns true if the geometry A is completely inside geometry B /// - /// - /// - /// public override bool Within(DbGeometry geometryValue, DbGeometry otherGeometry) { using (var cmd = _connection.CreateCommand()) { - cmd.Parameters.AddWithValue("p1", NpgsqlTypes.NpgsqlDbType.Geometry, geometryValue.ProviderValue); - cmd.Parameters.AddWithValue("p2", NpgsqlTypes.NpgsqlDbType.Geometry, otherGeometry.ProviderValue); - cmd.CommandText = - "SELECT st_within(:p1,:p2)"; + cmd.Parameters.AddWithValue("p1", NpgsqlDbType.Geometry, geometryValue.ProviderValue); + cmd.Parameters.AddWithValue("p2", NpgsqlDbType.Geometry, otherGeometry.ProviderValue); + cmd.CommandText = "SELECT ST_Within(:p1,:p2)"; using (var rdr = cmd.ExecuteReader()) { rdr.Read(); @@ -1808,13 +1269,13 @@ public override bool Within(DbGeometry geometryValue, DbGeometry otherGeometry) } } - private NpgsqlConnection _connection; + NpgsqlConnection _connection; /// /// Set the provider connection /// /// - public void SetConnection(Npgsql.NpgsqlConnection c) + public void SetConnection(NpgsqlConnection c) { _connection = c; } From d0a5ccc7e179f0fd0090e5ccf30fb6fe39efe44c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 19:18:37 +0100 Subject: [PATCH 27/60] Depend on EF 6.2.0 --- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index ce61dab..8a09d76 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -40,6 +40,6 @@ - + From 9722eaba5175c00be94f6ab2512d998d43a830c3 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 19:24:03 +0100 Subject: [PATCH 28/60] Update NUnit, set up cmdline testing --- .../EntityFramework6.Npgsql.Tests.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 6dce1a5..fc596ae 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -7,7 +7,9 @@ - + + + From 2d783a950d17bdb3558c3da5645767285cde9c8e Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sat, 7 Jul 2018 19:55:35 +0100 Subject: [PATCH 29/60] Depend on Npgsql 4.0.2 --- .../EntityFramework6.Npgsql.csproj | 2 +- src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs | 2 +- test/EntityFramework6.Npgsql.Tests/App.config | 8 ++++++++ .../EntityFramework6.Npgsql.Tests.csproj | 1 + .../Spatial/PostgisServiceTests.cs | 3 ++- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index 8a09d76..b0bb8ff 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -39,7 +39,7 @@ - + diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index 5eb788d..a6d4350 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -79,7 +79,7 @@ internal static NpgsqlDbType GetNpgsqlDbType(PrimitiveTypeKind primitiveType) case PrimitiveTypeKind.DateTime: return NpgsqlDbType.Timestamp; case PrimitiveTypeKind.DateTimeOffset: - return NpgsqlDbType.TimestampTZ; + return NpgsqlDbType.TimestampTz; case PrimitiveTypeKind.Decimal: return NpgsqlDbType.Numeric; case PrimitiveTypeKind.Double: diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/test/EntityFramework6.Npgsql.Tests/App.config index 119bb22..931aca8 100644 --- a/test/EntityFramework6.Npgsql.Tests/App.config +++ b/test/EntityFramework6.Npgsql.Tests/App.config @@ -25,4 +25,12 @@ + + + + + + + + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index fc596ae..de91a6a 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -11,5 +11,6 @@ + diff --git a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs index 0783539..e4fa6bc 100644 --- a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs @@ -1,7 +1,7 @@ using System; using Npgsql; +using Npgsql.LegacyPostgis; using Npgsql.Spatial; -using NpgsqlTypes; using NUnit.Framework; // ReSharper disable RedundantExplicitArrayCreation @@ -1321,6 +1321,7 @@ PostgisServices CreatePostgisServices() using (var conn = new NpgsqlConnection(ConnectionString)) { + NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); conn.Open(); using (var cmd = new NpgsqlCommand("CREATE EXTENSION IF NOT EXISTS postgis", conn)) cmd.ExecuteNonQuery(); From 3a4c675654fc60fe31155b7bbc38e9a4934a35a3 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Sun, 8 Jul 2018 16:56:33 +0100 Subject: [PATCH 30/60] Remove old TeamCity config --- .../EntityFramework6Npgsql_Build.xml | 137 ------------------ .../pluginData/plugin-settings.xml | 5 - .../EntityFramework6Npgsql/project-config.xml | 10 -- .../EntityFramework6Npgsql_Github.xml | 19 --- 4 files changed, 171 deletions(-) delete mode 100644 .teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml delete mode 100644 .teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml delete mode 100644 .teamcity/EntityFramework6Npgsql/project-config.xml delete mode 100644 .teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml diff --git a/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml b/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml deleted file mode 100644 index 3ae11b0..0000000 --- a/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - Build - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml b/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml deleted file mode 100644 index 784b770..0000000 --- a/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.teamcity/EntityFramework6Npgsql/project-config.xml b/.teamcity/EntityFramework6Npgsql/project-config.xml deleted file mode 100644 index 6c2ccfb..0000000 --- a/.teamcity/EntityFramework6Npgsql/project-config.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - EntityFramework6.Npgsql - Entity Framework 6/5 for PostgreSQL - - - - - - diff --git a/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml b/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml deleted file mode 100644 index 7c55983..0000000 --- a/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - https://github.com/npgsql/EntityFramework6.Npgsql.git - - - - - - - - - - - - - - From 08e00f11d535a45d5279e0ff73b1526534df049f Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 9 Jul 2018 16:37:10 +1200 Subject: [PATCH 31/60] added documentation paragraph. --- doc/index.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/index.md b/doc/index.md index 0a73365..bf228b7 100644 --- a/doc/index.md +++ b/doc/index.md @@ -6,6 +6,21 @@ title: Entity Framework 6 Npgsql has an Entity Framework 6 provider. You can use it by installing the [EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget. +## Basic Usage ## +Create an inheritor if DbConfiguration in the same assembly as your entity framework DbContext. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: + +``` +class NpgSqlConfiguration : DbConfiguration +{ + public NpgSqlConfiguration() + { + SetProviderFactory("Npgsql", NpgsqlFactory.Instance); + SetProviderServices("Npgsql", provider: NpgsqlServices.Instance); + SetDefaultConnectionFactory(new NpgsqlConnectionFactory()); + } +} +``` + ## Guid Support ## Npgsql EF migrations support uses `uuid_generate_v4()` function to generate guids. From a2a6ba979acf7f2944e3e591290eaf8a0d3912d1 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 9 Jul 2018 16:41:07 +1200 Subject: [PATCH 32/60] fixed spelling mistake --- doc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.md b/doc/index.md index bf228b7..d2cee0b 100644 --- a/doc/index.md +++ b/doc/index.md @@ -7,7 +7,7 @@ Npgsql has an Entity Framework 6 provider. You can use it by installing the [EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget. ## Basic Usage ## -Create an inheritor if DbConfiguration in the same assembly as your entity framework DbContext. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: +Create an inheritor of DbConfiguration in the same assembly as your entity framework DbContext. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: ``` class NpgSqlConfiguration : DbConfiguration From 374c357e0f53649243e29eb908a52ed75b8f6f4b Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 10 Jul 2018 21:41:07 +1200 Subject: [PATCH 33/60] refactored based on review + renamed title. + rephrased sentence. + added csharp snippet styling. + added line snippets to classes. + included namespaces required. --- doc/index.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/index.md b/doc/index.md index d2cee0b..21a7e4e 100644 --- a/doc/index.md +++ b/doc/index.md @@ -6,10 +6,13 @@ title: Entity Framework 6 Npgsql has an Entity Framework 6 provider. You can use it by installing the [EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget. -## Basic Usage ## -Create an inheritor of DbConfiguration in the same assembly as your entity framework DbContext. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: +## Basic Configuration ## +To use Entity Framework with Npgsql, define a class that inherits from `DbConfiguration` in the same assembly as your class inheriting `DbContext`. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: + +```csharp +using Npgsql; +using System.Data.Entity; -``` class NpgSqlConfiguration : DbConfiguration { public NpgSqlConfiguration() From b00d1533e64d5045a7e0875925f4f3cffe6ed10e Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 10 Jul 2018 21:49:10 +1200 Subject: [PATCH 34/60] added named parameters --- doc/index.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/index.md b/doc/index.md index 21a7e4e..1dd3137 100644 --- a/doc/index.md +++ b/doc/index.md @@ -17,9 +17,15 @@ class NpgSqlConfiguration : DbConfiguration { public NpgSqlConfiguration() { - SetProviderFactory("Npgsql", NpgsqlFactory.Instance); - SetProviderServices("Npgsql", provider: NpgsqlServices.Instance); - SetDefaultConnectionFactory(new NpgsqlConnectionFactory()); + var name = "Npgsql"; + + SetProviderFactory(providerInvariantName: name, + providerFactory: NpgsqlFactory.Instance); + + SetProviderServices(providerInvariantName: name, + provider: NpgsqlServices.Instance); + + SetDefaultConnectionFactory(connectionFactory: new NpgsqlConnectionFactory()); } } ``` From 428fb5dd22b00d767d361113b5bda8e5c2aeb669 Mon Sep 17 00:00:00 2001 From: rwasef1830 Date: Tue, 16 Apr 2019 21:10:51 +0200 Subject: [PATCH 35/60] Convert enum values to workaround Npgsql > 4.0 strict type checking. Fixes https://github.com/npgsql/EntityFramework6.Npgsql/issues/105 --- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 21 ++++++ .../EntityFrameworkBasicTests.cs | 65 +++++++++++++++++++ .../Support/EntityFrameworkTestBase.cs | 53 +++++++++++++++ 3 files changed, 139 insertions(+) diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index a7f1abd..70db12f 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -32,6 +32,7 @@ using Npgsql.SqlGenerators; using DbConnection = System.Data.Common.DbConnection; using DbCommand = System.Data.Common.DbCommand; +using System.Data.Common; #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member @@ -73,6 +74,26 @@ internal DbCommand CreateDbCommand(Version serverVersion, DbCommandTree commandT return command; } + protected override void SetDbParameterValue(DbParameter parameter, TypeUsage parameterType, object value) + { + base.SetDbParameterValue(parameter, parameterType, value); + ConvertValueToNumericIfEnum(parameter); + } + + // Npgsql > 4.0 does strict type checks on integral values and fails with enums passed with numeric DbType. + static void ConvertValueToNumericIfEnum(DbParameter parameter) + { + var parameterValueObjectType = parameter.Value.GetType(); + + if (!parameterValueObjectType.IsEnum) + { + return; + } + + var underlyingType = Enum.GetUnderlyingType(parameterValueObjectType); + parameter.Value = Convert.ChangeType(parameter.Value, underlyingType); + } + internal void TranslateCommandTree(Version serverVersion, DbCommandTree commandTree, DbCommand command, bool createParametersForNonSelect = true) { SqlBaseGenerator sqlGenerator; diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index cc7d85f..2dc1ff4 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -847,5 +847,70 @@ public void Test_string_multiple_null_propagation() query.ToString()); } } + + [Test] + public void Test_enum() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.ClrEnumEntities.Add( + new ClrEnumEntity + { + TestByte = TestByteEnum.Bar, + TestShort = TestShortEnum.Bar, + TestInt = TestIntEnum.Bar, + TestLong = TestLongEnum.Bar + }); + context.SaveChanges(); + + var query = context.ClrEnumEntities.Where( + x => x.TestByte == TestByteEnum.Bar + && x.TestShort == TestShortEnum.Bar + && x.TestInt == TestIntEnum.Bar + && x.TestLong == TestLongEnum.Bar); + + var result = query.First(); + Assert.That(result.TestByte, Is.EqualTo(TestByteEnum.Bar)); + Assert.That(result.TestShort, Is.EqualTo(TestShortEnum.Bar)); + Assert.That(result.TestInt, Is.EqualTo(TestIntEnum.Bar)); + Assert.That(result.TestLong, Is.EqualTo(TestLongEnum.Bar)); + } + } + + [Test] + public void Test_enum_composite_key() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.ClrEnumCompositeKeyEntities.Add( + new ClrEnumCompositeKeyEntity + { + TestByte = TestByteEnum.Bar, + TestShort = TestShortEnum.Bar, + TestInt = TestIntEnum.Bar, + TestLong = TestLongEnum.Bar + }); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionString)) + { + var result = context.ClrEnumCompositeKeyEntities.Find( + TestByteEnum.Bar, + TestShortEnum.Bar, + TestIntEnum.Bar, + TestLongEnum.Bar); + + Assert.That(result, Is.Not.Null); + Assert.That(result.TestByte, Is.EqualTo(TestByteEnum.Bar)); + Assert.That(result.TestShort, Is.EqualTo(TestShortEnum.Bar)); + Assert.That(result.TestInt, Is.EqualTo(TestIntEnum.Bar)); + Assert.That(result.TestLong, Is.EqualTo(TestLongEnum.Bar)); + } + } } } diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index d00f6ca..e7e980b 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -25,6 +25,7 @@ using NUnit.Framework; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Data.Common; using System.Data.Entity; using System.Linq; @@ -102,6 +103,54 @@ public class Post public virtual Blog Blog { get; set; } } + public class ClrEnumEntity + { + public int Id { get; set; } + public TestByteEnum TestByte { get; set; } + public TestShortEnum TestShort { get; set; } + public TestIntEnum TestInt { get; set; } + public TestLongEnum TestLong { get; set; } + } + + public class ClrEnumCompositeKeyEntity + { + [Key, Column(Order = 1)] + public TestByteEnum TestByte { get; set; } + + [Key, Column(Order = 2)] + public TestShortEnum TestShort { get; set; } + + [Key, Column(Order = 3)] + public TestIntEnum TestInt { get; set; } + + [Key, Column(Order = 4)] + public TestLongEnum TestLong { get; set; } + } + + public enum TestByteEnum : byte + { + Foo = 0, + Bar = 1 + } + + public enum TestShortEnum : short + { + Foo = 0, + Bar = 1 + } + + public enum TestIntEnum + { + Foo = 0, + Bar = 1 + } + + public enum TestLongEnum : long + { + Foo = 0, + Bar = 1 + } + public class NoColumnsEntity { public int Id { get; set; } @@ -131,6 +180,8 @@ public BloggingContext(string connection) public DbSet Blogs { get; set; } public DbSet Posts { get; set; } public DbSet NoColumnsEntities { get; set; } + public DbSet ClrEnumEntities { get; set; } + public DbSet ClrEnumCompositeKeyEntities { get; set; } public DbSet Users { get; set; } public DbSet Editors { get; set; } public DbSet Administrators { get; set; } @@ -164,6 +215,8 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) dbModelBuilder.Entity(); dbModelBuilder.Entity(); dbModelBuilder.Entity(); + dbModelBuilder.Entity(); + dbModelBuilder.Entity(); dbModelBuilder.Entity(); dbModelBuilder.Entity(); dbModelBuilder.Entity(); From f58b06857997636734464f2599995983902b297f Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 14:57:38 +0200 Subject: [PATCH 36/60] Update copyright to 2019 --- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index b0bb8ff..72a972e 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -2,7 +2,7 @@ PostgreSQL provider for Entity Framework 6 Shay Rojansky;Emil Lenngren;Francisco Figueiredo Jr.;Kenji Uno - Copyright 2018 © The Npgsql Development Team + Copyright 2019 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm 3.2.0 From 0a804a8e0d81308242f424892c474e9618db8c85 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 15:00:31 +0200 Subject: [PATCH 37/60] Depend on .NET Framework targeting pack nugets Depend on .NET Framework reference assemblies via the new nuget packages. This allows us to build .NET Framework on systems where .NET Framework isn't installed (e.g. Linux). --- Directory.Build.props | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..f1d9f98 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + + + + From 17ed69a6d364187f0172cbe47a89325a5728413c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 15:06:09 +0200 Subject: [PATCH 38/60] Remove license header from source files --- .../NpgsqlConnectionFactory.cs | 25 +-------------- .../NpgsqlMigrationSqlGenerator.cs | 27 ++-------------- .../NpgsqlProviderManifest.cs | 25 +-------------- src/EntityFramework6.Npgsql/NpgsqlServices.cs | 25 +-------------- .../SqlGenerators/PendingProjectsNode.cs | 25 +-------------- .../SqlGenerators/SqlBaseGenerator.cs | 25 +-------------- .../SqlGenerators/SqlDeleteGenerator.cs | 25 +-------------- .../SqlGenerators/SqlInsertGenerator.cs | 25 +-------------- .../SqlGenerators/SqlSelectGenerator.cs | 25 +-------------- .../SqlGenerators/SqlUpdateGenerator.cs | 25 +-------------- .../SqlGenerators/StringPair.cs | 25 +-------------- .../SqlGenerators/VisitedExpression.cs | 25 +-------------- .../EntityFrameworkBasicTests.cs | 27 ++-------------- .../EntityFrameworkMigrationTests.cs | 27 ++-------------- .../FullTextSearchTests.cs | 25 +-------------- .../NLogLoggingProvider.cs | 25 +-------------- .../PatternMatchingTests.cs | 25 +-------------- .../Support/EntityFrameworkTestBase.cs | 31 +++---------------- .../Support/TestBase.cs | 25 +-------------- .../Support/TestUtil.cs | 25 +-------------- 20 files changed, 26 insertions(+), 486 deletions(-) diff --git a/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs b/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs index 926d39c..1d5e499 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System.Data.Common; +using System.Data.Common; using System.Data.Entity.Infrastructure; namespace Npgsql diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs index cf8f413..c3f26e0 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Data.Entity.Migrations.Model; using System.Data.Entity.Migrations.Sql; @@ -436,7 +413,7 @@ protected virtual void Convert(RenameIndexOperation renameIndexOperation) string GetSchemaNameFromFullTableName(string tableFullName) { var dotIndex = tableFullName.IndexOf('.'); - return dotIndex != -1 ? tableFullName.Remove(dotIndex) : "dto"; + return dotIndex != -1 ? tableFullName.Remove(dotIndex) : "dto"; //TODO: Check always setting dto schema if no schema in table name is not bug } diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs index a6d4350..a76542a 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Core.Common; diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs index 70db12f..0a0351d 100644 --- a/src/EntityFramework6.Npgsql/NpgsqlServices.cs +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Text; using JetBrains.Annotations; using System.Data.Entity.Core.Common; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs index 646fba6..346a1e6 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System.Collections.Generic; +using System.Collections.Generic; namespace Npgsql.SqlGenerators { diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index c2247fc..b36413a 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs index 0766ac0..a24eb92 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Data.Common; using System.Data.Entity.Core.Common.CommandTrees; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs index 0e0fe5a..856a31a 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Entity.Core.Common.CommandTrees; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs index 22d22e6..ed2616a 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Linq; using System.Data.Common; using System.Diagnostics; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs index fde7c7a..acf3fb3 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Data.Common; using System.Data.Entity.Core.Common.CommandTrees; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs b/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs index c605574..72d2512 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs index 2621c74..b952deb 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 2dc1ff4..4e89635 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using Npgsql; +using Npgsql; using NUnit.Framework; using System; using System.Collections.Generic; @@ -898,7 +875,7 @@ public void Test_enum_composite_key() } using (var context = new BloggingContext(ConnectionString)) - { + { var result = context.ClrEnumCompositeKeyEntities.Find( TestByteEnum.Bar, TestShortEnum.Bar, diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs index dccc6fd..3fde9fb 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using Npgsql; +using Npgsql; using NUnit.Framework; using System; using System.Collections.Generic; @@ -491,7 +468,7 @@ public void RenameIndexOperation() } else { - Assert.AreEqual("ALTER INDEX someSchema.\"someOldIndexName\" RENAME TO \"someNewIndexName\"", statements.ElementAt(0).Sql); + Assert.AreEqual("ALTER INDEX someSchema.\"someOldIndexName\" RENAME TO \"someNewIndexName\"", statements.ElementAt(0).Sql); } } diff --git a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs index 101e8b3..6d81f43 100644 --- a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using Npgsql; +using Npgsql; using NUnit.Framework; using System; using System.Collections.Generic; diff --git a/test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs b/test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs index e8940e9..509a7f3 100644 --- a/test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs +++ b/test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using NLog; using Npgsql.Logging; diff --git a/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs b/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs index 6260b90..6f83d75 100644 --- a/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using Npgsql; +using Npgsql; using NUnit.Framework; using System; using System.Collections.Generic; diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index e7e980b..d07af64 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using Npgsql; +using Npgsql; using NUnit.Framework; using System; using System.Collections.Generic; @@ -202,7 +179,7 @@ public static int StoredEchoFunction(int value) public IQueryable GetBlogsByName(string name) { ObjectParameter nameParameter = new ObjectParameter("Name", name); - + return ((IObjectContextAdapter)this).ObjectContext.CreateQuery( $"[GetBlogsByName](@Name)", nameParameter); } @@ -337,7 +314,7 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) { IsFunctionImport = true, IsComposable = true, - Parameters = new[] + Parameters = new[] { FunctionParameter.Create("Name", stringPrimitiveType, ParameterMode.In) }, @@ -345,7 +322,7 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) { FunctionParameter.Create("ReturnType1", modelBlogConceptualType.GetCollectionType(), ParameterMode.ReturnValue) }, - EntitySets = new[] + EntitySets = new[] { dbModel.ConceptualModel.Container.EntitySets.First(x => x.ElementType == modelBlogConceptualType) } diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs index d11f508..0ccad6d 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using NLog.Config; using NLog.Targets; using NLog; diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs index b34eeab..5b46519 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs @@ -1,27 +1,4 @@ -#region License -// The PostgreSQL License -// -// Copyright (C) 2016 The Npgsql Development Team -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose, without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph and the following two paragraphs appear in all copies. -// -// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY -// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -// -// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS -// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -#endregion - -using System; +using System; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; From b0e726420c766021bd95a53a5197683c21bbf776 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 16:37:28 +0200 Subject: [PATCH 39/60] Add .idea to .gitignore --- .gitignore | 1 + EntityFramework6.Npgsql.sln.DotSettings | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index adc05e9..f10af03 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.sln.docstates *.userprefs /*.nupkg +.idea/ .nuget/ [Bb]in/ [Bb]uild/ diff --git a/EntityFramework6.Npgsql.sln.DotSettings b/EntityFramework6.Npgsql.sln.DotSettings index 78c61b1..5dfab15 100644 --- a/EntityFramework6.Npgsql.sln.DotSettings +++ b/EntityFramework6.Npgsql.sln.DotSettings @@ -58,6 +58,7 @@ True True True + True True True True From 76215722c6b4fc476f27cac596e4452a49949169 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 15:17:37 +0200 Subject: [PATCH 40/60] Depend on Npgsql 4.0.7 --- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj | 2 +- test/EntityFramework6.Npgsql.Tests/App.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index 72a972e..e580ee0 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -39,7 +39,7 @@ - + diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/test/EntityFramework6.Npgsql.Tests/App.config index 931aca8..3bd6d0b 100644 --- a/test/EntityFramework6.Npgsql.Tests/App.config +++ b/test/EntityFramework6.Npgsql.Tests/App.config @@ -29,7 +29,7 @@ - + From ce97536e81efff78ed71992024a9039195c35beb Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 15:21:47 +0200 Subject: [PATCH 41/60] Update test dependencies --- .../EntityFramework6.Npgsql.Tests.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index de91a6a..12e4322 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -7,10 +7,10 @@ - - - - - + + + + + From 90417e143ef46c6960db147fe6f5c015f994b9b4 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Tue, 21 May 2019 09:21:40 +0200 Subject: [PATCH 42/60] Switch to PackageLicenseExpression in nuget --- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index e580ee0..260303c 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -18,7 +18,7 @@ true http://www.npgsql.org http://www.npgsql.org/img/postgresql.gif - https://raw.githubusercontent.com/npgsql/npgsql/master/LICENSE.txt + PostgreSQL git git://github.com/npgsql/EntityFramework6.Npgsql true From 02b5793327b6275f7c9544efd30c5d17704ae5d9 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 20 May 2019 15:12:26 +0200 Subject: [PATCH 43/60] Target .NET Standard 2.1, update version * Version is now 3.3.0 * Take dependency on EntityFramework 6.3.0-preview5-19254-05 * All tests pass * Remove unneeded implicit assembly references for net45 Closes #119 --- Directory.Build.props | 4 +++ .../EntityFramework6.Npgsql.csproj | 8 ++--- .../EntityFramework6.Npgsql.Tests.csproj | 3 +- .../EntityFrameworkBasicTests.cs | 8 ++--- .../Support/AssemblySetup.cs | 30 +++++++++++++++++++ .../Support/TestBase.cs | 21 ------------- .../Support/TestDbConfiguration.cs | 15 ++++++++++ 7 files changed, 59 insertions(+), 30 deletions(-) create mode 100644 test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs diff --git a/Directory.Build.props b/Directory.Build.props index f1d9f98..d53ede3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,9 @@  + + true + + diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index 260303c..471878e 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -5,9 +5,9 @@ Copyright 2019 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm - 3.2.0 + 6.3.0 latest - net45 + net45;netstandard21 true CS1591 true @@ -29,7 +29,7 @@ - + @@ -40,6 +40,6 @@ - + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj index 12e4322..5c8d4cf 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -1,12 +1,13 @@  latest - net45 + net45;netcoreapp3.0 + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 4e89635..180fb08 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -17,7 +17,7 @@ namespace EntityFramework6.Npgsql.Tests { public class EntityFrameworkBasicTests : EntityFrameworkTestBase { - [Test] + [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/860")] public void InsertAndSelect() { var varbitVal = "10011"; @@ -457,7 +457,7 @@ public void DateFunctions() //Hunting season is open Happy hunting on OrderBy,GroupBy,Min,Max,Skip,Take,ThenBy... and all posible combinations - [Test] + [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] public void TestComplicatedQueries() { using (var context = new BloggingContext(ConnectionString)) @@ -517,7 +517,7 @@ public void TestComplicatedQueries() } } - [Test] + [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] [MonoIgnore("Probably bug in mono. See https://github.com/npgsql/Npgsql/issues/289.")] public void TestComplicatedQueriesMonoFails() { @@ -541,7 +541,7 @@ public void TestComplicatedQueriesMonoFails() } } - [Test] + [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] public void TestComplicatedQueriesWithApply() { using (var conn = OpenConnection(ConnectionString)) diff --git a/test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs b/test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs new file mode 100644 index 0000000..e503497 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs @@ -0,0 +1,30 @@ +using System.Data.Entity; +using NLog.Config; +using NLog.Targets; +using NUnit.Framework; +using Npgsql.Logging; +using EntityFramework6.Npgsql.Tests; +using EntityFramework6.Npgsql.Tests.Support; + +// ReSharper disable CheckNamespace + +[SetUpFixture] +public class AssemblySetup +{ + [OneTimeSetUp] + public void RegisterDbProvider() + { + var config = new LoggingConfiguration(); + var consoleTarget = new ConsoleTarget(); + consoleTarget.Layout = @"${message} ${exception:format=tostring}"; + config.AddTarget("console", consoleTarget); + var rule = new LoggingRule("*", NLog.LogLevel.Info, consoleTarget); + config.LoggingRules.Add(rule); + NLog.LogManager.Configuration = config; + + NpgsqlLogManager.Provider = new NLogLoggingProvider(); + NpgsqlLogManager.IsParameterLoggingEnabled = true; + + DbConfiguration.SetConfiguration(new TestDbConfiguration()); + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs index 0ccad6d..cf23265 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs @@ -23,8 +23,6 @@ public abstract class TestBase string _connectionString; - static bool _loggingSetUp; - /// /// Unless the NPGSQL_TEST_DB environment variable is defined, this is used as the connection string for the /// test database. @@ -36,28 +34,9 @@ public abstract class TestBase [OneTimeSetUp] public virtual void TestFixtureSetup() { - SetupLogging(); _log.Debug("Connection string is: " + ConnectionString); } - protected virtual void SetupLogging() - { - var config = new LoggingConfiguration(); - var consoleTarget = new ConsoleTarget(); - consoleTarget.Layout = @"${message} ${exception:format=tostring}"; - config.AddTarget("console", consoleTarget); - var rule = new LoggingRule("*", NLog.LogLevel.Debug, consoleTarget); - config.LoggingRules.Add(rule); - NLog.LogManager.Configuration = config; - - if (!_loggingSetUp) - { - NpgsqlLogManager.Provider = new NLogLoggingProvider(); - NpgsqlLogManager.IsParameterLoggingEnabled = true; - _loggingSetUp = true; - } - } - #endregion #region Utilities for use by tests diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs new file mode 100644 index 0000000..2276bed --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs @@ -0,0 +1,15 @@ +using System; +using System.Data.Entity; +using Npgsql; + +namespace EntityFramework6.Npgsql.Tests.Support +{ + public class TestDbConfiguration : DbConfiguration + { + public TestDbConfiguration() + { + SetProviderFactory("Npgsql", NpgsqlFactory.Instance); + SetProviderServices("Npgsql", NpgsqlServices.Instance); + } + } +} From 8180248c62fec3214727f4d9bc9d0a4b638edfbe Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 26 Sep 2019 15:50:45 +0200 Subject: [PATCH 44/60] Remove conceptual docs See https://github.com/npgsql/doc/issues/10 --- doc/index.md | 116 --------------------------------------------------- doc/toc.md | 1 - 2 files changed, 117 deletions(-) delete mode 100644 doc/index.md delete mode 100644 doc/toc.md diff --git a/doc/index.md b/doc/index.md deleted file mode 100644 index 1dd3137..0000000 --- a/doc/index.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -layout: doc -title: Entity Framework 6 ---- - -Npgsql has an Entity Framework 6 provider. You can use it by installing the -[EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget. - -## Basic Configuration ## -To use Entity Framework with Npgsql, define a class that inherits from `DbConfiguration` in the same assembly as your class inheriting `DbContext`. Ensure that you configure provider services, a provider factory, a default connection factory as shown below: - -```csharp -using Npgsql; -using System.Data.Entity; - -class NpgSqlConfiguration : DbConfiguration -{ - public NpgSqlConfiguration() - { - var name = "Npgsql"; - - SetProviderFactory(providerInvariantName: name, - providerFactory: NpgsqlFactory.Instance); - - SetProviderServices(providerInvariantName: name, - provider: NpgsqlServices.Instance); - - SetDefaultConnectionFactory(connectionFactory: new NpgsqlConnectionFactory()); - } -} -``` - -## Guid Support ## - -Npgsql EF migrations support uses `uuid_generate_v4()` function to generate guids. -In order to have access to this function, you have to install the extension uuid-ossp through the following command: - -```sql -create extension "uuid-ossp"; -``` - -If you don't have this extension installed, when you run Npgsql migrations you will get the following error message: - -``` -ERROR: function uuid_generate_v4() does not exist -``` - -If the database is being created by Npgsql Migrations, you will need to -[run the `create extension` command in the `template1` database](http://stackoverflow.com/a/11584751). -This way, when the new database is created, the extension will be installed already. - -## Template Database ## - -When the Entity Framework 6 provider creates a database, it issues a simple `CREATE DATABASE` command. -In PostgreSQL, this implicitly uses `template1` as the template - anything existing in `template1` will -be copied to your new database. If you wish to change the database used as a template, you can specify -the `EF Template Database` connection string parameter. For more info see the -[PostgreSQL docs](https://www.postgresql.org/docs/current/static/sql-createdatabase.html). - -## Customizing DataReader Behavior ## - -You can use [an Entity Framework 6 IDbCommandInterceptor](https://msdn.microsoft.com/en-us/library/dn469464(v=vs.113).aspx) to wrap the `DataReader` instance returned by Npgsql when Entity Framework executes queries. This is possible using a ```DbConfiguration``` class. - -Example use cases: -- Forcing all returned ```DateTime``` and ```DateTimeOffset``` values to be in the UTC timezone. -- Preventing accidental insertion of DateTime values having ```DateTimeKind.Unspecified```. -- Forcing all postgres date/time types to be returned to Entity Framework as ```DateTimeOffset```. - -```c# -[DbConfigurationType(typeof(AppDbContextConfiguration))] -public class AppDbContext : DbContext -{ - // ... -} - -public class AppDbContextConfiguration : DbConfiguration -{ - public AppDbContextConfiguration() - { - this.AddInterceptor(new MyEntityFrameworkInterceptor()); - } -} - -class MyEntityFrameworkInterceptor : DbCommandInterceptor -{ - public override void ReaderExecuted( - DbCommand command, - DbCommandInterceptionContext interceptionContext) - { - if (interceptionContext.Result == null) return; - interceptionContext.Result = new WrappingDbDataReader(interceptionContext.Result); - } - - public override void ScalarExecuted( - DbCommand command, - DbCommandInterceptionContext interceptionContext) - { - interceptionContext.Result = ModifyReturnValues(interceptionContext.Result); - } - - static object ModifyReturnValues(object result) - { - // Transform and then - return result; - } -} - -class WrappingDbDataReader : DbDataReader, IDataReader -{ - // Wrap an existing DbDataReader, proxy all calls to the underlying instance, - // modify return values and/or parameters as needed... - public WrappingDbDataReader(DbDataReader reader) - { - } -} -``` diff --git a/doc/toc.md b/doc/toc.md deleted file mode 100644 index 0d45642..0000000 --- a/doc/toc.md +++ /dev/null @@ -1 +0,0 @@ -# [Getting Started](index.md) From d3023711263b6ba7b9df405985c3e06062ff7ed7 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 10 Oct 2019 04:26:59 +0200 Subject: [PATCH 45/60] Update to version 6.3.0 * Take dependency on EF6 6.3.0 GA * Take dependency on Npgsql 4.0.10. Also tested successfully with 4.1.1, but not taking dependency in order to preserve compatibility with .NET Framework 4.5. * Package snupkg * Nuget icon * Use transforms instead of Add-EFProvider (in install.ps1). See https://github.com/aspnet/EntityFramework6/pull/953 * Various build cleanups, project renames, etc. Closes #137 --- Directory.Build.props | 5 +++-- Directory.Build.targets | 12 +++++++++++ .../App.config | 2 +- EF6.PG.Tests/EF6.PG.Tests.csproj | 19 ++++++++++++++++++ .../EntityFrameworkBasicTests.cs | 8 ++++---- .../EntityFrameworkMigrationTests.cs | 0 .../FullTextSearchTests.cs | 0 .../NLogLoggingProvider.cs | 0 .../PatternMatchingTests.cs | 0 .../Spatial/PostgisServiceTests.cs | 0 .../Support/AssemblySetup.cs | 0 .../Support/CodeAnnotations.cs | 0 .../Support/EntityFrameworkTestBase.cs | 0 .../Support/TestBase.cs | 0 .../Support/TestDbConfiguration.cs | 0 .../Support/TestUtil.cs | 0 .../xmlModel/XmlTest.ObjectLayer.EF6.cs | 0 .../xmlModel/XmlTest.ObjectLayer.cs | 0 .../xmlModel/XmlTest.csdl | 0 .../xmlModel/XmlTest.msl | 0 .../xmlModel/XmlTest.ssdl | 0 .../App.config | 0 .../EF6.PG.csproj | 17 ++++++++++------ .../NpgsqlConnectionFactory.cs | 0 .../NpgsqlMigrationSqlGenerator.cs | 0 .../NpgsqlProviderManifest.cs | 0 .../NpgsqlRankingNormalization.cs | 0 .../NpgsqlServices.cs | 0 .../NpgsqlTextFunctions.cs | 0 .../NpgsqlTypeFunctions.cs | 0 .../NpgsqlWeightLabel.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../NpgsqlProviderManifest.Manifest.xml | 0 .../Resources/NpgsqlSchema.msl | 0 .../Resources/NpgsqlSchema.ssdl | 0 .../Resources/NpgsqlSchemaV3.ssdl | 0 .../Spatial/PostgisDataReader.cs | 0 .../Spatial/PostgisServices.cs | 0 .../SqlGenerators/PendingProjectsNode.cs | 0 .../SqlGenerators/SqlBaseGenerator.cs | 0 .../SqlGenerators/SqlDeleteGenerator.cs | 0 .../SqlGenerators/SqlInsertGenerator.cs | 0 .../SqlGenerators/SqlSelectGenerator.cs | 0 .../SqlGenerators/SqlUpdateGenerator.cs | 0 .../SqlGenerators/StringPair.cs | 0 .../SqlGenerators/VisitedExpression.cs | 0 EF6.PG/content/App.config.install.xdt | 9 +++++++++ EF6.PG/content/App.config.transform | 11 ++++++++++ EF6.PG/content/Web.config.install.xdt | 9 +++++++++ EF6.PG/content/Web.config.transform | 11 ++++++++++ EF6.PG/postgresql.png | Bin 0 -> 9675 bytes EntityFramework6.Npgsql.sln | 10 ++++----- src/EntityFramework6.Npgsql/install.ps1 | 3 --- .../EntityFramework6.Npgsql.Tests.csproj | 17 ---------------- 54 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 Directory.Build.targets rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/App.config (95%) create mode 100644 EF6.PG.Tests/EF6.PG.Tests.csproj rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/EntityFrameworkBasicTests.cs (99%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/EntityFrameworkMigrationTests.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/FullTextSearchTests.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/NLogLoggingProvider.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/PatternMatchingTests.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Spatial/PostgisServiceTests.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/AssemblySetup.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/CodeAnnotations.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/EntityFrameworkTestBase.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/TestBase.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/TestDbConfiguration.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/Support/TestUtil.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/xmlModel/XmlTest.ObjectLayer.EF6.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/xmlModel/XmlTest.ObjectLayer.cs (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/xmlModel/XmlTest.csdl (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/xmlModel/XmlTest.msl (100%) rename {test/EntityFramework6.Npgsql.Tests => EF6.PG.Tests}/xmlModel/XmlTest.ssdl (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/App.config (100%) rename src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj => EF6.PG/EF6.PG.csproj (67%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlConnectionFactory.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlMigrationSqlGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlProviderManifest.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlRankingNormalization.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlServices.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlTextFunctions.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlTypeFunctions.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/NpgsqlWeightLabel.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Properties/AssemblyInfo.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Resources/NpgsqlProviderManifest.Manifest.xml (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Resources/NpgsqlSchema.msl (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Resources/NpgsqlSchema.ssdl (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Resources/NpgsqlSchemaV3.ssdl (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Spatial/PostgisDataReader.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/Spatial/PostgisServices.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/PendingProjectsNode.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/SqlBaseGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/SqlDeleteGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/SqlInsertGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/SqlSelectGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/SqlUpdateGenerator.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/StringPair.cs (100%) rename {src/EntityFramework6.Npgsql => EF6.PG}/SqlGenerators/VisitedExpression.cs (100%) create mode 100644 EF6.PG/content/App.config.install.xdt create mode 100644 EF6.PG/content/App.config.transform create mode 100644 EF6.PG/content/Web.config.install.xdt create mode 100644 EF6.PG/content/Web.config.transform create mode 100644 EF6.PG/postgresql.png delete mode 100644 src/EntityFramework6.Npgsql/install.ps1 delete mode 100644 test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj diff --git a/Directory.Build.props b/Directory.Build.props index d53ede3..c164035 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,13 +1,14 @@  - true + true + snupkg - + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..37c0136 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/EF6.PG.Tests/App.config similarity index 95% rename from test/EntityFramework6.Npgsql.Tests/App.config rename to EF6.PG.Tests/App.config index 3bd6d0b..f113db7 100644 --- a/test/EntityFramework6.Npgsql.Tests/App.config +++ b/EF6.PG.Tests/App.config @@ -29,7 +29,7 @@ - + diff --git a/EF6.PG.Tests/EF6.PG.Tests.csproj b/EF6.PG.Tests/EF6.PG.Tests.csproj new file mode 100644 index 0000000..e2a05da --- /dev/null +++ b/EF6.PG.Tests/EF6.PG.Tests.csproj @@ -0,0 +1,19 @@ + + + latest + net45;netcoreapp3.0 + EntityFramework6.Npgsql.Tests + EntityFramework6.Npgsql.Tests + + + + + + + + + + + + + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/EF6.PG.Tests/EntityFrameworkBasicTests.cs similarity index 99% rename from test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs rename to EF6.PG.Tests/EntityFrameworkBasicTests.cs index 180fb08..4e89635 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/EF6.PG.Tests/EntityFrameworkBasicTests.cs @@ -17,7 +17,7 @@ namespace EntityFramework6.Npgsql.Tests { public class EntityFrameworkBasicTests : EntityFrameworkTestBase { - [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/860")] + [Test] public void InsertAndSelect() { var varbitVal = "10011"; @@ -457,7 +457,7 @@ public void DateFunctions() //Hunting season is open Happy hunting on OrderBy,GroupBy,Min,Max,Skip,Take,ThenBy... and all posible combinations - [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] + [Test] public void TestComplicatedQueries() { using (var context = new BloggingContext(ConnectionString)) @@ -517,7 +517,7 @@ public void TestComplicatedQueries() } } - [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] + [Test] [MonoIgnore("Probably bug in mono. See https://github.com/npgsql/Npgsql/issues/289.")] public void TestComplicatedQueriesMonoFails() { @@ -541,7 +541,7 @@ public void TestComplicatedQueriesMonoFails() } } - [Test, Ignore("https://github.com/aspnet/EntityFramework6/issues/861")] + [Test] public void TestComplicatedQueriesWithApply() { using (var conn = OpenConnection(ConnectionString)) diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/EF6.PG.Tests/EntityFrameworkMigrationTests.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs rename to EF6.PG.Tests/EntityFrameworkMigrationTests.cs diff --git a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs b/EF6.PG.Tests/FullTextSearchTests.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs rename to EF6.PG.Tests/FullTextSearchTests.cs diff --git a/test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs b/EF6.PG.Tests/NLogLoggingProvider.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs rename to EF6.PG.Tests/NLogLoggingProvider.cs diff --git a/test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs b/EF6.PG.Tests/PatternMatchingTests.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/PatternMatchingTests.cs rename to EF6.PG.Tests/PatternMatchingTests.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs b/EF6.PG.Tests/Spatial/PostgisServiceTests.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs rename to EF6.PG.Tests/Spatial/PostgisServiceTests.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs b/EF6.PG.Tests/Support/AssemblySetup.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/AssemblySetup.cs rename to EF6.PG.Tests/Support/AssemblySetup.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/CodeAnnotations.cs b/EF6.PG.Tests/Support/CodeAnnotations.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/CodeAnnotations.cs rename to EF6.PG.Tests/Support/CodeAnnotations.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/EF6.PG.Tests/Support/EntityFrameworkTestBase.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs rename to EF6.PG.Tests/Support/EntityFrameworkTestBase.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs b/EF6.PG.Tests/Support/TestBase.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs rename to EF6.PG.Tests/Support/TestBase.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs b/EF6.PG.Tests/Support/TestDbConfiguration.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/TestDbConfiguration.cs rename to EF6.PG.Tests/Support/TestDbConfiguration.cs diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs b/EF6.PG.Tests/Support/TestUtil.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs rename to EF6.PG.Tests/Support/TestUtil.cs diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs b/EF6.PG.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs rename to EF6.PG.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs b/EF6.PG.Tests/xmlModel/XmlTest.ObjectLayer.cs similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs rename to EF6.PG.Tests/xmlModel/XmlTest.ObjectLayer.cs diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl b/EF6.PG.Tests/xmlModel/XmlTest.csdl similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl rename to EF6.PG.Tests/xmlModel/XmlTest.csdl diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl b/EF6.PG.Tests/xmlModel/XmlTest.msl similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl rename to EF6.PG.Tests/xmlModel/XmlTest.msl diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl b/EF6.PG.Tests/xmlModel/XmlTest.ssdl similarity index 100% rename from test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl rename to EF6.PG.Tests/xmlModel/XmlTest.ssdl diff --git a/src/EntityFramework6.Npgsql/App.config b/EF6.PG/App.config similarity index 100% rename from src/EntityFramework6.Npgsql/App.config rename to EF6.PG/App.config diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/EF6.PG/EF6.PG.csproj similarity index 67% rename from src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj rename to EF6.PG/EF6.PG.csproj index 471878e..87cf8ba 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -12,12 +12,13 @@ CS1591 true Npgsql + EntityFramework6.Npgsql true - ../../Npgsql.snk + ../Npgsql.snk true true - http://www.npgsql.org - http://www.npgsql.org/img/postgresql.gif + https://github.com/npgsql/EntityFramework6.Npgsql + postgresql.png PostgreSQL git git://github.com/npgsql/EntityFramework6.Npgsql @@ -27,7 +28,11 @@ - + + + + + @@ -39,7 +44,7 @@ - - + + diff --git a/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs b/EF6.PG/NpgsqlConnectionFactory.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs rename to EF6.PG/NpgsqlConnectionFactory.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/EF6.PG/NpgsqlMigrationSqlGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs rename to EF6.PG/NpgsqlMigrationSqlGenerator.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/EF6.PG/NpgsqlProviderManifest.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs rename to EF6.PG/NpgsqlProviderManifest.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs b/EF6.PG/NpgsqlRankingNormalization.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs rename to EF6.PG/NpgsqlRankingNormalization.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/EF6.PG/NpgsqlServices.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlServices.cs rename to EF6.PG/NpgsqlServices.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs b/EF6.PG/NpgsqlTextFunctions.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs rename to EF6.PG/NpgsqlTextFunctions.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs b/EF6.PG/NpgsqlTypeFunctions.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlTypeFunctions.cs rename to EF6.PG/NpgsqlTypeFunctions.cs diff --git a/src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs b/EF6.PG/NpgsqlWeightLabel.cs similarity index 100% rename from src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs rename to EF6.PG/NpgsqlWeightLabel.cs diff --git a/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs b/EF6.PG/Properties/AssemblyInfo.cs similarity index 100% rename from src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs rename to EF6.PG/Properties/AssemblyInfo.cs diff --git a/src/EntityFramework6.Npgsql/Resources/NpgsqlProviderManifest.Manifest.xml b/EF6.PG/Resources/NpgsqlProviderManifest.Manifest.xml similarity index 100% rename from src/EntityFramework6.Npgsql/Resources/NpgsqlProviderManifest.Manifest.xml rename to EF6.PG/Resources/NpgsqlProviderManifest.Manifest.xml diff --git a/src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.msl b/EF6.PG/Resources/NpgsqlSchema.msl similarity index 100% rename from src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.msl rename to EF6.PG/Resources/NpgsqlSchema.msl diff --git a/src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.ssdl b/EF6.PG/Resources/NpgsqlSchema.ssdl similarity index 100% rename from src/EntityFramework6.Npgsql/Resources/NpgsqlSchema.ssdl rename to EF6.PG/Resources/NpgsqlSchema.ssdl diff --git a/src/EntityFramework6.Npgsql/Resources/NpgsqlSchemaV3.ssdl b/EF6.PG/Resources/NpgsqlSchemaV3.ssdl similarity index 100% rename from src/EntityFramework6.Npgsql/Resources/NpgsqlSchemaV3.ssdl rename to EF6.PG/Resources/NpgsqlSchemaV3.ssdl diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs b/EF6.PG/Spatial/PostgisDataReader.cs similarity index 100% rename from src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs rename to EF6.PG/Spatial/PostgisDataReader.cs diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs b/EF6.PG/Spatial/PostgisServices.cs similarity index 100% rename from src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs rename to EF6.PG/Spatial/PostgisServices.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs b/EF6.PG/SqlGenerators/PendingProjectsNode.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs rename to EF6.PG/SqlGenerators/PendingProjectsNode.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/EF6.PG/SqlGenerators/SqlBaseGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs rename to EF6.PG/SqlGenerators/SqlBaseGenerator.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs b/EF6.PG/SqlGenerators/SqlDeleteGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs rename to EF6.PG/SqlGenerators/SqlDeleteGenerator.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs b/EF6.PG/SqlGenerators/SqlInsertGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs rename to EF6.PG/SqlGenerators/SqlInsertGenerator.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs b/EF6.PG/SqlGenerators/SqlSelectGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs rename to EF6.PG/SqlGenerators/SqlSelectGenerator.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs b/EF6.PG/SqlGenerators/SqlUpdateGenerator.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs rename to EF6.PG/SqlGenerators/SqlUpdateGenerator.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs b/EF6.PG/SqlGenerators/StringPair.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs rename to EF6.PG/SqlGenerators/StringPair.cs diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/EF6.PG/SqlGenerators/VisitedExpression.cs similarity index 100% rename from src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs rename to EF6.PG/SqlGenerators/VisitedExpression.cs diff --git a/EF6.PG/content/App.config.install.xdt b/EF6.PG/content/App.config.install.xdt new file mode 100644 index 0000000..ace92ed --- /dev/null +++ b/EF6.PG/content/App.config.install.xdt @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/EF6.PG/content/App.config.transform b/EF6.PG/content/App.config.transform new file mode 100644 index 0000000..1dad58e --- /dev/null +++ b/EF6.PG/content/App.config.transform @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EF6.PG/content/Web.config.install.xdt b/EF6.PG/content/Web.config.install.xdt new file mode 100644 index 0000000..ace92ed --- /dev/null +++ b/EF6.PG/content/Web.config.install.xdt @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/EF6.PG/content/Web.config.transform b/EF6.PG/content/Web.config.transform new file mode 100644 index 0000000..1dad58e --- /dev/null +++ b/EF6.PG/content/Web.config.transform @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EF6.PG/postgresql.png b/EF6.PG/postgresql.png new file mode 100644 index 0000000000000000000000000000000000000000..3a21b19f7a164a0d7de90043974a06a273fdbd7b GIT binary patch literal 9675 zcmV;+B{bTJP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>DC16QJK~#8N?VSgd z6vfuZucRes5Lj{sU09+Z86=4a0uog~KrkQ(`cT0SP~hp4pdunD3KA7j1OdrWRDwhW zmYj3WaliW4bobn;8JN{lpOq!1%kjN4*d5aY5KyTv#z#vw6&7h|6oF=B*;a0&n(QdTiCiVbqQs~mMr|?hR%8*wUk-?|L5#n}I4H(m zF;=Gkd-i41PV$2cab1@*Gwqd6L;6XPt1|GB%!ZlkA z2nXJbpYRJWV3IqF@thb~ny~~sPV(f*DO({T-xpU{}(4j+g z@7_J*-;N9ZyJE$PQQ5L(sZym%RIOSyDp;_f{JX)jfB$}3vSbNu*sy^XFJ3I~eK1;# zkz#}-2%$_Emi7PMT-`t8Z~NA;lhO}Dk@685oyw-p-h=F$p?k?c2A@H)HEoY`uQ*s~C}D6qI)iOmK8`G}WzJR}Q?T z{!G?^0|#jH=FRdm{r&gfv~b}<%9=GRJ^SplRHaH4DqR|ji*rB-APl2MjiS@1p%!># zs2BrWm*D|V4NK4^F`&^}Lp;#f#*G`tPM$nD_Wb$tVt(yGJp9pJ>((t+2$J&u z^fiR=#f}&;B31~N@s|>Y+js89Ub}fK_WI4+v3JCEFwC4eQ$AZy-%|`&64k{Bm_Szm zD04H#s3h+U@MaGfFn~IA=s*uX_@MDy=fKj4w{g{~RWyD2bmO;fYS*q!g9Z(va^=cV z#*8pJoJGtJ9X@@Lb{{!IhfZCfV`nbXfs^Oy>h;@n{_-`taqAA<7Te36yZ7jU2Ogk^ zl*uVW+SK%5=Jb>~eQL^^BQq7sorTI2&MkhzQ1Z@-6)R}SkRh~m=~Cl23WLQM0VxOL~Qd~hj}C!@Gfe2#s`&(T3KK^LxEr_&d% z(hc$X@R^b)dw|lVP9;ay3~A-0;nLj}FBa)0hVN~6ACO*;;rGJX>p^(z*mHnq!A zbWyl3RG>Tc?%kU{{~Xq#!e%k*iE&Qe`M@6mC@IDoF|x@!!Sl~QPhxM4^VXje%iWa4 zn`qglJ#<7YiFT4qyc%`N6_F3WVu`#|xUy z_&j6h{6_PB-$_?**f;T>s3j((UiqT*_#=2vR8C*GLhnskN^7^nmt_yw9(uQ`F1IEQ ztd&}|YSE=j(9JEdKVa@o$U6_jCjhWBUvpg&b?w@fKKke*X#<;J$$M||QaUV@pK#Ol z@ygWW$tuR33%vFH#?Ke~`wina;h|Liob-B|T2!_Oyvr(I&Ra*H&xM=cKHlz7SFS>w zW5@|6(;Y$GE>z*NooNaivR<2yBEc`Fdf}VRlunTp70#EUzETSV7kuUSd5_u2>!#`BGELkOm*q#Wbl~CcoX5iV17NF8)4vl3o}wOX@u)@Wm`z1l3L9|HQynpx{XWpiy;mT@vNXmyde& z>Sf%y6s-SFTb^Lc?DLH)$p>iy9YlZ7i3NPFuEW2V{tlCD8Pn3ZzAdS69^Ve1K!5}4 znPD@8rQ@CxxT?ST<{RVA;uGVig(m@MA_f9GlAb+#D*OI7i#F2s{a%$yM=4({lG;D! z_B%ir2Tfd@pnHCNz(Leu=nT5Zl+ui8BWQHb=9E5-eL>2jXD(8Ykv|xBE)cUokcxq@ zxDqSzBmmDCKjp-C>C(lxb2(JLU%Ab=3qRePK0?Wpxj*ul*=y<8S;g#0l*Al4P3?wE zQ}+G`v!tibUu$99*~3n;HUDSaJmb!V2mb)JcMDwr@T$XuBzf++=VbKD1m3iSdfQ<0 zS16v>xFcG#{Q%AW^)KTt@q@|78+!4odnG6-Ovg`pB7MR>mTlTghfljr^46_e>kd1( zi7j*iK#14+x9ilYV_b>lR!sc&s}k<*huO!OB1}H`@Bc|4Q1tT0KN@!~9(|}l9D6=g zCd^-NT!{%5D`tfXNX)W83Y+D~(FLHX@l#3-qG~1^V~)yTPC`&Je-5frI=^v8(x<;6 zCQcCKAHmK;r|GrN<{Eb{-fUk-m~%OeyU@Y&;UH;+fuIVKRwcRsSf(G`ihSugf!5kz*Y1dasG z>TN#LlN%(Gp9#Ny^BQ~V*Cy(CwBUcpQpU3ZH1o0eH@{HK$Hnr z~K$`x)0|cx-m=2G-n*q;SMp#JPVSWDUy! z!3Ds|xIn@tk|s^|ACEV$z!Bh6M>2>BT+nvs86-5wSBMec%Ot8$E@>Hr3|k~UWH(ze zAT9uwEy5=s96g&b54~t)cIi4b(Y4!u3kauk-qIp`!2sRK1erq`)-SjKpoUF?v~AA0 zODKp5KYDC^({8uY^lxIvp;PqBdUq~i?yMQ;iK-|q44xDz+*6BM2Mxz$$Lco?Q)B zI-OSKjpF&-pJVsYGj#o?tz~hE3RqgmT{J-wERth`A$z8DGLh9pOA`aulE4MPO03hh zMx;%L8>D6P6!C5Q5+(u}PNpu|WL&v;;R$5o2M(Sc2US)Y)_%hUz|su$bf$zbyCbu! z(!cYtJ!#g7892CjbkkD?us`I^rdFz>w2c9i;Hv9V6#&%fOHd@qfvYmyl-6?Zc|6?{ zsZ*tpOCKC5g>z@6TtbmbY#@uNLh(rI+N3hQ+qnUa>(hcJ_G>N2*xpak@E%Vn$s-xk zMg-*;(hFITG0ec*Z!M>MW)bR>reOQ_?P==NskoGMA2~~LTZV%kO{>TUWzwkM1Uhrk z5?uK(AtaBK%12d7<(K;<9+=LG&HHG@mc258HK9NX_p|lOOU>TXXY>V76}$*0^$!I+dDt9}c(_BZh8HKC*(|Xj6;k z4DCc?dNrr#8dMO*Ck*RpiOMpH5A)8A=N?dnAbJozAFy41#% z|8V7b*REZB@_`c5=K^5)dr=$DK@mo{!IExrR!lyY&Pi{!q49lNQkyzu1Adqgl1Xp2 zriTkzrHzh*90sIqBhaIRbhbUhvO!Ykmc7Si+PJ6era%*K)1^rz{Rk$1{`seIWub&p z`4%urjNZ6F82J2ocUzjz=lo7z&R=KTg$L}5{!SJi+{Rr;WQFdfYd7fD?YmM3Kp7b_ zi8y%hZQh+~YihP9;Klqx2rCy<`2N3Ju|;l62(Ed`uEJI}SFCO(BWJFrX-ie>z!z{M z^DHA2^PrHFQAiBS-sCHQ&6A`Sj# zi7X01&f=W4f6I*AUZ2jP_Cuyo3=3vqLV`7~0^zk*)s@LdQR zDu6i|v_#R%LZAadR~px@U29xP-~du$>0AI5O#|IAOiKAth-o(|lP5Q>R8ac$%&_V7 z!pI+FhB6#PCeROFYF3p7KKB^C()>|bn1RXfK4KP~W(s5z@$k8)%x((i$|B3VP2j`$ z^vAW7OPFV0i(&CMAeA*VUpFQoVSu&)N)w|37 z+#@S?OsbT!A>`_XVv*`Hyk+k(`E$V^I~9{o7THW)u9(>R629lCYLWQ@if&pK1w_Ls zjW`m)1pw|MtE^OW9#BDTX>uC)#!V0d@HDwP112ntpU*+Xbg>Euk>MqD|;_&PzR9xS<<$wGGO)NOemMt@`B+&8Vm;_t^fc0t6 zi-vZtlGA90-d|QQL`1Ih(QUOGh3jD;%vHyfCp@qj2@Hcgzxm|G2sizh%NM}c} zh$o>gp4V-|qkT;v)GXt69Une?n6_k!1-x@#!aZ;spTR(x+ zVeq;MfO38f^m>ScE&$59&-DO&kznJ~!GJy6B#^hr7kbwazTesjJbawU?EW>l;wA53 zcK`|?TGg0f_13m<^r(pw69&2fV9l{IK+zF|Q>lbIL&s@&*;le;_CzC5KF#fFryN|| z@dW&RZfHKm;d+oSatJe*XHQ}BwGc2`>Ut!uhC*Z&+v|#8I76&_|FUQLT^v2*_P5*F zsDXp*W!{x6x~PBKr@qzsn*oK&DIT$(G-;A?Wf5mTF!3Y+meU_ng#NuI)uU9ux|486 zik*cZrbPhsH_lEr>~cGI5Rvq6yHQ2m-)~**VYg2MZDH1|QB*m6Vf9UBcoG1`0l>Eb zc(QnXzLTJ9r-_|az!xsNGi0Hh>DfH{&{yJN`B&@FH9QFbqy;B+NYId(Q@NySZa76sme+nQ0B=}) zaCb0pYDI&SX9;s%qt$DCR@ABUYKS_%Z38O=uOC2*IL-WnKR-^lD2}&pZ~aHeC_ztu z6Lho=2i*IIngF}dw-ay8nC(E{1`w$7#dRU*T=~V8>kFjA@yzKjzW9P}-&S50bcyn* zN_hMBR?y(;)vJm%5H5!h_lVh9m!R+YHtLsg_+{NLCCjHl#bQ1cPY5Ru{-lZU?f+<2 zU8(1#nKQB7Ti~1dT>gPK0a$GOl;G3~6TF#);^}E`2U*zicT!s#LqYE=>~zr!Pew(! z_Q^+mpE81sCX?ck-u)CX$sb|c@$A{N>94<(o=I56)rg)4ya@pG04pA>D;B!j(QdG; z@i!&VtQcS9U`>{hQ{b<&C0KYT5P&2QU+g{RHd7-~c}|J}5G3w4_MrUXl(Bg6wEX5jzx?t`x^_)5A#t>vUti9b04V+du3#Xg%F_uJcEM}g z0gjom1HAoQYd&-`JOY4KVD4JWvX+zAteUF8ndrU%oGHY?vd>o#cx%Uw9c$cK#63vK z3%&#ZPsjSyKm4G!A#J3!Zm|=mO40N*^NnHbH-PkRPVbi0J$fN^KLv6GI87cYr9>A$ z`|LB>9h`x4o%}wy$d>>BYa4*1@jSsg(at4R>Y6!Mc0!?1B~@qq$v z7D^vqiSC!+F9V)KvubWD0;&7oefOPlXMy?-zll!(lq3R}8YcJxPUQ#anmIQKg9VBc z5C0-RFx;KbunO>OA#@1UpJ8e(_klkPymWjOn=@yQlC&ehG80hW{P+X_4ggF2*L%E~M zMH?0GAc|LbA}Bu%4R62s@3yQFrTlx}e)}zL+N6|>A&46357m(+-e&@yV*jmFw^+lY=K*Nx9g* zP!MZ^y&vZZYkVq(szLgJKLVhHm$)7PcrKcqtY--o(1hzmt6|STKnG3^dh;bDIB$vj z{A-jcB>fXeQqBLMyAs=Miq*PK8Kt5Ky&Kl8Q;Ky_#x=!t85sTu0L($_6auZ-z%c

Vgfw~C1V{MR!~0w#~**Jp9_dLa+d2daQqbj#T?X6u70e7+F9H##?Spj zF@s<>RShr>fx18wJXAe6laTO(9RQzb^bx?>$$a}l=N25?sWC*1po7}}3IMhN%ix?f zYnGBEV)uy`CUBk%ouY0zAH2}m?}82-$-@8Lg&Shz-%Ko^@wF#s6a;n7+8xxZMKvW; z7{|tA1!f@PheN%C#$N#dmgvD0oHorJY(jp3Q%)f~B%DBQg2GF5*Yb2ks}2r#=B(JP zES-shx4-ZXt;Bi^Ak$at^ns=EJ=bOM1ma_bANWnzrOOn-p;9JrQ?A+O zb`{$ROu|PWE@(A%K&23ZDLBOpJ$AhDpLVsaWfe7px<5WK0M8(lTi)0K4YDeg$Y)hV zq1P{3y~M;QmBjxOW3uZ~0y`PLZg`e(>~Cu^a4Z=P41#IlvCn>>YBfxa4z5e0{rmS@ zoyD9OS`V1yE)@<7^1we0I1I4dJixza_ zMx3lDG*Lu)5#D-y(f9%;*zU11V1g{|GjPM&wG~KJT<<1^nm9CNasnuG*!#Jr>@Tn+ zCNKU|CV=iccGhR7k%R)@49OU|z5?r%ahrx{I|wfdD6n%Aip& z0syn4zw1>zUmlojSSOnxXRrnjhE+ykuDZd8QC5m(c(L$D;-Vx{C26jf4WLRj-!S zWqyUHGI$*JFk-|A+3w}|@#C`e3#s2Y)dgn(<<6a((A~XAks|WE;8LYZQGo(#kD|BU zdW+tFU-1>eZ_o-C!3Y2p3hT9xii)DGTiv|}mkUk%jnCENOG5z<2yZ_6-me$c*VH%s8$Y!wJ%?Su<&Ucw^6=J=C&gOG?iA3?ih8t?B7OQ|OyTYM&(Z6in`5 zb&xk8+&r@vR@AVm%c#xZsr1fQ3#n=Ui8OKHhJf7G_#5bgveQErHLvXuSke{D7GQ$) z#8SyoLRP%ETY-6Y*o=_Uxsf@GH^c;!k2hP7M(Q9*qHo{6#+^`kh35b2CqF3-B?on? zuM}&(EA)YI=LaB}X84Ox%3YwJ5r!vlc0#$Lk+RWbie$-TbQC4?=PzHQi&tGehjC8e zRbeT$sud-Vo8ijxxN+mCM~@!HodoscHE%P(%P76KhD2Xa4! z|8#h)9KF^`em)6Oo}YjId6@*^i`QR&U5S*z?K^1V;y9;`;q6;Ks=IL~_OoT1W&5^p z(q0I6AC?}DH$Idc1@squxp`HkQy74LgkgYZItzMNrb z=mDGmr=NZ@eq(`2?<|I*MA;z#h+7t=qkUH}ZeoA6KGZ=H6AI zLIwKjtFI`3{`d=0(MkM^dFyDyE~W3a0yJ-|GMt6$cTxWdUi&CH0zcNp4$u~6=+L3k zYp5;x0KY&C$I{tM><|Eeu;c*OrR(T-dTu0 z*u%sFl=#6_i(Y|ouuA{{%8@KPuu-E%v|xeSo({zr(~QU+CLV`Az1^XXQtE^+(W+G| znRSE+7|(t+Cw%Q+2kG~}4|zRxLkIt_zHMrH?b9=R&0jQRikju*G&u9ftW!ja7xwKE zCA^p0AsB?X3tlYb2H^Q%@_8&q1JW>93%{_g9Z(vfddE1YXEz9%92ffp8$r6A{;8E=LPB@OBha=aDg*~77y=cCAp3nGlpJy z1(90U!QD9JD@BSFQYeslh2hSHVz##v4*!0XWX( zztcj>tO^LY%4fV|rBz6!4FQ`F!CQ_!9=5RGiH~**0Kh9d$aU!gI>CSe1C$IR6G%2r zw(8iiW1Q2<02Dzz6+KuGTZe^$tY$2!<`KCwS8k;brhDzBXglb$G_Fre#vi0I!OHP8ETIFO1iry}V;!OMpul3MRsv`Z4z$yzMYY(KjCntmedC>l|(Lclt zFwq!TU9`3-3P`jxb%5`M4)A^$bpYK7q&13wJsj76?GR22fC<)a&m|iw-qqDXEUn$kgLE2u54uUFyIaI?#Z&5a0S9Ku{f|8 zb{{N-c49yv;6jcP12tc$JJ9ztCUh&pYKG&<(Td!kVggeqz)V4S;NZZf4W&rWc*MGo9`}fOBZ>q; zL)uM4F)W*sCra|p-@ESyHcr)59NICI!3q!zz!fhFf*}gz?qJYlE@ju(uvk( zh)v)p5(*Icf}oizi{&=tD}e5hauQTf@t#MTa;hFR5(fT>0^kWeIP9C~ErTcOtyt1Z zuIDR&lLtrW=xyJ$9zV{WXzhW2ivakGWfmaa+9aF;fCLT>9AS+60^l%~0PtQ%cAZM* z57{!Ql|S0yj=B=;I7wCjc&Sx{O??Rcp(IOjM}e(o1vpb(>w}~w09KAQ?{APM!oPzZ z?I2wmcW??R>~Kgi?ymq2W9_lL`?ZGlvtD zVBN~$iRA6~1>vntGe~Lz05eOj{d@}m;ShlG#oUdcv=hF7+B!5$BsBp5GIJT#%$$On zi`H&%0939l?hYqf3;-z2f5Sym6ad*E2_85e5iF9&SpmRd73leIq8-T#WgzSdAV`V= zAe}7;!y+5U1Rchlq(+q534|ZYEeKyiqDE2_0PBMT-`drWtzha%QdGMk_Y$qaBA% z(uFH7_i@^Yl=6sscn{&=sVA2C+$cpCLZE}mfBEH?b%nEw7@iv^+$XG{J_}ZX9OcTD zi}l6jYd2y~U$_!`>FN#RH{Q8-?_TWe*|TE{7A$D}ePgI?RqvDFpzWAK*q?v?IW{^vnol|gw8}WAKHMj9fMfBL3G3RmtKWivNnf~dVQlBlony0S z&#wF(W1x`_>KhXsNnHovKnR++F5SRPY~H*%<;#~(_Th()fSLjnbRef62QnbHj~ALS zpzOitfRcAB7vVmM7wpfT-rzt7-uUri_}drZK8XlS8oYC!Cf3)$q{GSoq8PqgnI_UdT!`u-*n>#nMi2+NW#}$}cz)OmJ3@o#{{ban)HTt50$l(A N002ovPDHLkV1k}&RRI71 literal 0 HcmV?d00001 diff --git a/EntityFramework6.Npgsql.sln b/EntityFramework6.Npgsql.sln index 54bf88e..2609a94 100644 --- a/EntityFramework6.Npgsql.sln +++ b/EntityFramework6.Npgsql.sln @@ -5,16 +5,14 @@ VisualStudioVersion = 15.0.27703.2035 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A5A60DD-41B6-40BF-B677-227A921ECCC8}" ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets Npgsql.snk = Npgsql.snk EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF6.PG", "EF6.PG\EF6.PG.csproj", "{3EC85CBA-5B79-11E3-8104-0022198AB089}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{ED612DB1-AB32-4603-95E7-891BACA71C39}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework6.Npgsql", "src\EntityFramework6.Npgsql\EntityFramework6.Npgsql.csproj", "{3EC85CBA-5B79-11E3-8104-0022198AB089}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework6.Npgsql.Tests", "test\EntityFramework6.Npgsql.Tests\EntityFramework6.Npgsql.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EF6.PG.Tests", "EF6.PG.Tests\EF6.PG.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/EntityFramework6.Npgsql/install.ps1 b/src/EntityFramework6.Npgsql/install.ps1 deleted file mode 100644 index b6b6c15..0000000 --- a/src/EntityFramework6.Npgsql/install.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -param($installPath, $toolsPath, $package, $project) - -Add-EFProvider $project 'Npgsql' 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj deleted file mode 100644 index 5c8d4cf..0000000 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - latest - net45;netcoreapp3.0 - - - - - - - - - - - - - From 60c349a0363e15e4f01a4fdded2da5f6ec7d7723 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 10 Oct 2019 06:40:11 +0200 Subject: [PATCH 46/60] Bump version to 6.4.0 --- EF6.PG/EF6.PG.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 87cf8ba..d3a5dd6 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -5,7 +5,7 @@ Copyright 2019 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm - 6.3.0 + 6.4.0 latest net45;netstandard21 true From d120f9bed623017163a155ba77b03d43c829fded Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 4 Nov 2019 20:06:27 +0100 Subject: [PATCH 47/60] Stop using pg_attrdef.adsrc, obsoleted in PG12 Use pg_get_expr() on adbin instead Fixes #138 --- EF6.PG/Resources/NpgsqlSchema.ssdl | 4 ++-- EF6.PG/Resources/NpgsqlSchemaV3.ssdl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/EF6.PG/Resources/NpgsqlSchema.ssdl b/EF6.PG/Resources/NpgsqlSchema.ssdl index 50df816..627ce10 100644 --- a/EF6.PG/Resources/NpgsqlSchema.ssdl +++ b/EF6.PG/Resources/NpgsqlSchema.ssdl @@ -57,7 +57,7 @@ end as is_identity, false as is_generated, -- default value column - ad.adsrc as default_value + pg_get_expr(ad.adbin, ad.adrelid) as default_value from pg_attribute a join pg_class c on a.attrelid = c.oid @@ -178,7 +178,7 @@ end as is_identity, false as is_generated, -- default value column - ad.adsrc as default_value + pg_get_expr(ad.adbin, ad.adrelid) as default_value from pg_attribute a join pg_class c on a.attrelid = c.oid diff --git a/EF6.PG/Resources/NpgsqlSchemaV3.ssdl b/EF6.PG/Resources/NpgsqlSchemaV3.ssdl index dd04ebd..4e84667 100644 --- a/EF6.PG/Resources/NpgsqlSchemaV3.ssdl +++ b/EF6.PG/Resources/NpgsqlSchemaV3.ssdl @@ -57,7 +57,7 @@ end as is_identity, false as is_generated, -- default value column - ad.adsrc as default_value + pg_get_expr(ad.adbin, ad.adrelid) as default_value from pg_attribute a join pg_class c on a.attrelid = c.oid @@ -178,7 +178,7 @@ end as is_identity, false as is_generated, -- default value column - ad.adsrc as default_value + pg_get_expr(ad.adbin, ad.adrelid) as default_value from pg_attribute a join pg_class c on a.attrelid = c.oid From 912cdee256c7ff4c09f237489d8c2d8f4c0ff448 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 4 Dec 2019 13:00:45 +0100 Subject: [PATCH 48/60] Use Npgsql 4.1 unless targeting net45 --- Directory.Build.targets | 12 ++++++++++-- EF6.PG.Tests/EF6.PG.Tests.csproj | 2 +- EF6.PG/EF6.PG.csproj | 4 ++-- EntityFramework6.Npgsql.sln | 7 +------ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 37c0136..90c88d8 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,7 +1,15 @@ - + + + + + + + + + @@ -9,4 +17,4 @@ - \ No newline at end of file + diff --git a/EF6.PG.Tests/EF6.PG.Tests.csproj b/EF6.PG.Tests/EF6.PG.Tests.csproj index e2a05da..5f9b005 100644 --- a/EF6.PG.Tests/EF6.PG.Tests.csproj +++ b/EF6.PG.Tests/EF6.PG.Tests.csproj @@ -1,7 +1,7 @@  latest - net45;netcoreapp3.0 + net45;netcoreapp3.1 EntityFramework6.Npgsql.Tests EntityFramework6.Npgsql.Tests diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index d3a5dd6..86e2e0b 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -7,7 +7,7 @@ npgsql postgresql postgres data database entity framework ef orm 6.4.0 latest - net45;netstandard21 + net45;net461;netstandard21 true CS1591 true @@ -34,7 +34,7 @@ - + diff --git a/EntityFramework6.Npgsql.sln b/EntityFramework6.Npgsql.sln index 2609a94..d04e93d 100644 --- a/EntityFramework6.Npgsql.sln +++ b/EntityFramework6.Npgsql.sln @@ -1,5 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27703.2035 MinimumVisualStudioVersion = 10.0.40219.1 @@ -32,10 +31,6 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {3EC85CBA-5B79-11E3-8104-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} - {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} = {ED612DB1-AB32-4603-95E7-891BACA71C39} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {84B4C9EA-ED4F-4E87-8809-297958315622} EndGlobalSection From c2099ef370a3f1febb7f533a169d81746c54237c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 4 Dec 2019 13:07:40 +0100 Subject: [PATCH 49/60] Depend on EF 6.4.0 GA --- Directory.Build.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 90c88d8..f4ea8ab 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -10,10 +10,10 @@ - + - + From 91e37331b2da0f5bb30e7115cc9820f6eefc9123 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 6 Dec 2019 14:26:39 +0100 Subject: [PATCH 50/60] Depend on Microsoft.NETFramework.ReferenceAssemblies 1.0.0 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index c164035..3c65479 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,7 @@ - + From 7547263c3edf7d5d512fa61e766d22217df857c8 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 3 Feb 2020 10:29:08 +0100 Subject: [PATCH 51/60] Manage Npgsql ADO version better * Depend on Npgsql 4.1.3 * Differentiate Npgsql versions in App.config/Web.config transforms. Fixes #147 --- Directory.Build.targets | 8 ++++++-- EF6.PG/content/{ => net45}/App.config.transform | 0 EF6.PG/content/{ => net45}/Web.config.transform | 0 EF6.PG/content/net461/App.config.transform | 11 +++++++++++ EF6.PG/content/net461/Web.config.transform | 11 +++++++++++ 5 files changed, 28 insertions(+), 2 deletions(-) rename EF6.PG/content/{ => net45}/App.config.transform (100%) rename EF6.PG/content/{ => net45}/Web.config.transform (100%) create mode 100644 EF6.PG/content/net461/App.config.transform create mode 100644 EF6.PG/content/net461/Web.config.transform diff --git a/Directory.Build.targets b/Directory.Build.targets index f4ea8ab..d3fa71d 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,10 +1,14 @@ - - + + + + diff --git a/EF6.PG/content/App.config.transform b/EF6.PG/content/net45/App.config.transform similarity index 100% rename from EF6.PG/content/App.config.transform rename to EF6.PG/content/net45/App.config.transform diff --git a/EF6.PG/content/Web.config.transform b/EF6.PG/content/net45/Web.config.transform similarity index 100% rename from EF6.PG/content/Web.config.transform rename to EF6.PG/content/net45/Web.config.transform diff --git a/EF6.PG/content/net461/App.config.transform b/EF6.PG/content/net461/App.config.transform new file mode 100644 index 0000000..0899448 --- /dev/null +++ b/EF6.PG/content/net461/App.config.transform @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/EF6.PG/content/net461/Web.config.transform b/EF6.PG/content/net461/Web.config.transform new file mode 100644 index 0000000..0899448 --- /dev/null +++ b/EF6.PG/content/net461/Web.config.transform @@ -0,0 +1,11 @@ + + + + + + + + + + + From 639d08636d5597cd2e102f449bf97138c30aa051 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 17 Feb 2020 13:51:29 +0100 Subject: [PATCH 52/60] Stop using pg_constraint.consrc, obsoleted in PG12 Use pg_get_expr() on conbin instead Fixes #143 --- EF6.PG/Resources/NpgsqlSchema.ssdl | 2 +- EF6.PG/Resources/NpgsqlSchemaV3.ssdl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EF6.PG/Resources/NpgsqlSchema.ssdl b/EF6.PG/Resources/NpgsqlSchema.ssdl index 627ce10..d40b9d4 100644 --- a/EF6.PG/Resources/NpgsqlSchema.ssdl +++ b/EF6.PG/Resources/NpgsqlSchema.ssdl @@ -78,7 +78,7 @@ c.condeferrable as is_deferrable, c.condeferred as is_initially_deferred, c.contype as constraint_type, - c.consrc as expression, + pg_get_expr(c.conbin, c.conrelid) as expression, case c.confupdtype when 'c' then 'CASCADE' when 'n' then 'SET NULL' diff --git a/EF6.PG/Resources/NpgsqlSchemaV3.ssdl b/EF6.PG/Resources/NpgsqlSchemaV3.ssdl index 4e84667..5411c61 100644 --- a/EF6.PG/Resources/NpgsqlSchemaV3.ssdl +++ b/EF6.PG/Resources/NpgsqlSchemaV3.ssdl @@ -78,7 +78,7 @@ c.condeferrable as is_deferrable, c.condeferred as is_initially_deferred, c.contype as constraint_type, - c.consrc as expression, + pg_get_expr(c.conbin, c.conrelid) as expression, case c.confupdtype when 'c' then 'CASCADE' when 'n' then 'SET NULL' From f411273199f482d84d72b3855b787346fc00d04c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 17 Feb 2020 13:02:41 +0100 Subject: [PATCH 53/60] Bump version to 6.4.1 --- EF6.PG/EF6.PG.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 86e2e0b..32fb4d7 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -5,7 +5,7 @@ Copyright 2019 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm - 6.4.0 + 6.4.1 latest net45;net461;netstandard21 true From 652534c1c91105b7c62eb04f409ffa5f723fe44f Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 17 Feb 2020 13:09:02 +0100 Subject: [PATCH 54/60] Update copyright year --- EF6.PG/EF6.PG.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 32fb4d7..66ebbde 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -2,7 +2,7 @@ PostgreSQL provider for Entity Framework 6 Shay Rojansky;Emil Lenngren;Francisco Figueiredo Jr.;Kenji Uno - Copyright 2019 © The Npgsql Development Team + Copyright 2020 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm 6.4.1 From f07c45c764e461038c1d2d4ba5da43e8c1b403c9 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 17 Feb 2020 13:12:08 +0100 Subject: [PATCH 55/60] Fix transforms management per TFM Leftover from 7547263c3edf7d5d512fa61e766d22217df857c8 --- EF6.PG/EF6.PG.csproj | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 66ebbde..7357dd0 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -29,9 +29,15 @@ - + - + + + + + + + From 55c19004838451d62e364fa7da38b6cf3b471640 Mon Sep 17 00:00:00 2001 From: Duy-KMS <59947708+Duy-KMS@users.noreply.github.com> Date: Sun, 15 Mar 2020 16:28:48 +0700 Subject: [PATCH 56/60] Error while calling Postgresql function by using Database First (#151) Closes #150 --- EF6.PG.Tests/EntityFrameworkBasicTests.cs | 25 ++++++++ .../Support/EntityFrameworkTestBase.cs | 64 +++++++++++++++++++ EF6.PG/NpgsqlServices.cs | 3 + EF6.PG/SqlGenerators/SqlFunctionGenerator.cs | 22 +++++++ 4 files changed, 114 insertions(+) create mode 100644 EF6.PG/SqlGenerators/SqlFunctionGenerator.cs diff --git a/EF6.PG.Tests/EntityFrameworkBasicTests.cs b/EF6.PG.Tests/EntityFrameworkBasicTests.cs index 4e89635..cb52e3d 100644 --- a/EF6.PG.Tests/EntityFrameworkBasicTests.cs +++ b/EF6.PG.Tests/EntityFrameworkBasicTests.cs @@ -889,5 +889,30 @@ public void Test_enum_composite_key() Assert.That(result.TestLong, Is.EqualTo(TestLongEnum.Bar)); } } + + [Test] + public void Test_non_composable_function() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + // Add some data and query it back using Stored Function + context.Blogs.Add(new Blog + { + Name = "Some blog1 name", + Posts = new List() + }); + context.SaveChanges(); + + // Query back + var nameParameter = new ObjectParameter("Name", "blog1"); + var blogs = ((IObjectContextAdapter)context).ObjectContext.ExecuteFunction("GetBlogsByName2", nameParameter).ToArray(); + + Assert.AreEqual(1, blogs.Length); + Assert.AreEqual("Some blog1 name", blogs[0].Name); + } + } + } } diff --git a/EF6.PG.Tests/Support/EntityFrameworkTestBase.cs b/EF6.PG.Tests/Support/EntityFrameworkTestBase.cs index d07af64..5504281 100644 --- a/EF6.PG.Tests/Support/EntityFrameworkTestBase.cs +++ b/EF6.PG.Tests/Support/EntityFrameworkTestBase.cs @@ -38,6 +38,7 @@ public abstract class EntityFrameworkTestBase : TestBase createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"StoredAddFunction\"(integer, integer) RETURNS integer AS $$ SELECT $1 + $2; $$ LANGUAGE SQL;"); createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"StoredEchoFunction\"(integer) RETURNS integer AS $$ SELECT $1; $$ LANGUAGE SQL;"); createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"GetBlogsByName\"(text) RETURNS TABLE(\"BlogId\" int, \"Name\" text, \"IntComputedValue\" int) as $$ select \"BlogId\", \"Name\", \"IntComputedValue\" from \"dbo\".\"Blogs\" where \"Name\" ilike '%' || $1 || '%' $$ LANGUAGE SQL;"); + createSequenceConn.ExecuteNonQuery("CREATE OR REPLACE FUNCTION \"dbo\".\"GetBlogsByName2\"(text) RETURNS TABLE(\"BlogId\" int, \"Name\" text, \"IntComputedValue\" int) as $$ select \"BlogId\", \"Name\", \"IntComputedValue\" from \"dbo\".\"Blogs\" where \"Name\" ilike '%' || $1 || '%' $$ LANGUAGE SQL;"); } } @@ -336,8 +337,71 @@ private static DbCompiledModel CreateModel(NpgsqlConnection connection) new FunctionImportResultMapping(), dbModel.ConceptualToStoreMapping)); + + var getBlogs2Func = EdmFunction.Create( + "GetBlogsByName2", + "BloggingContext", + DataSpace.SSpace, + new EdmFunctionPayload + { + ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, + Schema = "dbo", + IsComposable = false, + IsNiladic = false, + IsBuiltIn = false, + IsAggregate = false, + StoreFunctionName = "GetBlogsByName2", + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType1", rowType.GetCollectionType(), ParameterMode.ReturnValue) + }, + Parameters = new[] + { + FunctionParameter.Create("Name", stringStoreType, ParameterMode.In) + } + }, + null); + dbModel.StoreModel.AddItem(getBlogs2Func); + + EdmFunction getBlogs2FuncModel = EdmFunction.Create( + "GetBlogsByName2", + dbModel.ConceptualModel.Container.Name, + DataSpace.CSpace, + new EdmFunctionPayload + { + IsFunctionImport = true, + IsComposable = false, + Parameters = new[] + { + FunctionParameter.Create("Name", stringPrimitiveType, ParameterMode.In) + }, + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType1", modelBlogConceptualType.GetCollectionType(), ParameterMode.ReturnValue) + }, + EntitySets = new[] + { + dbModel.ConceptualModel.Container.EntitySets.First(x => x.ElementType == modelBlogConceptualType) + } + }, + null); + dbModel.ConceptualModel.Container.AddFunctionImport(getBlogs2FuncModel); + + dbModel.ConceptualToStoreMapping.AddFunctionImportMapping(new FunctionImportMappingNonComposable( + getBlogs2FuncModel, + getBlogs2Func, + new FunctionImportResultMapping[] { }, + dbModel.ConceptualToStoreMapping)); + + var compiledModel = dbModel.Compile(); return compiledModel; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + //modelBuilder.Conventions.Add(new FunctionsConvention("dbo")); + base.OnModelCreating(modelBuilder); + } } } diff --git a/EF6.PG/NpgsqlServices.cs b/EF6.PG/NpgsqlServices.cs index 0a0351d..4c9fe93 100644 --- a/EF6.PG/NpgsqlServices.cs +++ b/EF6.PG/NpgsqlServices.cs @@ -79,6 +79,7 @@ internal void TranslateCommandTree(Version serverVersion, DbCommandTree commandT DbInsertCommandTree insert; DbUpdateCommandTree update; DbDeleteCommandTree delete; + DbFunctionCommandTree function; if ((select = commandTree as DbQueryCommandTree) != null) sqlGenerator = new SqlSelectGenerator(select); else if ((insert = commandTree as DbInsertCommandTree) != null) @@ -87,6 +88,8 @@ internal void TranslateCommandTree(Version serverVersion, DbCommandTree commandT sqlGenerator = new SqlUpdateGenerator(update); else if ((delete = commandTree as DbDeleteCommandTree) != null) sqlGenerator = new SqlDeleteGenerator(delete); + else if ((function = commandTree as DbFunctionCommandTree) != null) + sqlGenerator = new SqlFunctionGenerator(function); else { // TODO: get a message (unsupported DbCommandTree type) diff --git a/EF6.PG/SqlGenerators/SqlFunctionGenerator.cs b/EF6.PG/SqlGenerators/SqlFunctionGenerator.cs new file mode 100644 index 0000000..25ed47c --- /dev/null +++ b/EF6.PG/SqlGenerators/SqlFunctionGenerator.cs @@ -0,0 +1,22 @@ +using System.Linq; +using System.Data.Common; +using System.Data.Entity.Core.Common.CommandTrees; + +namespace Npgsql.SqlGenerators +{ + class SqlFunctionGenerator : SqlBaseGenerator + { + readonly DbFunctionCommandTree _commandTree; + + public SqlFunctionGenerator(DbFunctionCommandTree commandTree) + { + _commandTree = commandTree; + } + + public override void BuildCommand(DbCommand command) + { + var paramStr = string.Join(",", command.Parameters.OfType().Select(x => "@" + x.ParameterName).ToArray()); + command.CommandText = $"SELECT * FROM { QuoteIdentifier(_commandTree.EdmFunction.Schema) }.{ QuoteIdentifier(_commandTree.EdmFunction.Name) } ({paramStr})"; + } + } +} From 9298acdc299133c93cc9cbbd2fbf67589f057fbc Mon Sep 17 00:00:00 2001 From: HoberMellow Date: Thu, 20 May 2021 00:34:58 +0400 Subject: [PATCH 57/60] Add check for null db parameter value (#161) --- EF6.PG/NpgsqlServices.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EF6.PG/NpgsqlServices.cs b/EF6.PG/NpgsqlServices.cs index 4c9fe93..4108f76 100644 --- a/EF6.PG/NpgsqlServices.cs +++ b/EF6.PG/NpgsqlServices.cs @@ -60,6 +60,11 @@ protected override void SetDbParameterValue(DbParameter parameter, TypeUsage par // Npgsql > 4.0 does strict type checks on integral values and fails with enums passed with numeric DbType. static void ConvertValueToNumericIfEnum(DbParameter parameter) { + if (parameter.Value == null) + { + return; + } + var parameterValueObjectType = parameter.Value.GetType(); if (!parameterValueObjectType.IsEnum) From 2fe32bc9b609bc74a99bbcf344e22e8797a59d0c Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 19 May 2021 22:37:19 +0200 Subject: [PATCH 58/60] Bump version to 6.4.2 --- EF6.PG/EF6.PG.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 7357dd0..90bf865 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -5,7 +5,7 @@ Copyright 2020 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm - 6.4.1 + 6.4.2 latest net45;net461;netstandard21 true From 4b54a479d6975b9b39c79dc310664e735a1719b4 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 19 May 2021 22:37:19 +0200 Subject: [PATCH 59/60] Bump version to 6.4.3 --- EF6.PG/EF6.PG.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EF6.PG/EF6.PG.csproj b/EF6.PG/EF6.PG.csproj index 90bf865..b84b9bc 100644 --- a/EF6.PG/EF6.PG.csproj +++ b/EF6.PG/EF6.PG.csproj @@ -5,7 +5,7 @@ Copyright 2020 © The Npgsql Development Team Npgsql npgsql postgresql postgres data database entity framework ef orm - 6.4.2 + 6.4.3 latest net45;net461;netstandard21 true From a6f9e5954a0c9821f739952ba52051fca74618df Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 18 Aug 2022 12:55:39 +0200 Subject: [PATCH 60/60] Add README Closes #187 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a00fdb6 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Entity Framework 6 Provider for PostgreSQL + +This is the Npgsql PostgreSQL provider for Entity Framework 6; note that this is the old, non-core version of EF. For the EF Core provider, see https://github.com/npgsql/efcore.pg. + +Like non-core Entity Framework 6, this provider is no longer being maintained. It is unlikely that any enhancements or bug fixes will be worked upon, unless they're absolutely critical. \ No newline at end of file