From 219cb11d44a984c55421f2e6387c16a90806a365 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 12 May 2016 13:22:30 +0300 Subject: [PATCH 1/8] Initial import from Npgsql repository From commit 32d6186daa0b9a42e8d7dbf78508cc62bf1b99fe Project does not compile. --- .editorconfig | 13 + .gitattributes | 10 + .gitignore | 20 + EntityFramework6.Npgsql.sln | 74 + EntityFramework6.Npgsql.sln.DotSettings | 58 + LICENSE.txt | 7 + Npgsql.snk | Bin 0 -> 596 bytes .../EntityFramework5.Npgsql.csproj | 85 + .../EntityFramework5.Npgsql.nuspec | 29 + src/EntityFramework5.Npgsql/project.json | 52 + .../EntityFramework6.Npgsql.csproj | 87 + .../EntityFramework6.Npgsql.nuspec | 30 + .../NpgsqlConnectionFactory.cs | 44 + .../NpgsqlMigrationSqlGenerator.cs | 879 ++++++++ .../NpgsqlProviderManifest.Manifest.xml | 115 + .../NpgsqlProviderManifest.cs | 442 ++++ .../NpgsqlRankingNormalization.cs | 50 + src/EntityFramework6.Npgsql/NpgsqlSchema.msl | 355 +++ src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl | 724 ++++++ .../NpgsqlSchemaV3.ssdl | 724 ++++++ src/EntityFramework6.Npgsql/NpgsqlServices.cs | 210 ++ .../NpgsqlTextFunctions.cs | 372 ++++ .../NpgsqlWeightLabel.cs | 28 + .../Properties/AssemblyInfo.cs | 15 + .../PublisherPolicy.config | 13 + .../PublisherPolicyLegacy.config | 13 + .../Spatial/PostgisDataReader.cs | 423 ++++ .../Spatial/PostgisServices.cs | 1826 ++++++++++++++++ .../SqlGenerators/PendingProjectsNode.cs | 73 + .../SqlGenerators/SqlBaseGenerator.cs | 1430 ++++++++++++ .../SqlGenerators/SqlDeleteGenerator.cs | 67 + .../SqlGenerators/SqlInsertGenerator.cs | 76 + .../SqlGenerators/SqlSelectGenerator.cs | 152 ++ .../SqlGenerators/SqlUpdateGenerator.cs | 75 + .../SqlGenerators/StringPair.cs | 65 + .../SqlGenerators/VisitedExpression.cs | 1240 +++++++++++ src/EntityFramework6.Npgsql/install.ps1 | 3 + src/EntityFramework6.Npgsql/project.json | 54 + test/EntityFramework6.Npgsql.Tests/App.config | 42 + .../EntityFramework6.Npgsql.Tests.csproj | 90 + .../EntityFrameworkBasicTests.cs | 655 ++++++ .../EntityFrameworkMigrationTests.cs | 808 +++++++ .../EntityFrameworkTestBase.cs | 201 ++ .../FullTextSearchTests.cs | 607 ++++++ test/EntityFramework6.Npgsql.Tests/Program.cs | 22 + .../Properties/AssemblyInfo.cs | 54 + .../Spatial/PostgisServiceTests.cs | 1824 ++++++++++++++++ .../project.json | 27 + .../xmlModel/XmlTest.ObjectLayer.EF6.cs | 1938 ++++++++++++++++ .../xmlModel/XmlTest.ObjectLayer.cs | 1940 +++++++++++++++++ .../xmlModel/XmlTest.csdl | 162 ++ .../xmlModel/XmlTest.msl | 109 + .../xmlModel/XmlTest.ssdl | 229 ++ 53 files changed, 18641 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 EntityFramework6.Npgsql.sln create mode 100644 EntityFramework6.Npgsql.sln.DotSettings create mode 100644 LICENSE.txt create mode 100644 Npgsql.snk create mode 100644 src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj create mode 100644 src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec create mode 100644 src/EntityFramework5.Npgsql/project.json create mode 100644 src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj create mode 100644 src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec create mode 100644 src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlProviderManifest.Manifest.xml create mode 100644 src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlSchema.msl create mode 100644 src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl create mode 100644 src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl create mode 100644 src/EntityFramework6.Npgsql/NpgsqlServices.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs create mode 100644 src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs create mode 100644 src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs create mode 100644 src/EntityFramework6.Npgsql/PublisherPolicy.config create mode 100644 src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config create mode 100644 src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs create mode 100644 src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs create mode 100644 src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs create mode 100644 src/EntityFramework6.Npgsql/install.ps1 create mode 100644 src/EntityFramework6.Npgsql/project.json create mode 100644 test/EntityFramework6.Npgsql.Tests/App.config create mode 100644 test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj create mode 100644 test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Program.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/project.json create mode 100644 test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl create mode 100644 test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl create mode 100644 test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..71b54e4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +; Top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +; 4-column space indentation +[*.cs] +indent_style = space +indent_size = 4 +; trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fa84b48 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,10 @@ +* text=auto + +*.cs text=auto diff=csharp +*.csproj text=auto +*.sln text=auto +*.resx text=auto +*.xml text=auto +*.txt text=auto + +packages/ binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a262f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +.DS_Store +*.resources +*.suo +*.user +*.sln.docstates +*.userprefs +/*.nupkg +.nuget/ +[Bb]in/ +[Bb]uild/ +[Oo]bj/ +[Oo]bj/ +packages/*/ +packages.stable +artifacts/ +# Roslyn cache directories +*.ide/ +*.lock.json +.build +TestResult.xml diff --git a/EntityFramework6.Npgsql.sln b/EntityFramework6.Npgsql.sln new file mode 100644 index 0000000..0bd3ac9 --- /dev/null +++ b/EntityFramework6.Npgsql.sln @@ -0,0 +1,74 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +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 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8537E50E-CF7F-49CB-B4EF-3E2A1B11F050}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{ED612DB1-AB32-4603-95E7-891BACA71C39}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql", "src\Npgsql\Npgsql.csproj", "{9D13B739-62B1-4190-B386-7A9547304EB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "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}" + ProjectSection(ProjectDependencies) = postProject + {E9C258D7-0D8E-4E6A-9857-5C6438591755} = {E9C258D7-0D8E-4E6A-9857-5C6438591755} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.Tests", "test\Npgsql.Tests\Npgsql.Tests.csproj", "{E9C258D7-0D8E-4E6A-9857-5C6438591755}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework6.Npgsql.Tests", "test\EntityFramework6.Npgsql.Tests\EntityFramework6.Npgsql.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release|Any CPU.Build.0 = Release|Any CPU + {3EC85CBA-5B79-11E3-8104-0022198AB089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.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 + {4A0A42DE-C8B8-11E4-8EC9-005056A163A4}.Release|Any CPU.Build.0 = Release|Any CPU + {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {9D13B739-62B1-4190-B386-7A9547304EB3} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} + {3EC85CBA-5B79-11E3-8104-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} + {100998C4-5B85-11E3-911C-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} + {E9C258D7-0D8E-4E6A-9857-5C6438591755} = {ED612DB1-AB32-4603-95E7-891BACA71C39} + {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} = {ED612DB1-AB32-4603-95E7-891BACA71C39} + {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3} = {ED612DB1-AB32-4603-95E7-891BACA71C39} + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Npgsql.csproj + EndGlobalSection +EndGlobal diff --git a/EntityFramework6.Npgsql.sln.DotSettings b/EntityFramework6.Npgsql.sln.DotSettings new file mode 100644 index 0000000..db04052 --- /dev/null +++ b/EntityFramework6.Npgsql.sln.DotSettings @@ -0,0 +1,58 @@ + + True + Implicit + False + False + True + GSS + MD + OID + SCM + SQL + SRID + SSL + SSPI + TZ + UTF + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0a45364 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,7 @@ +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. diff --git a/Npgsql.snk b/Npgsql.snk new file mode 100644 index 0000000000000000000000000000000000000000..c54133da35e728475916ab2cb3d3a779f4534e75 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096iJXs4WPCYb!Xn5QY^wJ)%R;2_WB@AX4 z1Vb=z9W}{-c%|Q$rY(cXqT4M8B_pW(NfVeQOlyfUn~WXK^g14TpMH4^aTHc0 zf^T5g$mbl;CACzb7kk+?r+}6z@TafGcnx#tc+(5fz14awN}6Z5680)C6Jw-sjLQpV=(U0GFeE$Ff_yLJ$_NKK?IDb zW0({)$Zx46UC){!`Uav0fK)?<*^FZSUYc=-zN;Xv+0|4&6KM4e@G961d3|${VUA}YKFWQdZ8Utr%kmIW_ z$hKf-N&wOE2QJ8AK(3F4@zDOsnlo+Czp;#)9>DEUH!5w6JX5zU9}OMS3Dl~}l#0CR zn!QmahKG5f(pLI4hr*g5DO}Jl_+T$`DlQ-HtKZWhPgKA=Dl+A~pt_A-ugswv_UP1% iu|{4YuikGZvp + + + Debug + AnyCPU + {100998C4-5B85-11E3-911C-0022198AB089} + Library + Properties + EntityFramework5.Npgsql + Npgsql + 512 + true + ..\..\Npgsql.snk + ..\ + true + + v4.5.1 + 5 + + false + + + true + full + false + bin\Debug\ + TRACE;DEBUG;NET451 + prompt + 4 + bin\Debug\EntityFramework5.Npgsql.xml + + + pdbonly + true + bin\Release\ + TRACE;NET451 + prompt + 4 + bin\Release\EntityFramework5.Npgsql.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Properties\CommonAssemblyInfo.cs + Code + + + + + + {9d13b739-62b1-4190-b386-7a9547304eb3} + Npgsql + + + + diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec new file mode 100644 index 0000000..5ff4a66 --- /dev/null +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec @@ -0,0 +1,29 @@ + + + + EntityFramework5.Npgsql + Npgsql for Entity Framework 5 + 0.0.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/npgsql/blob/develop/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/project.json b/src/EntityFramework5.Npgsql/project.json new file mode 100644 index 0000000..383ec1b --- /dev/null +++ b/src/EntityFramework5.Npgsql/project.json @@ -0,0 +1,52 @@ +{ + "version": "3.1.0-*", + "packOptions": { + "owners": [ + "Shay Rojansky", + "Emil Lenngren", + "Francisco Figueiredo Jr.", + "Kenji Uno" + ], + "authors": [ + "Shay Rojansky", + "Emil Lenngren", + "Francisco Figueiredo Jr.", + "Kenji Uno", + "Jon Asher", + "Josh Cooley", + "Federico Di Gregorio", + "Jon Hanna", + "Chris Morgan", + "Dave Page", + "Glen Parker", + "Brar Piening", + "Hiroshi Saito" + ], + "description" : "PostgreSQL provider for Entity Framework 5", + "iconUrl": "http://www.npgsql.org/img/postgresql.gif", + "licenseUrl": "https://raw.githubusercontent.com/npgsql/npgsql/develop/LICENSE.txt", + "repository": { + "type": "git", + "url": "git://github.com/npgsql/npgsql" + } + }, + "buildOptions": { + "keyFile": "../../Npgsql.snk" + }, + "dependencies" : { + "Npgsql": "3.1.0-*" + }, + "frameworks": { + "net451": { + "frameworkAssemblies": { + "System.Collections": { "version": "4.0.0.0", "type": "build" }, + "System.Data": { "version": "4.0.0.0", "type": "build" }, + "System.Data.Entity": { "version": "4.0.0.0", "type": "build" }, + "System.Reflection": { "version": "4.0.0.0", "type": "build" }, + "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, + "System.Linq.Expressions": { "version": "4.0.0.0", "type": "build" }, + "System.Runtime": { "version": "4.0.0.0", "type": "build" } + } + } + } +} diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj new file mode 100644 index 0000000..ff27fd8 --- /dev/null +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -0,0 +1,87 @@ + + + + Debug + AnyCPU + {3EC85CBA-5B79-11E3-8104-0022198AB089} + Library + Properties + EntityFramework6.Npgsql + Npgsql + 512 + true + ..\..\Npgsql.snk + ..\ + true + + v4.5.1 + + false + + + true + full + false + bin\Debug\ + TRACE;DEBUG;NET451;ENTITIES6 + prompt + 4 + bin\Debug\EntityFramework6.Npgsql.xml + + + pdbonly + true + bin\Release\ + TRACE;NET451;ENTITIES6 + prompt + 4 + bin\Release\EntityFramework6.Npgsql.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Properties\CommonAssemblyInfo.cs + Code + + + + + {9d13b739-62b1-4190-b386-7a9547304eb3} + Npgsql + + + + diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec new file mode 100644 index 0000000..7d550c1 --- /dev/null +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -0,0 +1,30 @@ + + + + EntityFramework6.Npgsql + Npgsql for Entity Framework 6 + 0.0.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/npgsql/blob/develop/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/NpgsqlConnectionFactory.cs b/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs new file mode 100644 index 0000000..926d39c --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlConnectionFactory.cs @@ -0,0 +1,44 @@ +#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.Entity.Infrastructure; + +namespace Npgsql +{ + /// + /// Instances of this class are used to create DbConnection objects for Postgresql + /// + public class NpgsqlConnectionFactory : IDbConnectionFactory + { + /// + /// Creates a connection for Postgresql for the given connection string. + /// + /// The connection string. + /// An initialized DbConnection. + public DbConnection CreateConnection(string nameOrConnectionString) + { + return new NpgsqlConnection(nameOrConnectionString); + } + } +} diff --git a/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs new file mode 100644 index 0000000..e00aa01 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlMigrationSqlGenerator.cs @@ -0,0 +1,879 @@ +#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.Collections.Generic; +using System.Data.Entity.Migrations.Model; +using System.Data.Entity.Migrations.Sql; +using System.Globalization; +using System.Text; +using System.Data.Entity.Core.Metadata.Edm; +using System.Data.Entity.Spatial; +using System.Linq; + +namespace Npgsql +{ + /// + /// Used to generate migration sql + /// + public class NpgsqlMigrationSqlGenerator : MigrationSqlGenerator + { + List migrationStatments; + private List addedSchemas; + private List addedExtensions; + private Version serverVersion; + + /// + /// Generates the migration sql. + /// + /// The operations in the migration + /// The provider manifest token used for server versioning. + public override IEnumerable Generate( + IEnumerable migrationOperations, string providerManifestToken) + { + migrationStatments = new List(); + addedSchemas = new List(); + addedExtensions = new List(); + serverVersion = new Version(providerManifestToken); + Convert(migrationOperations); + return migrationStatments; + } + + #region MigrationOperation to MigrationStatement converters + + #region General + + protected virtual void Convert(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 = ";" + }); + } + + private void AddStatment(StringBuilder sql, bool suppressTransacion = false) + { + AddStatment(sql.ToString(), suppressTransacion); + } + + #endregion + + #region History + + protected virtual void Convert(HistoryOperation historyOperation) + { + foreach (var command in historyOperation.CommandTrees) + { + var npgsqlCommand = new NpgsqlCommand(); + NpgsqlServices.Instance.TranslateCommandTree(serverVersion, command, npgsqlCommand, false); + AddStatment(npgsqlCommand.CommandText); + } + } + + #endregion + + #region Tables + + protected virtual void Convert(CreateTableOperation createTableOperation) + { + StringBuilder sql = new StringBuilder(); + int dotIndex = createTableOperation.Name.IndexOf('.'); + if (dotIndex != -1) + { + CreateSchema(createTableOperation.Name.Remove(dotIndex)); + } + + sql.Append("CREATE TABLE "); + AppendTableName(createTableOperation.Name, sql); + sql.Append('('); + foreach (var column in createTableOperation.Columns) + { + AppendColumn(column, sql); + sql.Append(","); + } + if (createTableOperation.Columns.Any()) + sql.Remove(sql.Length - 1, 1); + if (createTableOperation.PrimaryKey != null) + { + sql.Append(","); + sql.Append("CONSTRAINT "); + sql.Append('"'); + sql.Append(createTableOperation.PrimaryKey.Name); + sql.Append('"'); + sql.Append(" PRIMARY KEY "); + sql.Append("("); + foreach (var column in createTableOperation.PrimaryKey.Columns) + { + sql.Append('"'); + sql.Append(column); + sql.Append("\","); + } + sql.Remove(sql.Length - 1, 1); + sql.Append(")"); + } + sql.Append(")"); + AddStatment(sql); + } + + protected virtual void Convert(DropTableOperation dropTableOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("DROP TABLE "); + AppendTableName(dropTableOperation.Name, sql); + AddStatment(sql); + } + + protected virtual void Convert(RenameTableOperation renameTableOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(renameTableOperation.Name, sql); + sql.Append(" RENAME TO "); + AppendTableName(renameTableOperation.NewName, sql); + AddStatment(sql); + } + + private void CreateSchema(string schemaName) + { + if (schemaName == "public" || addedSchemas.Contains(schemaName)) + return; + 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 + AddStatment("CREATE SCHEMA " + schemaName); + } + } + + //private void CreateExtension(string exensionName) + //{ + // //This is compatible only with server 9.1+ + // if (serverVersion.Major > 9 || (serverVersion.Major == 9 && serverVersion.Minor >= 1)) + // { + // if (addedExtensions.Contains(exensionName)) + // return; + // addedExtensions.Add(exensionName); + // AddStatment("CREATE EXTENSION IF NOT EXISTS \"" + exensionName + "\""); + // } + //} + + protected virtual void Convert(MoveTableOperation moveTableOperation) + { + StringBuilder sql = new StringBuilder(); + var newSchema = moveTableOperation.NewSchema ?? "dbo"; + CreateSchema(newSchema); + sql.Append("ALTER TABLE "); + AppendTableName(moveTableOperation.Name, sql); + sql.Append(" SET SCHEMA "); + sql.Append(newSchema); + AddStatment(sql); + } + + #endregion + + #region Columns + protected virtual void Convert(AddColumnOperation addColumnOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(addColumnOperation.Table, sql); + sql.Append(" ADD "); + AppendColumn(addColumnOperation.Column, sql); + AddStatment(sql); + } + + protected virtual void Convert(DropColumnOperation dropColumnOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(dropColumnOperation.Table, sql); + sql.Append(" DROP COLUMN \""); + sql.Append(dropColumnOperation.Name); + sql.Append('"'); + AddStatment(sql); + } + + protected virtual void Convert(AlterColumnOperation alterColumnOperation) + { + StringBuilder sql = new StringBuilder(); + + //TYPE + AppendAlterColumn(alterColumnOperation, sql); + sql.Append(" TYPE "); + AppendColumnType(alterColumnOperation.Column, sql, false); + AddStatment(sql); + sql.Clear(); + + //NOT NULL + AppendAlterColumn(alterColumnOperation, sql); + if (alterColumnOperation.Column.IsNullable != null && !alterColumnOperation.Column.IsNullable.Value) + sql.Append(" SET NOT NULL"); + else + sql.Append(" DROP NOT NULL"); + AddStatment(sql); + sql.Clear(); + + //DEFAULT + AppendAlterColumn(alterColumnOperation, sql); + if (alterColumnOperation.Column.DefaultValue != null) + { + sql.Append(" SET DEFAULT "); + AppendValue(alterColumnOperation.Column.DefaultValue, sql); + } + else if (!string.IsNullOrWhiteSpace(alterColumnOperation.Column.DefaultValueSql)) + { + sql.Append(" SET DEFAULT "); + sql.Append(alterColumnOperation.Column.DefaultValueSql); + } + else if (alterColumnOperation.Column.IsIdentity) + { + sql.Append(" SET DEFAULT "); + switch (alterColumnOperation.Column.Type) + { + case PrimitiveTypeKind.Byte: + case PrimitiveTypeKind.SByte: + case PrimitiveTypeKind.Int16: + case PrimitiveTypeKind.Int32: + case PrimitiveTypeKind.Int64: + //TODO: need function CREATE SEQUENCE IF NOT EXISTS and set to it... + //Until this is resolved changing IsIdentity from false to true + //on types int2, int4 and int8 won't switch to type serial2, serial4 and serial8 + throw new NotImplementedException("Not supporting creating sequence for integer types"); + case PrimitiveTypeKind.Guid: + //CreateExtension("uuid-ossp"); + //If uuid-ossp is not enabled migrations throw exception + AddStatment("select * from uuid_generate_v4()"); + sql.Append("uuid_generate_v4()"); + break; + default: + throw new NotImplementedException("Not supporting creating IsIdentity for " + alterColumnOperation.Column.Type); + } + } + else + { + sql.Append(" DROP DEFAULT"); + } + AddStatment(sql); + } + + private void AppendAlterColumn(AlterColumnOperation alterColumnOperation, StringBuilder sql) + { + sql.Append("ALTER TABLE "); + AppendTableName(alterColumnOperation.Table, sql); + sql.Append(" ALTER COLUMN \""); + sql.Append(alterColumnOperation.Column.Name); + sql.Append('"'); + } + + protected virtual void Convert(RenameColumnOperation renameColumnOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(renameColumnOperation.Table, sql); + sql.Append(" RENAME COLUMN \""); + sql.Append(renameColumnOperation.Name); + sql.Append("\" TO \""); + sql.Append(renameColumnOperation.NewName); + sql.Append('"'); + AddStatment(sql); + } + + #endregion + + #region Keys and indexes + + protected virtual void Convert(AddForeignKeyOperation addForeignKeyOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(addForeignKeyOperation.DependentTable, sql); + sql.Append(" ADD CONSTRAINT \""); + sql.Append(addForeignKeyOperation.Name); + sql.Append("\" FOREIGN KEY ("); + foreach (var column in addForeignKeyOperation.DependentColumns) + { + sql.Append('"'); + sql.Append(column); + sql.Append("\","); + } + sql.Remove(sql.Length - 1, 1); + sql.Append(") REFERENCES "); + AppendTableName(addForeignKeyOperation.PrincipalTable, sql); + sql.Append(" ("); + foreach (var column in addForeignKeyOperation.PrincipalColumns) + { + sql.Append('"'); + sql.Append(column); + sql.Append("\","); + } + sql.Remove(sql.Length - 1, 1); + sql.Append(")"); + + if (addForeignKeyOperation.CascadeDelete) + { + sql.Append(" ON DELETE CASCADE"); + } + AddStatment(sql); + } + + protected virtual void Convert(DropForeignKeyOperation dropForeignKeyOperation) + { + StringBuilder 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(dropForeignKeyOperation.Name); + sql.Append('"'); + AddStatment(sql); + } + + protected virtual void Convert(CreateIndexOperation createIndexOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("CREATE "); + + if (createIndexOperation.IsUnique) + sql.Append("UNIQUE "); + + sql.Append("INDEX \""); + sql.Append(GetTableNameFromFullTableName(createIndexOperation.Table) + "_" + createIndexOperation.Name); + sql.Append("\" ON "); + AppendTableName(createIndexOperation.Table, sql); + sql.Append(" ("); + foreach (var column in createIndexOperation.Columns) + { + sql.Append('"'); + sql.Append(column); + sql.Append("\","); + } + sql.Remove(sql.Length - 1, 1); + sql.Append(")"); + AddStatment(sql); + } + + protected virtual void Convert(RenameIndexOperation renameIndexOperation) + { + StringBuilder 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(GetSchemaNameFromFullTableName(renameIndexOperation.Table)); + sql.Append(".\""); + sql.Append(renameIndexOperation.Name); + sql.Append("\" RENAME TO \""); + sql.Append(renameIndexOperation.NewName); + sql.Append('"'); + AddStatment(sql); + } + + private 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 + } + + /// + /// Removes schema prefix e.g. "dto.Blogs" returns "Blogs" and "Posts" returns "Posts" + /// + /// + /// + private string GetTableNameFromFullTableName(string tableName) + { + int dotIndex = tableName.IndexOf('.'); + if (dotIndex != -1) + return tableName.Substring(dotIndex + 1); + else + return tableName; + } + + protected virtual void Convert(DropIndexOperation dropIndexOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("DROP INDEX IF EXISTS "); + sql.Append(GetSchemaNameFromFullTableName(dropIndexOperation.Table)); + sql.Append(".\""); + sql.Append(GetTableNameFromFullTableName(dropIndexOperation.Table) + "_" + dropIndexOperation.Name); + sql.Append('"'); + AddStatment(sql); + } + + protected virtual void Convert(AddPrimaryKeyOperation addPrimaryKeyOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(addPrimaryKeyOperation.Table, sql); + sql.Append(" ADD CONSTRAINT \""); + sql.Append(addPrimaryKeyOperation.Name); + sql.Append("\" PRIMARY KEY "); + + sql.Append("("); + foreach (var column in addPrimaryKeyOperation.Columns) + { + sql.Append('"'); + sql.Append(column); + sql.Append("\","); + } + sql.Remove(sql.Length - 1, 1); + sql.Append(")"); + AddStatment(sql); + } + + protected virtual void Convert(DropPrimaryKeyOperation dropPrimaryKeyOperation) + { + StringBuilder sql = new StringBuilder(); + sql.Append("ALTER TABLE "); + AppendTableName(dropPrimaryKeyOperation.Table, sql); + sql.Append(" DROP CONSTRAINT \""); + sql.Append(dropPrimaryKeyOperation.Name); + sql.Append('"'); + AddStatment(sql); + } + + #endregion + + #endregion + + #region Misc functions + + private void AppendColumn(ColumnModel column, StringBuilder sql) + { + sql.Append('"'); + sql.Append(column.Name); + sql.Append("\" "); + AppendColumnType(column, sql, true); + + if (column.IsNullable != null && !column.IsNullable.Value) + sql.Append(" NOT NULL"); + + if (column.DefaultValue != null) + { + sql.Append(" DEFAULT "); + AppendValue(column.DefaultValue, sql); + } + else if (!string.IsNullOrWhiteSpace(column.DefaultValueSql)) + { + sql.Append(" DEFAULT "); + sql.Append(column.DefaultValueSql); + } + else if (column.IsIdentity) + { + 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; + } + } + 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); + } + } + + private 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('.'); + if (dotIndex == -1) + { + sql.Append('"'); + sql.Append(tableName); + sql.Append('"'); + } + else + { + sql.Append('"'); + sql.Append(tableName.Remove(dotIndex)); + sql.Append("\".\""); + sql.Append(tableName.Substring(dotIndex + 1)); + sql.Append('"'); + } + } + + #endregion + + #region Value appenders + + private void AppendValue(byte[] values, StringBuilder sql) + { + if (values.Length == 0) + { + sql.Append("''"); + } + else + { + sql.Append("E'\\\\"); + foreach (var value in values) + sql.Append(value.ToString("X2")); + sql.Append("'"); + } + } + + private void AppendValue(bool value, StringBuilder sql) + { + sql.Append(value ? "TRUE" : "FALSE"); + } + + private void AppendValue(DateTime value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(new NpgsqlTypes.NpgsqlDateTime(value)); + sql.Append("'"); + } + + private void AppendValue(DateTimeOffset value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(new NpgsqlTypes.NpgsqlDateTime(value.UtcDateTime)); + sql.Append("'"); + } + + private void AppendValue(Guid value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(value); + sql.Append("'"); + } + + private void AppendValue(string value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(value); + sql.Append("'"); + } + + private void AppendValue(TimeSpan value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(new NpgsqlTypes.NpgsqlTimeSpan(value).ToString()); + sql.Append("'"); + } + + private void AppendValue(DbGeometry value, StringBuilder sql) + { + sql.Append("'"); + sql.Append(value); + sql.Append("'"); + } + + private 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.Manifest.xml b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.Manifest.xml new file mode 100644 index 0000000..78e4d75 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.Manifest.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs new file mode 100644 index 0000000..b990f72 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlProviderManifest.cs @@ -0,0 +1,442 @@ +#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.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 NpgsqlTypes; + +namespace Npgsql +{ + internal class NpgsqlProviderManifest : DbXmlEnabledProviderManifest + { + private Version _version; + + public Version Version { get { return _version; } } + + public NpgsqlProviderManifest(string serverVersion) + : base(CreateXmlReaderForResource("Npgsql.NpgsqlProviderManifest.Manifest.xml")) + { + if (!Version.TryParse(serverVersion, out _version)) + { + _version = new Version(9, 5); + } + } + + protected override XmlReader GetDbInformation(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 xmlReader; + } + + private const string MaxLengthFacet = "MaxLength"; + private const string ScaleFacet = "Scale"; + private const string PrecisionFacet = "Precision"; + private const string FixedLengthFacet = "FixedLength"; + + internal static NpgsqlDbType GetNpgsqlDbType(PrimitiveTypeKind _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; + } + } + + public override TypeUsage GetEdmType(TypeUsage storeType) + { + if (storeType == null) + throw new ArgumentNullException("storeType"); + + string storeTypeName = storeType.EdmType.Name; + PrimitiveType primitiveType = StoreTypeNameToEdmPrimitiveType[storeTypeName]; + // TODO: come up with way to determin if unicode is used + bool 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": + { + byte scale; + byte precision; + if (storeType.Facets.TryGetValue(ScaleFacet, 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); + } + } + 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.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.CreateBinaryTypeUsage(primitiveType, false, (int)facet.Value); + } + 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) + { + if (edmType == null) + throw new ArgumentNullException("edmType"); + + PrimitiveType 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; + 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: + { + byte scale; + byte precision; + if (edmType.Facets.TryGetValue(ScaleFacet, 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); + } + } + 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) + { + 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); + } + if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && + !facet.IsUnbounded && facet.Value != null) + { + return TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], isUnicode, false, (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); + } + 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.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"]); + } + + 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)); + } + + public override bool SupportsEscapingLikeArgument(out char escapeCharacter) + { + escapeCharacter = '\\'; + return true; + } + + public override string EscapeLikeArgument(string argument) + { + return argument.Replace("\\","\\\\").Replace("%", "\\%").Replace("_", "\\_"); + } + +#if ENTITIES6 + public override bool SupportsInExpression() + { + return 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))); + + return functions.AsReadOnly(); + } + + private static EdmFunction CreateFullTextEdmFunction(MethodInfo method, DbFunctionAttribute dbFunctionInfo) + { + if (method == null) throw new ArgumentNullException("method"); + if (dbFunctionInfo == null) throw new ArgumentNullException("dbFunctionInfo"); + + return EdmFunction.Create( + dbFunctionInfo.FunctionName, + dbFunctionInfo.NamespaceName, + DataSpace.SSpace, + new EdmFunctionPayload + { + ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, + Schema = string.Empty, + IsBuiltIn = true, + IsAggregate = false, + IsFromProviderManifest = true, + StoreFunctionName = dbFunctionInfo.FunctionName, + IsComposable = true, + ReturnParameters = new[] + { + FunctionParameter.Create( + "ReturnType", + MapTypeToEdmType(method.ReturnType), + ParameterMode.ReturnValue) + }, + Parameters = method.GetParameters().Select( + x => FunctionParameter.Create( + x.Name, + MapTypeToEdmType(x.ParameterType), + ParameterMode.In)).ToList() + }, + new List()); + } + + private 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)); + } +#endif + } +} diff --git a/src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs b/src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs new file mode 100644 index 0000000..7df6cd5 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlRankingNormalization.cs @@ -0,0 +1,50 @@ +using System; + +namespace Npgsql +{ + /// + /// Specifies whether and how a document's length should impact its rank. + /// This is used with the ranking functions in . + /// + /// See http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING + /// for more information about the behaviors that are controlled by this value. + /// + [Flags] + public enum NpgsqlRankingNormalization + { + /// + /// Ignores the document length. + /// + Default = 0, + + /// + /// Divides the rank by 1 + the logarithm of the document length. + /// + DivideBy1PlusLogLength = 1, + + /// + /// Divides the rank by the document length. + /// + DivideByLength = 2, + + /// + /// Divides the rank by the mean harmonic distance between extents (this is implemented only by ts_rank_cd). + /// + DivideByMeanHarmonicDistanceBetweenExtents = 4, + + /// + /// Divides the rank by the number of unique words in document. + /// + DivideByUniqueWordCount = 8, + + /// + /// Divides the rank by 1 + the logarithm of the number of unique words in document. + /// + DividesBy1PlusLogUniqueWordCount = 16, + + /// + /// Divides the rank by itself + 1. + /// + DivideByItselfPlusOne = 32 + } +} \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchema.msl b/src/EntityFramework6.Npgsql/NpgsqlSchema.msl new file mode 100644 index 0000000..aca1179 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlSchema.msl @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl b/src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl new file mode 100644 index 0000000..50df816 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlSchema.ssdl @@ -0,0 +1,724 @@ + + + + + + select + cast(c.oid as varchar) as id, + c.relname AS name, + current_database() as catalog_name, + n.nspname AS schema_name + from pg_class c + left join pg_namespace n + on n.oid = c.relnamespace + where c.relkind = 'r' and n.nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as id, + cast(c.oid as varchar) as table_id, + a.attname as name, + a.attnum as ordinal, + not a.attnotnull as is_nullable, + t.typname as type_name, + case + when t.typname in ('bpchar', 'varchar') and a.atttypmod != -1 then a.atttypmod - 4 + when t.typname in ('bit', 'varbit') and a.atttypmod != -1 then a.atttypmod + else null + end as max_length, + case + when t.typname = 'numeric' and a.atttypmod != -1 then ((a.atttypmod - 4) >> 16) & 65535 + else null + end as precision, + case + when t.typname in ('time', 'timestamp', 'timestamptz') and a.atttypmod != -1 then a.atttypmod + when t.typname = 'interval' and a.atttypmod & 65535 != 65535 then a.atttypmod & 65535 + else null + end as datetime_precision, + case + when t.typname = 'numeric' and a.atttypmod != -1 then (a.atttypmod - 4) & 65535 + else null + end as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when pg_get_expr(ad.adbin, ad.adrelid) like 'nextval%' then true + else false + end as is_identity, + false as is_generated, +-- default value column + ad.adsrc as default_value + from pg_attribute a + join pg_class c + on a.attrelid = c.oid + join pg_type t + on a.atttypid = t.oid + left join pg_attrdef ad + on a.attrelid = ad.adrelid and a.attnum = ad.adnum + where t.typtype = 'b' and c.relkind = 'r' and a.attnum >= 0 and c.relnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select + cast(c.oid as varchar) as id, + cast(c.conrelid as varchar) as table_id, + c.conname as name, + c.condeferrable as is_deferrable, + c.condeferred as is_initially_deferred, + c.contype as constraint_type, + c.consrc as expression, + case c.confupdtype + when 'c' then 'CASCADE' + when 'n' then 'SET NULL' + when 'd' then 'SET DEFAULT' + when 'r' then 'RESTRICT' + when 'a' then 'NO ACTION' + else NULL + end AS update_rule, + case c.confdeltype + when 'c' then 'CASCADE' + when 'n' then 'SET NULL' + when 'd' then 'SET DEFAULT' + when 'r' then 'RESTRICT' + when 'a' then 'NO ACTION' + else NULL + end AS delete_rule + from pg_constraint c + + + + + select + cast(c.oid as varchar) || '.' || cast((c.confkey).n as varchar) as id, + (c.confkey).n as ordinal, + cast(pkc.attrelid as varchar) || '.' || cast (pkc.attnum as varchar) as from_columnid, + cast(fkc.attrelid as varchar) || '.' || cast (fkc.attnum as varchar) as to_columnid, + cast(c.oid as varchar) as constraint_id + from (select c.oid, + c.conname, + c.conrelid, + information_schema._pg_expandarray(c.conkey) as conkey, + c.confrelid, + information_schema._pg_expandarray(c.confkey) as confkey + from pg_constraint c + where contype = 'f') c + join pg_class pt on pt.oid = c.conrelid + join pg_class ft on ft.oid = c.confrelid + join pg_attribute pkc on pkc.attrelid = c.conrelid and pkc.attnum = (c.conkey).x + join pg_attribute fkc on fkc.attrelid = c.confrelid and fkc.attnum = (c.confkey).x + + + + + select + cast(c.oid as varchar) as id, + c.relname AS name, + current_database() as catalog_name, + n.nspname AS schema_name, + false as is_updatable, + pg_get_viewdef(c.oid) AS definition + from pg_class c + left join pg_namespace n + on n.oid = c.relnamespace + where c.relkind = 'v' and n.nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as id, + cast(c.oid as varchar) as view_id, + a.attname as name, + a.attnum as ordinal, + not a.attnotnull as is_nullable, + t.typname as type_name, + case + when t.typname in ('bpchar', 'varchar') and a.atttypmod != -1 then a.atttypmod - 4 + when t.typname in ('bit', 'varbit') and a.atttypmod != -1 then a.atttypmod + else null + end as max_length, + case + when t.typname = 'numeric' and a.atttypmod != -1 then ((a.atttypmod - 4) >> 16) & 65535 + else null + end as precision, + case + when t.typname in ('time', 'timestamp', 'timestamptz') and a.atttypmod != -1 then a.atttypmod + when t.typname = 'interval' and a.atttypmod & 65535 != 65535 then a.atttypmod & 65535 + else null + end as datetime_precision, + case + when t.typname = 'numeric' and a.atttypmod != -1 then (a.atttypmod - 4) & 65535 + else null + end as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when pg_get_expr(ad.adbin, ad.adrelid) like 'nextval%' then true + else false + end as is_identity, + false as is_generated, +-- default value column + ad.adsrc as default_value + from pg_attribute a + join pg_class c + on a.attrelid = c.oid + join pg_type t + on a.atttypid = t.oid + left join pg_attrdef ad + on a.attrelid = ad.adrelid AND a.attnum = ad.adnum + where t.typtype = 'b' and c.relkind = 'v' and a.attnum >= 0 and c.relnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select '1'::varchar as id, '1'::varchar as view_id, '1'::varchar as name, false as is_deferrable, false as is_initially_deferred, 'p'::varchar as constraint_type, '1'::varchar as expression, '1'::varchar as update_rule, '1'::varchar as delete_rule where 1=0 + + + + + select '1'::varchar as id, 0 as ordinal where 1=0 + + + + + select + cast(p.oid as varchar) as id, + current_database() as catalog_name, + n.nspname AS schema_name, + p.proname as name, + false as is_builtin, + false as is_niladic, + t.typname as returntype, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + false as is_aggregate + from pg_proc p + left join pg_namespace n + on n.oid = p.pronamespace + left join pg_type t + on p.prorettype = t.oid + where (p.proretset = false and t.typname != 'void') and n.nspname not in ('pg_catalog','information_schema') and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1) + + + + + select + cast(ss.p_oid as varchar) || '.' || cast((ss.x).n as varchar) as id, + cast(ss.p_oid as varchar) as function_id, + case + when NULLIF(ss.proargnames[(ss.x).n], '') is null then 'x' + else ss.proargnames[(ss.x).n] + end as name, + (ss.x).n as ordinal, + t.typname as type_name, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when ss.proargmodes IS null then 'IN' + when ss.proargmodes[(ss.x).n] = 'i' then 'IN' + when ss.proargmodes[(ss.x).n] = 'o' then 'OUT' + when ss.proargmodes[(ss.x).n] = 'b' then 'INOUT' + else null + end as mode, + null as default + from pg_type t + join (select + n.nspname AS n_nspname, + p.proname, + p.oid AS p_oid, + p.proargnames, + p.proargmodes, + p.proretset, + p.prorettype, + information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x + from pg_namespace n + join pg_proc p + on n.oid = p.pronamespace and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1)) ss + on t.oid = (ss.x).x + join pg_type rt + on ss.prorettype = rt.oid + where (ss.proretset = false and rt.typname != 'void') and ss.n_nspname not in ('pg_catalog','information_schema') + + + + + select + cast(p.oid as varchar) as id, + current_database() as catalog_name, + n.nspname AS schema_name, + p.proname as name, + false as is_builtin, + false as is_niladic, + --t.typname as returntype, + false as is_aggregate + from pg_proc p + left join pg_namespace n + on n.oid = p.pronamespace + left join pg_type t + on p.prorettype = t.oid + where (p.proretset = true or t.typname = 'void') and n.nspname not in ('pg_catalog','information_schema') and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1) + + + + + select + cast(ss.p_oid as varchar) || '.' || cast((ss.x).n as varchar) as id, + cast(ss.p_oid as varchar) as procedure_id, + case + when NULLIF(ss.proargnames[(ss.x).n], '') is null then 'x' + else ss.proargnames[(ss.x).n] + end as name, + (ss.x).n as ordinal, + t.typname as type_name, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when ss.proargmodes IS null then 'IN' + when ss.proargmodes[(ss.x).n] = 'i' then 'IN' + when ss.proargmodes[(ss.x).n] = 'o' then 'OUT' + when ss.proargmodes[(ss.x).n] = 'b' then 'INOUT' + else null + end as mode, + null as default + from pg_type t + join (select + n.nspname AS n_nspname, + p.proname, + p.oid AS p_oid, + p.proargnames, + p.proargmodes, + p.proretset, + p.prorettype, + information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x + from pg_namespace n + join pg_proc p + on n.oid = p.pronamespace and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1)) ss + on t.oid = (ss.x).x + join pg_type rt + on ss.prorettype = rt.oid + where (ss.proretset = true or rt.typname = 'void') and ss.n_nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as column_id, + cast(coid as varchar) as constraint_id, + (ss.x).n as ordinal + from pg_attribute a + join (select + r.oid AS roid, + c.oid as coid, + c.conname, + information_schema._pg_expandarray(c.conkey) as x, + r.relnamespace as rrelnamespace + from pg_constraint c + join pg_class r + on r.oid = c.conrelid + where r.relkind = 'r') ss + on a.attrelid = ss.roid and a.attnum = (ss.x).x and not a.attisdropped and rrelnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select '1'::varchar as column_id, '1'::varchar as constraint_id where 1=0 + + + + + select '1'::varchar as id, '1'::varchar as constraint_id, '1'::varchar as from_columnid, '1'::varchar as to_columnid, 0 as ordinal where 1=0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl b/src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl new file mode 100644 index 0000000..dd04ebd --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlSchemaV3.ssdl @@ -0,0 +1,724 @@ + + + + + + select + cast(c.oid as varchar) as id, + c.relname AS name, + current_database() as catalog_name, + n.nspname AS schema_name + from pg_class c + left join pg_namespace n + on n.oid = c.relnamespace + where c.relkind = 'r' and n.nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as id, + cast(c.oid as varchar) as table_id, + a.attname as name, + a.attnum as ordinal, + not a.attnotnull as is_nullable, + t.typname as type_name, + case + when t.typname in ('bpchar', 'varchar') and a.atttypmod != -1 then a.atttypmod - 4 + when t.typname in ('bit', 'varbit') and a.atttypmod != -1 then a.atttypmod + else null + end as max_length, + case + when t.typname = 'numeric' and a.atttypmod != -1 then ((a.atttypmod - 4) >> 16) & 65535 + else null + end as precision, + case + when t.typname in ('time', 'timestamp', 'timestamptz') and a.atttypmod != -1 then a.atttypmod + when t.typname = 'interval' and a.atttypmod & 65535 != 65535 then a.atttypmod & 65535 + else null + end as datetime_precision, + case + when t.typname = 'numeric' and a.atttypmod != -1 then (a.atttypmod - 4) & 65535 + else null + end as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when pg_get_expr(ad.adbin, ad.adrelid) like 'nextval%' then true + else false + end as is_identity, + false as is_generated, +-- default value column + ad.adsrc as default_value + from pg_attribute a + join pg_class c + on a.attrelid = c.oid + join pg_type t + on a.atttypid = t.oid + left join pg_attrdef ad + on a.attrelid = ad.adrelid and a.attnum = ad.adnum + where t.typtype = 'b' and c.relkind = 'r' and a.attnum >= 0 and c.relnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select + cast(c.oid as varchar) as id, + cast(c.conrelid as varchar) as table_id, + c.conname as name, + c.condeferrable as is_deferrable, + c.condeferred as is_initially_deferred, + c.contype as constraint_type, + c.consrc as expression, + case c.confupdtype + when 'c' then 'CASCADE' + when 'n' then 'SET NULL' + when 'd' then 'SET DEFAULT' + when 'r' then 'RESTRICT' + when 'a' then 'NO ACTION' + else NULL + end AS update_rule, + case c.confdeltype + when 'c' then 'CASCADE' + when 'n' then 'SET NULL' + when 'd' then 'SET DEFAULT' + when 'r' then 'RESTRICT' + when 'a' then 'NO ACTION' + else NULL + end AS delete_rule + from pg_constraint c + + + + + select + cast(c.oid as varchar) || '.' || cast((c.confkey).n as varchar) as id, + (c.confkey).n as ordinal, + cast(pkc.attrelid as varchar) || '.' || cast (pkc.attnum as varchar) as from_columnid, + cast(fkc.attrelid as varchar) || '.' || cast (fkc.attnum as varchar) as to_columnid, + cast(c.oid as varchar) as constraint_id + from (select c.oid, + c.conname, + c.conrelid, + information_schema._pg_expandarray(c.conkey) as conkey, + c.confrelid, + information_schema._pg_expandarray(c.confkey) as confkey + from pg_constraint c + where contype = 'f') c + join pg_class pt on pt.oid = c.conrelid + join pg_class ft on ft.oid = c.confrelid + join pg_attribute pkc on pkc.attrelid = c.conrelid and pkc.attnum = (c.conkey).x + join pg_attribute fkc on fkc.attrelid = c.confrelid and fkc.attnum = (c.confkey).x + + + + + select + cast(c.oid as varchar) as id, + c.relname AS name, + current_database() as catalog_name, + n.nspname AS schema_name, + false as is_updatable, + pg_get_viewdef(c.oid) AS definition + from pg_class c + left join pg_namespace n + on n.oid = c.relnamespace + where c.relkind = 'v' and n.nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as id, + cast(c.oid as varchar) as view_id, + a.attname as name, + a.attnum as ordinal, + not a.attnotnull as is_nullable, + t.typname as type_name, + case + when t.typname in ('bpchar', 'varchar') and a.atttypmod != -1 then a.atttypmod - 4 + when t.typname in ('bit', 'varbit') and a.atttypmod != -1 then a.atttypmod + else null + end as max_length, + case + when t.typname = 'numeric' and a.atttypmod != -1 then ((a.atttypmod - 4) >> 16) & 65535 + else null + end as precision, + case + when t.typname in ('time', 'timestamp', 'timestamptz') and a.atttypmod != -1 then a.atttypmod + when t.typname = 'interval' and a.atttypmod & 65535 != 65535 then a.atttypmod & 65535 + else null + end as datetime_precision, + case + when t.typname = 'numeric' and a.atttypmod != -1 then (a.atttypmod - 4) & 65535 + else null + end as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when pg_get_expr(ad.adbin, ad.adrelid) like 'nextval%' then true + else false + end as is_identity, + false as is_generated, +-- default value column + ad.adsrc as default_value + from pg_attribute a + join pg_class c + on a.attrelid = c.oid + join pg_type t + on a.atttypid = t.oid + left join pg_attrdef ad + on a.attrelid = ad.adrelid AND a.attnum = ad.adnum + where t.typtype = 'b' and c.relkind = 'v' and a.attnum >= 0 and c.relnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select '1'::varchar as id, '1'::varchar as view_id, '1'::varchar as name, false as is_deferrable, false as is_initially_deferred, 'p'::varchar as constraint_type, '1'::varchar as expression, '1'::varchar as update_rule, '1'::varchar as delete_rule where 1=0 + + + + + select '1'::varchar as id, 0 as ordinal where 1=0 + + + + + select + cast(p.oid as varchar) as id, + current_database() as catalog_name, + n.nspname AS schema_name, + p.proname as name, + false as is_builtin, + false as is_niladic, + t.typname as returntype, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + false as is_aggregate + from pg_proc p + left join pg_namespace n + on n.oid = p.pronamespace + left join pg_type t + on p.prorettype = t.oid + where (p.proretset = false and t.typname != 'void') and n.nspname not in ('pg_catalog','information_schema') and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1) + + + + + select + cast(ss.p_oid as varchar) || '.' || cast((ss.x).n as varchar) as id, + cast(ss.p_oid as varchar) as function_id, + case + when NULLIF(ss.proargnames[(ss.x).n], '') is null then 'x' + else ss.proargnames[(ss.x).n] + end as name, + (ss.x).n as ordinal, + t.typname as type_name, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when ss.proargmodes IS null then 'IN' + when ss.proargmodes[(ss.x).n] = 'i' then 'IN' + when ss.proargmodes[(ss.x).n] = 'o' then 'OUT' + when ss.proargmodes[(ss.x).n] = 'b' then 'INOUT' + else null + end as mode, + null as default + from pg_type t + join (select + n.nspname AS n_nspname, + p.proname, + p.oid AS p_oid, + p.proargnames, + p.proargmodes, + p.proretset, + p.prorettype, + information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x + from pg_namespace n + join pg_proc p + on n.oid = p.pronamespace and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1)) ss + on t.oid = (ss.x).x + join pg_type rt + on ss.prorettype = rt.oid + where (ss.proretset = false and rt.typname != 'void') and ss.n_nspname not in ('pg_catalog','information_schema') + + + + + select + cast(p.oid as varchar) as id, + current_database() as catalog_name, + n.nspname AS schema_name, + p.proname as name, + false as is_builtin, + false as is_niladic, + --t.typname as returntype, + false as is_aggregate + from pg_proc p + left join pg_namespace n + on n.oid = p.pronamespace + left join pg_type t + on p.prorettype = t.oid + where (p.proretset = true or t.typname = 'void') and n.nspname not in ('pg_catalog','information_schema') and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1) + + + + + select + cast(ss.p_oid as varchar) || '.' || cast((ss.x).n as varchar) as id, + cast(ss.p_oid as varchar) as procedure_id, + case + when NULLIF(ss.proargnames[(ss.x).n], '') is null then 'x' + else ss.proargnames[(ss.x).n] + end as name, + (ss.x).n as ordinal, + t.typname as type_name, + null as max_length, + null as precision, + null as datetime_precision, + null as scale, + case + when t.typlen = -1 and t.typelem != 0 then true + else false + end as is_multiset, + null as collation_catalog_name, + null as collation_schema_name, + null as collation_name, + null as char_set_catalog_name, + null as char_set_schema_name, + null as char_set_name, + case + when ss.proargmodes IS null then 'IN' + when ss.proargmodes[(ss.x).n] = 'i' then 'IN' + when ss.proargmodes[(ss.x).n] = 'o' then 'OUT' + when ss.proargmodes[(ss.x).n] = 'b' then 'INOUT' + else null + end as mode, + null as default + from pg_type t + join (select + n.nspname AS n_nspname, + p.proname, + p.oid AS p_oid, + p.proargnames, + p.proargmodes, + p.proretset, + p.prorettype, + information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x + from pg_namespace n + join pg_proc p + on n.oid = p.pronamespace and p.proname not in (select pg_proc.proname from pg_proc group by pg_proc.proname having count(pg_proc.proname) > 1)) ss + on t.oid = (ss.x).x + join pg_type rt + on ss.prorettype = rt.oid + where (ss.proretset = true or rt.typname = 'void') and ss.n_nspname not in ('pg_catalog','information_schema') + + + + + select + cast(a.attrelid as varchar) || '.' || cast (a.attnum as varchar) as column_id, + cast(coid as varchar) as constraint_id, + (ss.x).n as ordinal + from pg_attribute a + join (select + r.oid AS roid, + c.oid as coid, + c.conname, + information_schema._pg_expandarray(c.conkey) as x, + r.relnamespace as rrelnamespace + from pg_constraint c + join pg_class r + on r.oid = c.conrelid + where r.relkind = 'r') ss + on a.attrelid = ss.roid and a.attnum = (ss.x).x and not a.attisdropped and rrelnamespace in + (select oid from pg_namespace where nspname not in ('pg_catalog','information_schema')) + + + + + select '1'::varchar as column_id, '1'::varchar as constraint_id where 1=0 + + + + + select '1'::varchar as id, '1'::varchar as constraint_id, '1'::varchar as from_columnid, '1'::varchar as to_columnid, 0 as ordinal where 1=0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/NpgsqlServices.cs b/src/EntityFramework6.Npgsql/NpgsqlServices.cs new file mode 100644 index 0000000..9fe793d --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlServices.cs @@ -0,0 +1,210 @@ +#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.Collections.Generic; +using System.Text; +#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; + +namespace Npgsql +{ +#if ENTITIES6 + public class NpgsqlServices : DbProviderServices +#else + internal class NpgsqlServices : DbProviderServices +#endif + { + private static readonly NpgsqlServices _instance = new NpgsqlServices(); + +#if ENTITIES6 + public NpgsqlServices() + { + AddDependencyResolver(new SingletonDependencyResolver>( + () => new NpgsqlMigrationSqlGenerator(), "Npgsql")); + } +#endif + + public static NpgsqlServices Instance + { + get { return _instance; } + } + + protected override DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree) + { + return CreateCommandDefinition(CreateDbCommand(((NpgsqlProviderManifest)providerManifest).Version, commandTree)); + } + + internal DbCommand CreateDbCommand(Version serverVersion, DbCommandTree commandTree) + { + if (commandTree == null) + throw new ArgumentNullException("commandTree"); + + NpgsqlCommand command = new NpgsqlCommand(); + + foreach (KeyValuePair parameter in commandTree.Parameters) + { + NpgsqlParameter dbParameter = new NpgsqlParameter(); + dbParameter.ParameterName = parameter.Key; + dbParameter.NpgsqlDbType = NpgsqlProviderManifest.GetNpgsqlDbType(((PrimitiveType)parameter.Value.EdmType).PrimitiveTypeKind); + command.Parameters.Add(dbParameter); + } + + TranslateCommandTree(serverVersion, commandTree, command); + + return command; + } + + internal void TranslateCommandTree(Version serverVersion, DbCommandTree commandTree, DbCommand command, bool createParametersForNonSelect = true) + { + SqlBaseGenerator sqlGenerator = null; + + 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.Version = serverVersion; + + sqlGenerator.BuildCommand(command); + } + + protected override string GetDbProviderManifestToken(DbConnection connection) + { + if (connection == null) + throw new ArgumentNullException("connection"); + string serverVersion = ""; + UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + { + serverVersion = conn.ServerVersion; + }); + return serverVersion; + } + + protected override DbProviderManifest GetDbProviderManifest(string versionHint) + { + if (versionHint == null) + throw new ArgumentNullException("versionHint"); + return new NpgsqlProviderManifest(versionHint); + } + +#if ENTITIES6 + protected override bool DbDatabaseExists(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection) + { + bool exists = false; + UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + { + using (NpgsqlCommand 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) + { + UsingPostgresDBConnection((NpgsqlConnection)connection, conn => + { + var sb = new StringBuilder(); + sb.Append("CREATE DATABASE \""); + sb.Append(connection.Database); + sb.Append("\""); + if (conn.EntityTemplateDatabase != null) + { + sb.Append(" TEMPLATE \""); + sb.Append(conn.EntityTemplateDatabase); + sb.Append("\""); + } + + using (NpgsqlCommand command = new NpgsqlCommand(sb.ToString(), conn)) + { + command.ExecuteNonQuery(); + } + }); + } + + protected override void DbDeleteDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection) + { + 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)) + { + command.ExecuteNonQuery(); + } + }); + } +#endif + + private static void UsingPostgresDBConnection(NpgsqlConnection connection, Action action) + { + var connectionBuilder = new NpgsqlConnectionStringBuilder(connection.ConnectionString) + { + Database = connection.EntityAdminDatabase ?? "template1", + Pooling = false + }; + + using (var masterConnection = new NpgsqlConnection(connectionBuilder.ConnectionString)) + { + masterConnection.Open();//using's Dispose will close it even if exception... + action(masterConnection); + } + } + } +} diff --git a/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs new file mode 100644 index 0000000..d31a7a5 --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlTextFunctions.cs @@ -0,0 +1,372 @@ +using System; +using System.Data.Entity; +using System.Diagnostics.CodeAnalysis; + +namespace Npgsql +{ + /// + /// Use this class in LINQ queries to generate full-text search expressions using tsvector and tsquery. + /// None of these functions can be called directly. + /// See http://www.postgresql.org/docs/current/static/functions-textsearch.html for the latest documentation. + /// + [SuppressMessage("ReSharper", "UnusedParameter.Global")] + public static class NpgsqlTextFunctions + { + /// + /// Cast to the tsvector data type. + /// + [DbFunction("Npgsql", "as_tsvector")] + 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(); + } + + /// + /// Reduce to tsvector using the text search configuration specified + /// by . + /// 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(); + } + + /// + /// Cast to the tsquery data type. + /// + [DbFunction("Npgsql", "as_tsquery")] + 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(); + } + + /// + /// Produce tsquery from ignoring punctuation and using the text search + /// configuration specified by . + /// 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(); + } + + /// + /// Normalize words in and convert to tsquery. If your input + /// contains punctuation that should not be treated as text search operators, use + /// instead. + /// 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(); + } + + /// + /// Normalize words in and convert to tsquery using the text search + /// configuration specified by . If your input contains punctuation + /// that should not be treated as text search operators, use + /// instead. + /// 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(); + } + + /// + /// 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(); + } + + /// + /// 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(); + } + + /// + /// 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(); + } + + /// + /// Returns whether contains . + /// Generates the "@>" operator. + /// 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(); + } + + /// + /// Returns whether is contained within . + /// Generates the "<@" operator. + /// 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(); + } + + /// + /// 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(); + } + + /// + /// Assign weight to each element of and return a new + /// weighted tsvector. + /// 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(); + } + + /// + /// 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(); + } + + /// + /// 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(); + } + + /// + /// Removes weights and positions from and returns + /// a new stripped tsvector. + /// 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(); + } + + /// + /// 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(); + } + + /// + /// Returns a string suitable for display containing a query match. + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-HEADLINE + /// + [DbFunction("Npgsql", "ts_headline")] + public static string TsHeadline(string document, string tsquery, string options) + { + throw new NotSupportedException(); + } + + /// + /// Returns a string suitable for display containing a query match using the text + /// search configuration specified by . + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-HEADLINE + /// + [DbFunction("Npgsql", "ts_headline")] + public static string TsHeadline(string config, string document, string tsquery, string options) + { + 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(); + } + + /// + /// Calculates the rank of for while normalizing + /// the result according to the behaviors specified by . + /// 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(); + } + + /// + /// Calculates the rank of for with custom + /// weighting for word instances depending on their labels (D, C, B or A). + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING + /// + [DbFunction("Npgsql", "ts_rank")] + public static float TsRank( + float weightD, + float weightC, + float weightB, + float weightA, + string vector, + string query) + { + throw new NotSupportedException(); + } + + /// + /// Calculates the rank of for while normalizing + /// the result according to the behaviors specified by + /// and using custom weighting for word instances depending on their labels (D, C, B or A). + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING + /// + [DbFunction("Npgsql", "ts_rank")] + public static float TsRank( + float weightD, + float weightC, + float weightB, + float weightA, + string vector, + string query, + NpgsqlRankingNormalization normalization) + { + throw new NotSupportedException(); + } + + /// + /// Calculates the rank of for using the cover + /// density method. + /// 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(); + } + + /// + /// Calculates the rank of for using the cover + /// density method while normalizing the result according to the behaviors specified by + /// . + /// 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(); + } + + /// + /// Calculates the rank of for using the cover + /// density method with custom weighting for word instances depending on their labels (D, C, B or A). + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING + /// + [DbFunction("Npgsql", "ts_rank_cd")] + public static float TsRankCd( + float weightD, + float weightC, + float weightB, + float weightA, + string vector, + string query) + { + throw new NotSupportedException(); + } + + /// + /// Calculates the rank of for using the cover density + /// method while normalizing the result according to the behaviors specified by + /// and using custom weighting for word instances depending on their labels (D, C, B or A). + /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-RANKING + /// + [DbFunction("Npgsql", "ts_rank_cd")] + public static float TsRankCd( + float weightD, + float weightC, + float weightB, + float weightA, + string vector, + string query, + NpgsqlRankingNormalization normalization) + { + throw new NotSupportedException(); + } + + /// + /// Searchs for occurrences of , and replaces + /// each occurrence with a . All parameters are of type tsquery. + /// http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY + /// + [DbFunction("Npgsql", "ts_rewrite")] + public static string TsRewrite(string query, string target, string substitute) + { + throw new NotSupportedException(); + } + } +} diff --git a/src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs b/src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs new file mode 100644 index 0000000..ee2e18c --- /dev/null +++ b/src/EntityFramework6.Npgsql/NpgsqlWeightLabel.cs @@ -0,0 +1,28 @@ +namespace Npgsql +{ + /// + /// Label given to positions in vectors. + /// + public enum NpgsqlWeightLabel + { + /// + /// D (Default). + /// + D = 0, + + /// + /// C + /// + C = 1, + + /// + /// B + /// + B = 2, + + /// + /// A + /// + A = 3 + } +} \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs b/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..aeb1aee --- /dev/null +++ b/src/EntityFramework6.Npgsql/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.CompilerServices; +using System.Security; +using System.Reflection; +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 diff --git a/src/EntityFramework6.Npgsql/PublisherPolicy.config b/src/EntityFramework6.Npgsql/PublisherPolicy.config new file mode 100644 index 0000000..bbfd05c --- /dev/null +++ b/src/EntityFramework6.Npgsql/PublisherPolicy.config @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config b/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config new file mode 100644 index 0000000..db8b53f --- /dev/null +++ b/src/EntityFramework6.Npgsql/PublisherPolicyLegacy.config @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs new file mode 100644 index 0000000..63a9c53 --- /dev/null +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisDataReader.cs @@ -0,0 +1,423 @@ +using System; +using System.Data; + +#if ENTITIES6 +using System.Data.Entity.Spatial; +#else +using System.Data.Spatial; +#endif + +namespace Npgsql.Spatial +{ + /// + /// A postgis geometry service API. + /// + public class PostgisDataReader + : DbSpatialDataReader, System.Data.IDataReader + { + private PostgisServices _svcs; + private NpgsqlDataReader _rdr; + + /// + /// Creates a new instance of postgis data reader using a specific instance of PostgisService. + /// + /// The service provider that DbGeometry instances will use. + /// The underlying data reader. + public PostgisDataReader(PostgisServices svcs, NpgsqlDataReader rdr) + :base() + { + _svcs = svcs; + _rdr = rdr; + } + + /// + /// Creates a new instance of postgis data reader. + /// + /// The underlying data reader. + 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(); + } + + /// + /// Get the DbGeometry value of a column, given its zero-based ordinal. + /// + /// + /// + public override DbGeometry GetGeometry(int ordinal) + { + return _svcs.GeometryFromProviderValue(_rdr[ordinal]); + } + + /// + /// Get the value indicating wether a column is a Geometry value, given its zero-based ordinal. + /// + /// + /// +#if ENTITIES6 + public override bool IsGeometryColumn(int ordinal) +#else + public bool IsGeometryColumn(int ordinal) +#endif + { + return _rdr[ordinal] is NpgsqlTypes.PostgisGeometry; + } + + /// + /// Get the value indicating wether a column is a Geography value, given its zero-based ordinal. + /// + /// + /// +#if ENTITIES6 + public override bool IsGeographyColumn(int ordinal) +#else + public bool IsGeographyColumn(int ordinal) +#endif + { + throw new NotImplementedException(); + } + + /// + /// Gets a value indicating the depth of nesting of the current row. Always Zero. + /// + public int Depth + { + get + { + return _rdr.Depth; + } + } + + /// + /// Gets a value indicating wether the data reader is closed. + /// + public bool IsClosed + { + get + { + return _rdr.IsClosed; + } + } + + /// + /// Gets the number of row affected by the SQL statement. + /// + public int RecordsAffected + { + get + { + return _rdr.RecordsAffected; + } + } + + + /// + /// Gets the number of columns in the current row. + /// + public int FieldCount + { + get + { + return _rdr.FieldCount; + } + } + + /// + /// Gets the value of the specified column name of the current row. + /// + /// + /// + public object this[string name] + { + get + { + return _rdr[name]; + } + } + + /// + /// Gets the value of the specified column index of the current row. + /// + /// + /// + public object this[int i] + { + get + { + return _rdr[i]; + } + } + + /// + /// Close the underlying datareader object. + /// + public void Close() + { + _rdr.Close(); + } + + /// + /// Returns a DataTable which contains metadata about the current row. + /// + /// + public DataTable GetSchemaTable() + { + return _rdr.GetSchemaTable(); + } + + /// + /// Advances the reader to the next result when reading data from a batch of statements. + /// + /// + public bool NextResult() + { + return _rdr.NextResult(); + } + + /// + /// Advances the reader to the next record in a result set. + /// + /// + public bool Read() + { + return _rdr.Read(); + } + + /// + /// Frees the resources hold by the data reader. + /// + 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); + } + + /// + /// 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); + } + + /// + /// Populates an array of objects with the values of the current row. + /// + /// + /// + public int GetValues(object[] values) + { + return _rdr.GetValues(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); + } + + /// + /// Get the value of a column as a byte, given its zero-based ordinal. + /// + /// + /// + public byte GetByte(int i) + { + return _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); + } + + /// + /// Get the value of a column as a char, given its zero-based ordinal. + /// + /// + /// + public char GetChar(int i) + { + return _rdr.GetChar(i); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + return _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); + } + + /// + /// Get the value of a column as an int16, given its zero-based ordinal. + /// + /// + /// + public short GetInt16(int i) + { + return _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); + } + + /// + /// Get the value of a column as an int64, given its zero-based ordinal. + /// + /// + /// + public long GetInt64(int i) + { + return _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); + } + + /// + /// Get the value of a column as a double, given its zero-based ordinal. + /// + /// + /// + public double GetDouble(int i) + { + return _rdr.GetDouble(i); + } + + /// + /// Get the value of a column as a string, given its zero-based ordinal. + /// + /// + /// + public string GetString(int i) + { + return _rdr.GetString(i); + } + + /// + /// Get the value of a column as a decimal, given its zero-based ordinal. + /// + /// + /// + public decimal GetDecimal(int i) + { + return _rdr.GetDecimal(i); + } + + /// + /// Get the value of a column as a datetime, given its zero-based ordinal. + /// + /// + /// + public DateTime GetDateTime(int i) + { + return _rdr.GetDateTime(i); + } + + /// + /// Returns a DbDataReader of a column, given its zero-based ordinal. + /// + /// + /// + public IDataReader GetData(int i) + { + return _rdr.GetData(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 new file mode 100644 index 0000000..232b683 --- /dev/null +++ b/src/EntityFramework6.Npgsql/Spatial/PostgisServices.cs @@ -0,0 +1,1826 @@ +using System; +#if ENTITIES6 +using System.Data.Entity.Spatial; +#else +using System.Data.Spatial; +#endif + +namespace Npgsql.Spatial +{ + /// + /// A class exposing spatial services. + /// + 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)"; + return (byte[])cmd.ExecuteScalar(); + } + } + + /// + /// Returns the well known binary value of the geography input. + /// + /// + /// + public override byte[] AsBinary(DbGeography geographyValue) + { + 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)"; + return (string)cmd.ExecuteScalar(); + } + } + + /// + /// Returns the geographical markup language representation of the geography input. + /// + /// + /// + public override string AsGml(DbGeography geographyValue) + { + 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)"; + return (string)cmd.ExecuteScalar(); + } + } + + /// + /// Returns the well known text representation of the geography input. + /// + /// + /// + public override string AsText(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// + /// + /// + /// + 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)"; + return cmd.ExecuteScalar(); + } + } + + /// + /// + /// + /// + /// + public override object CreateProviderValue(DbGeographyWellKnownValue wellKnownValue) + { + 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)"; + var d = new DbGeometryWellKnownValue(); + d.WellKnownText = (string)cmd.ExecuteScalar(); + cmd.CommandText = "SELECT st_asbinary(:p1)"; + d.WellKnownBinary = (byte[])cmd.ExecuteScalar(); + cmd.CommandText = "SELECT st_srid(:p1)"; + d.CoordinateSystemId = (int)cmd.ExecuteScalar(); + return d; + } + } + + /// + /// + /// + /// + /// + public override DbGeographyWellKnownValue CreateWellKnownValue(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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()); + } + } + + /// + /// 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetDouble(0); + } + } + } + + /// + /// 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(); + } + + /// + /// 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()); + } + } + + /// + /// Given a geography collection, returns the index-nth geography. + /// + /// + /// + /// + public override DbGeography ElementAt(DbGeography geographyValue, int index) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyCollectionFromBinary(byte[] geographyCollectionWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyCollectionFromText(string geographyCollectionWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + public override DbGeography GeographyFromBinary(byte[] wellKnownBinary) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyFromBinary(byte[] wellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + public override DbGeography GeographyFromGml(string geographyMarkup) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyFromGml(string geographyMarkup, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + public override DbGeography GeographyFromProviderValue(object providerValue) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + public override DbGeography GeographyFromText(string wellKnownText) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyFromText(string wellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyLineFromBinary(byte[] lineWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyLineFromText(string lineWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiLineFromBinary(byte[] multiLineWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiLineFromText(string multiLineWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiPointFromBinary(byte[] multiPointWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiPointFromText(string multiPointWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiPolygonFromBinary(byte[] multiPolygonWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyMultiPolygonFromText(string multiPolygonWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyPointFromBinary(byte[] pointWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyPointFromText(string pointWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyPolygonFromBinary(byte[] polygonWellKnownBinary, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public override DbGeography GeographyPolygonFromText(string polygonWellKnownText, int coordinateSystemId) + { + throw new NotImplementedException(); + } + + /// + /// Get the geometry collection from a well know binary representation. + /// + /// + /// + /// + public override DbGeometry GeometryCollectionFromBinary(byte[] geometryCollectionWellKnownBinary, int coordinateSystemId) + { + 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// Wrap a npgsql geometry in a DbGeometry structure. + /// + /// + /// + public override DbGeometry GeometryFromProviderValue(object providerValue) + { + return DbSpatialServices.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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// Get a point from its well known text value. + /// + /// + /// + /// + public override DbGeometry GeometryPointFromText(string pointWellKnownText, int coordinateSystemId) + { + 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + } + } + } + + /// + /// Returns the area of the surface if it is a polygon or multi-polygon. + /// + /// + /// + public override double? GetArea(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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)"; + 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetInt32(0); + } + + } + } + + /// + /// Get the geograpy dimension. + /// + /// + /// + public override int GetDimension(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new int() : new int?(rdr.GetInt32(0)); + } + } + } + + /// + /// Get the element count of the geometry collection. + /// + /// + /// + public override int? GetElementCount(DbGeography geographyValue) + { + throw new NotImplementedException(); + } + + /// + /// Returns the elevation of the geometry + /// + /// + /// + public override double? GetElevation(DbGeometry geometryValue) + { + throw new NotImplementedException(); + } + + /// + /// Returns the elevation of the geography. + /// + /// + /// + public override double? GetElevation(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// Get the endpoint of the geography. + /// + /// + /// + public override DbGeography GetEndPoint(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// 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()); + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetInt32(0); + } + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// Check if the geography is closed; + /// + /// + /// + public override bool? GetIsClosed(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// Check if the geography is empty. + /// + /// + /// + public override bool GetIsEmpty(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// Returns the latitude of the geography. + /// + /// + /// + public override double? GetLatitude(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + } + } + } + + /// + /// Returns the length of the geography. + /// + /// + /// + public override double? GetLength(DbGeography geographyValue) + { + throw new NotImplementedException(); + } + + /// + /// Returns the longitutde of the geography. + /// + /// + /// + public override double? GetLongitude(DbGeography geographyValue) + { + throw new NotImplementedException(); + } + + /// + /// / + /// + /// + /// + public override double? GetMeasure(DbGeometry geometryValue) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + public override double? GetMeasure(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new int?() : new int?(rdr.GetInt32(0)); + } + } + } + + /// + /// Returns the point count of the geography. + /// + /// + /// + public override int? GetPointCount(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// 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)"; + return (string)cmd.ExecuteScalar(); + } + } + + /// + /// Returns the spatial type of the geography. + /// + /// + /// + public override string GetSpatialTypeName(DbGeography geographyValue) + { + 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()); + } + } + + /// + /// Returns the start point of the geography. + /// + /// + /// + public override DbGeography GetStartPoint(DbGeography geographyValue) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + } + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.IsDBNull(0) ? new double?() : new double?(rdr.GetDouble(0)); + } + } + } + + /// + /// 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()); + } + } + + /// + ///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()); + } + } + + /// + /// Returns the intersection of two geographies. + /// + /// + /// + /// + public override DbGeography Intersection(DbGeography geographyValue, DbGeography otherGeography) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// ??? + /// + /// + /// + /// + public override DbGeometry PointAt(DbGeometry geometryValue, int index) + { + throw new NotImplementedException(); + } + + /// + /// ??? + /// + /// + /// + /// + public override DbGeography PointAt(DbGeography geographyValue, int index) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// Returns true if the given geometries represent the same geometry. Directionality is ignored. + /// + /// + /// + /// + public override bool SpatialEquals(DbGeography geographyValue, DbGeography otherGeography) + { + throw new NotImplementedException(); + } + + /// + /// 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()); + } + } + + /// + /// 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(); + } + + /// + /// 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + /// + /// 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()); + } + } + + /// + /// Returns a geometry that represents the point set union of the Geometries. + /// + /// + /// + /// + public override DbGeography Union(DbGeography geographyValue, DbGeography otherGeography) + { + 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)"; + using (var rdr = cmd.ExecuteReader()) + { + rdr.Read(); + return rdr.GetBoolean(0); + } + } + } + + private NpgsqlConnection _connection; + + /// + /// Set the provider connection + /// + /// + public void SetConnection(Npgsql.NpgsqlConnection c) + { + _connection = c; + } + } +} diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs new file mode 100644 index 0000000..9f5bbc4 --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/PendingProjectsNode.cs @@ -0,0 +1,73 @@ +#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.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Npgsql.SqlGenerators +{ + /// + /// Represents an InputExpression and what alias it will have when used in a FROM clause + /// + internal class NameAndInputExpression + { + public string AsName { get; set; } + public InputExpression Exp { get; set; } + + public NameAndInputExpression(string asName, InputExpression exp) + { + AsName = asName; + Exp = exp; + } + } + + /// + /// A tree of subqueries, used when evaluating SQL text for DbPropertyExpressions in SqlSelectGenerator. + /// See SqlSelectGenerator.Visit(DbPropertyExpression) for more information. + /// + internal class PendingProjectsNode + { + public readonly List Selects = new List(); + public PendingProjectsNode JoinParent { get; set; } + public string TopName + { + get + { + return 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]; } } + } +} diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs new file mode 100644 index 0000000..ad76f38 --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -0,0 +1,1430 @@ +#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.Collections.Generic; +using System.Data.Common; +#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 NpgsqlTypes; + +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() + { + {"Avg","avg"}, + {"Count","count"}, + {"Min","min"}, + {"Max","max"}, + {"Sum","sum"}, + {"BigCount","count"}, + {"StDev","stddev_samp"}, + {"StDevP","stddev_pop"}, + {"Var","var_samp"}, + {"VarP","var_pop"}, + }; + +#if ENTITIES6 + private static readonly Dictionary BinaryOperatorFunctionNames = new Dictionary() + { + {"@@",Operator.QueryMatch}, + {"operator_tsquery_and",Operator.QueryAnd}, + {"operator_tsquery_or",Operator.QueryOr}, + {"operator_tsquery_contains",Operator.QueryContains}, + {"operator_tsquery_is_contained",Operator.QueryIsContained} + }; +#endif + + protected SqlBaseGenerator() + { + } + + private void EnterExpression(PendingProjectsNode n) + { + _currentExpressions.Add(n.Last.Exp); + } + private void LeaveExpression(PendingProjectsNode n) + { + _currentExpressions.Remove(n.Last.Exp); + } + + protected string NextAlias() + { + return "Alias" + _aliasCounter++; + } + + private 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"); + } + } + + private PendingProjectsNode GetInput(DbExpression expression, string childBindingName, string parentBindingName, DbExpressionKind parentKind) + { + PendingProjectsNode 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 n; + switch (expression.ExpressionKind) + { + case DbExpressionKind.Scan: + { + ScanExpression scan = (ScanExpression)expression.Accept(this); + InputExpression 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: + { + 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; + } + case DbExpressionKind.UnionAll: + case DbExpressionKind.Intersect: + case DbExpressionKind.Except: + { + 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; + } + case DbExpressionKind.Project: + { + 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; + } + case DbExpressionKind.GroupBy: + { + 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; + } + 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); + + JoinExpression from = VisitJoinChildren(expression, input, n); + + input.From = from; + + break; + } + default: throw new NotImplementedException(); + } + _refToNode[bindingName] = n; + return n; + } + + private 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; + } + return false; + } + + private JoinExpression VisitJoinChildren(DbExpression expression, InputExpression input, PendingProjectsNode n) + { + DbExpressionBinding left, right; + DbExpression condition = null; + if (expression.ExpressionKind == DbExpressionKind.CrossJoin) + { + left = ((DbCrossJoinExpression)expression).Inputs[0]; + right = ((DbCrossJoinExpression)expression).Inputs[1]; + if (((DbCrossJoinExpression)expression).Inputs.Count > 2) + { + // I have never seen more than 2 inputs in CrossJoin + throw new NotImplementedException(); + } + } + else if (expression.ExpressionKind == DbExpressionKind.CrossApply || expression.ExpressionKind == DbExpressionKind.OuterApply) + { + left = ((DbApplyExpression)expression).Input; + right = ((DbApplyExpression)expression).Apply; + } + else + { + left = ((DbJoinExpression)expression).Left; + right = ((DbJoinExpression)expression).Right; + condition = ((DbJoinExpression)expression).JoinCondition; + } + + 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 join = new JoinExpression(); + join.JoinType = joinType; + + if (IsJoin(left.ExpressionKind)) + { + join.Left = VisitJoinChildren(left, input, n); + } + else + { + PendingProjectsNode l = VisitInputWithBinding(left, leftName); + l.JoinParent = n; + join.Left = new FromExpression(l.Last.Exp, l.Last.AsName); + } + + if (joinType == DbExpressionKind.OuterApply || joinType == DbExpressionKind.CrossApply) + { + EnterExpression(n); + PendingProjectsNode r = VisitInputWithBinding(right, rightName); + LeaveExpression(n); + r.JoinParent = n; + join.Right = new FromExpression(r.Last.Exp, r.Last.AsName) { ForceSubquery = true }; + } + else + { + if (IsJoin(right.ExpressionKind)) + { + join.Right = VisitJoinChildren(right, input, n); + } + else + { + PendingProjectsNode r = VisitInputWithBinding(right, rightName); + r.JoinParent = n; + join.Right = new FromExpression(r.Last.Exp, r.Last.AsName); + } + } + + if (condition != null) + { + EnterExpression(n); + join.Condition = condition.Accept(this); + LeaveExpression(n); + } + return join; + } + + public override VisitedExpression Visit(DbVariableReferenceExpression expression) + { + //return new VariableReferenceExpression(expression.VariableName, _variableSubstitution); + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbUnionAllExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbTreatExpression expression) + { + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbSkipExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbSortExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbScanExpression expression) + { + MetadataProperty metadata; + string tableName; + string 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); + 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"; + 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) + { + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbRefExpression expression) + { + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbQuantifierExpression expression) + { + // TODO: EXISTS or NOT EXISTS depending on expression.ExpressionKind + // comes with it's built in test (subselect for EXISTS) + // This kind of expression is never even created in the EF6 code base + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbProjectExpression expression) + { + return VisitInputWithBinding(expression, NextAlias()).Last.Exp; + } + + public override VisitedExpression Visit(DbParameterReferenceExpression expression) + { + // use parameter in sql + return 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(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"); + } + + 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); + } + + public override VisitedExpression Visit(DbNewInstanceExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbLimitExpression expression) + { + // Normally handled by VisitInputWithBinding + + // Otherwise, it is (probably) a child of a DbElementExpression, + // 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()); + if (node.Last.Exp.Projection == null) + { + // This DbLimitExpression is (probably) a child of DbElementExpression + // and this expression's child is not a DbProjectExpression, but we should + // find a DbProjectExpression if we look deeper in the command tree. + // The child of this expression is (probably) a DbSortExpression or something else + // that will (probably) be an ancestor to a DbProjectExpression. + + // 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++) + { + ColumnExpression 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)); + } + + public override VisitedExpression Visit(DbJoinExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(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(DbIsEmptyExpression expression) + { + // NOT EXISTS + return OperatorExpression.Negate(new ExistsExpression(expression.Argument.Accept(this)), _useNewPrecedences); + } + + public override VisitedExpression Visit(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; + } + + public override VisitedExpression Visit(DbRefKeyExpression expression) + { + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(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); + } + + public override VisitedExpression Visit(DbFilterExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbExceptExpression expression) + { + // EXCEPT keyword + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(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("("); + scalar.Append(expression.Argument.Accept(this)); + scalar.Append(")"); + return scalar; + } + + public override VisitedExpression Visit(DbDistinctExpression expression) + { + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbDerefExpression expression) + { + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbCrossJoinExpression expression) + { + // join without ON + // Handled by VisitInputWithBinding + throw new NotImplementedException(); + } + + public override VisitedExpression Visit(DbConstantExpression expression) + { + 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); + return new LiteralExpression("@" + parameter.ParameterName); + } + else + { + return new ConstantExpression(expression.Value, expression.ResultType); + } + } + + public override VisitedExpression Visit(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(); + } + 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)); + } + + protected string GetDbType(EdmType edmType) + { + PrimitiveType 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"; + } + throw new NotSupportedException(); + } + + public override VisitedExpression Visit(DbCaseExpression expression) + { + LiteralExpression caseExpression = new LiteralExpression(" CASE "); + for (int i = 0; i < expression.When.Count && i < expression.Then.Count; ++i) + { + caseExpression.Append(" WHEN ("); + caseExpression.Append(expression.When[i].Accept(this)); + caseExpression.Append(") THEN ("); + 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) + { + 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(); + } + + if (expression.ExpressionKind == DbExpressionKind.UnaryMinus) + { + System.Diagnostics.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)); + } + } + + public override VisitedExpression Visit(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 + // left hand side (the Input part). + // sql standard is lateral join + + // Handled by VisitInputWithBinding + 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(DbExpression expression) + { + // only concrete types visited + throw new NotSupportedException(); + } + + public abstract void BuildCommand(DbCommand command); + + internal static string QuoteIdentifier(string identifier) + { + return "\"" + identifier.Replace("\"", "\"\"") + "\""; + } + + private VisitedExpression VisitFunction(DbFunctionAggregate functionAggregate) + { + if (functionAggregate.Function.NamespaceName == "Edm") + { + FunctionExpression aggregate; + try + { + aggregate = new FunctionExpression(AggregateFunctionNames[functionAggregate.Function.Name]); + } catch (KeyNotFoundException) + { + throw new NotSupportedException(); + } + System.Diagnostics.Debug.Assert(functionAggregate.Arguments.Count == 1); + VisitedExpression aggregateArg; + if (functionAggregate.Distinct) + { + aggregateArg = new LiteralExpression("DISTINCT "); + ((LiteralExpression)aggregateArg).Append(functionAggregate.Arguments[0].Accept(this)); + } + else + { + aggregateArg = functionAggregate.Arguments[0].Accept(this); + } + aggregate.AddArgument(aggregateArg); + return new CastExpression(aggregate, GetDbType(functionAggregate.ResultType.EdmType)); + } + throw new NotSupportedException(); + } + + private 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); + } + } + +#if ENTITIES6 + var functionName = function.StoreFunctionNameAttribute ?? function.Name; + if (function.NamespaceName == "Npgsql") + { + Operator binaryOperator; + if (BinaryOperatorFunctionNames.TryGetValue(functionName, out binaryOperator)) + { + if (args.Count != 2) + throw new ArgumentException($"Invalid number of {functionName} arguments. Expected 2.", nameof(args)); + + return OperatorExpression.Build( + binaryOperator, + _useNewPrecedences, + args[0].Accept(this), + args[1].Accept(this)); + } + + if (functionName == "operator_tsquery_negate") + { + if (args.Count != 1) + throw new ArgumentException("Invalid number of operator_tsquery_not arguments. Expected 1.", nameof(args)); + + return OperatorExpression.Build(Operator.QueryNegate, _useNewPrecedences, args[0].Accept(this)); + } + + if (functionName == "ts_rank" || functionName == "ts_rank_cd") + { + if (args.Count > 4) + { + var weightD = args[0] as DbConstantExpression; + var weightC = args[1] as DbConstantExpression; + var weightB = args[2] as DbConstantExpression; + var weightA = args[3] as DbConstantExpression; + + if (weightD == null || weightC == null || weightB == null || weightA == null) + throw new NotSupportedException("All weight values must be constant expressions."); + + var newValue = string.Format( + CultureInfo.InvariantCulture, + "{{ {0:r}, {1:r}, {2:r}, {3:r} }}", + weightD.Value, + weightC.Value, + weightB.Value, + weightA.Value); + + args = new[] { DbExpression.FromString(newValue) }.Concat(args.Skip(4)).ToList(); + } + } + else if (functionName == "setweight") + { + if (args.Count != 2) + throw new ArgumentException("Invalid number of setweight arguments. Expected 2.", nameof(args)); + + var weightLabelExpression = args[1] as DbConstantExpression; + if (weightLabelExpression == null) + throw new NotSupportedException("setweight label argument must be a constant expression."); + + var weightLabel = (NpgsqlWeightLabel)weightLabelExpression.Value; + if (!Enum.IsDefined(typeof(NpgsqlWeightLabel), weightLabelExpression.Value)) + throw new NotSupportedException("Unsupported weight label value: " + weightLabel); + + args = new[] { args[0], DbExpression.FromString(weightLabel.ToString()) }; + } + else if (functionName == "as_tsvector") + { + if (args.Count != 1) + throw new ArgumentException("Invalid number of arguments. Expected 1.", nameof(args)); + + return new CastExpression(args[0].Accept(this), "tsvector"); + } + else if (functionName == "as_tsquery") + { + if (args.Count != 1) + throw new ArgumentException("Invalid number of arguments. Expected 1.", nameof(args)); + + return new CastExpression(args[0].Accept(this), "tsquery"); + } + } + + var customFuncCall = new FunctionExpression( + string.IsNullOrEmpty(function.Schema) + ? QuoteIdentifier(functionName) + : QuoteIdentifier(function.Schema) + "." + QuoteIdentifier(functionName) + ); + + foreach (var a in args) + customFuncCall.AddArgument(a.Accept(this)); + return customFuncCall; +#else + throw new NotSupportedException(); +#endif + } + + private VisitedExpression Substring(VisitedExpression source, VisitedExpression start, VisitedExpression count) + { + FunctionExpression substring = new FunctionExpression("substr"); + substring.AddArgument(source); + substring.AddArgument(start); + substring.AddArgument(count); + return substring; + } + + private VisitedExpression Substring(VisitedExpression source, VisitedExpression start) + { + FunctionExpression substring = new FunctionExpression("substr"); + substring.AddArgument(source); + substring.AddArgument(start); + return substring; + } + + private VisitedExpression UnaryMath(string funcName, IList args) + { + FunctionExpression mathFunction = new FunctionExpression(funcName); + System.Diagnostics.Debug.Assert(args.Count == 1); + mathFunction.AddArgument(args[0].Accept(this)); + return mathFunction; + } + + private VisitedExpression BinaryMath(string funcName, IList args) + { + FunctionExpression mathFunction = new FunctionExpression(funcName); + System.Diagnostics.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) + { + FunctionExpression modifierFunction = new FunctionExpression(modifier); + System.Diagnostics.Debug.Assert(args.Count == 1); + modifierFunction.AddArgument(args[0].Accept(this)); + return modifierFunction; + } + + private VisitedExpression DatePart(string partName, IList args) + { + + FunctionExpression extract_date = new FunctionExpression("cast(extract"); + System.Diagnostics.Debug.Assert(args.Count == 1); + VisitedExpression arg = new LiteralExpression(partName + " FROM "); + arg.Append(args[0].Accept(this)); + extract_date.AddArgument(arg); + // need to convert to Int32 to match cononical function + extract_date.Append(" as int4)"); + return extract_date; + } + + /// + /// PostgreSQL has no direct functions to implements DateTime canonical functions + /// http://msdn.microsoft.com/en-us/library/bb738626.aspx + /// http://msdn.microsoft.com/en-us/library/bb738626.aspx + /// but we can use workaround: + /// expression + number * INTERVAL '1 number_type' + /// where number_type is the number type (days, years and etc) + /// + /// + /// + /// + private VisitedExpression DateAdd(string functionName, IList args) + { + bool nano = false; + string part = functionName.Substring(3); + + if (part == "Nanoseconds") + { + nano = true; + part = "Microseconds"; + } + + System.Diagnostics.Debug.Assert(args.Count == 2); + VisitedExpression time = args[0].Accept(this); + VisitedExpression 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)); + return OperatorExpression.Build(Operator.Add, _useNewPrecedences, time, OperatorExpression.Build(Operator.Mul, _useNewPrecedences, mulLeft, mulRight)); + } + + private 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); + } + } + + private VisitedExpression BitwiseOperator(IList args, Operator oper) + { + System.Diagnostics.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) + { + VisitedExpression item = expression.Item.Accept(this); + + ConstantExpression[] elements = new ConstantExpression[expression.List.Count]; + for (int 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) + { + // 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 new file mode 100644 index 0000000..a0cc522 --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlDeleteGenerator.cs @@ -0,0 +1,67 @@ +#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.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 +{ + internal class SqlDeleteGenerator : SqlBaseGenerator + { + private DbDeleteCommandTree _commandTree; + private string _tableName; + + public SqlDeleteGenerator(DbDeleteCommandTree commandTree) + { + _commandTree = commandTree; + } + + public override VisitedExpression Visit(DbPropertyExpression expression) + { + DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + if (variable == null || variable.VariableName != _tableName) + throw new NotSupportedException(); + return new PropertyExpression(expression.Property); + } + + public override void BuildCommand(DbCommand command) + { + // TODO: handle _commandTree.Returning and _commandTree.Parameters + DeleteExpression 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 new file mode 100644 index 0000000..b018bca --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlInsertGenerator.cs @@ -0,0 +1,76 @@ +#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.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 +{ + internal class SqlInsertGenerator : SqlBaseGenerator + { + private DbInsertCommandTree _commandTree; + private string _tableName; + + public SqlInsertGenerator(DbInsertCommandTree commandTree) + { + _commandTree = commandTree; + } + + public override VisitedExpression Visit(DbPropertyExpression expression) + { + DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + if (variable == null || variable.VariableName != _tableName) + throw new NotSupportedException(); + return new PropertyExpression(expression.Property); + } + + public override void BuildCommand(DbCommand command) + { + // TODO: handle_commandTree.Parameters + InsertExpression insert = new InsertExpression(); + _tableName = _commandTree.Target.VariableName; + insert.AppendTarget(_commandTree.Target.Expression.Accept(this)); + List columns = new List(); + List values = new List(); + foreach (DbSetClause clause in _commandTree.SetClauses) + { + columns.Add(clause.Property.Accept(this)); + values.Add(clause.Value.Accept(this)); + } + insert.AppendColumns(columns); + insert.AppendValues(values); + if (_commandTree.Returning != null) + { + insert.AppendReturning(_commandTree.Returning as DbNewInstanceExpression); + } + _tableName = null; + command.CommandText = insert.ToString(); + } + } +} diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs new file mode 100644 index 0000000..ef4e8ba --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlSelectGenerator.cs @@ -0,0 +1,152 @@ +#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.Linq; +using System.Collections.Generic; +using System.Data.Common; +#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 +{ + internal class SqlSelectGenerator : SqlBaseGenerator + { + private DbQueryCommandTree _commandTree; + + public SqlSelectGenerator(DbQueryCommandTree commandTree) + { + _commandTree = commandTree; + } + + protected SqlSelectGenerator() + { + // used only for other generators such as returning + } + + public override VisitedExpression Visit(DbPropertyExpression expression) + { + /* + * Algorithm for finding the correct reference expression: "Collection"."Name" + * The collection is always a leaf InputExpression, found by lookup in _refToNode. + * The name for the collection is found using node.TopName. + * + * We must now follow the path from the leaf down to the root, + * and make sure the column is projected all the way down. + * + * We need not project columns at a current InputExpression. + * For example, in + * SELECT ? FROM AS "X" WHERE "X"."field" = + * we use the property "field" but it should not be projected. + * Current expressions are stored in _currentExpressions. + * There can be many of these, for example if we are in a WHERE EXISTS (SELECT ...) or in the right hand side of an Apply expression. + * + * At join nodes, column names might have to be renamed, if a name collision occurs. + * For example, the following would be illegal, + * SELECT "X"."A" AS "A", "Y"."A" AS "A" FROM (SELECT 1 AS "A") AS "X" CROSS JOIN (SELECT 1 AS "A") AS "Y" + * so we write + * SELECT "X"."A" AS "A", "Y"."A" AS "A_Alias" FROM (SELECT 1 AS "A") AS "X" CROSS JOIN (SELECT 1 AS "A") AS "Y" + * The new name is then propagated down to the root. + */ + + string name = expression.Property.Name; + string from = (expression.Instance.ExpressionKind == DbExpressionKind.Property) + ? ((DbPropertyExpression)expression.Instance).Property.Name + : ((DbVariableReferenceExpression)expression.Instance).VariableName; + + PendingProjectsNode node = _refToNode[from]; + from = node.TopName; + while (node != null) + { + foreach (var item in node.Selects) + { + if (_currentExpressions.Contains(item.Exp)) + continue; + + var use = new StringPair(from, name); + + if (!item.Exp.ColumnsToProject.ContainsKey(use)) + { + var oldName = name; + while (item.Exp.ProjectNewNames.Contains(name)) + name = oldName + "_" + NextAlias(); + item.Exp.ColumnsToProject[use] = name; + item.Exp.ProjectNewNames.Add(name); + } + else + { + name = item.Exp.ColumnsToProject[use]; + } + from = item.AsName; + } + node = node.JoinParent; + } + return new ColumnReferenceExpression { Variable = from, Name = name }; + } + + 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)); + } + + 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; + command.CommandText = pe.ToString(); + + // We retrieve all strings as unknowns in text format in the case the data types aren't really texts + ((NpgsqlCommand)command).UnknownResultTypeList = pe.Projection.Arguments.Select(a => ((PrimitiveType)((ColumnExpression)a).ColumnType.EdmType).PrimitiveTypeKind == PrimitiveTypeKind.String).ToArray(); + + // We must treat sbyte and DateTimeOffset specially so the value is read correctly + if (pe.Projection.Arguments.Any(a => { + var kind = ((PrimitiveType)((ColumnExpression)a).ColumnType.EdmType).PrimitiveTypeKind; + return kind == PrimitiveTypeKind.SByte || kind == PrimitiveTypeKind.DateTimeOffset; + })) + { + ((NpgsqlCommand)command).ObjectResultTypes = pe.Projection.Arguments.Select(a => { + var kind = ((PrimitiveType)((ColumnExpression)a).ColumnType.EdmType).PrimitiveTypeKind; + if (kind == PrimitiveTypeKind.SByte) + { + return typeof(sbyte); + } + else if (kind == PrimitiveTypeKind.DateTimeOffset) + { + return typeof(DateTimeOffset); + } + return null; + }).ToArray(); + } + } + } +} diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs new file mode 100644 index 0000000..9912e4e --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlUpdateGenerator.cs @@ -0,0 +1,75 @@ +#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.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 +{ + class SqlUpdateGenerator : SqlBaseGenerator + { + private DbUpdateCommandTree _commandTree; + private string _tableName; + + public SqlUpdateGenerator(DbUpdateCommandTree commandTree) + { + _commandTree = commandTree; + } + + public override VisitedExpression Visit(DbPropertyExpression expression) + { + DbVariableReferenceExpression variable = expression.Instance as DbVariableReferenceExpression; + if (variable == null || variable.VariableName != _tableName) + throw new NotSupportedException(); + return new PropertyExpression(expression.Property); + } + + public override void BuildCommand(DbCommand command) + { + // TODO: handle _commandTree.Parameters + UpdateExpression 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 new file mode 100644 index 0000000..7cd6779 --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/StringPair.cs @@ -0,0 +1,65 @@ +#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.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Npgsql.SqlGenerators +{ + /// + /// Used for lookup in a Dictionary, since Tuple is not available in .NET 3.5 + /// + internal class StringPair + { + private string _item1; + private string _item2; + + public string Item1 { get { return _item1; } } + public string Item2 { get { return _item2; } } + + public StringPair(string s1, string s2) + { + _item1 = s1; + _item2 = s2; + } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + StringPair o = obj as StringPair; + if (o == null) + return false; + + return _item1 == o._item1 && _item2 == o._item2; + } + + public override int GetHashCode() + { + return (_item1 + "." + _item2).GetHashCode(); + } + } +} diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs new file mode 100644 index 0000000..0f468d0 --- /dev/null +++ b/src/EntityFramework6.Npgsql/SqlGenerators/VisitedExpression.cs @@ -0,0 +1,1240 @@ +#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.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.Data; +using System.Globalization; + +namespace Npgsql.SqlGenerators +{ + internal abstract class VisitedExpression + { + protected VisitedExpression() + { + ExpressionList = new List(); + } + + public VisitedExpression Append(VisitedExpression expression) + { + ExpressionList.Add(expression); + return this; + } + + public VisitedExpression Append(string literal) + { + ExpressionList.Add(new LiteralExpression(literal)); + return this; + } + + public override string ToString() + { + StringBuilder sqlText = new StringBuilder(); + WriteSql(sqlText); + return sqlText.ToString(); + } + + protected List ExpressionList { get; private set; } + + internal virtual void WriteSql(StringBuilder sqlText) + { + foreach (VisitedExpression expression in ExpressionList) + { + expression.WriteSql(sqlText); + } + } + } + + internal class LiteralExpression : VisitedExpression + { + private string _literal; + + public LiteralExpression(string literal) + { + _literal = literal; + } + + public new LiteralExpression Append(VisitedExpression expresion) + { + base.Append(expresion); + return this; + } + + public new void Append(string literal) + { + base.Append(literal); + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(_literal); + base.WriteSql(sqlText); + } + } + + internal class CommaSeparatedExpression : VisitedExpression + { + public readonly List Arguments = new List(); + + internal override void WriteSql(StringBuilder sqlText) + { + for (int i = 0; i < Arguments.Count; ++i) + { + if (i != 0) + sqlText.Append(", "); + Arguments[i].WriteSql(sqlText); + } + base.WriteSql(sqlText); + } + } + + internal class ConstantExpression : VisitedExpression + { + private PrimitiveTypeKind _primitiveType; + private object _value; + + public ConstantExpression(object value, TypeUsage edmType) + { + if (edmType == null) + throw new ArgumentNullException("edmType"); + if (edmType.EdmType == null || edmType.EdmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) + throw new ArgumentException("Require primitive EdmType", "edmType"); + _primitiveType = ((PrimitiveType)edmType.EdmType).PrimitiveTypeKind; + _value = value; + } + + internal override void WriteSql(StringBuilder sqlText) + { + var ni = CultureInfo.InvariantCulture.NumberFormat; + object 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)); + } + base.WriteSql(sqlText); + } + } + + internal class InsertExpression : VisitedExpression + { + public void AppendTarget(VisitedExpression target) + { + Append(target); + } + + public void AppendColumns(IEnumerable columns) + { + if (!columns.Any()) + return; + + Append("("); + bool first = true; + foreach (VisitedExpression expression in columns) + { + if (!first) + Append(","); + Append(expression); + first = false; + } + Append(")"); + } + + public void AppendValues(IEnumerable columns) + { + if (columns.Any()) + { + Append(" VALUES ("); + bool first = true; + foreach (VisitedExpression expression in columns) + { + if (!first) + Append(","); + Append(expression); + first = false; + } + 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; + foreach (var returingProperty in expression.Arguments) + { + if (!first) + Append(","); + Append(SqlBaseGenerator.QuoteIdentifier((returingProperty as DbPropertyExpression).Property.Name)); + first = false; + } + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("INSERT INTO "); + base.WriteSql(sqlText); + } + } + + internal class UpdateExpression : VisitedExpression + { + private bool _setSeperatorRequired; + + public void AppendTarget(VisitedExpression target) + { + Append(target); + } + + public void AppendSet(VisitedExpression property, VisitedExpression value) + { + if (_setSeperatorRequired) + Append(","); + else + Append(" SET "); + Append(property); + Append("="); + Append(value); + _setSeperatorRequired = true; + } + + public void AppendWhere(VisitedExpression where) + { + Append(" WHERE "); + Append(where); + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("UPDATE "); + base.WriteSql(sqlText); + } + + internal void AppendReturning(DbNewInstanceExpression expression) + { + Append(" RETURNING ");//Don't put () around columns it will probably have unwanted effect + bool first = true; + foreach (var returingProperty in expression.Arguments) + { + if (!first) + Append(","); + Append(SqlBaseGenerator.QuoteIdentifier((returingProperty as DbPropertyExpression).Property.Name)); + first = false; + } + } + } + + internal class DeleteExpression : VisitedExpression + { + public void AppendFrom(VisitedExpression from) + { + Append(from); + } + + public void AppendWhere(VisitedExpression where) + { + Append(" WHERE "); + Append(where); + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("DELETE FROM "); + base.WriteSql(sqlText); + } + } + + internal class ColumnExpression : VisitedExpression + { + private VisitedExpression _column; + private string _columnName; + private TypeUsage _columnType; + + public ColumnExpression(VisitedExpression column, string columnName, TypeUsage columnType) + { + _column = column; + _columnName = columnName; + _columnType = columnType; + } + + public string Name { get { return _columnName; } } + internal TypeUsage ColumnType { get { return _columnType; ;} } + + public Type CLRType + { + get + { + if (_columnType == null) + return null; + PrimitiveType pt = _columnType.EdmType as PrimitiveType; + if (pt != null) + return pt.ClrEquivalentType; + else + return null; + } + } + + internal override void WriteSql(StringBuilder sqlText) + { + _column.WriteSql(sqlText); + + ColumnReferenceExpression column = _column as ColumnReferenceExpression; + if (column == null || column.Name != _columnName) + { + sqlText.Append(" AS "); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_columnName)); + } + + base.WriteSql(sqlText); + } + } + + internal class ColumnReferenceExpression : VisitedExpression + { + public string Variable { get; set; } + public string Name { get; set; } + + internal override void WriteSql(StringBuilder sqlText) + { + if (Variable != null) + { + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(Variable)); + sqlText.Append("."); + } + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(Name)); + base.WriteSql(sqlText); + } + } + + internal class ScanExpression : VisitedExpression + { + private string _scanString; + private EntitySetBase _target; + + public ScanExpression(string scanString, EntitySetBase target) + { + _scanString = scanString; + _target = target; + } + + internal EntitySetBase Target { get { return _target; } } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(_scanString); + base.WriteSql(sqlText); + } + } + + internal class InputExpression : VisitedExpression + { + public bool Distinct { get; set; } + + public CommaSeparatedExpression Projection { get; set; } + + public readonly Dictionary ColumnsToProject = new Dictionary(); // (from, name) -> newName + public readonly HashSet ProjectNewNames = new HashSet(); + + // 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 InputExpression() { } + + public InputExpression(VisitedExpression from, string asName) + { + From = new FromExpression(from, asName); + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("SELECT "); + 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; + foreach (var column in ColumnsToProject) + { + if (!first) + { + sqlText.Append(", "); + } + else first = false; + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(column.Key.Item1)); + sqlText.Append("."); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(column.Key.Item2)); + if (column.Key.Item2 != column.Value) + { + sqlText.Append(" AS "); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(column.Value)); + } + } + } + } + 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); + base.WriteSql(sqlText); + } + } + + internal class FromExpression : VisitedExpression + { + private VisitedExpression _from; + private string _name; + + public FromExpression(VisitedExpression from, string name) + { + _from = from; + _name = name; + } + + public string Name + { + get { return _name; } + } + + public bool ForceSubquery { get; set; } + + internal override void WriteSql(StringBuilder sqlText) + { + if (_from is InputExpression) + { + InputExpression input = (InputExpression)_from; + if (!ForceSubquery && input.Projection == null && input.Where == null && input.Distinct == false && input.OrderBy == null && + input.Skip == null && input.Limit == null) + { + // There is no point of writing + // (SELECT ? FROM AS ) AS + // so just write AS + // is always the same for both nodes + // However, PostgreSQL needs a subquery in case we are in the right hand side of an Apply expression + if (((FromExpression)input.From).Name != Name) + throw new ArgumentException(); + input.From.WriteSql(sqlText); + } + else + { + sqlText.Append("("); + input.WriteSql(sqlText); + sqlText.Append(") AS "); + sqlText.Append(SqlBaseGenerator.QuoteIdentifier(_name)); + } + } + else + { + bool 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)); + } + base.WriteSql(sqlText); + } + } + + internal class JoinExpression : VisitedExpression + { + private VisitedExpression _left; + private DbExpressionKind _joinType; + private VisitedExpression _right; + private VisitedExpression _condition; + + 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; } + } + + internal override void WriteSql(StringBuilder sqlText) + { + _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(); + } + _right.WriteSql(sqlText); + if (_joinType == DbExpressionKind.OuterApply) + sqlText.Append(" ON TRUE"); + else if (_joinType != DbExpressionKind.CrossJoin && _joinType != DbExpressionKind.CrossApply) + { + sqlText.Append(" ON "); + _condition.WriteSql(sqlText); + } + base.WriteSql(sqlText); + } + } + + internal class WhereExpression : VisitedExpression + { + private VisitedExpression _where; + + public WhereExpression(VisitedExpression where) + { + _where = where; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(" WHERE "); + _where.WriteSql(sqlText); + base.WriteSql(sqlText); + } + + internal void And(VisitedExpression andAlso) + { + // useNewPrecedence doesn't matter here since there was no change with the AND operator + _where = OperatorExpression.Build(Operator.And, true, _where, andAlso); + } + } + + internal class PropertyExpression : VisitedExpression + { + private EdmMember _property; + + // used for inserts or updates where the column is not qualified + 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)); + base.WriteSql(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; + } + } + + internal class FunctionExpression : VisitedExpression + { + private string _name; + private List _args = new List(); + + public FunctionExpression(string name) + { + _name = name; + } + + internal FunctionExpression AddArgument(VisitedExpression visitedExpression) + { + _args.Add(visitedExpression); + return this; + } + + internal FunctionExpression AddArgument(string argument) + { + _args.Add(new LiteralExpression(argument)); + return this; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(_name); + sqlText.Append("("); + bool first = true; + foreach (var arg in _args) + { + if (!first) + sqlText.Append(","); + arg.WriteSql(sqlText); + first = false; + } + sqlText.Append(")"); + base.WriteSql(sqlText); + } + } + + internal class CastExpression : VisitedExpression + { + private VisitedExpression _value; + private string _type; + + public CastExpression(VisitedExpression value, string type) + { + _value = value; + _type = type; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("CAST ("); + _value.WriteSql(sqlText); + sqlText.AppendFormat(" AS {0})", _type); + base.WriteSql(sqlText); + } + } + + internal class GroupByExpression : VisitedExpression + { + private bool _requiresGroupSeperator; + + public void AppendGroupingKey(VisitedExpression key) + { + if (_requiresGroupSeperator) + Append(","); + Append(key); + _requiresGroupSeperator = true; + } + + internal override void WriteSql(StringBuilder sqlText) + { + if (ExpressionList.Count != 0) + sqlText.Append(" GROUP BY "); + base.WriteSql(sqlText); + } + } + + internal class LimitExpression : VisitedExpression + { + private VisitedExpression _arg; + + public VisitedExpression Arg { get { return _arg; } set { _arg = value; } } + + public LimitExpression(VisitedExpression arg) + { + _arg = arg; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(" LIMIT "); + _arg.WriteSql(sqlText); + base.WriteSql(sqlText); + } + } + + internal class SkipExpression : VisitedExpression + { + private VisitedExpression _arg; + + public SkipExpression(VisitedExpression arg) + { + _arg = arg; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(" OFFSET "); + _arg.WriteSql(sqlText); + base.WriteSql(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 enum UnaryTypes { + Binary, + Prefix, + Postfix + } + + private Operator(string op, int precedence, int newPrecedence) + { + this.op = ' ' + op + ' '; + this.leftPrecedence = precedence; + this.rightPrecedence = precedence; + this.newPrecedence = newPrecedence; + this.unaryType = UnaryTypes.Binary; + } + + private 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; + } + + private 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; + } + + /* + * Operator table + * Corresponds to the operator precedence table at + * http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html + * + * Note that in versions up to 9.4, NOT IN and NOT LIKE have different precedences depending on + * if the other operator is to the left or to the right. + * For example, "a = b NOT LIKE c" is parsed as "(a = b) NOT LIKE c" + * but "a NOT LIKE b = c" is parsed as "(a NOT LIKE b) = c" + * This is because PostgreSQL's parser uses Bison's automatic + * operator precedence handling, and NOT and LIKE has different precedences, + * so this happens when the two keywords are put together like this. + * + */ + public static readonly Operator UnaryMinus = new Operator("-", 17, 12, UnaryTypes.Prefix, true); + public static readonly Operator Mul = new Operator("*", 15, 10); + public static readonly Operator Div = new Operator("/", 15, 10); + public static readonly Operator Mod = new Operator("%", 15, 10); + public static readonly Operator Add = new Operator("+", 14, 9); + public static readonly Operator Sub = new Operator("-", 14, 9); + public static readonly Operator IsNull = new Operator("IS NULL", 13, 4, UnaryTypes.Postfix, false); + public static readonly Operator IsNotNull = new Operator("IS NOT NULL", 13, 4, UnaryTypes.Postfix, false); + public static readonly Operator LessThanOrEquals = new Operator("<=", 10, 5); + public static readonly Operator GreaterThanOrEquals = new Operator(">=", 10, 5); + public static readonly Operator NotEquals = new Operator("!=", 10, 5); + public static readonly Operator BitwiseAnd = new Operator("&", 10, 8); + public static readonly Operator BitwiseOr = new Operator("|", 10, 8); + public static readonly Operator BitwiseXor = new Operator("#", 10, 8); + public static readonly Operator BitwiseNot = new Operator("~", 10, 8, UnaryTypes.Prefix, false); + public static readonly Operator Concat = new Operator("||", 10, 8); + public static readonly Operator In = new Operator("IN", 9, 6); + public static readonly Operator NotIn = new Operator("NOT IN", 3, 9, 6); + public static readonly Operator Like = new Operator("LIKE", 6, 6); + 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 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); + + public static readonly Operator QueryMatch = new Operator("@@", 10, 8); + public static readonly Operator QueryAnd = new Operator("&&", 10, 8); + public static readonly Operator QueryOr = Concat; + 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 Dictionary NegateDict; + + 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} + }; + } + } + + internal class OperatorExpression : VisitedExpression + { + private Operator op; + private bool useNewPrecedences; + private VisitedExpression left; + private VisitedExpression right; + + private OperatorExpression(Operator op, bool useNewPrecedences, VisitedExpression left, VisitedExpression right) + { + this.op = op; + this.useNewPrecedences = useNewPrecedences; + this.left = left; + this.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"); + } + } + + public static OperatorExpression Build(Operator op, bool useNewPrecedences, VisitedExpression exp) + { + if (op.UnaryType == Operator.UnaryTypes.Prefix) + { + return new OperatorExpression(op, useNewPrecedences, null, exp); + } + else if (op.UnaryType == Operator.UnaryTypes.Postfix) + { + return new OperatorExpression(op, useNewPrecedences, exp, null); + } + else + { + throw new InvalidOperationException("Binary operator with one operand"); + } + } + + /// + /// Negates an expression. + /// If possible, replaces the operator of exp if exp is a negatable OperatorExpression, + /// else return a new OperatorExpression of type Not that wraps exp. + /// + public static VisitedExpression Negate(VisitedExpression exp, bool useNewPrecedences) + { + OperatorExpression expOp = exp as OperatorExpression; + if (expOp != null) + { + Operator op = expOp.op; + Operator newOp = null; + if (Operator.NegateDict.TryGetValue(op, out newOp)) + { + expOp.op = newOp; + return expOp; + } + if (expOp.op == Operator.Not) + { + return expOp.right; + } + } + + return OperatorExpression.Build(Operator.Not, useNewPrecedences, exp); + } + + internal override void WriteSql(StringBuilder sqlText) + { + WriteSql(sqlText, null); + } + + private void WriteSql(StringBuilder sqlText, OperatorExpression rightParent) + { + OperatorExpression leftOp = left as OperatorExpression; + OperatorExpression rightOp = right as OperatorExpression; + + bool wrapLeft, wrapRight; + + 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); + } + 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); + } + + // 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 (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))) + wrapRight = false; + } + + if (left != null) + { + if (wrapLeft) + sqlText.Append("("); + if (leftOp != null && !wrapLeft) + leftOp.WriteSql(sqlText, this); + else + left.WriteSql(sqlText); + if (wrapLeft) + sqlText.Append(")"); + } + + sqlText.Append(op.Op); + + if (right != null) + { + if (wrapRight) + sqlText.Append("("); + if (rightOp != null && !wrapRight) + rightOp.WriteSql(sqlText, rightParent); + else + right.WriteSql(sqlText); + if (wrapRight) + sqlText.Append(")"); + } + + base.WriteSql(sqlText); + } + } + + internal class ConstantListExpression : VisitedExpression + { + private IEnumerable _list; + + public ConstantListExpression(IEnumerable list) + { + _list = list; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("("); + bool first = true; + foreach (var constant in _list) + { + if (!first) + sqlText.Append(","); + constant.WriteSql(sqlText); + first = false; + } + sqlText.Append(")"); + base.WriteSql(sqlText); + } + } + + internal class CombinedProjectionExpression : VisitedExpression + { + private List _list; + private string _setOperator; + + public CombinedProjectionExpression(DbExpressionKind setOperator, List list) + { + _setOperator = setOperator == DbExpressionKind.UnionAll ? "UNION ALL" : setOperator == DbExpressionKind.Except ? "EXCEPT" : "INTERSECT"; + _list = list; + } + + 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(')'); + } + + base.WriteSql(sqlText); + } + } + + internal class ExistsExpression : VisitedExpression + { + private VisitedExpression _argument; + + public ExistsExpression(VisitedExpression argument) + { + _argument = argument; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("EXISTS ("); + _argument.WriteSql(sqlText); + sqlText.Append(")"); + base.WriteSql(sqlText); + } + } + + class OrderByExpression : VisitedExpression + { + private bool _requiresOrderSeperator; + + public void AppendSort(VisitedExpression sort, bool ascending) + { + if (_requiresOrderSeperator) + Append(","); + Append(sort); + if (ascending) + Append(" ASC "); + else + Append(" DESC "); + _requiresOrderSeperator = true; + } + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append(" ORDER BY "); + base.WriteSql(sqlText); + } + } + + internal class TruncateTimeExpression : VisitedExpression + { + readonly VisitedExpression _arg; + readonly string _truncationType; + public TruncateTimeExpression(string truncationType, VisitedExpression visitedExpression) + { + _arg = visitedExpression; + _truncationType = truncationType; + } + + + internal override void WriteSql(StringBuilder sqlText) + { + sqlText.Append("date_trunc"); + sqlText.Append("("); + sqlText.Append("'" + _truncationType + "',"); + _arg.WriteSql(sqlText); + sqlText.Append(")"); + base.WriteSql(sqlText); + } + } +} diff --git a/src/EntityFramework6.Npgsql/install.ps1 b/src/EntityFramework6.Npgsql/install.ps1 new file mode 100644 index 0000000..b6b6c15 --- /dev/null +++ b/src/EntityFramework6.Npgsql/install.ps1 @@ -0,0 +1,3 @@ +param($installPath, $toolsPath, $package, $project) + +Add-EFProvider $project 'Npgsql' 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' diff --git a/src/EntityFramework6.Npgsql/project.json b/src/EntityFramework6.Npgsql/project.json new file mode 100644 index 0000000..fc9f7a1 --- /dev/null +++ b/src/EntityFramework6.Npgsql/project.json @@ -0,0 +1,54 @@ +{ + "version": "3.1.0-*", + "packOptions": { + "owners": [ + "Shay Rojansky", + "Emil Lenngren", + "Francisco Figueiredo Jr.", + "Kenji Uno" + ], + "authors": [ + "Shay Rojansky", + "Emil Lenngren", + "Francisco Figueiredo Jr.", + "Kenji Uno", + "Jon Asher", + "Josh Cooley", + "Federico Di Gregorio", + "Jon Hanna", + "Chris Morgan", + "Dave Page", + "Glen Parker", + "Brar Piening", + "Hiroshi Saito" + ], + "description" : "PostgreSQL provider for Entity Framework 6", + "iconUrl": "http://www.npgsql.org/img/postgresql.gif", + "licenseUrl": "https://raw.githubusercontent.com/npgsql/npgsql/develop/LICENSE.txt", + "repository": { + "type": "git", + "url": "git://github.com/npgsql/npgsql" + } + }, + "buildOptions": { + "define": [ "ENTITIES6" ], + "keyFile": "../../Npgsql.snk" + }, + "dependencies" : { + "EntityFramework": "6.1.3", + "Npgsql": "3.1.0-*" + }, + "frameworks": { + "net451": { + "frameworkAssemblies": { + "System.Collections": { "version": "4.0.0.0", "type": "build" }, + "System.Data": { "version": "4.0.0.0", "type": "build" }, + "System.Data.Entity": { "version": "4.0.0.0", "type": "build" }, + "System.Reflection": { "version": "4.0.0.0", "type": "build" }, + "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, + "System.Linq.Expressions": { "version": "4.0.0.0", "type": "build" }, + "System.Runtime": { "version": "4.0.0.0", "type": "build" } + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/test/EntityFramework6.Npgsql.Tests/App.config new file mode 100644 index 0000000..bc096b3 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/App.config @@ -0,0 +1,42 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj new file mode 100644 index 0000000..c3246a7 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -0,0 +1,90 @@ + + + + {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} + EntityFramework6.Npgsql.Tests + Debug + AnyCPU + true + ..\..\Npgsql.snk + Library + EntityFramework6.Npgsql.Tests + ..\..\ + true + + v4.6 + + false + + + bin\Debug\ + true + full + false + + + true + 4 + TRACE;DEBUG;NET46 + + + bin\Release\ + + + true + true + 4 + TRACE;NET46 + + + + + 3.5 + + + + + 3.0 + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + + + {3ec85cba-5b79-11e3-8104-0022198ab089} + EntityFramework6.Npgsql + + + {9D13B739-62B1-4190-B386-7A9547304EB3} + Npgsql + + + {e9c258d7-0d8e-4e6a-9857-5c6438591755} + Npgsql.Tests + + + + diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs new file mode 100644 index 0000000..ec12f4f --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -0,0 +1,655 @@ +#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 Npgsql.Tests; +using NpgsqlTypes; + +namespace EntityFramework6.Npgsql.Tests +{ + public class EntityFrameworkBasicTests : EntityFrameworkTestBase + { + [Test] + public void InsertAndSelect() + { + var varbitVal = "10011"; + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var blog = new Blog() + { + Name = "Some blog name" + }; + blog.Posts = new List(); + for (int i = 0; i < 5; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)i, + Title = "Some post Title " + i, + VarbitColumn = varbitVal + }); + context.Blogs.Add(blog); + context.NoColumnsEntities.Add(new NoColumnsEntity()); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts = from p in context.Posts + select p; + Assert.AreEqual(5, posts.Count()); + foreach (var post in posts) + { + StringAssert.StartsWith("Some post Title ", post.Title); + Assert.AreEqual(varbitVal, post.VarbitColumn); + } + var someParameter = "Some"; + Assert.IsTrue(context.Posts.Any(p => p.Title.StartsWith(someParameter))); + Assert.IsTrue(context.Posts.Select(p => p.VarbitColumn == varbitVal).First()); + Assert.IsTrue(context.Posts.Select(p => p.VarbitColumn == "10011").First()); + Assert.AreEqual(1, context.NoColumnsEntities.Count()); + } + } + + [Test] + public void SelectWithWhere() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + var blog = new Blog() + { + Name = "Some blog name" + }; + blog.Posts = new List(); + for (int i = 0; i < 5; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)i, + Title = "Some post Title " + i + }); + context.Blogs.Add(blog); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts = from p in context.Posts + where p.Rating < 3 + select p; + Assert.AreEqual(3, posts.Count()); + foreach (var post in posts) + { + Assert.Less(post.Rating, 3); + } + } + } + + [Test] + public void SelectWithWhere_Ef_TruncateTime() + { + DateTime createdOnDate = new DateTime(2014, 05, 08); + using (var context = new BloggingContext(ConnectionStringEF)) + { + var blog = new Blog() + { + Name = "Some blog name" + }; + blog.Posts = new List(); + + for (int i = 0; i < 5; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)i, + Title = "Some post Title " + i, + CreationDate = createdOnDate.AddHours(i) + }); + context.Blogs.Add(blog); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts = from p in context.Posts + let datePosted = DbFunctions.TruncateTime(p.CreationDate) + where p.Rating < 3 && datePosted == createdOnDate + select p; + Assert.AreEqual(3, posts.Count()); + foreach (var post in posts) + { + Assert.Less(post.Rating, 3); + } + } + } + + [Test] + public void SelectWithLike_SpecialCharacters() + { + DateTime createdOnDate = new DateTime(2014, 05, 08); + using (var context = new BloggingContext(ConnectionStringEF)) + { + var blog = new Blog() + { + Name = "Special Characters Test" + }; + blog.Posts = new List(); + + blog.Posts.Add(new Post() + { + Content = "C:\\blog\\Some_post_title%", + Rating = (byte)1, + Title = "Some post Title ", + CreationDate = createdOnDate.AddHours(1) + }); + blog.Posts.Add(new Post() + { + Content = "C:\\blog\\Some_post_title\\", + Rating = (byte)2, + Title = "Some post Title ", + CreationDate = createdOnDate.AddHours(2) + }); + blog.Posts.Add(new Post() + { + Content = "%Test", + Rating = (byte)3, + Title = "Some post Title ", + CreationDate = createdOnDate.AddHours(3) + }); + context.Blogs.Add(blog); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts1 = from p in context.Posts + where p.Content.Contains("_") + select p; + Assert.AreEqual(2, posts1.Count()); + + var posts2 = from p in context.Posts + where p.Content.EndsWith("\\") + select p; + Assert.AreEqual(1, posts2.Count()); + + var posts3 = from p in context.Posts + where p.Content.StartsWith("%") + select p; + Assert.AreEqual(1, posts3.Count()); + } + } + + [Test] + public void OrderBy() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + Random random = new Random(); + var blog = new Blog() + { + Name = "Some blog name" + }; + + blog.Posts = new List(); + for (int i = 0; i < 10; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)random.Next(0, 255), + Title = "Some post Title " + i + }); + context.Blogs.Add(blog); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts = from p in context.Posts + orderby p.Rating + select p; + Assert.AreEqual(10, posts.Count()); + byte previousValue = 0; + foreach (var post in posts) + { + Assert.GreaterOrEqual(post.Rating, previousValue); + previousValue = post.Rating; + } + } + } + + [Test] + public void OrderByThenBy() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + Random random = new Random(); + var blog = new Blog() + { + Name = "Some blog name" + }; + + blog.Posts = new List(); + for (int i = 0; i < 10; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)random.Next(0, 255), + Title = "Some post Title " + (i % 3) + }); + context.Blogs.Add(blog); + context.SaveChanges(); + } + + using (var context = new BloggingContext(ConnectionStringEF)) + { + var posts = context.Posts.AsQueryable().OrderBy((p) => p.Title).ThenByDescending((p) => p.Rating); + Assert.AreEqual(10, posts.Count()); + foreach (var post in posts) + { + //TODO: Check outcome + Console.WriteLine(post.Title + " " + post.Rating); + } + } + } + + [Test] + public void TestComputedValue() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + var blog = new Blog() + { + Name = "Some blog name" + }; + + context.Blogs.Add(blog); + context.SaveChanges(); + + Assert.Greater(blog.BlogId, 0); + Assert.Greater(blog.IntComputedValue, 0); + } + + } + + [Test] + public void Operators() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + int one = 1, two = 2, three = 3, four = 4; + bool True = true, False = false; + bool[] boolArr = { true, false }; + IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); + Assert.AreEqual(oneRow.Select(p => one & (two ^ three)).First(), 1); + Assert.AreEqual(oneRow.Select(p => ~(one & two)).First(), ~(one & two)); + Assert.AreEqual(oneRow.Select(p => one + ~(two * three) + ~(two ^ ~three) - one ^ three * ~two / three | four).First(), + one + ~(two * three) + ~(two ^ ~three) - one ^ three * ~two / three | four); + Assert.AreEqual(oneRow.Select(p => one - (two - three) - four - (- one - two) - (- three)).First(), + one - (two - three) - four - (- one - two) - (- three)); + Assert.AreEqual(oneRow.Select(p => one <= (one & one)).First(), + one <= (one & one)); + Assert.AreEqual(oneRow.Select(p => boolArr.Contains(True == true)).First(), true); + Assert.AreEqual(oneRow.Select(p => !boolArr.Contains(False == true)).First(), false); + Assert.AreEqual(oneRow.Select(p => !boolArr.Contains(False != true)).First(), false); + } + } + + [Test] + public void DataTypes() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); + + Assert.AreEqual((byte)1, oneRow.Select(p => (byte)1).First()); + Assert.AreEqual((short)1, oneRow.Select(p => (short)1).First()); + Assert.AreEqual((long)1, oneRow.Select(p => (long)1).First()); + Assert.AreEqual(1.25M, oneRow.Select(p => 1.25M).First()); + Assert.AreEqual(double.NaN, oneRow.Select(p => double.NaN).First()); + Assert.AreEqual(double.PositiveInfinity, oneRow.Select(p => double.PositiveInfinity).First()); + Assert.AreEqual(double.NegativeInfinity, oneRow.Select(p => double.NegativeInfinity).First()); + Assert.AreEqual(1.12e+12, oneRow.Select(p => 1.12e+12).First()); + Assert.AreEqual(1.12e-12, oneRow.Select(p => 1.12e-12).First()); + Assert.AreEqual(float.NaN, oneRow.Select(p => float.NaN).First()); + Assert.AreEqual(float.PositiveInfinity, oneRow.Select(p => float.PositiveInfinity).First()); + Assert.AreEqual(float.NegativeInfinity, oneRow.Select(p => float.NegativeInfinity).First()); + Assert.AreEqual(1.12e+12f, oneRow.Select(p => 1.12e+12f).First()); + Assert.AreEqual(1.12e-12f, oneRow.Select(p => 1.12e-12f).First()); + Assert.AreEqual((short)-32768, oneRow.Select(p => (short)-32768).First()); + Assert.IsTrue(new byte[] { 1, 2 }.SequenceEqual(oneRow.Select(p => new byte[] { 1, 2 }).First())); + + byte byteVal = 1; + short shortVal = -32768; + long longVal = 1L << 33; + decimal decimalVal = 1.25M; + double doubleVal = 1.12; + float floatVal = 1.22f; + byte[] byteArrVal = new byte[] { 1, 2 }; + + Assert.AreEqual(byteVal, oneRow.Select(p => byteVal).First()); + Assert.AreEqual(shortVal, oneRow.Select(p => shortVal).First()); + Assert.AreEqual(longVal, oneRow.Select(p => longVal).First()); + Assert.AreEqual(decimalVal, oneRow.Select(p => decimalVal).First()); + Assert.AreEqual(doubleVal, oneRow.Select(p => doubleVal).First()); + Assert.AreEqual(floatVal, oneRow.Select(p => floatVal).First()); + Assert.IsTrue(byteArrVal.SequenceEqual(oneRow.Select(p => byteArrVal).First())); + + // A literal TimeSpan is written as an interval + Assert.AreEqual(new TimeSpan(1, 2, 3, 4), oneRow.Select(p => new TimeSpan(1, 2, 3, 4)).First()); + var val1 = new TimeSpan(1, 2, 3, 4); + Assert.AreEqual(val1, oneRow.Select(p => new TimeSpan(1, 2, 3, 4)).First()); + Assert.AreEqual(val1, oneRow.Select(p => val1).First()); + + // DateTimeOffset -> timestamptz + Assert.AreEqual(new DateTimeOffset(2014, 2, 3, 4, 5, 6, 0, TimeSpan.Zero), oneRow.Select(p => new DateTimeOffset(2014, 2, 3, 4, 5, 6, 0, TimeSpan.Zero)).First()); + var val2 = new DateTimeOffset(2014, 2, 3, 4, 5, 6, 0, TimeSpan.Zero); + Assert.AreEqual(val2, oneRow.Select(p => new DateTimeOffset(2014, 2, 3, 4, 5, 6, 0, TimeSpan.Zero)).First()); + Assert.AreEqual(val2, oneRow.Select(p => val2).First()); + + // DateTime -> timestamp + Assert.AreEqual(new DateTime(2014, 2, 3, 4, 5, 6, 0), oneRow.Select(p => new DateTime(2014, 2, 3, 4, 5, 6, 0)).First()); + var val3 = new DateTime(2014, 2, 3, 4, 5, 6, 0); + Assert.AreEqual(val3, oneRow.Select(p => new DateTime(2014, 2, 3, 4, 5, 6, 0)).First()); + Assert.AreEqual(val3, oneRow.Select(p => val3).First()); + + var val4 = new Guid("1234567890abcdef1122334455667788"); + Assert.AreEqual(val4, oneRow.Select(p => new Guid("1234567890abcdef1122334455667788")).First()); + Assert.AreEqual(val4, oneRow.Select(p => val4).First()); + + // String + Assert.AreEqual(@"a'b\c", oneRow.Select(p => @"a'b\c").First()); + } + } + + [Test] + public void SByteTest() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); + + sbyte sbyteVal = -1; + Assert.AreEqual(sbyteVal, oneRow.Select(p => sbyteVal).First()); + Assert.AreEqual((sbyte)1, oneRow.Select(p => (sbyte)1).First()); + } + } + + [Test] + public void DateFunctions() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); + + var dateAdds = oneRow.Select(p => new List + { + DbFunctions.AddDays(new DateTime(2014, 2, 28), 1), + DbFunctions.AddHours(new DateTime(2014, 2, 28, 23, 0, 0), 1), + DbFunctions.AddMinutes(new DateTime(2014, 2, 28, 23, 59, 0), 1), + DbFunctions.AddSeconds(new DateTime(2014, 2, 28, 23, 59, 59), 1), + DbFunctions.AddMilliseconds(new DateTime(2014, 2, 28, 23, 59, 59, 999), 2 - p), + DbFunctions.AddMicroseconds(DbFunctions.AddMicroseconds(new DateTime(2014, 2, 28, 23, 59, 59, 999), 500), 500), + DbFunctions.AddNanoseconds(new DateTime(2014, 2, 28, 23, 59, 59, 999), 999999 + p), + DbFunctions.AddMonths(new DateTime(2014, 2, 1), 1), + DbFunctions.AddYears(new DateTime(2013, 3, 1), 1) + }).First(); + foreach (var result in dateAdds) + { + Assert.IsTrue(result.Value == new DateTime(2014, 3, 1, 0, 0, 0)); + } + + var dateDiffs = oneRow.Select(p => new { + a = DbFunctions.DiffDays(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + b = DbFunctions.DiffHours(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + c = DbFunctions.DiffMinutes(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + d = DbFunctions.DiffSeconds(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + e = DbFunctions.DiffMilliseconds(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + f = DbFunctions.DiffMicroseconds(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + g = DbFunctions.DiffNanoseconds(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(2000, 1, 1, 0, 0, 0)), + h = DbFunctions.DiffMonths(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(3000, 1, 1, 0, 0, 0)), + i = DbFunctions.DiffYears(new DateTime(1999, 12, 31, 23, 59, 59, 999), new DateTime(3000, 1, 1, 0, 0, 0)), + j = DbFunctions.DiffYears(null, new DateTime(2000, 1, 1)), + k = DbFunctions.DiffMinutes(new TimeSpan(1, 2, 3), new TimeSpan(4, 5, 6)), + l = DbFunctions.DiffMinutes(new TimeSpan(1, 2, 3), null) + }).First(); + Assert.AreEqual(dateDiffs.a, 1); + Assert.AreEqual(dateDiffs.b, 1); + Assert.AreEqual(dateDiffs.c, 1); + Assert.AreEqual(dateDiffs.d, 1); + Assert.AreEqual(dateDiffs.e, 1); + Assert.AreEqual(dateDiffs.f, 1000); + Assert.AreEqual(dateDiffs.g, 1000000); + Assert.AreEqual(dateDiffs.h, 12001); + Assert.AreEqual(dateDiffs.i, 1001); + Assert.AreEqual(dateDiffs.j, null); + Assert.AreEqual(dateDiffs.k, 183); + Assert.AreEqual(dateDiffs.l, null); + } + } + + //Hunting season is open Happy hunting on OrderBy,GroupBy,Min,Max,Skip,Take,ThenBy... and all posible combinations + + [Test] + public void TestComplicatedQueries() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + // Test that the subqueries are evaluated in the correct order + context.Posts.Select(p => p.Content).Distinct().OrderBy(l => l).ToArray(); + context.Posts.OrderByDescending(p => p.BlogId).Take(2).OrderBy(p => p.BlogId).Skip(1).Take(1).Select(l => l.BlogId).ToArray(); + context.Posts.Take(3).Take(4).ToArray(); + context.Posts.OrderByDescending(p => p.BlogId).Take(3).OrderBy(p => p.BlogId).Take(2).ToArray(); + context.Posts.OrderByDescending(p => p.BlogId).Take(3).OrderBy(p => p.BlogId).ToArray(); + + // Test that lhs and rhs of UNION ALL is wrapped in parentheses + context.Blogs.Take(3).Concat(context.Blogs.Take(4)).ToArray(); + + // Flatten set ops + context.Blogs.Concat(context.Blogs).Concat(context.Blogs.Concat(context.Blogs)).ToArray(); + context.Blogs.Intersect(context.Blogs).Intersect(context.Blogs).ToArray(); + // But not except + context.Blogs.Concat(context.Blogs.Except(context.Blogs)).ToArray(); + + // In + int[] arr = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40}; + context.Blogs.Where(b => arr.Contains(b.BlogId)).ToArray(); + + // Subquery as a select column + context.Blogs.Select(b => new { b.Name, b.BlogId, c = context.Posts.Count(p => p.BlogId == b.BlogId) + 1 }).ToArray(); + context.Blogs.Where(b => b.Name == context.Blogs.FirstOrDefault().Name).ToArray(); + + context.Blogs.Where(b => b.Name == context.Blogs.Where(b2 => b2.BlogId < 100).FirstOrDefault().Name).ToArray(); + + // Similar to https://github.com/npgsql/Npgsql/issues/156 However EF is turning the GroupBy into a Distinct here + context.Posts.OrderBy(p => p.Title).ThenBy(p => p.Content).Take(100).GroupBy(p => p.Title).Select(p => p.Key).ToArray(); + + // Check precedence for || + // http://stackoverflow.com/questions/21908464/wrong-query-generated-by-postgresql-provider-to-entity-framework-for-contains-an + context.Posts.Where(p => "a" != string.Concat("a", "b")).ToArray(); + + Action elinq = (string query) => { + new System.Data.Entity.Core.Objects.ObjectQuery(query, ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext).ToArray(); + }; + + elinq("Select a, max(b) from {1,2,3,3,4} as b group by b as a"); + elinq("Select (select count(a.Name) from ((select a1.Name from Blogs as a1) union all (select b2.Name from Blogs as b2)) as a) as cnt, b.BlogId from Posts as b"); + + elinq("Select a.ID from (select distinct c.ID, c.ID2 From (select b.Name as ID, b.Name = '' as ID2 From Blogs as b order by ID asc limit 3) as c) as a where a.ID = 'a'"); + + // a LEFT JOIN b LEFT JOIN c ON x ON y => Parsed as: a LEFT JOIN (b LEFT JOIN c ON x) ON y, which is correct + elinq("Select a.BlogId, d.id2, d.id3 from Blogs as a left outer join (Select b.BlogId as id2, c.BlogId as id3 From Blogs as b left outer join Blogs as c on true) as d on true"); + // Aliasing + elinq("Select a.BlogId, d.id2, d.id3 from Blogs as a left outer join (Select top(1) b.BlogId as id2, c.BlogId as id3 From Blogs as b left outer join Blogs as c on true) as d on true"); + + // Anyelement (creates DbNewInstanceExpressions) + elinq("Anyelement (Select Blogs.BlogId, Blogs.Name from Blogs)"); + elinq("Select a.BlogId, Anyelement (Select value b.BlogId + 1 from Blogs as b) as c from Blogs as a"); + } + } + + [Test] + [MonoIgnore("Probably bug in mono. See https://github.com/npgsql/Npgsql/issues/289.")] + public void TestComplicatedQueriesMonoFails() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + // Similar to https://github.com/npgsql/Npgsql/issues/216 + (from d in context.Posts + group d by new { d.Content, d.Title }).FirstOrDefault(); + + // NewInstance(Column(Element(Limit(Sort(Project(...)))))) + // https://github.com/npgsql/Npgsql/issues/280 + (from postsGrouped in context.Posts.GroupBy(x => x.BlogId) + let lastPostDate = postsGrouped.OrderByDescending(x => x.CreationDate) + .Select(x => x.CreationDate) + .FirstOrDefault() + select new { + LastPostDate = lastPostDate + }).ToArray(); + } + } + + [Test] + public void TestComplicatedQueriesWithApply() + { + using (var conn = OpenConnection(ConnectionStringEF)) + TestUtil.MinimumPgVersion(conn, "9.3.0"); + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + // Test Apply + (from t1 in context.Blogs + from t2 in context.Posts.Where(p => p.BlogId == t1.BlogId).Take(1) + select new { t1, t2 }).ToArray(); + + Action elinq = (string query) => + { + new System.Data.Entity.Core.Objects.ObjectQuery(query, ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext).ToArray(); + }; + + // Joins, apply + elinq("Select value Blogs.BlogId From Blogs outer apply (Select p1.BlogId as bid, p1.PostId as bid2 from Posts as p1 left outer join (Select value p.PostId from Posts as p where p.PostId < Blogs.BlogId)) as b outer apply (Select p.PostId from Posts as p where p.PostId < b.bid)"); + + // Just some really crazy query that results in an apply as well + context.Blogs.Select(b => new { b, b.BlogId, n = b.Posts.Select(p => new { t = p.Title + b.Name, n = p.Blog.Posts.Count(p2 => p2.BlogId < 4) }).Take(2) }).ToArray(); + } + } + + [Test] + public void TestScalarValuedStoredFunctions() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + // Try to call stored function using ESQL + var directCallQuery = ((IObjectContextAdapter)context).ObjectContext.CreateQuery( + "SELECT VALUE BloggingContext.ClrStoredAddFunction(@p1, @p2) FROM {1}", + new ObjectParameter("p1", 1), + new ObjectParameter("p2", 10) + ); + var directSQL = directCallQuery.ToTraceString(); + var directCallResult = directCallQuery.First(); + + // Add some data and query it back using Stored Function + var blog = new Blog + { + Name = "Some blog name", + Posts = new List() + }; + for (int i = 0; i < 5; i++) + blog.Posts.Add(new Post() + { + Content = "Some post content " + i, + Rating = (byte)i, + Title = "Some post Title " + i + }); + context.Blogs.Add(blog); + context.NoColumnsEntities.Add(new NoColumnsEntity()); + context.SaveChanges(); + + // Query back + var modifiedIds = context.Posts + .Select(x => new { Id = x.PostId, Changed = BloggingContext.StoredAddFunction(x.PostId, 100) }) + .ToList(); + var localChangedIds = modifiedIds.Select(x => x.Id + 100).ToList(); + var remoteChangedIds = modifiedIds.Select(x => x.Changed).ToList(); + + // Comapre results + Assert.AreEqual(directCallResult, 11); + Assert.IsTrue(directSQL.Contains("\"dbo\".\"StoredAddFunction\"")); + CollectionAssert.AreEqual(localChangedIds, remoteChangedIds); + } + } + + [Test] + public void TestScalarValuedStoredFunctions_with_null_StoreFunctionName() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + // Direct ESQL + var directCallQuery = ((IObjectContextAdapter)context).ObjectContext.CreateQuery( + "SELECT VALUE BloggingContext.StoredEchoFunction(@p1) FROM {1}", + new ObjectParameter("p1", 1337)); + var directSQL = directCallQuery.ToTraceString(); + var directCallResult = directCallQuery.First(); + + // LINQ + var echo = context.Blogs + .Select(x => BloggingContext.StoredEchoFunction(1337)) + .First(); + + // Comapre results + Assert.AreEqual(directCallResult, 1337); + Assert.IsTrue(directSQL.Contains("\"dbo\".\"StoredEchoFunction\"")); + Assert.That(echo, Is.EqualTo(1337)); + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs new file mode 100644 index 0000000..95b79b8 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs @@ -0,0 +1,808 @@ +#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.ComponentModel.DataAnnotations.Schema; +using System.Data.Common; +using System.Data.Entity; +using System.Data.Entity.Core.Metadata.Edm; +using System.Data.Entity.Migrations; +using System.Data.Entity.Migrations.History; +using System.Data.Entity.Migrations.Model; +using System.Data.Entity.Spatial; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using Npgsql.Tests; + +namespace EntityFramework6.Npgsql.Tests +{ + public class EntityFrameworkMigrationTests : TestBase + { + #region Helper method + + /// + /// Helper function which I put behind var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, BackendVersion.ToString()); + /// after filling operations list run test and then copy-paste content from D:\temp\printedCode.txt after var statments = new Np.. + /// Ofcourse check if generated code makes sense or UnitTests would be useless :D + /// + /// + private void PrintCode(IEnumerable statments) + { + + using (var SW = new System.IO.StreamWriter(@"D:\temp\printedCode.txt")) + { + SW.WriteLine("Assert.AreEqual(" + statments.Count() + ", statments.Count());"); + int i = 0; + foreach (var statement in statments) + SW.WriteLine("Assert.AreEqual(\"" + statement.Sql.Replace("\"", "\\\"") + "\", statments.ElementAt(" + i++ + ").Sql);"); + } + Assert.Fail(); + } + + #endregion + + #region Actual test against database + + [Test] + public void CreateBloggingContext() + { + using (var db = new BloggingContext(new NpgsqlConnection(ConnectionStringEF))) + { + if (!(db.Database.Connection is NpgsqlConnection)) + { + Assert.Fail( + "Connection type is \"" + db.Database.Connection.GetType().FullName + "\" should be \"" + typeof(NpgsqlConnection).FullName + "\"." + Environment.NewLine + + "Most likely wrong configuration in App.config file of Tests project."); + } + db.Database.Delete(); + var blog = new Blog { Name = "blogNameTest1" }; + db.Blogs.Add(blog); + db.SaveChanges(); + + var query = from b in db.Blogs + where b.Name == "blogNameTest1" + select b; + Assert.AreEqual(1, query.Count()); + + db.Database.Connection.Open(); + using (var command = db.Database.Connection.CreateCommand()) + { + command.CommandText = "select column_name, data_type, is_nullable, column_default from information_schema.columns where table_name = 'Blogs';"; + List expectedColumns = new List(new string[] { "Name", "BlogId" }); + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine((string)reader[0] + " " + (string)reader[1] + " " + (string)reader[2] + " " + (reader[3] ?? "").ToString()); + switch ((string)reader[0]) + { + case "Name": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("text", (string)reader[1]); + Assert.AreEqual("YES", (string)reader[2]); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); + break; + case "BlogId": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("integer", (string)reader[1]); + Assert.AreEqual("NO", (string)reader[2]); + Assert.AreEqual("nextval('dbo.\"Blogs_BlogId_seq\"'::regclass)", reader[3] as string); + break; + default: + Assert.Fail("Unknown column '" + (string)reader[0] + "' in Blogs table."); + break; + } + } + } + foreach (var columnName in expectedColumns) + { + Assert.Fail("Column '" + columnName + "' was not created in Blogs table."); + } + } + + using (var command = db.Database.Connection.CreateCommand()) + { + command.CommandText = "select column_name, data_type, is_nullable, column_default from information_schema.columns where table_name = 'Posts';"; + List expectedColumns = new List(new string[] { "PostId", "Title", "Content", "BlogId" }); + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine((string)reader[0] + " " + (string)reader[1] + " " + (string)reader[2] + " " + (reader[3] ?? "").ToString()); + switch ((string)reader[0]) + { + case "PostId": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("integer", (string)reader[1]); + Assert.AreEqual("NO", (string)reader[2]); + Assert.AreEqual("nextval('dbo.\"Posts_PostId_seq\"'::regclass)", (string)reader[3]); + break; + case "Title": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("text", (string)reader[1]); + Assert.AreEqual("YES", (string)reader[2]); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); + break; + case "Content": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("text", (string)reader[1]); + Assert.AreEqual("YES", (string)reader[2]); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); + break; + case "BlogId": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("integer", (string)reader[1]); + Assert.AreEqual("NO", (string)reader[2]); + Assert.AreEqual("0", (string)reader[3]); + 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.AreEqual("uuid_generate_v4()", reader[3] as string); + break; + case "Rating": + expectedColumns.Remove((string)reader[0]); + Assert.AreEqual("smallint", (string)reader[1]); + Assert.AreEqual("YES", (string)reader[2]); + Assert.That(string.IsNullOrEmpty(reader[3] as string)); + break; + default: + Assert.Fail("Unknown column '" + (string)reader[0] + "' in Post table."); + break; + } + } + } + foreach (var columnName in expectedColumns) + { + Assert.Fail("Column '" + columnName + "' was not created in Posts table."); + } + } + } + } + + + + public class Blog + { + public int BlogId { get; set; } + public string Name { get; set; } + + public virtual List Posts { get; set; } + } + + public class Post + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int PostId { get; set; } + public string Title { get; set; } + public string Content { get; set; } + //[DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public Guid UniqueId { get; set; } + public byte? Rating { get; set; } + + public int BlogId { get; set; } + public virtual Blog Blog { get; set; } + } + + public class BloggingContext : DbContext + { + public BloggingContext(DbConnection connection) + : base(connection, true) + { + } + + public DbSet Blogs { get; set; } + public DbSet Posts { get; set; } + } + + #endregion + + [Test] + public void DatabaseExistsCreateDelete() + { + using (var db = new BloggingContext(new NpgsqlConnection(ConnectionStringEF))) + { + if (db.Database.Exists()) + { + db.Database.Delete(); + Assert.IsFalse(db.Database.Exists()); + db.Database.Create(); + } + else + { + db.Database.Create(); + } + Assert.IsTrue(db.Database.Exists()); + db.Database.Delete(); + Assert.IsFalse(db.Database.Exists()); + } + } + + [Test] + public void AddColumnOperation() + { + var operations = new List(); + operations.Add(new AddColumnOperation("tableName", new ColumnModel(PrimitiveTypeKind.Double) + { + Name = "columnName" + })); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"tableName\" ADD \"columnName\" float8", statments.ElementAt(0).Sql); + } + + [Test] + public void AddColumnOperationDefaultValue() + { + var operations = new List(); + operations.Add(new AddColumnOperation("tableName", new ColumnModel(PrimitiveTypeKind.Single) + { + Name = "columnName", + DefaultValue = 4.4f + })); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"tableName\" ADD \"columnName\" float4 DEFAULT 4.4", statments.ElementAt(0).Sql); + } + + [Test] + public void AddColumnOperationDefaultValueSql() + { + var operations = new List(); + operations.Add(new AddColumnOperation("tableName", new ColumnModel(PrimitiveTypeKind.Single) + { + Name = "columnName", + DefaultValueSql = "4.6" + })); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"tableName\" ADD \"columnName\" float4 DEFAULT 4.6", statments.ElementAt(0).Sql); + } + + [Test] + public void AlterColumnOperation() + { + var operations = new List(); + operations.Add(new AlterColumnOperation("tableName", new ColumnModel(PrimitiveTypeKind.Double) + { + Name = "columnName" + }, false)); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(3, statments.Count()); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" TYPE float8", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" DROP NOT NULL", statments.ElementAt(1).Sql); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" DROP DEFAULT", statments.ElementAt(2).Sql); + } + + [Test] + public void AlterColumnOperationDefaultAndNullable() + { + var operations = new List(); + operations.Add(new AlterColumnOperation("tableName", new ColumnModel(PrimitiveTypeKind.Double) + { + Name = "columnName", + DefaultValue = 2.3, + IsNullable = false + }, false)); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(3, statments.Count()); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" TYPE float8", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" SET NOT NULL", statments.ElementAt(1).Sql); + Assert.AreEqual("ALTER TABLE \"tableName\" ALTER COLUMN \"columnName\" SET DEFAULT 2.3", statments.ElementAt(2).Sql); + } + + [Test] + public void CreateTableOperation() + { + var operations = new List(); + var operation = new CreateTableOperation("someSchema.someTable"); + + operation.Columns.Add( + new ColumnModel(PrimitiveTypeKind.String) + { + Name = "SomeString", + MaxLength = 233, + IsNullable = false + }); + + operation.Columns.Add( + new ColumnModel(PrimitiveTypeKind.String) + { + Name = "AnotherString", + IsNullable = true + }); + + operation.Columns.Add( + new ColumnModel(PrimitiveTypeKind.Binary) + { + Name = "SomeBytes" + }); + + operation.Columns.Add( + new ColumnModel(PrimitiveTypeKind.Int64) + { + Name = "SomeLong", + IsIdentity = true + }); + + operation.Columns.Add( + new ColumnModel(PrimitiveTypeKind.DateTime) + { + Name = "SomeDateTime" + }); + + operations.Add(operation); + 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); + 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); + } + + [Test] + public void CreateTableWithoutSchema() + { + var statements = new NpgsqlMigrationSqlGenerator().Generate(new List { new CreateTableOperation("some_table") }, _backendVersion.ToString()).ToList(); + Assert.That(statements.Count, Is.EqualTo(1)); + Assert.That(statements[0].Sql, Is.EqualTo("CREATE TABLE \"some_table\"()")); + } + + [Test] + public void CreateTableInPublicSchema() + { + var statements = new NpgsqlMigrationSqlGenerator().Generate(new List { new CreateTableOperation("public.some_table") }, _backendVersion.ToString()).ToList(); + Assert.That(statements.Count, Is.EqualTo(1)); + Assert.That(statements[0].Sql, Is.EqualTo("CREATE TABLE \"public\".\"some_table\"()")); + } + + [Test] + public void DropColumnOperation() + { + var operations = new List(); + operations.Add(new DropColumnOperation("someTable", "someColumn")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" DROP COLUMN \"someColumn\"", statments.ElementAt(0).Sql); + } + + [Test] + public void DropTableOperation() + { + var operations = new List(); + operations.Add(new DropTableOperation("someTable")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("DROP TABLE \"someTable\"", statments.ElementAt(0).Sql); + } + + [Test] + public void RenameTableOperation() + { + var operations = new List(); + operations.Add(new RenameTableOperation("schema.someOldTableName", "someNewTablename")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"schema\".\"someOldTableName\" RENAME TO \"someNewTablename\"", statments.ElementAt(0).Sql); + } + + [Test] + public void HistoryOperation() + { + var operations = new List(); + //TODO: fill operations + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + //TODO: check statments + } + + [Test] + public void DropIndexOperation() + { + var operations = new List(); + operations.Add(new DropIndexOperation() + { + Name = "someIndex", + Table = "someTable" + }); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("DROP INDEX IF EXISTS dto.\"someTable_someIndex\"", statments.ElementAt(0).Sql); + } + + [Test] + public void DropIndexOperationTableNameWithSchema() + { + var operations = new List(); + operations.Add(new DropIndexOperation() + { + Name = "someIndex", + Table = "someSchema.someTable" + }); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("DROP INDEX IF EXISTS someSchema.\"someTable_someIndex\"", statments.ElementAt(0).Sql); + } + + [Test] + public void CreateIndexOperation() + { + var operations = new List(); + var operation = new CreateIndexOperation(); + operation.Table = "someTable"; + operation.Name = "someIndex"; + operation.Columns.Add("column1"); + operation.Columns.Add("column2"); + operation.Columns.Add("column3"); + operation.IsUnique = false; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("CREATE INDEX \"someTable_someIndex\" ON \"someTable\" (\"column1\",\"column2\",\"column3\")", statments.ElementAt(0).Sql); + } + + [Test] + public void CreateIndexOperationUnique() + { + var operations = new List(); + var operation = new CreateIndexOperation(); + operation.Table = "someTable"; + operation.Name = "someIndex"; + operation.Columns.Add("column1"); + operation.Columns.Add("column2"); + operation.Columns.Add("column3"); + operation.IsUnique = true; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("CREATE UNIQUE INDEX \"someTable_someIndex\" ON \"someTable\" (\"column1\",\"column2\",\"column3\")", statments.ElementAt(0).Sql); + } + + [Test] + public void RenameIndexOperation() + { + var operations = new List(); + operations.Add(new RenameIndexOperation("someSchema.someTable", "someOldIndexName", "someNewIndexName")); + var statements = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statements.Count()); + if (_backendVersion.Major > 9 || (_backendVersion.Major == 9 && _backendVersion.Minor >= 2)) + { + Assert.AreEqual("ALTER INDEX IF EXISTS someSchema.\"someOldIndexName\" RENAME TO \"someNewIndexName\"", statements.ElementAt(0).Sql); + } + else + { + Assert.AreEqual("ALTER INDEX someSchema.\"someOldIndexName\" RENAME TO \"someNewIndexName\"", statements.ElementAt(0).Sql); + } + } + + [Test] + public void MoveTableOperation() + { + var operations = new List(); + operations.Add(new MoveTableOperation("someOldSchema.someTable", "someNewSchema")); + 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); + else + Assert.AreEqual("CREATE SCHEMA someNewSchema", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"someOldSchema\".\"someTable\" SET SCHEMA someNewSchema", statments.ElementAt(1).Sql); + } + + [Test] + public void MoveTableOperationNewSchemaIsNull() + { + var operations = new List(); + operations.Add(new MoveTableOperation("someOldSchema.someTable", null)); + 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); + else + 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 AddPrimaryKeyOperation() + { + var operations = new List(); + var operation = new AddPrimaryKeyOperation(); + operation.Table = "someTable"; + operation.Name = "somePKName"; + operation.Columns.Add("column1"); + operation.Columns.Add("column2"); + operation.Columns.Add("column3"); + operation.IsClustered = false; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD CONSTRAINT \"somePKName\" PRIMARY KEY (\"column1\",\"column2\",\"column3\")", statments.ElementAt(0).Sql); + } + + [Test] + public void AddPrimaryKeyOperationClustered() + { + var operations = new List(); + var operation = new AddPrimaryKeyOperation(); + operation.Table = "someTable"; + operation.Name = "somePKName"; + operation.Columns.Add("column1"); + operation.Columns.Add("column2"); + operation.Columns.Add("column3"); + operation.IsClustered = true; + //TODO: PostgreSQL support something like IsClustered? + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD CONSTRAINT \"somePKName\" PRIMARY KEY (\"column1\",\"column2\",\"column3\")", statments.ElementAt(0).Sql); + } + + [Test] + public void DropPrimaryKeyOperation() + { + var operations = new List(); + var operation = new DropPrimaryKeyOperation(); + operation.Table = "someTable"; + operation.Name = "somePKName"; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" DROP CONSTRAINT \"somePKName\"", statments.ElementAt(0).Sql); + } + + [Test] + public void RenameColumnOperation() + { + var operations = new List(); + operations.Add(new RenameColumnOperation("someTable", "someOldColumnName", "someNewColumnName")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" RENAME COLUMN \"someOldColumnName\" TO \"someNewColumnName\"", statments.ElementAt(0).Sql); + } + + [Test] + public void SqlOperation() + { + var operations = new List(); + operations.Add(new SqlOperation("SELECT someColumn FROM someTable")); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("SELECT someColumn FROM someTable", statments.ElementAt(0).Sql); + } + + [Test] + public void UpdateDatabaseOperation() + { + var operations = new List(); + //TODO: fill operations + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + //TODO: check statments + } + + [Test] + public void AddForeignKeyOperation() + { + var operations = new List(); + var operation = new AddForeignKeyOperation(); + operation.Name = "someFK"; + operation.PrincipalTable = "somePrincipalTable"; + operation.DependentTable = "someDependentTable"; + operation.DependentColumns.Add("column1"); + operation.DependentColumns.Add("column2"); + operation.DependentColumns.Add("column3"); + operation.CascadeDelete = false; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someDependentTable\" ADD CONSTRAINT \"someFK\" FOREIGN KEY (\"column1\",\"column2\",\"column3\") REFERENCES \"somePrincipalTable\" )", statments.ElementAt(0).Sql); + } + + [Test] + public void AddForeignKeyOperationCascadeDelete() + { + var operations = new List(); + var operation = new AddForeignKeyOperation(); + operation.Name = "someFK"; + operation.PrincipalTable = "somePrincipalTable"; + operation.DependentTable = "someDependentTable"; + operation.DependentColumns.Add("column1"); + operation.DependentColumns.Add("column2"); + operation.DependentColumns.Add("column3"); + operation.CascadeDelete = true; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someDependentTable\" ADD CONSTRAINT \"someFK\" FOREIGN KEY (\"column1\",\"column2\",\"column3\") REFERENCES \"somePrincipalTable\" ) ON DELETE CASCADE", statments.ElementAt(0).Sql); + } + + + [Test] + public void DropForeignKeyOperation() + { + var operations = new List(); + var operation = new DropForeignKeyOperation(); + operation.Name = "someFK"; + operation.DependentTable = "someTable"; + operations.Add(operation); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(1, statments.Count()); + if (_backendVersion.Major > 8) + Assert.AreEqual("ALTER TABLE \"someTable\" DROP CONSTRAINT IF EXISTS \"someFK\"", statments.ElementAt(0).Sql); + else + Assert.AreEqual("ALTER TABLE \"someTable\" DROP CONSTRAINT \"someFK\"", statments.ElementAt(0).Sql); + } + + [Test] + public void DefaultTypes() + { + var operations = new List(); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Binary) + { + Name = "someByteaColumn", + DefaultValue = new byte[6] { 1, 2, 127, 128, 254, 255 } + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Boolean) + { + Name = "someFalseBooleanColumn", + DefaultValue = false + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Boolean) + { + Name = "someTrueBooleanColumn", + DefaultValue = true + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Byte) + { + Name = "someByteColumn", + DefaultValue = 15 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.DateTime) + { + Name = "someDateTimeColumn", + DefaultValue = new DateTime(2014, 1, 31, 5, 15, 23, 435) + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.DateTimeOffset) + { + Name = "someDateTimeOffsetColumn", + DefaultValue = new DateTimeOffset(new DateTime(2014, 1, 31, 5, 18, 43, 186), TimeSpan.FromHours(1)) + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Decimal) + { + Name = "someDecimalColumn", + DefaultValue = 23432423.534534m + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Double) + { + Name = "someDoubleColumn", + DefaultValue = 44.66 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Guid) + { + Name = "someGuidColumn", + DefaultValue = new Guid("de303070-afb8-4ec1-bcb0-c637f3316501") + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Int16) + { + Name = "someInt16Column", + DefaultValue = 16 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Int32) + { + Name = "someInt32Column", + DefaultValue = 32 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Int64) + { + Name = "someInt64Column", + DefaultValue = 64 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.SByte) + { + Name = "someSByteColumn", + DefaultValue = -24 + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Single) + { + Name = "someSingleColumn", + DefaultValue = 12.4f + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.String) + { + Name = "someStringColumn", + DefaultValue = "Hello EF" + }, false) + ); + operations.Add(new AddColumnOperation("someTable", + new ColumnModel(PrimitiveTypeKind.Time) + { + Name = "someColumn", + DefaultValue = new TimeSpan(937840050067)//1 day, 2 hours, 3 minutes, 4 seconds, 5 miliseconds, 6 microseconds, 700 nanoseconds + }, false) + ); + var statments = new NpgsqlMigrationSqlGenerator().Generate(operations, _backendVersion.ToString()); + Assert.AreEqual(16, statments.Count()); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someByteaColumn\" bytea DEFAULT E'\\\\01027F80FEFF'", statments.ElementAt(0).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someFalseBooleanColumn\" boolean DEFAULT FALSE", statments.ElementAt(1).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someTrueBooleanColumn\" boolean DEFAULT TRUE", statments.ElementAt(2).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someByteColumn\" int2 DEFAULT 15", statments.ElementAt(3).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someDateTimeColumn\" timestamp DEFAULT '2014-01-31 05:15:23.4350000'", statments.ElementAt(4).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someDateTimeOffsetColumn\" timestamptz DEFAULT '2014-01-31 04:18:43.1860000'", statments.ElementAt(5).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someDecimalColumn\" numeric DEFAULT 23432423.534534", statments.ElementAt(6).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someDoubleColumn\" float8 DEFAULT 44.66", statments.ElementAt(7).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someGuidColumn\" uuid DEFAULT 'de303070-afb8-4ec1-bcb0-c637f3316501'", statments.ElementAt(8).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someInt16Column\" int2 DEFAULT 16", statments.ElementAt(9).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someInt32Column\" int4 DEFAULT 32", statments.ElementAt(10).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someInt64Column\" int8 DEFAULT 64", statments.ElementAt(11).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someSByteColumn\" int2 DEFAULT -24", statments.ElementAt(12).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someSingleColumn\" float4 DEFAULT 12.4", statments.ElementAt(13).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someStringColumn\" text DEFAULT 'Hello EF'", statments.ElementAt(14).Sql); + Assert.AreEqual("ALTER TABLE \"someTable\" ADD \"someColumn\" interval DEFAULT '1 day 02:03:04.005007'", statments.ElementAt(15).Sql); + } + + [OneTimeSetUp] + public void OneTimeSetUp() + { + using (var conn = OpenConnection(ConnectionStringEF)) + _backendVersion = conn.PostgreSqlVersion; + } + + Version _backendVersion; + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs new file mode 100644 index 0000000..83ae561 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs @@ -0,0 +1,201 @@ +#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 Npgsql.Tests; +using NpgsqlTypes; + +namespace EntityFramework6.Npgsql.Tests +{ + public abstract class EntityFrameworkTestBase : TestBase + { + [OneTimeSetUp] + public override void TestFixtureSetup() + { + base.TestFixtureSetup(); + using (var context = new BloggingContext(ConnectionStringEF)) + { + if (context.Database.Exists()) + context.Database.Delete();//We delete to be 100% schema is synced + context.Database.Create(); + } + + // Create sequence for the IntComputedValue property. + using (var createSequenceConn = OpenConnection(ConnectionStringEF)) + { + createSequenceConn.ExecuteNonQuery("create sequence blog_int_computed_value_seq"); + createSequenceConn.ExecuteNonQuery("alter table \"dbo\".\"Blogs\" alter column \"IntComputedValue\" set default nextval('blog_int_computed_value_seq');"); + 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;"); + } + } + + /// + /// Clean any previous entites before our test + /// + [SetUp] + protected void SetUp() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Blogs.RemoveRange(context.Blogs); + context.Posts.RemoveRange(context.Posts); + context.SaveChanges(); + } + } + } + + public class Blog + { + public int BlogId { get; set; } + public string Name { get; set; } + + public virtual List Posts { get; set; } + + [DatabaseGenerated(DatabaseGeneratedOption.Computed)] + public int IntComputedValue { get; set; } + } + + public class Post + { + public int PostId { get; set; } + public string Title { get; set; } + public string Content { get; set; } + public byte Rating { get; set; } + public DateTime CreationDate { get; set; } + public string VarbitColumn { get; set; } + public int BlogId { get; set; } + public virtual Blog Blog { get; set; } + } + + public class NoColumnsEntity + { + public int Id { get; set; } + } + + public class BloggingContext : DbContext + { + public BloggingContext(string connection) + : base(new NpgsqlConnection(connection), CreateModel(new NpgsqlConnection(connection)), true) + { + } + + public DbSet Blogs { get; set; } + public DbSet Posts { get; set; } + public DbSet NoColumnsEntities { get; set; } + + [DbFunction("BloggingContext", "ClrStoredAddFunction")] + public static int StoredAddFunction(int val1, int val2) + { + throw new NotSupportedException(); + } + + [DbFunction("BloggingContext", "StoredEchoFunction")] + public static int StoredEchoFunction(int value) + { + throw new NotSupportedException(); + } + + private static DbCompiledModel CreateModel(NpgsqlConnection connection) + { + var dbModelBuilder = new DbModelBuilder(DbModelBuilderVersion.Latest); + + // Import Sets + dbModelBuilder.Entity(); + dbModelBuilder.Entity(); + dbModelBuilder.Entity(); + + // Import function + var dbModel = dbModelBuilder.Build(connection); + var edmType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32); + + var addFunc = EdmFunction.Create( + "ClrStoredAddFunction", + "BloggingContext", + DataSpace.SSpace, + new EdmFunctionPayload + { + ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, + Schema = "dbo", + IsComposable = true, + IsNiladic = false, + IsBuiltIn = false, + IsAggregate = false, + IsFromProviderManifest = true, + StoreFunctionName = "StoredAddFunction", + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType", edmType, ParameterMode.ReturnValue) + }, + Parameters = new[] + { + FunctionParameter.Create("Value1", edmType, ParameterMode.In), + FunctionParameter.Create("Value2", edmType, ParameterMode.In) + } + }, + null); + dbModel.StoreModel.AddItem(addFunc); + + var echoFunc = EdmFunction.Create( + "StoredEchoFunction", + "BloggingContext", + DataSpace.SSpace, + new EdmFunctionPayload + { + ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, + Schema = "dbo", + IsComposable = true, + IsNiladic = false, + IsBuiltIn = false, + IsAggregate = false, + IsFromProviderManifest = true, + StoreFunctionName = null, // intentional + ReturnParameters = new[] + { + FunctionParameter.Create("ReturnType", edmType, ParameterMode.ReturnValue) + }, + Parameters = new[] + { + FunctionParameter.Create("Value1", edmType, ParameterMode.In) + } + }, + null); + dbModel.StoreModel.AddItem(echoFunc); + + var compiledModel = dbModel.Compile(); + return compiledModel; + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs new file mode 100644 index 0000000..28aa8cf --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/FullTextSearchTests.cs @@ -0,0 +1,607 @@ +#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 Npgsql.Tests; +using NpgsqlTypes; + +namespace EntityFramework6.Npgsql.Tests +{ + class FullTextSearchTests : EntityFrameworkTestBase + { + [Test] + public void ConversionToTsVector() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + const string expected = "'a':5 'b':10"; + var casted = context.Blogs.Select(x => NpgsqlTextFunctions.AsTsVector(expected)).First(); + Assert.That( + NpgsqlTsVector.Parse(casted).ToString(), + Is.EqualTo(NpgsqlTsVector.Parse(expected).ToString())); + + var converted = context.Blogs.Select(x => NpgsqlTextFunctions.ToTsVector("banana car")).First(); + Assert.That( + NpgsqlTsVector.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsVector.Parse("'banana':1 'car':2").ToString())); + + converted = context.Blogs.Select(x => NpgsqlTextFunctions.ToTsVector("english", "banana car")).First(); + Assert.That( + NpgsqlTsVector.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsVector.Parse("'banana':1 'car':2").ToString())); + } + } + + [Test] + public void ConversionToTsQuery() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + const string expected = "'b' & 'c'"; + var casted = context.Blogs.Select(x => NpgsqlTextFunctions.AsTsQuery(expected)).First(); + Assert.That( + NpgsqlTsQuery.Parse(casted).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse(expected).ToString())); + + var converted = context.Blogs.Select(x => NpgsqlTextFunctions.ToTsQuery("b & c")).First(); + Assert.That( + NpgsqlTsQuery.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse(expected).ToString())); + + converted = context.Blogs.Select(x => NpgsqlTextFunctions.ToTsQuery("english", "b & c")).First(); + Assert.That( + NpgsqlTsQuery.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse(expected).ToString())); + + converted = context.Blogs.Select(x => NpgsqlTextFunctions.PlainToTsQuery("b & c")).First(); + Assert.That( + NpgsqlTsQuery.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse(expected).ToString())); + + converted = context.Blogs.Select(x => NpgsqlTextFunctions.PlainToTsQuery("english", "b & c")).First(); + Assert.That( + NpgsqlTsQuery.Parse(converted).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse(expected).ToString())); + } + } + + [Test] + public void TsVectorConcat() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => NpgsqlTextFunctions.AsTsVector("a:1 b:2") + + NpgsqlTextFunctions.AsTsVector("c:1 d:2 b:3")).First(); + + Assert.That( + NpgsqlTsVector.Parse(result).ToString(), + Is.EqualTo(NpgsqlTsVector.Parse("'a':1 'b':2,5 'c':3 'd':4").ToString())); + } + } + + [Test] + public void TsQueryAnd() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => NpgsqlTextFunctions.QueryAnd( + NpgsqlTextFunctions.AsTsQuery("fat | rat"), + NpgsqlTextFunctions.AsTsQuery("cat"))).First(); + + Assert.That( + NpgsqlTsQuery.Parse(result).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("( 'fat' | 'rat' ) & 'cat'").ToString())); + } + } + + [Test] + public void TsQueryOr() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => NpgsqlTextFunctions.QueryOr( + NpgsqlTextFunctions.AsTsQuery("fat | rat"), + NpgsqlTextFunctions.AsTsQuery("cat"))).First(); + + Assert.That( + NpgsqlTsQuery.Parse(result).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("( 'fat' | 'rat' ) | 'cat'").ToString())); + + result = context.Blogs.Select( + x => NpgsqlTextFunctions.AsTsQuery("fat | rat") + + NpgsqlTextFunctions.AsTsQuery("cat")).First(); + + Assert.That( + NpgsqlTsQuery.Parse(result).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("( 'fat' | 'rat' ) | 'cat'").ToString())); + } + } + + [Test] + public void TsQueryNot() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => NpgsqlTextFunctions.QueryNot(NpgsqlTextFunctions.AsTsQuery("cat"))).First(); + + Assert.That( + NpgsqlTsQuery.Parse(result).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("! 'cat'").ToString())); + } + } + + [Test] + public void TsContains() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => + NpgsqlTextFunctions.QueryContains( + NpgsqlTextFunctions.AsTsQuery("cat"), + NpgsqlTextFunctions.AsTsQuery("cat & rat"))).First(); + + Assert.That(result, Is.False); + } + } + + [Test] + public void TsIsContained() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add(new Blog { Name = "_" }); + context.SaveChanges(); + + var result = context.Blogs.Select( + x => + NpgsqlTextFunctions.QueryIsContained( + NpgsqlTextFunctions.AsTsQuery("cat"), + NpgsqlTextFunctions.AsTsQuery("cat & rat"))).First(); + + Assert.That(result, Is.True); + } + } + + [Test] + public void Match() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "The quick brown fox jumps over the lazy dog." + }; + var blog2 = new Blog + { + Name = "Jackdaws loves my big sphinx of quartz." + }; + context.Blogs.Add(blog1); + context.Blogs.Add(blog2); + context.SaveChanges(); + + var foundBlog = context + .Blogs + .FirstOrDefault( + x => + NpgsqlTextFunctions.Match( + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.ToTsQuery("jump & dog"))); + + Assert.That(foundBlog != null); + Assert.That(foundBlog.Name, Is.EqualTo(blog1.Name)); + } + } + + [Test] + public void SetWeight() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "The quick brown fox jumps over the lazy dog." + }; + context.Blogs.Add(blog1); + + var post1 = new Post + { + Blog = blog1, + Title = "Lorem ipsum", + Content = "Dolor sit amet", + Rating = 5 + }; + context.Posts.Add(post1); + + var post2 = new Post + { + Blog = blog1, + Title = "consectetur adipiscing elit", + Content = "Sed sed rhoncus", + Rating = 4 + }; + context.Posts.Add(post2); + context.SaveChanges(); + + var foundPost = context.Posts.FirstOrDefault( + x => NpgsqlTextFunctions.Match( + NpgsqlTextFunctions.SetWeight( + NpgsqlTextFunctions.ToTsVector(x.Title ?? string.Empty), + NpgsqlWeightLabel.D) + + NpgsqlTextFunctions.SetWeight( + NpgsqlTextFunctions.ToTsVector(x.Content ?? string.Empty), + NpgsqlWeightLabel.C), + NpgsqlTextFunctions.PlainToTsQuery("dolor"))); + + Assert.That(foundPost != null); + Assert.That(foundPost.Title, Is.EqualTo(post1.Title)); + } + } + + [Test] + public void Length() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog = new Blog + { + Name = "cooky cookie cookies piano pianos" + }; + context.Blogs.Add(blog); + context.SaveChanges(); + + var lexemeCount = context + .Blogs + .Select(x => NpgsqlTextFunctions.Length(NpgsqlTextFunctions.ToTsVector(x.Name))) + .FirstOrDefault(); + + Assert.That(lexemeCount, Is.EqualTo(2)); + } + } + + [Test] + public void NumNode() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog = new Blog + { + Name = "_" + }; + context.Blogs.Add(blog); + context.SaveChanges(); + + var nodeCount = context + .Blogs + .Select(x => NpgsqlTextFunctions.NumNode(NpgsqlTextFunctions.ToTsQuery("(fat & rat) | cat"))) + .FirstOrDefault(); + + Assert.That(nodeCount, Is.EqualTo(5)); + } + } + + [Test] + public void Strip() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog = new Blog + { + Name = "cooky cookie cookies piano pianos" + }; + context.Blogs.Add(blog); + context.SaveChanges(); + + var strippedTsVector = context + .Blogs + .Select(x => NpgsqlTextFunctions.Strip(NpgsqlTextFunctions.ToTsVector(x.Name))) + .FirstOrDefault(); + + Assert.That( + NpgsqlTsVector.Parse(strippedTsVector).ToString(), + Is.EqualTo(NpgsqlTsVector.Parse("'cooki' 'piano'").ToString())); + } + } + + [Test] + public void QueryTree() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog = new Blog + { + Name = "_" + }; + context.Blogs.Add(blog); + context.SaveChanges(); + + var queryTree = context + .Blogs + .Select(x => NpgsqlTextFunctions.QueryTree(NpgsqlTextFunctions.ToTsQuery("foo & ! bar"))) + .FirstOrDefault(); + + Assert.That( + NpgsqlTsQuery.Parse(queryTree).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("'foo'").ToString())); + } + } + + [Test] + public void TsHeadline() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "cooky cookie piano pianos" + }; + context.Blogs.Add(blog1); + + var blog2 = new Blog + { + Name = "blue crab denominates elephant" + }; + context.Blogs.Add(blog2); + context.SaveChanges(); + + var headlines = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsHeadline( + x.Name, + NpgsqlTextFunctions.ToTsQuery("cookie"), + "StartSel= StopSel=")) + .ToList(); + + Assert.That(headlines.Count, Is.EqualTo(2)); + Assert.That(headlines[0], Is.EqualTo("cooky cookie piano pianos")); + Assert.That(headlines[1], Is.EqualTo(blog2.Name)); + + headlines = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsHeadline( + "english", + x.Name, + NpgsqlTextFunctions.ToTsQuery("piano"), + "StartSel= StopSel=")) + .ToList(); + + Assert.That(headlines.Count, Is.EqualTo(2)); + Assert.That(headlines[0], Is.EqualTo("cooky cookie piano pianos")); + Assert.That(headlines[1], Is.EqualTo(blog2.Name)); + } + } + + [Test] + public void TsRank() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "cooky cookie piano pianos" + }; + context.Blogs.Add(blog1); + context.SaveChanges(); + + var rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRank( + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"))) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRank( + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"), + NpgsqlRankingNormalization.DivideByLength + | NpgsqlRankingNormalization.DivideByUniqueWordCount)) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRank( + 0.1f, 0.2f, 0.4f, 1.0f, + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"))) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRank( + 0.1f, 0.2f, 0.4f, 1.0f, + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"), + NpgsqlRankingNormalization.DivideByLength + | NpgsqlRankingNormalization.DivideByUniqueWordCount)) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + } + } + + [Test] + public void TsRankCd() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "cooky cookie piano pianos" + }; + context.Blogs.Add(blog1); + context.SaveChanges(); + + var rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRankCd( + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"))) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRankCd( + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"), + NpgsqlRankingNormalization.DivideByLength + | NpgsqlRankingNormalization.DivideByUniqueWordCount)) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRankCd( + 0.1f, 0.2f, 0.4f, 1.0f, + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"))) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + + rank = context + .Blogs + .Select( + x => NpgsqlTextFunctions.TsRankCd( + 0.1f, 0.2f, 0.4f, 1.0f, + NpgsqlTextFunctions.ToTsVector(x.Name), + NpgsqlTextFunctions.PlainToTsQuery("cookie"), + NpgsqlRankingNormalization.DivideByLength + | NpgsqlRankingNormalization.DivideByUniqueWordCount)) + .FirstOrDefault(); + Assert.That(rank, Is.GreaterThan(0)); + } + } + + [Test] + public void TsRewrite() + { + using (var context = new BloggingContext(ConnectionStringEF)) + { + context.Database.Log = Console.Out.WriteLine; + + var blog1 = new Blog + { + Name = "_" + }; + context.Blogs.Add(blog1); + context.SaveChanges(); + + var newQuery = context + .Blogs.Select( + x => + NpgsqlTextFunctions.TsRewrite( + "a & b", + "a", + "foo|bar")) + .FirstOrDefault(); + + Assert.That( + NpgsqlTsQuery.Parse(newQuery).ToString(), + Is.EqualTo(NpgsqlTsQuery.Parse("'b' & ( 'foo' | 'bar' )").ToString())); + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/Program.cs b/test/EntityFramework6.Npgsql.Tests/Program.cs new file mode 100644 index 0000000..87168b4 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Program.cs @@ -0,0 +1,22 @@ +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 new file mode 100644 index 0000000..fac0285 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,54 @@ +// +// 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/Spatial/PostgisServiceTests.cs b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs new file mode 100644 index 0000000..a568815 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs @@ -0,0 +1,1824 @@ +using NpgsqlTypes; +using NUnit.Framework; +using System; +using Npgsql.Spatial; + +namespace Npgsql.Tests.Spatial +{ + public class PostgisServiceTests : TestBase + { + NpgsqlConnection _conn; + NpgsqlConnection Conn + { + get + { + if (_conn == null) + { + _conn = new NpgsqlConnection(ConnectionString); + _conn.Open(); + } + return _conn; + } + } + + [Test()] + public void AsBinaryTest() + { + var p = new PostgisPoint(1D, 1D); + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.AsBinary(svcs.GeometryFromProviderValue(p)); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void AsBinaryTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void AsGmlTest() + { + var p = new PostgisPoint(1D, 1D); + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.AsGml(svcs.GeometryFromProviderValue(p)); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void AsGmlTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void AsTextTest() + { + var p = new PostgisPoint(1D, 1D); + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.AsText(svcs.GeometryFromProviderValue(p)); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void AsTextTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void BufferTest() + { + var p = new PostgisPoint(1D, 1D); + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.Buffer(svcs.GeometryFromProviderValue(p), 19D); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void BufferTest1() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void ContainsTest() + { + var p = new PostgisPoint(1D, 1D); + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + var pol = new PostgisPolygon(new Coordinate2D[1][] + {new Coordinate2D[5] + { + new Coordinate2D(0D,0D), + new Coordinate2D(5D,0D), + new Coordinate2D(5D,5D), + new Coordinate2D(0D,5D), + new Coordinate2D(0D,0D) + } + }); + try + { + Assert.True(svcs.Contains(svcs.GeometryFromProviderValue(pol), svcs.GeometryFromProviderValue(p))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void CreateProviderValueTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.CreateProviderValue( + svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))) + ); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void CreateProviderValueTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void CreateWellKnownValueTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void CreateWellKnownValueTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void CrossesTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.Crosses(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void DifferenceTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.Difference(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void DifferenceTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void DisjointTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.Disjoint(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void DisjointTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void DistanceTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.Distance(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void DistanceTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void ElementAtTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.ElementAt(svcs.GeometryFromProviderValue( + new PostgisGeometryCollection(new PostgisGeometry[1] { new PostgisPoint(0D, 0D) })), + 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void ElementAtTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyCollectionFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyCollectionFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromBinaryTest1() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromGmlTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromGmlTest1() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromProviderValueTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyFromTextTest1() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyLineFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyLineFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiLineFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiLineFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiPointFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiPointFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiPolygonFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyMultiPolygonFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyPointFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyPointFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyPolygonFromBinaryTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeographyPolygonFromTextTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeometryCollectionFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisGeometryCollection + (new PostgisGeometry[] { new PostgisPoint(0D, 0D) }))); + svcs.GeometryCollectionFromBinary(b, 1); + } + catch (NotImplementedException exi) + { + Assert.Ignore("not implemented"); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryCollectionFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisGeometryCollection + (new PostgisGeometry[] { new PostgisPoint(0D, 0D) }))); + svcs.GeometryCollectionFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryFromBinaryTestGeog() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeometryFromGmlTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryCollectionFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryFromGmlTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeometryFromProviderValueTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + svcs.GeometryFromProviderValue(new PostgisPoint(0d, 0d)); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryCollectionFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryFromTextTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GeometryLineFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) }))); + svcs.GeometryLineFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryLineFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) }))); + svcs.GeometryLineFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiLineFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiLineString( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryMultiLineFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiLineFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiLineString( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryMultiLineFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiPointFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiPoint( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + ))); + svcs.GeometryMultiPointFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiPointFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiPoint( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + ))); + svcs.GeometryMultiPointFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiPolygonFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiPolygon(new PostgisPolygon[] + {new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + } + ) + } + ))); + svcs.GeometryMultiPolygonFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryMultiPolygonFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiPolygon(new PostgisPolygon[] + {new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + } + ) + } + ))); + svcs.GeometryMultiPolygonFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryPointFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); + svcs.GeometryPointFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryPointFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); + svcs.GeometryPointFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryPolygonFromBinaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryPolygonFromBinary(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GeometryPolygonFromTextTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryPolygonFromText(b, 1); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetAreaTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetArea(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetAreaTestGeom() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetBoundaryTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetBoundary(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetCentroidTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetCentroid(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetConvexHullTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetConvexHull(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetCoordinateSystemIdTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }) + { SRID = 3742 }); + svcs.GetCoordinateSystemId(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetCoordinateSystemIdTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetDimensionTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetDimension(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetDimensionTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetElementCountTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisGeometryCollection( + new PostgisGeometry[] { + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }) + }) + ); + svcs.GetElementCount(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetElementCountTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetElevationTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetElevationTest1() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetEndPointTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetEndPoint(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetEndPointTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetEnvelopeTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetEnvelope(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetExteriorRingTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetExteriorRing(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetInteriorRingCountTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetInteriorRingCount(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetIsClosedTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsClosed(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetIsClosedTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetIsEmptyTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsEmpty(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetIsEmptyTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetIsRingTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisLineString( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + })); + svcs.GetIsRing(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetIsSimpleTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsSimple(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetIsValidTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsSimple(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetLatitudeTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetLengthTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetLength(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetLengthTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetLongitudeTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetMeasureTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetMeasureTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetPointCountTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetPointCount(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetPointCountTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetPointOnSurfaceTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetPointOnSurface(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetSpatialTypeNameTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + Assert.IsTrue(svcs.GetSpatialTypeName(b).ToLower() == "polygon"); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetSpatialTypeNameTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetStartPointTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetStartPoint(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetStartPointTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void GetXCoordinateTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPoint(0D, 0D)); + svcs.GetXCoordinate(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void GetYCoordinateTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPoint(0D, 0D)); + svcs.GetYCoordinate(b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void InteriorRingAtTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + ,new Coordinate2D[] { + new Coordinate2D(0.5D, 0.5D), + new Coordinate2D(0.5d,0.8d), + new Coordinate2D(0.8d,0.8d), + new Coordinate2D(0.8d,0.5d), + new Coordinate2D(0.5d,0.5d) + } + })); + svcs.InteriorRingAt(b, 2); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void IntersectionTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Intersection(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void IntersectionTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void IntersectsTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Intersection(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void IntersectsTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void OverlapsTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Overlaps(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void PointAtTest() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void PointAtTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void RelateTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Relate(b, b, "0FFFFF212"); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void SpatialEqualsTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.SpatialEquals(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void SpatialEqualsTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void SymmetricDifferenceTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.SymmetricDifference(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void SymmetricDifferenceTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void TouchesTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Touches(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void UnionTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Union(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void UnionTestGeog() + { + Assert.Ignore("not implemented"); + } + + [Test()] + public void WithinTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + try + { + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Within(b, b); + } + catch (Exception ex) + { + Assert.Fail(ex.Message); + } + } + + [Test()] + public void InstanceTest() + { + var svcs = new PostgisServices(); + svcs.SetConnection(Conn); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + try + { + var x = b.Area; + } + catch (Exception) + { + Assert.Fail(); + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/project.json b/test/EntityFramework6.Npgsql.Tests/project.json new file mode 100644 index 0000000..52b1d64 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/project.json @@ -0,0 +1,27 @@ +{ + "version": "0.0.0", + "buildOptions": { + "keyFile": "../../Npgsql.snk", + "emitEntryPoint": true + }, + "dependencies": { + "NUnit": "3.2.1", + "NUnitLite": "3.2.1", + "NLog": "3.2.0.0", + "EntityFramework6.Npgsql": "3.1.0-*", + "Npgsql.Tests": "0.0.0" + }, + "frameworks": { + "net46": { + "frameworkAssemblies": { + "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, + "System.Runtime.Serialization": { "version": "4.0.0.0", "type": "build" }, + "System.Transactions": { "version": "4.0.0.0", "type": "build" }, + "System.DirectoryServices": { "version": "4.0.0.0", "type": "build" }, + "System.Data": { "version": "4.0.0.0", "type": "build" }, + "System.Xml": { "version": "4.0.0.0", "type": "build" }, + "System.Web": { "version": "4.0.0.0", "type": "build" } + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs new file mode 100644 index 0000000..db8db31 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.EF6.cs @@ -0,0 +1,1938 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.4927 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +[assembly: global::System.Data.Entity.Core.Objects.DataClasses.EdmSchema()] +[assembly: global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "Customer", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.Customer), "SalesOrderHeader", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.SalesOrderHeader))] +[assembly: global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "UserDetails_FK", "User", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.User), "UserDetails", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(XmlTest.UserDetails))] +[assembly: global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "UserToken_FK", "User", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.User), "UserToken", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(XmlTest.UserToken))] +[assembly: global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "dispTargetViews", "dispViews", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.dispViews), "dispViews1", global::System.Data.Entity.Core.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.dispViews))] + +// Original file name: XmlTest.ObjectLayer.cs +// Generation date: 12/21/2009 7:46:26 PM +namespace XmlTest +{ + + /// + /// There are no comments for XmlTestContext in the schema. + /// + public partial class XmlTestContext : global::System.Data.Entity.Core.Objects.ObjectContext + { + /// + /// Initializes a new XmlTestContext object using the connection string found in the 'XmlTestContext' section of the application configuration file. + /// + public XmlTestContext() : + base("name=XmlTestContext", "XmlTestContext") + { + this.OnContextCreated(); + } + /// + /// Initialize a new XmlTestContext object. + /// + public XmlTestContext(string connectionString) : + base(connectionString, "XmlTestContext") + { + this.OnContextCreated(); + } + /// + /// Initialize a new XmlTestContext object. + /// + public XmlTestContext(global::System.Data.Entity.Core.EntityClient.EntityConnection connection) : + base(connection, "XmlTestContext") + { + this.OnContextCreated(); + } + partial void OnContextCreated(); + /// + /// There are no comments for Customer in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery Customer + { + get + { + if ((this._Customer == null)) + { + this._Customer = base.CreateQuery("[Customer]"); + } + return this._Customer; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _Customer; + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery SalesOrderHeader + { + get + { + if ((this._SalesOrderHeader == null)) + { + this._SalesOrderHeader = base.CreateQuery("[SalesOrderHeader]"); + } + return this._SalesOrderHeader; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _SalesOrderHeader; + /// + /// There are no comments for User in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery User + { + get + { + if ((this._User == null)) + { + this._User = base.CreateQuery("[User]"); + } + return this._User; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _User; + /// + /// There are no comments for UserDetails in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery UserDetails + { + get + { + if ((this._UserDetails == null)) + { + this._UserDetails = base.CreateQuery("[UserDetails]"); + } + return this._UserDetails; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _UserDetails; + /// + /// There are no comments for UserToken in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery UserToken + { + get + { + if ((this._UserToken == null)) + { + this._UserToken = base.CreateQuery("[UserToken]"); + } + return this._UserToken; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _UserToken; + /// + /// There are no comments for XmlTable in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery XmlTable + { + get + { + if ((this._XmlTable == null)) + { + this._XmlTable = base.CreateQuery("[XmlTable]"); + } + return this._XmlTable; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _XmlTable; + /// + /// There are no comments for dispViews in the schema. + /// + public global::System.Data.Entity.Core.Objects.ObjectQuery dispViews + { + get + { + if ((this._dispViews == null)) + { + this._dispViews = base.CreateQuery("[dispViews]"); + } + return this._dispViews; + } + } + private global::System.Data.Entity.Core.Objects.ObjectQuery _dispViews; + /// + /// There are no comments for Customer in the schema. + /// + public void AddToCustomer(Customer customer) + { + base.AddObject("Customer", customer); + } + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + public void AddToSalesOrderHeader(SalesOrderHeader salesOrderHeader) + { + base.AddObject("SalesOrderHeader", salesOrderHeader); + } + /// + /// There are no comments for User in the schema. + /// + public void AddToUser(User user) + { + base.AddObject("User", user); + } + /// + /// There are no comments for UserDetails in the schema. + /// + public void AddToUserDetails(UserDetails userDetails) + { + base.AddObject("UserDetails", userDetails); + } + /// + /// There are no comments for UserToken in the schema. + /// + public void AddToUserToken(UserToken userToken) + { + base.AddObject("UserToken", userToken); + } + /// + /// There are no comments for XmlTable in the schema. + /// + public void AddToXmlTable(XmlTable xmlTable) + { + base.AddObject("XmlTable", xmlTable); + } + /// + /// There are no comments for dispViews in the schema. + /// + public void AddTodispViews(dispViews dispViews) + { + base.AddObject("dispViews", dispViews); + } + } + /// + /// There are no comments for XmlTest.Customer in the schema. + /// + /// + /// OrderID + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="Customer")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class Customer : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new Customer object. + /// + /// Initial value of OrderID. + /// Initial value of NameStyle. + /// Initial value of Active. + /// Initial value of ModifiedDate. + /// Initial value of Created. + /// Initial value of NewCustomer. + /// Initial value of Potential. + /// Initial value of NewAssigned. + /// Initial value of OldActive. + /// Initial value of Total. + public static Customer CreateCustomer(int orderID, int nameStyle, bool active, global::System.DateTime modifiedDate, global::System.DateTime created, bool newCustomer, bool potential, bool newAssigned, bool oldActive, decimal total) + { + Customer customer = new Customer(); + customer.OrderID = orderID; + customer.NameStyle = nameStyle; + customer.Active = active; + customer.ModifiedDate = modifiedDate; + customer.Created = created; + customer.NewCustomer = newCustomer; + customer.Potential = potential; + customer.NewAssigned = newAssigned; + customer.OldActive = oldActive; + customer.Total = total; + return customer; + } + /// + /// There are no comments for Property OrderID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int OrderID + { + get + { + return this._OrderID; + } + set + { + this.OnOrderIDChanging(value); + this.ReportPropertyChanging("OrderID"); + this._OrderID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + private int _OrderID; + partial void OnOrderIDChanging(int value); + partial void OnOrderIDChanged(); + /// + /// There are no comments for Property NameStyle in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int NameStyle + { + get + { + return this._NameStyle; + } + set + { + this.OnNameStyleChanging(value); + this.ReportPropertyChanging("NameStyle"); + this._NameStyle = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NameStyle"); + this.OnNameStyleChanged(); + } + } + private int _NameStyle; + partial void OnNameStyleChanging(int value); + partial void OnNameStyleChanged(); + /// + /// There are no comments for Property FirstName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string FirstName + { + get + { + return this._FirstName; + } + set + { + this.OnFirstNameChanging(value); + this.ReportPropertyChanging("FirstName"); + this._FirstName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("FirstName"); + this.OnFirstNameChanged(); + } + } + private string _FirstName; + partial void OnFirstNameChanging(string value); + partial void OnFirstNameChanged(); + /// + /// There are no comments for Property LastName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string LastName + { + get + { + return this._LastName; + } + set + { + this.OnLastNameChanging(value); + this.ReportPropertyChanging("LastName"); + this._LastName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("LastName"); + this.OnLastNameChanged(); + } + } + private string _LastName; + partial void OnLastNameChanging(string value); + partial void OnLastNameChanged(); + /// + /// There are no comments for Property Active in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool Active + { + get + { + return this._Active; + } + set + { + this.OnActiveChanging(value); + this.ReportPropertyChanging("Active"); + this._Active = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Active"); + this.OnActiveChanged(); + } + } + private bool _Active; + partial void OnActiveChanging(bool value); + partial void OnActiveChanged(); + /// + /// There are no comments for Property ModifiedDate in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.DateTime ModifiedDate + { + get + { + return this._ModifiedDate; + } + set + { + this.OnModifiedDateChanging(value); + this.ReportPropertyChanging("ModifiedDate"); + this._ModifiedDate = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ModifiedDate"); + this.OnModifiedDateChanged(); + } + } + private global::System.DateTime _ModifiedDate; + partial void OnModifiedDateChanging(global::System.DateTime value); + partial void OnModifiedDateChanged(); + /// + /// There are no comments for Property TourNumber in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable TourNumber + { + get + { + return this._TourNumber; + } + set + { + this.OnTourNumberChanging(value); + this.ReportPropertyChanging("TourNumber"); + this._TourNumber = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("TourNumber"); + this.OnTourNumberChanged(); + } + } + private global::System.Nullable _TourNumber; + partial void OnTourNumberChanging(global::System.Nullable value); + partial void OnTourNumberChanged(); + /// + /// There are no comments for Property ExternalNumber in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable ExternalNumber + { + get + { + return this._ExternalNumber; + } + set + { + this.OnExternalNumberChanging(value); + this.ReportPropertyChanging("ExternalNumber"); + this._ExternalNumber = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ExternalNumber"); + this.OnExternalNumberChanged(); + } + } + private global::System.Nullable _ExternalNumber; + partial void OnExternalNumberChanging(global::System.Nullable value); + partial void OnExternalNumberChanged(); + /// + /// There are no comments for Property MainPhone1 in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MainPhone1 + { + get + { + return this._MainPhone1; + } + set + { + this.OnMainPhone1Changing(value); + this.ReportPropertyChanging("MainPhone1"); + this._MainPhone1 = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("MainPhone1"); + this.OnMainPhone1Changed(); + } + } + private string _MainPhone1; + partial void OnMainPhone1Changing(string value); + partial void OnMainPhone1Changed(); + /// + /// There are no comments for Property MainPhone2 in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MainPhone2 + { + get + { + return this._MainPhone2; + } + set + { + this.OnMainPhone2Changing(value); + this.ReportPropertyChanging("MainPhone2"); + this._MainPhone2 = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("MainPhone2"); + this.OnMainPhone2Changed(); + } + } + private string _MainPhone2; + partial void OnMainPhone2Changing(string value); + partial void OnMainPhone2Changed(); + /// + /// There are no comments for Property PreOrderID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string PreOrderID + { + get + { + return this._PreOrderID; + } + set + { + this.OnPreOrderIDChanging(value); + this.ReportPropertyChanging("PreOrderID"); + this._PreOrderID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("PreOrderID"); + this.OnPreOrderIDChanged(); + } + } + private string _PreOrderID; + partial void OnPreOrderIDChanging(string value); + partial void OnPreOrderIDChanged(); + /// + /// There are no comments for Property LastVisit in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable LastVisit + { + get + { + return this._LastVisit; + } + set + { + this.OnLastVisitChanging(value); + this.ReportPropertyChanging("LastVisit"); + this._LastVisit = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("LastVisit"); + this.OnLastVisitChanged(); + } + } + private global::System.Nullable _LastVisit; + partial void OnLastVisitChanging(global::System.Nullable value); + partial void OnLastVisitChanged(); + /// + /// There are no comments for Property Created in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.DateTime Created + { + get + { + return this._Created; + } + set + { + this.OnCreatedChanging(value); + this.ReportPropertyChanging("Created"); + this._Created = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Created"); + this.OnCreatedChanged(); + } + } + private global::System.DateTime _Created; + partial void OnCreatedChanging(global::System.DateTime value); + partial void OnCreatedChanged(); + /// + /// There are no comments for Property ExternalName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ExternalName + { + get + { + return this._ExternalName; + } + set + { + this.OnExternalNameChanging(value); + this.ReportPropertyChanging("ExternalName"); + this._ExternalName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("ExternalName"); + this.OnExternalNameChanged(); + } + } + private string _ExternalName; + partial void OnExternalNameChanging(string value); + partial void OnExternalNameChanged(); + /// + /// There are no comments for Property NewCustomer in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool NewCustomer + { + get + { + return this._NewCustomer; + } + set + { + this.OnNewCustomerChanging(value); + this.ReportPropertyChanging("NewCustomer"); + this._NewCustomer = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NewCustomer"); + this.OnNewCustomerChanged(); + } + } + private bool _NewCustomer; + partial void OnNewCustomerChanging(bool value); + partial void OnNewCustomerChanged(); + /// + /// There are no comments for Property Potential in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool Potential + { + get + { + return this._Potential; + } + set + { + this.OnPotentialChanging(value); + this.ReportPropertyChanging("Potential"); + this._Potential = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Potential"); + this.OnPotentialChanged(); + } + } + private bool _Potential; + partial void OnPotentialChanging(bool value); + partial void OnPotentialChanged(); + /// + /// There are no comments for Property CustomerID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable CustomerID + { + get + { + return this._CustomerID; + } + set + { + this.OnCustomerIDChanging(value); + this.ReportPropertyChanging("CustomerID"); + this._CustomerID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + private global::System.Nullable _CustomerID; + partial void OnCustomerIDChanging(global::System.Nullable value); + partial void OnCustomerIDChanged(); + /// + /// There are no comments for Property OldExternalNumber in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OldExternalNumber + { + get + { + return this._OldExternalNumber; + } + set + { + this.OnOldExternalNumberChanging(value); + this.ReportPropertyChanging("OldExternalNumber"); + this._OldExternalNumber = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldExternalNumber"); + this.OnOldExternalNumberChanged(); + } + } + private global::System.Nullable _OldExternalNumber; + partial void OnOldExternalNumberChanging(global::System.Nullable value); + partial void OnOldExternalNumberChanged(); + /// + /// There are no comments for Property OldTourNumber in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OldTourNumber + { + get + { + return this._OldTourNumber; + } + set + { + this.OnOldTourNumberChanging(value); + this.ReportPropertyChanging("OldTourNumber"); + this._OldTourNumber = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldTourNumber"); + this.OnOldTourNumberChanged(); + } + } + private global::System.Nullable _OldTourNumber; + partial void OnOldTourNumberChanging(global::System.Nullable value); + partial void OnOldTourNumberChanged(); + /// + /// There are no comments for Property NewAssigned in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool NewAssigned + { + get + { + return this._NewAssigned; + } + set + { + this.OnNewAssignedChanging(value); + this.ReportPropertyChanging("NewAssigned"); + this._NewAssigned = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NewAssigned"); + this.OnNewAssignedChanged(); + } + } + private bool _NewAssigned; + partial void OnNewAssignedChanging(bool value); + partial void OnNewAssignedChanged(); + /// + /// There are no comments for Property OldActive in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool OldActive + { + get + { + return this._OldActive; + } + set + { + this.OnOldActiveChanging(value); + this.ReportPropertyChanging("OldActive"); + this._OldActive = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldActive"); + this.OnOldActiveChanged(); + } + } + private bool _OldActive; + partial void OnOldActiveChanging(bool value); + partial void OnOldActiveChanged(); + /// + /// There are no comments for Property StartDate in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable StartDate + { + get + { + return this._StartDate; + } + set + { + this.OnStartDateChanging(value); + this.ReportPropertyChanging("StartDate"); + this._StartDate = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("StartDate"); + this.OnStartDateChanged(); + } + } + private global::System.Nullable _StartDate; + partial void OnStartDateChanging(global::System.Nullable value); + partial void OnStartDateChanged(); + /// + /// There are no comments for Property Total in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Total + { + get + { + return this._Total; + } + set + { + this.OnTotalChanging(value); + this.ReportPropertyChanging("Total"); + this._Total = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Total"); + this.OnTotalChanged(); + } + } + private decimal _Total; + partial void OnTotalChanging(decimal value); + partial void OnTotalChanged(); + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "SalesOrderHeader")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityCollection SalesOrderHeader + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.SalesOrderHeader_OrderID_fkey", "SalesOrderHeader"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.SalesOrderHeader_OrderID_fkey", "SalesOrderHeader", value); + } + } + } + } + /// + /// There are no comments for XmlTest.SalesOrderHeader in the schema. + /// + /// + /// ID + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="SalesOrderHeader")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class SalesOrderHeader : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new SalesOrderHeader object. + /// + /// Initial value of Status. + /// Initial value of SubTotal. + /// Initial value of TotalDue. + /// Initial value of BookCounter. + /// Initial value of SubSubTotal. + /// Initial value of PriceRabatt15. + /// Initial value of Total. + /// Initial value of Discount. + /// Initial value of Rabatt. + /// Initial value of ID. + /// Initial value of Saison. + public static SalesOrderHeader CreateSalesOrderHeader(int status, decimal subTotal, decimal totalDue, int bookCounter, decimal subSubTotal, bool priceRabatt15, decimal total, decimal discount, decimal rabatt, int id, string saison) + { + SalesOrderHeader salesOrderHeader = new SalesOrderHeader(); + salesOrderHeader.Status = status; + salesOrderHeader.SubTotal = subTotal; + salesOrderHeader.TotalDue = totalDue; + salesOrderHeader.BookCounter = bookCounter; + salesOrderHeader.SubSubTotal = subSubTotal; + salesOrderHeader.PriceRabatt15 = priceRabatt15; + salesOrderHeader.Total = total; + salesOrderHeader.Discount = discount; + salesOrderHeader.Rabatt = rabatt; + salesOrderHeader.ID = id; + salesOrderHeader.Saison = saison; + return salesOrderHeader; + } + /// + /// There are no comments for Property OrderDate in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OrderDate + { + get + { + return this._OrderDate; + } + set + { + this.OnOrderDateChanging(value); + this.ReportPropertyChanging("OrderDate"); + this._OrderDate = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); + } + } + private global::System.Nullable _OrderDate; + partial void OnOrderDateChanging(global::System.Nullable value); + partial void OnOrderDateChanged(); + /// + /// There are no comments for Property Status in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int Status + { + get + { + return this._Status; + } + set + { + this.OnStatusChanging(value); + this.ReportPropertyChanging("Status"); + this._Status = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Status"); + this.OnStatusChanged(); + } + } + private int _Status; + partial void OnStatusChanging(int value); + partial void OnStatusChanged(); + /// + /// There are no comments for Property BillToAddressID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable BillToAddressID + { + get + { + return this._BillToAddressID; + } + set + { + this.OnBillToAddressIDChanging(value); + this.ReportPropertyChanging("BillToAddressID"); + this._BillToAddressID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("BillToAddressID"); + this.OnBillToAddressIDChanged(); + } + } + private global::System.Nullable _BillToAddressID; + partial void OnBillToAddressIDChanging(global::System.Nullable value); + partial void OnBillToAddressIDChanged(); + /// + /// There are no comments for Property SubTotal in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal SubTotal + { + get + { + return this._SubTotal; + } + set + { + this.OnSubTotalChanging(value); + this.ReportPropertyChanging("SubTotal"); + this._SubTotal = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SubTotal"); + this.OnSubTotalChanged(); + } + } + private decimal _SubTotal; + partial void OnSubTotalChanging(decimal value); + partial void OnSubTotalChanged(); + /// + /// There are no comments for Property TotalDue in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal TotalDue + { + get + { + return this._TotalDue; + } + set + { + this.OnTotalDueChanging(value); + this.ReportPropertyChanging("TotalDue"); + this._TotalDue = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("TotalDue"); + this.OnTotalDueChanged(); + } + } + private decimal _TotalDue; + partial void OnTotalDueChanging(decimal value); + partial void OnTotalDueChanged(); + /// + /// There are no comments for Property Comment in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Comment + { + get + { + return this._Comment; + } + set + { + this.OnCommentChanging(value); + this.ReportPropertyChanging("Comment"); + this._Comment = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Comment"); + this.OnCommentChanged(); + } + } + private string _Comment; + partial void OnCommentChanging(string value); + partial void OnCommentChanged(); + /// + /// There are no comments for Property ModifiedDate in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable ModifiedDate + { + get + { + return this._ModifiedDate; + } + set + { + this.OnModifiedDateChanging(value); + this.ReportPropertyChanging("ModifiedDate"); + this._ModifiedDate = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ModifiedDate"); + this.OnModifiedDateChanged(); + } + } + private global::System.Nullable _ModifiedDate; + partial void OnModifiedDateChanging(global::System.Nullable value); + partial void OnModifiedDateChanged(); + /// + /// There are no comments for Property PaymentVersion in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable PaymentVersion + { + get + { + return this._PaymentVersion; + } + set + { + this.OnPaymentVersionChanging(value); + this.ReportPropertyChanging("PaymentVersion"); + this._PaymentVersion = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("PaymentVersion"); + this.OnPaymentVersionChanged(); + } + } + private global::System.Nullable _PaymentVersion; + partial void OnPaymentVersionChanging(global::System.Nullable value); + partial void OnPaymentVersionChanged(); + /// + /// There are no comments for Property BillID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string BillID + { + get + { + return this._BillID; + } + set + { + this.OnBillIDChanging(value); + this.ReportPropertyChanging("BillID"); + this._BillID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("BillID"); + this.OnBillIDChanged(); + } + } + private string _BillID; + partial void OnBillIDChanging(string value); + partial void OnBillIDChanged(); + /// + /// There are no comments for Property BookCounter in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int BookCounter + { + get + { + return this._BookCounter; + } + set + { + this.OnBookCounterChanging(value); + this.ReportPropertyChanging("BookCounter"); + this._BookCounter = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("BookCounter"); + this.OnBookCounterChanged(); + } + } + private int _BookCounter; + partial void OnBookCounterChanging(int value); + partial void OnBookCounterChanged(); + /// + /// There are no comments for Property SendID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable SendID + { + get + { + return this._SendID; + } + set + { + this.OnSendIDChanging(value); + this.ReportPropertyChanging("SendID"); + this._SendID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SendID"); + this.OnSendIDChanged(); + } + } + private global::System.Nullable _SendID; + partial void OnSendIDChanging(global::System.Nullable value); + partial void OnSendIDChanged(); + /// + /// There are no comments for Property SubSubTotal in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal SubSubTotal + { + get + { + return this._SubSubTotal; + } + set + { + this.OnSubSubTotalChanging(value); + this.ReportPropertyChanging("SubSubTotal"); + this._SubSubTotal = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SubSubTotal"); + this.OnSubSubTotalChanged(); + } + } + private decimal _SubSubTotal; + partial void OnSubSubTotalChanging(decimal value); + partial void OnSubSubTotalChanged(); + /// + /// There are no comments for Property PriceRabatt15 in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool PriceRabatt15 + { + get + { + return this._PriceRabatt15; + } + set + { + this.OnPriceRabatt15Changing(value); + this.ReportPropertyChanging("PriceRabatt15"); + this._PriceRabatt15 = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("PriceRabatt15"); + this.OnPriceRabatt15Changed(); + } + } + private bool _PriceRabatt15; + partial void OnPriceRabatt15Changing(bool value); + partial void OnPriceRabatt15Changed(); + /// + /// There are no comments for Property Total in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Total + { + get + { + return this._Total; + } + set + { + this.OnTotalChanging(value); + this.ReportPropertyChanging("Total"); + this._Total = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Total"); + this.OnTotalChanged(); + } + } + private decimal _Total; + partial void OnTotalChanging(decimal value); + partial void OnTotalChanged(); + /// + /// There are no comments for Property Discount in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Discount + { + get + { + return this._Discount; + } + set + { + this.OnDiscountChanging(value); + this.ReportPropertyChanging("Discount"); + this._Discount = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Discount"); + this.OnDiscountChanged(); + } + } + private decimal _Discount; + partial void OnDiscountChanging(decimal value); + partial void OnDiscountChanged(); + /// + /// There are no comments for Property Rabatt in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Rabatt + { + get + { + return this._Rabatt; + } + set + { + this.OnRabattChanging(value); + this.ReportPropertyChanging("Rabatt"); + this._Rabatt = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Rabatt"); + this.OnRabattChanged(); + } + } + private decimal _Rabatt; + partial void OnRabattChanging(decimal value); + partial void OnRabattChanged(); + /// + /// There are no comments for Property SendDate in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable SendDate + { + get + { + return this._SendDate; + } + set + { + this.OnSendDateChanging(value); + this.ReportPropertyChanging("SendDate"); + this._SendDate = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SendDate"); + this.OnSendDateChanged(); + } + } + private global::System.Nullable _SendDate; + partial void OnSendDateChanging(global::System.Nullable value); + partial void OnSendDateChanged(); + /// + /// There are no comments for Property ID in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int ID + { + get + { + return this._ID; + } + set + { + this.OnIDChanging(value); + this.ReportPropertyChanging("ID"); + this._ID = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ID"); + this.OnIDChanged(); + } + } + private int _ID; + partial void OnIDChanging(int value); + partial void OnIDChanged(); + /// + /// There are no comments for Property Saison in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Saison + { + get + { + return this._Saison; + } + set + { + this.OnSaisonChanging(value); + this.ReportPropertyChanging("Saison"); + this._Saison = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("Saison"); + this.OnSaisonChanged(); + } + } + private string _Saison; + partial void OnSaisonChanging(string value); + partial void OnSaisonChanged(); + /// + /// There are no comments for Customer in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "Customer")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public Customer Customer + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer").Value; + } + set + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer").Value = value; + } + } + /// + /// There are no comments for Customer in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityReference CustomerReference + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer", value); + } + } + } + } + /// + /// There are no comments for XmlTest.User in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="User")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class User : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new User object. + /// + /// Initial value of UserId. + public static User CreateUser(int userId) + { + User user = new User(); + user.UserId = userId; + return user; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Name in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Name + { + get + { + return this._Name; + } + set + { + this.OnNameChanging(value); + this.ReportPropertyChanging("Name"); + this._Name = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Name"); + this.OnNameChanged(); + } + } + private string _Name; + partial void OnNameChanging(string value); + partial void OnNameChanged(); + /// + /// There are no comments for Property Login in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Login + { + get + { + return this._Login; + } + set + { + this.OnLoginChanging(value); + this.ReportPropertyChanging("Login"); + this._Login = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Login"); + this.OnLoginChanged(); + } + } + private string _Login; + partial void OnLoginChanging(string value); + partial void OnLoginChanged(); + /// + /// There are no comments for Property StatusId in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable StatusId + { + get + { + return this._StatusId; + } + set + { + this.OnStatusIdChanging(value); + this.ReportPropertyChanging("StatusId"); + this._StatusId = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("StatusId"); + this.OnStatusIdChanged(); + } + } + private global::System.Nullable _StatusId; + partial void OnStatusIdChanging(global::System.Nullable value); + partial void OnStatusIdChanged(); + /// + /// There are no comments for UserDetails in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserDetails_FK", "UserDetails")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public UserDetails UserDetails + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails").Value; + } + set + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails").Value = value; + } + } + /// + /// There are no comments for UserDetails in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityReference UserDetailsReference + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserDetails_FK", "UserDetails", value); + } + } + } + /// + /// There are no comments for UserToken in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserToken_FK", "UserToken")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public UserToken UserToken + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken").Value; + } + set + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken").Value = value; + } + } + /// + /// There are no comments for UserToken in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityReference UserTokenReference + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserToken_FK", "UserToken", value); + } + } + } + } + /// + /// There are no comments for XmlTest.UserDetails in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="UserDetails")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class UserDetails : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new UserDetails object. + /// + /// Initial value of UserId. + public static UserDetails CreateUserDetails(int userId) + { + UserDetails userDetails = new UserDetails(); + userDetails.UserId = userId; + return userDetails; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Details in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Details + { + get + { + return this._Details; + } + set + { + this.OnDetailsChanging(value); + this.ReportPropertyChanging("Details"); + this._Details = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Details"); + this.OnDetailsChanged(); + } + } + private string _Details; + partial void OnDetailsChanging(string value); + partial void OnDetailsChanged(); + /// + /// There are no comments for User in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserDetails_FK", "User")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public User User + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User").Value; + } + set + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User").Value = value; + } + } + /// + /// There are no comments for User in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityReference UserReference + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserDetails_FK", "User", value); + } + } + } + } + /// + /// There are no comments for XmlTest.UserToken in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="UserToken")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class UserToken : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new UserToken object. + /// + /// Initial value of UserId. + public static UserToken CreateUserToken(int userId) + { + UserToken userToken = new UserToken(); + userToken.UserId = userId; + return userToken; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Token in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Token + { + get + { + return this._Token; + } + set + { + this.OnTokenChanging(value); + this.ReportPropertyChanging("Token"); + this._Token = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Token"); + this.OnTokenChanged(); + } + } + private string _Token; + partial void OnTokenChanging(string value); + partial void OnTokenChanged(); + /// + /// There are no comments for User in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserToken_FK", "User")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public User User + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User").Value; + } + set + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User").Value = value; + } + } + /// + /// There are no comments for User in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityReference UserReference + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserToken_FK", "User", value); + } + } + } + } + /// + /// There are no comments for XmlTest.XmlTable in the schema. + /// + /// + /// key + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="XmlTable")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class XmlTable : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new XmlTable object. + /// + /// Initial value of key. + public static XmlTable CreateXmlTable(int key) + { + XmlTable xmlTable = new XmlTable(); + xmlTable.key = key; + return xmlTable; + } + /// + /// There are no comments for Property key in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int key + { + get + { + return this._key; + } + set + { + this.OnkeyChanging(value); + this.ReportPropertyChanging("key"); + this._key = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("key"); + this.OnkeyChanged(); + } + } + private int _key; + partial void OnkeyChanging(int value); + partial void OnkeyChanged(); + /// + /// There are no comments for Property test_xml in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string test_xml + { + get + { + return this._test_xml; + } + set + { + this.Ontest_xmlChanging(value); + this.ReportPropertyChanging("test_xml"); + this._test_xml = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("test_xml"); + this.Ontest_xmlChanged(); + } + } + private string _test_xml; + partial void Ontest_xmlChanging(string value); + partial void Ontest_xmlChanged(); + } + /// + /// There are no comments for XmlTest.dispViews in the schema. + /// + /// + /// ViewName + /// MdsIdPlatformId + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="dispViews")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class dispViews : global::System.Data.Entity.Core.Objects.DataClasses.EntityObject + { + /// + /// Create a new dispViews object. + /// + /// Initial value of ViewName. + /// Initial value of MdsIdPlatformId. + public static dispViews CreatedispViews(string viewName, string mdsIdPlatformId) + { + dispViews dispViews = new dispViews(); + dispViews.ViewName = viewName; + dispViews.MdsIdPlatformId = mdsIdPlatformId; + return dispViews; + } + /// + /// There are no comments for Property ViewName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ViewName + { + get + { + return this._ViewName; + } + set + { + this.OnViewNameChanging(value); + this.ReportPropertyChanging("ViewName"); + this._ViewName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("ViewName"); + this.OnViewNameChanged(); + } + } + private string _ViewName; + partial void OnViewNameChanging(string value); + partial void OnViewNameChanged(); + /// + /// There are no comments for Property MdsIdPlatformId in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MdsIdPlatformId + { + get + { + return this._MdsIdPlatformId; + } + set + { + this.OnMdsIdPlatformIdChanging(value); + this.ReportPropertyChanging("MdsIdPlatformId"); + this._MdsIdPlatformId = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("MdsIdPlatformId"); + this.OnMdsIdPlatformIdChanged(); + } + } + private string _MdsIdPlatformId; + partial void OnMdsIdPlatformIdChanging(string value); + partial void OnMdsIdPlatformIdChanged(); + /// + /// There are no comments for Property DisplayName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string DisplayName + { + get + { + return this._DisplayName; + } + set + { + this.OnDisplayNameChanging(value); + this.ReportPropertyChanging("DisplayName"); + this._DisplayName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("DisplayName"); + this.OnDisplayNameChanged(); + } + } + private string _DisplayName; + partial void OnDisplayNameChanging(string value); + partial void OnDisplayNameChanged(); + /// + /// There are no comments for Property ImageFileName in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ImageFileName + { + get + { + return this._ImageFileName; + } + set + { + this.OnImageFileNameChanging(value); + this.ReportPropertyChanging("ImageFileName"); + this._ImageFileName = global::System.Data.Entity.Core.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("ImageFileName"); + this.OnImageFileNameChanged(); + } + } + private string _ImageFileName; + partial void OnImageFileNameChanging(string value); + partial void OnImageFileNameChanged(); + /// + /// There are no comments for dispViews1 in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "dispTargetViews", "dispViews1")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityCollection dispViews1 + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.dispTargetViews", "dispViews1"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.dispTargetViews", "dispViews1", value); + } + } + } + /// + /// There are no comments for dispViews2 in the schema. + /// + [global::System.Data.Entity.Core.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "dispTargetViews", "dispViews")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Entity.Core.Objects.DataClasses.EntityCollection dispViews2 + { + get + { + return ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.dispTargetViews", "dispViews"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Entity.Core.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.dispTargetViews", "dispViews", value); + } + } + } + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs new file mode 100644 index 0000000..f2eff77 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ObjectLayer.cs @@ -0,0 +1,1940 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.4927 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if ENTITIES +[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "Customer", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.Customer), "SalesOrderHeader", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.SalesOrderHeader))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "UserDetails_FK", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.User), "UserDetails", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(XmlTest.UserDetails))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "UserToken_FK", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(XmlTest.User), "UserToken", global::System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(XmlTest.UserToken))] +[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("XmlTest", "dispTargetViews", "dispViews", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.dispViews), "dispViews1", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(XmlTest.dispViews))] + +// Original file name: XmlTest.ObjectLayer.cs +// Generation date: 12/21/2009 7:46:26 PM +namespace XmlTest +{ + + /// + /// There are no comments for XmlTestContext in the schema. + /// + public partial class XmlTestContext : global::System.Data.Objects.ObjectContext + { + /// + /// Initializes a new XmlTestContext object using the connection string found in the 'XmlTestContext' section of the application configuration file. + /// + public XmlTestContext() : + base("name=XmlTestContext", "XmlTestContext") + { + this.OnContextCreated(); + } + /// + /// Initialize a new XmlTestContext object. + /// + public XmlTestContext(string connectionString) : + base(connectionString, "XmlTestContext") + { + this.OnContextCreated(); + } + /// + /// Initialize a new XmlTestContext object. + /// + public XmlTestContext(global::System.Data.EntityClient.EntityConnection connection) : + base(connection, "XmlTestContext") + { + this.OnContextCreated(); + } + partial void OnContextCreated(); + /// + /// There are no comments for Customer in the schema. + /// + public global::System.Data.Objects.ObjectQuery Customer + { + get + { + if ((this._Customer == null)) + { + this._Customer = base.CreateQuery("[Customer]"); + } + return this._Customer; + } + } + private global::System.Data.Objects.ObjectQuery _Customer; + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + public global::System.Data.Objects.ObjectQuery SalesOrderHeader + { + get + { + if ((this._SalesOrderHeader == null)) + { + this._SalesOrderHeader = base.CreateQuery("[SalesOrderHeader]"); + } + return this._SalesOrderHeader; + } + } + private global::System.Data.Objects.ObjectQuery _SalesOrderHeader; + /// + /// There are no comments for User in the schema. + /// + public global::System.Data.Objects.ObjectQuery User + { + get + { + if ((this._User == null)) + { + this._User = base.CreateQuery("[User]"); + } + return this._User; + } + } + private global::System.Data.Objects.ObjectQuery _User; + /// + /// There are no comments for UserDetails in the schema. + /// + public global::System.Data.Objects.ObjectQuery UserDetails + { + get + { + if ((this._UserDetails == null)) + { + this._UserDetails = base.CreateQuery("[UserDetails]"); + } + return this._UserDetails; + } + } + private global::System.Data.Objects.ObjectQuery _UserDetails; + /// + /// There are no comments for UserToken in the schema. + /// + public global::System.Data.Objects.ObjectQuery UserToken + { + get + { + if ((this._UserToken == null)) + { + this._UserToken = base.CreateQuery("[UserToken]"); + } + return this._UserToken; + } + } + private global::System.Data.Objects.ObjectQuery _UserToken; + /// + /// There are no comments for XmlTable in the schema. + /// + public global::System.Data.Objects.ObjectQuery XmlTable + { + get + { + if ((this._XmlTable == null)) + { + this._XmlTable = base.CreateQuery("[XmlTable]"); + } + return this._XmlTable; + } + } + private global::System.Data.Objects.ObjectQuery _XmlTable; + /// + /// There are no comments for dispViews in the schema. + /// + public global::System.Data.Objects.ObjectQuery dispViews + { + get + { + if ((this._dispViews == null)) + { + this._dispViews = base.CreateQuery("[dispViews]"); + } + return this._dispViews; + } + } + private global::System.Data.Objects.ObjectQuery _dispViews; + /// + /// There are no comments for Customer in the schema. + /// + public void AddToCustomer(Customer customer) + { + base.AddObject("Customer", customer); + } + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + public void AddToSalesOrderHeader(SalesOrderHeader salesOrderHeader) + { + base.AddObject("SalesOrderHeader", salesOrderHeader); + } + /// + /// There are no comments for User in the schema. + /// + public void AddToUser(User user) + { + base.AddObject("User", user); + } + /// + /// There are no comments for UserDetails in the schema. + /// + public void AddToUserDetails(UserDetails userDetails) + { + base.AddObject("UserDetails", userDetails); + } + /// + /// There are no comments for UserToken in the schema. + /// + public void AddToUserToken(UserToken userToken) + { + base.AddObject("UserToken", userToken); + } + /// + /// There are no comments for XmlTable in the schema. + /// + public void AddToXmlTable(XmlTable xmlTable) + { + base.AddObject("XmlTable", xmlTable); + } + /// + /// There are no comments for dispViews in the schema. + /// + public void AddTodispViews(dispViews dispViews) + { + base.AddObject("dispViews", dispViews); + } + } + /// + /// There are no comments for XmlTest.Customer in the schema. + /// + /// + /// OrderID + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="Customer")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class Customer : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new Customer object. + /// + /// Initial value of OrderID. + /// Initial value of NameStyle. + /// Initial value of Active. + /// Initial value of ModifiedDate. + /// Initial value of Created. + /// Initial value of NewCustomer. + /// Initial value of Potential. + /// Initial value of NewAssigned. + /// Initial value of OldActive. + /// Initial value of Total. + public static Customer CreateCustomer(int orderID, int nameStyle, bool active, global::System.DateTime modifiedDate, global::System.DateTime created, bool newCustomer, bool potential, bool newAssigned, bool oldActive, decimal total) + { + Customer customer = new Customer(); + customer.OrderID = orderID; + customer.NameStyle = nameStyle; + customer.Active = active; + customer.ModifiedDate = modifiedDate; + customer.Created = created; + customer.NewCustomer = newCustomer; + customer.Potential = potential; + customer.NewAssigned = newAssigned; + customer.OldActive = oldActive; + customer.Total = total; + return customer; + } + /// + /// There are no comments for Property OrderID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int OrderID + { + get + { + return this._OrderID; + } + set + { + this.OnOrderIDChanging(value); + this.ReportPropertyChanging("OrderID"); + this._OrderID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + private int _OrderID; + partial void OnOrderIDChanging(int value); + partial void OnOrderIDChanged(); + /// + /// There are no comments for Property NameStyle in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int NameStyle + { + get + { + return this._NameStyle; + } + set + { + this.OnNameStyleChanging(value); + this.ReportPropertyChanging("NameStyle"); + this._NameStyle = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NameStyle"); + this.OnNameStyleChanged(); + } + } + private int _NameStyle; + partial void OnNameStyleChanging(int value); + partial void OnNameStyleChanged(); + /// + /// There are no comments for Property FirstName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string FirstName + { + get + { + return this._FirstName; + } + set + { + this.OnFirstNameChanging(value); + this.ReportPropertyChanging("FirstName"); + this._FirstName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("FirstName"); + this.OnFirstNameChanged(); + } + } + private string _FirstName; + partial void OnFirstNameChanging(string value); + partial void OnFirstNameChanged(); + /// + /// There are no comments for Property LastName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string LastName + { + get + { + return this._LastName; + } + set + { + this.OnLastNameChanging(value); + this.ReportPropertyChanging("LastName"); + this._LastName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("LastName"); + this.OnLastNameChanged(); + } + } + private string _LastName; + partial void OnLastNameChanging(string value); + partial void OnLastNameChanged(); + /// + /// There are no comments for Property Active in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool Active + { + get + { + return this._Active; + } + set + { + this.OnActiveChanging(value); + this.ReportPropertyChanging("Active"); + this._Active = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Active"); + this.OnActiveChanged(); + } + } + private bool _Active; + partial void OnActiveChanging(bool value); + partial void OnActiveChanged(); + /// + /// There are no comments for Property ModifiedDate in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.DateTime ModifiedDate + { + get + { + return this._ModifiedDate; + } + set + { + this.OnModifiedDateChanging(value); + this.ReportPropertyChanging("ModifiedDate"); + this._ModifiedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ModifiedDate"); + this.OnModifiedDateChanged(); + } + } + private global::System.DateTime _ModifiedDate; + partial void OnModifiedDateChanging(global::System.DateTime value); + partial void OnModifiedDateChanged(); + /// + /// There are no comments for Property TourNumber in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable TourNumber + { + get + { + return this._TourNumber; + } + set + { + this.OnTourNumberChanging(value); + this.ReportPropertyChanging("TourNumber"); + this._TourNumber = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("TourNumber"); + this.OnTourNumberChanged(); + } + } + private global::System.Nullable _TourNumber; + partial void OnTourNumberChanging(global::System.Nullable value); + partial void OnTourNumberChanged(); + /// + /// There are no comments for Property ExternalNumber in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable ExternalNumber + { + get + { + return this._ExternalNumber; + } + set + { + this.OnExternalNumberChanging(value); + this.ReportPropertyChanging("ExternalNumber"); + this._ExternalNumber = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ExternalNumber"); + this.OnExternalNumberChanged(); + } + } + private global::System.Nullable _ExternalNumber; + partial void OnExternalNumberChanging(global::System.Nullable value); + partial void OnExternalNumberChanged(); + /// + /// There are no comments for Property MainPhone1 in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MainPhone1 + { + get + { + return this._MainPhone1; + } + set + { + this.OnMainPhone1Changing(value); + this.ReportPropertyChanging("MainPhone1"); + this._MainPhone1 = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("MainPhone1"); + this.OnMainPhone1Changed(); + } + } + private string _MainPhone1; + partial void OnMainPhone1Changing(string value); + partial void OnMainPhone1Changed(); + /// + /// There are no comments for Property MainPhone2 in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MainPhone2 + { + get + { + return this._MainPhone2; + } + set + { + this.OnMainPhone2Changing(value); + this.ReportPropertyChanging("MainPhone2"); + this._MainPhone2 = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("MainPhone2"); + this.OnMainPhone2Changed(); + } + } + private string _MainPhone2; + partial void OnMainPhone2Changing(string value); + partial void OnMainPhone2Changed(); + /// + /// There are no comments for Property PreOrderID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string PreOrderID + { + get + { + return this._PreOrderID; + } + set + { + this.OnPreOrderIDChanging(value); + this.ReportPropertyChanging("PreOrderID"); + this._PreOrderID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("PreOrderID"); + this.OnPreOrderIDChanged(); + } + } + private string _PreOrderID; + partial void OnPreOrderIDChanging(string value); + partial void OnPreOrderIDChanged(); + /// + /// There are no comments for Property LastVisit in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable LastVisit + { + get + { + return this._LastVisit; + } + set + { + this.OnLastVisitChanging(value); + this.ReportPropertyChanging("LastVisit"); + this._LastVisit = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("LastVisit"); + this.OnLastVisitChanged(); + } + } + private global::System.Nullable _LastVisit; + partial void OnLastVisitChanging(global::System.Nullable value); + partial void OnLastVisitChanged(); + /// + /// There are no comments for Property Created in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.DateTime Created + { + get + { + return this._Created; + } + set + { + this.OnCreatedChanging(value); + this.ReportPropertyChanging("Created"); + this._Created = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Created"); + this.OnCreatedChanged(); + } + } + private global::System.DateTime _Created; + partial void OnCreatedChanging(global::System.DateTime value); + partial void OnCreatedChanged(); + /// + /// There are no comments for Property ExternalName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ExternalName + { + get + { + return this._ExternalName; + } + set + { + this.OnExternalNameChanging(value); + this.ReportPropertyChanging("ExternalName"); + this._ExternalName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("ExternalName"); + this.OnExternalNameChanged(); + } + } + private string _ExternalName; + partial void OnExternalNameChanging(string value); + partial void OnExternalNameChanged(); + /// + /// There are no comments for Property NewCustomer in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool NewCustomer + { + get + { + return this._NewCustomer; + } + set + { + this.OnNewCustomerChanging(value); + this.ReportPropertyChanging("NewCustomer"); + this._NewCustomer = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NewCustomer"); + this.OnNewCustomerChanged(); + } + } + private bool _NewCustomer; + partial void OnNewCustomerChanging(bool value); + partial void OnNewCustomerChanged(); + /// + /// There are no comments for Property Potential in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool Potential + { + get + { + return this._Potential; + } + set + { + this.OnPotentialChanging(value); + this.ReportPropertyChanging("Potential"); + this._Potential = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Potential"); + this.OnPotentialChanged(); + } + } + private bool _Potential; + partial void OnPotentialChanging(bool value); + partial void OnPotentialChanged(); + /// + /// There are no comments for Property CustomerID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable CustomerID + { + get + { + return this._CustomerID; + } + set + { + this.OnCustomerIDChanging(value); + this.ReportPropertyChanging("CustomerID"); + this._CustomerID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + private global::System.Nullable _CustomerID; + partial void OnCustomerIDChanging(global::System.Nullable value); + partial void OnCustomerIDChanged(); + /// + /// There are no comments for Property OldExternalNumber in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OldExternalNumber + { + get + { + return this._OldExternalNumber; + } + set + { + this.OnOldExternalNumberChanging(value); + this.ReportPropertyChanging("OldExternalNumber"); + this._OldExternalNumber = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldExternalNumber"); + this.OnOldExternalNumberChanged(); + } + } + private global::System.Nullable _OldExternalNumber; + partial void OnOldExternalNumberChanging(global::System.Nullable value); + partial void OnOldExternalNumberChanged(); + /// + /// There are no comments for Property OldTourNumber in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OldTourNumber + { + get + { + return this._OldTourNumber; + } + set + { + this.OnOldTourNumberChanging(value); + this.ReportPropertyChanging("OldTourNumber"); + this._OldTourNumber = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldTourNumber"); + this.OnOldTourNumberChanged(); + } + } + private global::System.Nullable _OldTourNumber; + partial void OnOldTourNumberChanging(global::System.Nullable value); + partial void OnOldTourNumberChanged(); + /// + /// There are no comments for Property NewAssigned in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool NewAssigned + { + get + { + return this._NewAssigned; + } + set + { + this.OnNewAssignedChanging(value); + this.ReportPropertyChanging("NewAssigned"); + this._NewAssigned = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("NewAssigned"); + this.OnNewAssignedChanged(); + } + } + private bool _NewAssigned; + partial void OnNewAssignedChanging(bool value); + partial void OnNewAssignedChanged(); + /// + /// There are no comments for Property OldActive in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool OldActive + { + get + { + return this._OldActive; + } + set + { + this.OnOldActiveChanging(value); + this.ReportPropertyChanging("OldActive"); + this._OldActive = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OldActive"); + this.OnOldActiveChanged(); + } + } + private bool _OldActive; + partial void OnOldActiveChanging(bool value); + partial void OnOldActiveChanged(); + /// + /// There are no comments for Property StartDate in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable StartDate + { + get + { + return this._StartDate; + } + set + { + this.OnStartDateChanging(value); + this.ReportPropertyChanging("StartDate"); + this._StartDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("StartDate"); + this.OnStartDateChanged(); + } + } + private global::System.Nullable _StartDate; + partial void OnStartDateChanging(global::System.Nullable value); + partial void OnStartDateChanged(); + /// + /// There are no comments for Property Total in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Total + { + get + { + return this._Total; + } + set + { + this.OnTotalChanging(value); + this.ReportPropertyChanging("Total"); + this._Total = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Total"); + this.OnTotalChanged(); + } + } + private decimal _Total; + partial void OnTotalChanging(decimal value); + partial void OnTotalChanged(); + /// + /// There are no comments for SalesOrderHeader in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "SalesOrderHeader")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityCollection SalesOrderHeader + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.SalesOrderHeader_OrderID_fkey", "SalesOrderHeader"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.SalesOrderHeader_OrderID_fkey", "SalesOrderHeader", value); + } + } + } + } + /// + /// There are no comments for XmlTest.SalesOrderHeader in the schema. + /// + /// + /// ID + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="SalesOrderHeader")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class SalesOrderHeader : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new SalesOrderHeader object. + /// + /// Initial value of Status. + /// Initial value of SubTotal. + /// Initial value of TotalDue. + /// Initial value of BookCounter. + /// Initial value of SubSubTotal. + /// Initial value of PriceRabatt15. + /// Initial value of Total. + /// Initial value of Discount. + /// Initial value of Rabatt. + /// Initial value of ID. + /// Initial value of Saison. + public static SalesOrderHeader CreateSalesOrderHeader(int status, decimal subTotal, decimal totalDue, int bookCounter, decimal subSubTotal, bool priceRabatt15, decimal total, decimal discount, decimal rabatt, int id, string saison) + { + SalesOrderHeader salesOrderHeader = new SalesOrderHeader(); + salesOrderHeader.Status = status; + salesOrderHeader.SubTotal = subTotal; + salesOrderHeader.TotalDue = totalDue; + salesOrderHeader.BookCounter = bookCounter; + salesOrderHeader.SubSubTotal = subSubTotal; + salesOrderHeader.PriceRabatt15 = priceRabatt15; + salesOrderHeader.Total = total; + salesOrderHeader.Discount = discount; + salesOrderHeader.Rabatt = rabatt; + salesOrderHeader.ID = id; + salesOrderHeader.Saison = saison; + return salesOrderHeader; + } + /// + /// There are no comments for Property OrderDate in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable OrderDate + { + get + { + return this._OrderDate; + } + set + { + this.OnOrderDateChanging(value); + this.ReportPropertyChanging("OrderDate"); + this._OrderDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); + } + } + private global::System.Nullable _OrderDate; + partial void OnOrderDateChanging(global::System.Nullable value); + partial void OnOrderDateChanged(); + /// + /// There are no comments for Property Status in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int Status + { + get + { + return this._Status; + } + set + { + this.OnStatusChanging(value); + this.ReportPropertyChanging("Status"); + this._Status = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Status"); + this.OnStatusChanged(); + } + } + private int _Status; + partial void OnStatusChanging(int value); + partial void OnStatusChanged(); + /// + /// There are no comments for Property BillToAddressID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable BillToAddressID + { + get + { + return this._BillToAddressID; + } + set + { + this.OnBillToAddressIDChanging(value); + this.ReportPropertyChanging("BillToAddressID"); + this._BillToAddressID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("BillToAddressID"); + this.OnBillToAddressIDChanged(); + } + } + private global::System.Nullable _BillToAddressID; + partial void OnBillToAddressIDChanging(global::System.Nullable value); + partial void OnBillToAddressIDChanged(); + /// + /// There are no comments for Property SubTotal in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal SubTotal + { + get + { + return this._SubTotal; + } + set + { + this.OnSubTotalChanging(value); + this.ReportPropertyChanging("SubTotal"); + this._SubTotal = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SubTotal"); + this.OnSubTotalChanged(); + } + } + private decimal _SubTotal; + partial void OnSubTotalChanging(decimal value); + partial void OnSubTotalChanged(); + /// + /// There are no comments for Property TotalDue in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal TotalDue + { + get + { + return this._TotalDue; + } + set + { + this.OnTotalDueChanging(value); + this.ReportPropertyChanging("TotalDue"); + this._TotalDue = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("TotalDue"); + this.OnTotalDueChanged(); + } + } + private decimal _TotalDue; + partial void OnTotalDueChanging(decimal value); + partial void OnTotalDueChanged(); + /// + /// There are no comments for Property Comment in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Comment + { + get + { + return this._Comment; + } + set + { + this.OnCommentChanging(value); + this.ReportPropertyChanging("Comment"); + this._Comment = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Comment"); + this.OnCommentChanged(); + } + } + private string _Comment; + partial void OnCommentChanging(string value); + partial void OnCommentChanged(); + /// + /// There are no comments for Property ModifiedDate in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable ModifiedDate + { + get + { + return this._ModifiedDate; + } + set + { + this.OnModifiedDateChanging(value); + this.ReportPropertyChanging("ModifiedDate"); + this._ModifiedDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ModifiedDate"); + this.OnModifiedDateChanged(); + } + } + private global::System.Nullable _ModifiedDate; + partial void OnModifiedDateChanging(global::System.Nullable value); + partial void OnModifiedDateChanged(); + /// + /// There are no comments for Property PaymentVersion in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable PaymentVersion + { + get + { + return this._PaymentVersion; + } + set + { + this.OnPaymentVersionChanging(value); + this.ReportPropertyChanging("PaymentVersion"); + this._PaymentVersion = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("PaymentVersion"); + this.OnPaymentVersionChanged(); + } + } + private global::System.Nullable _PaymentVersion; + partial void OnPaymentVersionChanging(global::System.Nullable value); + partial void OnPaymentVersionChanged(); + /// + /// There are no comments for Property BillID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string BillID + { + get + { + return this._BillID; + } + set + { + this.OnBillIDChanging(value); + this.ReportPropertyChanging("BillID"); + this._BillID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("BillID"); + this.OnBillIDChanged(); + } + } + private string _BillID; + partial void OnBillIDChanging(string value); + partial void OnBillIDChanged(); + /// + /// There are no comments for Property BookCounter in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int BookCounter + { + get + { + return this._BookCounter; + } + set + { + this.OnBookCounterChanging(value); + this.ReportPropertyChanging("BookCounter"); + this._BookCounter = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("BookCounter"); + this.OnBookCounterChanged(); + } + } + private int _BookCounter; + partial void OnBookCounterChanging(int value); + partial void OnBookCounterChanged(); + /// + /// There are no comments for Property SendID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable SendID + { + get + { + return this._SendID; + } + set + { + this.OnSendIDChanging(value); + this.ReportPropertyChanging("SendID"); + this._SendID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SendID"); + this.OnSendIDChanged(); + } + } + private global::System.Nullable _SendID; + partial void OnSendIDChanging(global::System.Nullable value); + partial void OnSendIDChanged(); + /// + /// There are no comments for Property SubSubTotal in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal SubSubTotal + { + get + { + return this._SubSubTotal; + } + set + { + this.OnSubSubTotalChanging(value); + this.ReportPropertyChanging("SubSubTotal"); + this._SubSubTotal = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SubSubTotal"); + this.OnSubSubTotalChanged(); + } + } + private decimal _SubSubTotal; + partial void OnSubSubTotalChanging(decimal value); + partial void OnSubSubTotalChanged(); + /// + /// There are no comments for Property PriceRabatt15 in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public bool PriceRabatt15 + { + get + { + return this._PriceRabatt15; + } + set + { + this.OnPriceRabatt15Changing(value); + this.ReportPropertyChanging("PriceRabatt15"); + this._PriceRabatt15 = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("PriceRabatt15"); + this.OnPriceRabatt15Changed(); + } + } + private bool _PriceRabatt15; + partial void OnPriceRabatt15Changing(bool value); + partial void OnPriceRabatt15Changed(); + /// + /// There are no comments for Property Total in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Total + { + get + { + return this._Total; + } + set + { + this.OnTotalChanging(value); + this.ReportPropertyChanging("Total"); + this._Total = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Total"); + this.OnTotalChanged(); + } + } + private decimal _Total; + partial void OnTotalChanging(decimal value); + partial void OnTotalChanged(); + /// + /// There are no comments for Property Discount in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Discount + { + get + { + return this._Discount; + } + set + { + this.OnDiscountChanging(value); + this.ReportPropertyChanging("Discount"); + this._Discount = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Discount"); + this.OnDiscountChanged(); + } + } + private decimal _Discount; + partial void OnDiscountChanging(decimal value); + partial void OnDiscountChanged(); + /// + /// There are no comments for Property Rabatt in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public decimal Rabatt + { + get + { + return this._Rabatt; + } + set + { + this.OnRabattChanging(value); + this.ReportPropertyChanging("Rabatt"); + this._Rabatt = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("Rabatt"); + this.OnRabattChanged(); + } + } + private decimal _Rabatt; + partial void OnRabattChanging(decimal value); + partial void OnRabattChanged(); + /// + /// There are no comments for Property SendDate in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable SendDate + { + get + { + return this._SendDate; + } + set + { + this.OnSendDateChanging(value); + this.ReportPropertyChanging("SendDate"); + this._SendDate = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("SendDate"); + this.OnSendDateChanged(); + } + } + private global::System.Nullable _SendDate; + partial void OnSendDateChanging(global::System.Nullable value); + partial void OnSendDateChanged(); + /// + /// There are no comments for Property ID in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int ID + { + get + { + return this._ID; + } + set + { + this.OnIDChanging(value); + this.ReportPropertyChanging("ID"); + this._ID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("ID"); + this.OnIDChanged(); + } + } + private int _ID; + partial void OnIDChanging(int value); + partial void OnIDChanged(); + /// + /// There are no comments for Property Saison in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Saison + { + get + { + return this._Saison; + } + set + { + this.OnSaisonChanging(value); + this.ReportPropertyChanging("Saison"); + this._Saison = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("Saison"); + this.OnSaisonChanged(); + } + } + private string _Saison; + partial void OnSaisonChanging(string value); + partial void OnSaisonChanged(); + /// + /// There are no comments for Customer in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "SalesOrderHeader_OrderID_fkey", "Customer")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public Customer Customer + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer").Value; + } + set + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer").Value = value; + } + } + /// + /// There are no comments for Customer in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityReference CustomerReference + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.SalesOrderHeader_OrderID_fkey", "Customer", value); + } + } + } + } + /// + /// There are no comments for XmlTest.User in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="User")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class User : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new User object. + /// + /// Initial value of UserId. + public static User CreateUser(int userId) + { + User user = new User(); + user.UserId = userId; + return user; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Name in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Name + { + get + { + return this._Name; + } + set + { + this.OnNameChanging(value); + this.ReportPropertyChanging("Name"); + this._Name = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Name"); + this.OnNameChanged(); + } + } + private string _Name; + partial void OnNameChanging(string value); + partial void OnNameChanged(); + /// + /// There are no comments for Property Login in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Login + { + get + { + return this._Login; + } + set + { + this.OnLoginChanging(value); + this.ReportPropertyChanging("Login"); + this._Login = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Login"); + this.OnLoginChanged(); + } + } + private string _Login; + partial void OnLoginChanging(string value); + partial void OnLoginChanged(); + /// + /// There are no comments for Property StatusId in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Nullable StatusId + { + get + { + return this._StatusId; + } + set + { + this.OnStatusIdChanging(value); + this.ReportPropertyChanging("StatusId"); + this._StatusId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("StatusId"); + this.OnStatusIdChanged(); + } + } + private global::System.Nullable _StatusId; + partial void OnStatusIdChanging(global::System.Nullable value); + partial void OnStatusIdChanged(); + /// + /// There are no comments for UserDetails in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserDetails_FK", "UserDetails")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public UserDetails UserDetails + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails").Value; + } + set + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails").Value = value; + } + } + /// + /// There are no comments for UserDetails in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityReference UserDetailsReference + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "UserDetails"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserDetails_FK", "UserDetails", value); + } + } + } + /// + /// There are no comments for UserToken in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserToken_FK", "UserToken")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public UserToken UserToken + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken").Value; + } + set + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken").Value = value; + } + } + /// + /// There are no comments for UserToken in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityReference UserTokenReference + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "UserToken"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserToken_FK", "UserToken", value); + } + } + } + } + /// + /// There are no comments for XmlTest.UserDetails in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="UserDetails")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class UserDetails : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new UserDetails object. + /// + /// Initial value of UserId. + public static UserDetails CreateUserDetails(int userId) + { + UserDetails userDetails = new UserDetails(); + userDetails.UserId = userId; + return userDetails; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Details in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Details + { + get + { + return this._Details; + } + set + { + this.OnDetailsChanging(value); + this.ReportPropertyChanging("Details"); + this._Details = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Details"); + this.OnDetailsChanged(); + } + } + private string _Details; + partial void OnDetailsChanging(string value); + partial void OnDetailsChanged(); + /// + /// There are no comments for User in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserDetails_FK", "User")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public User User + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User").Value; + } + set + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User").Value = value; + } + } + /// + /// There are no comments for User in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityReference UserReference + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserDetails_FK", "User"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserDetails_FK", "User", value); + } + } + } + } + /// + /// There are no comments for XmlTest.UserToken in the schema. + /// + /// + /// UserId + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="UserToken")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class UserToken : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new UserToken object. + /// + /// Initial value of UserId. + public static UserToken CreateUserToken(int userId) + { + UserToken userToken = new UserToken(); + userToken.UserId = userId; + return userToken; + } + /// + /// There are no comments for Property UserId in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int UserId + { + get + { + return this._UserId; + } + set + { + this.OnUserIdChanging(value); + this.ReportPropertyChanging("UserId"); + this._UserId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("UserId"); + this.OnUserIdChanged(); + } + } + private int _UserId; + partial void OnUserIdChanging(int value); + partial void OnUserIdChanged(); + /// + /// There are no comments for Property Token in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string Token + { + get + { + return this._Token; + } + set + { + this.OnTokenChanging(value); + this.ReportPropertyChanging("Token"); + this._Token = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("Token"); + this.OnTokenChanged(); + } + } + private string _Token; + partial void OnTokenChanging(string value); + partial void OnTokenChanged(); + /// + /// There are no comments for User in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "UserToken_FK", "User")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public User User + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User").Value; + } + set + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User").Value = value; + } + } + /// + /// There are no comments for User in the schema. + /// + [global::System.ComponentModel.BrowsableAttribute(false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityReference UserReference + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference("XmlTest.UserToken_FK", "User"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference("XmlTest.UserToken_FK", "User", value); + } + } + } + } + /// + /// There are no comments for XmlTest.XmlTable in the schema. + /// + /// + /// key + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="XmlTable")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class XmlTable : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new XmlTable object. + /// + /// Initial value of key. + public static XmlTable CreateXmlTable(int key) + { + XmlTable xmlTable = new XmlTable(); + xmlTable.key = key; + return xmlTable; + } + /// + /// There are no comments for Property key in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public int key + { + get + { + return this._key; + } + set + { + this.OnkeyChanging(value); + this.ReportPropertyChanging("key"); + this._key = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value); + this.ReportPropertyChanged("key"); + this.OnkeyChanged(); + } + } + private int _key; + partial void OnkeyChanging(int value); + partial void OnkeyChanged(); + /// + /// There are no comments for Property test_xml in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string test_xml + { + get + { + return this._test_xml; + } + set + { + this.Ontest_xmlChanging(value); + this.ReportPropertyChanging("test_xml"); + this._test_xml = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("test_xml"); + this.Ontest_xmlChanged(); + } + } + private string _test_xml; + partial void Ontest_xmlChanging(string value); + partial void Ontest_xmlChanged(); + } + /// + /// There are no comments for XmlTest.dispViews in the schema. + /// + /// + /// ViewName + /// MdsIdPlatformId + /// + [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="XmlTest", Name="dispViews")] + [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)] + [global::System.Serializable()] + public partial class dispViews : global::System.Data.Objects.DataClasses.EntityObject + { + /// + /// Create a new dispViews object. + /// + /// Initial value of ViewName. + /// Initial value of MdsIdPlatformId. + public static dispViews CreatedispViews(string viewName, string mdsIdPlatformId) + { + dispViews dispViews = new dispViews(); + dispViews.ViewName = viewName; + dispViews.MdsIdPlatformId = mdsIdPlatformId; + return dispViews; + } + /// + /// There are no comments for Property ViewName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ViewName + { + get + { + return this._ViewName; + } + set + { + this.OnViewNameChanging(value); + this.ReportPropertyChanging("ViewName"); + this._ViewName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("ViewName"); + this.OnViewNameChanged(); + } + } + private string _ViewName; + partial void OnViewNameChanging(string value); + partial void OnViewNameChanged(); + /// + /// There are no comments for Property MdsIdPlatformId in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string MdsIdPlatformId + { + get + { + return this._MdsIdPlatformId; + } + set + { + this.OnMdsIdPlatformIdChanging(value); + this.ReportPropertyChanging("MdsIdPlatformId"); + this._MdsIdPlatformId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false); + this.ReportPropertyChanged("MdsIdPlatformId"); + this.OnMdsIdPlatformIdChanged(); + } + } + private string _MdsIdPlatformId; + partial void OnMdsIdPlatformIdChanging(string value); + partial void OnMdsIdPlatformIdChanged(); + /// + /// There are no comments for Property DisplayName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string DisplayName + { + get + { + return this._DisplayName; + } + set + { + this.OnDisplayNameChanging(value); + this.ReportPropertyChanging("DisplayName"); + this._DisplayName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("DisplayName"); + this.OnDisplayNameChanged(); + } + } + private string _DisplayName; + partial void OnDisplayNameChanging(string value); + partial void OnDisplayNameChanged(); + /// + /// There are no comments for Property ImageFileName in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public string ImageFileName + { + get + { + return this._ImageFileName; + } + set + { + this.OnImageFileNameChanging(value); + this.ReportPropertyChanging("ImageFileName"); + this._ImageFileName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true); + this.ReportPropertyChanged("ImageFileName"); + this.OnImageFileNameChanged(); + } + } + private string _ImageFileName; + partial void OnImageFileNameChanging(string value); + partial void OnImageFileNameChanged(); + /// + /// There are no comments for dispViews1 in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "dispTargetViews", "dispViews1")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityCollection dispViews1 + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.dispTargetViews", "dispViews1"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.dispTargetViews", "dispViews1", value); + } + } + } + /// + /// There are no comments for dispViews2 in the schema. + /// + [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("XmlTest", "dispTargetViews", "dispViews")] + [global::System.Xml.Serialization.XmlIgnoreAttribute()] + [global::System.Xml.Serialization.SoapIgnoreAttribute()] + [global::System.Runtime.Serialization.DataMemberAttribute()] + public global::System.Data.Objects.DataClasses.EntityCollection dispViews2 + { + get + { + return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection("XmlTest.dispTargetViews", "dispViews"); + } + set + { + if ((value != null)) + { + ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection("XmlTest.dispTargetViews", "dispViews", value); + } + } + } + } +} +#endif diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl new file mode 100644 index 0000000..f802010 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.csdl @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl new file mode 100644 index 0000000..6f6edc5 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.msl @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl new file mode 100644 index 0000000..2a9d0d7 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/xmlModel/XmlTest.ssdl @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e847c64c25cc678ccb758a21b997ff02974dacb8 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 12 May 2016 13:35:44 +0300 Subject: [PATCH 2/8] Project now builds * Reverted to old csproj-based build, project.json and dotnet cli don't provide any actual value here. * Target net45 instead of net451 Still need to work out CI build and version management. --- EntityFramework6.Npgsql.sln | 22 -- src/CommonAssemblyInfo.cs | 21 ++ src/EntityFramework5.Npgsql/App.config | 17 ++ .../EntityFramework5.Npgsql.csproj | 22 +- .../EntityFramework5.Npgsql.nuspec | 6 +- src/EntityFramework5.Npgsql/packages.config | 4 + src/EntityFramework5.Npgsql/project.json | 52 ---- src/EntityFramework6.Npgsql/App.config | 17 ++ .../EntityFramework6.Npgsql.csproj | 29 +- .../EntityFramework6.Npgsql.nuspec | 6 +- src/EntityFramework6.Npgsql/packages.config | 5 + src/EntityFramework6.Npgsql/project.json | 54 ---- test/EntityFramework6.Npgsql.Tests/App.config | 28 +- .../EntityFramework6.Npgsql.Tests.csproj | 40 ++- .../EntityFrameworkBasicTests.cs | 47 ++-- .../EntityFrameworkMigrationTests.cs | 13 +- .../FullTextSearchTests.cs | 37 ++- .../NLogLoggingProvider.cs | 84 ++++++ .../Spatial/PostgisServiceTests.cs | 253 ++++++++--------- .../Support/CodeAnnotations.cs | 254 ++++++++++++++++++ .../{ => Support}/EntityFrameworkTestBase.cs | 8 +- .../Support/TestBase.cs | 117 ++++++++ .../Support/TestUtil.cs | 144 ++++++++++ .../packages.config | 7 + .../project.json | 27 -- 25 files changed, 921 insertions(+), 393 deletions(-) create mode 100644 src/CommonAssemblyInfo.cs create mode 100644 src/EntityFramework5.Npgsql/App.config create mode 100644 src/EntityFramework5.Npgsql/packages.config delete mode 100644 src/EntityFramework5.Npgsql/project.json create mode 100644 src/EntityFramework6.Npgsql/App.config create mode 100644 src/EntityFramework6.Npgsql/packages.config delete mode 100644 src/EntityFramework6.Npgsql/project.json create mode 100644 test/EntityFramework6.Npgsql.Tests/NLogLoggingProvider.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Support/CodeAnnotations.cs rename test/EntityFramework6.Npgsql.Tests/{ => Support}/EntityFrameworkTestBase.cs (99%) create mode 100644 test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs create mode 100644 test/EntityFramework6.Npgsql.Tests/packages.config delete mode 100644 test/EntityFramework6.Npgsql.Tests/project.json diff --git a/EntityFramework6.Npgsql.sln b/EntityFramework6.Npgsql.sln index 0bd3ac9..f4ccf6f 100644 --- a/EntityFramework6.Npgsql.sln +++ b/EntityFramework6.Npgsql.sln @@ -13,16 +13,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}") = "Npgsql", "src\Npgsql\Npgsql.csproj", "{9D13B739-62B1-4190-B386-7A9547304EB3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "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}" - ProjectSection(ProjectDependencies) = postProject - {E9C258D7-0D8E-4E6A-9857-5C6438591755} = {E9C258D7-0D8E-4E6A-9857-5C6438591755} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql.Tests", "test\Npgsql.Tests\Npgsql.Tests.csproj", "{E9C258D7-0D8E-4E6A-9857-5C6438591755}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework6.Npgsql.Tests", "test\EntityFramework6.Npgsql.Tests\EntityFramework6.Npgsql.Tests.csproj", "{4A0A42DE-C8B8-11E4-8EC9-005056A163A4}" EndProject @@ -32,10 +25,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release|Any CPU.Build.0 = Release|Any CPU {3EC85CBA-5B79-11E3-8104-0022198AB089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {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 @@ -44,29 +33,18 @@ Global {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 - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.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 {4A0A42DE-C8B8-11E4-8EC9-005056A163A4}.Release|Any CPU.Build.0 = Release|Any CPU - {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {9D13B739-62B1-4190-B386-7A9547304EB3} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} {3EC85CBA-5B79-11E3-8104-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} {100998C4-5B85-11E3-911C-0022198AB089} = {8537E50E-CF7F-49CB-B4EF-3E2A1B11F050} - {E9C258D7-0D8E-4E6A-9857-5C6438591755} = {ED612DB1-AB32-4603-95E7-891BACA71C39} {4A0A42DE-C8B8-11E4-8EC9-005056A163A4} = {ED612DB1-AB32-4603-95E7-891BACA71C39} - {4EB6FD81-6A30-4C35-AA89-BD2B0EDDAFF3} = {ED612DB1-AB32-4603-95E7-891BACA71C39} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Npgsql.csproj diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs new file mode 100644 index 0000000..3a32f39 --- /dev/null +++ b/src/CommonAssemblyInfo.cs @@ -0,0 +1,21 @@ +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.1.0.0")] +[assembly: AssemblyFileVersion("3.1.0.0")] +[assembly: AssemblyInformationalVersion("3.1.0-beta7-1+Branch.develop.Sha.a017bfc066ce372041992d892423c34089090402")] diff --git a/src/EntityFramework5.Npgsql/App.config b/src/EntityFramework5.Npgsql/App.config new file mode 100644 index 0000000..0c119f7 --- /dev/null +++ b/src/EntityFramework5.Npgsql/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj index 666f43b..493f266 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj @@ -14,18 +14,15 @@ ..\ true - v4.5.1 + v4.5 5 - - false true full false bin\Debug\ - TRACE;DEBUG;NET451 + TRACE;DEBUG;NET45 prompt 4 bin\Debug\EntityFramework5.Npgsql.xml @@ -34,12 +31,16 @@ pdbonly true bin\Release\ - TRACE;NET451 + TRACE;NET45 prompt 4 bin\Release\EntityFramework5.Npgsql.xml + + ..\..\packages\Npgsql.3.1.0-beta0001\lib\net45\Npgsql.dll + True + @@ -74,12 +75,9 @@ Code - - - {9d13b739-62b1-4190-b386-7a9547304eb3} - Npgsql - + + - + \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec index 5ff4a66..239e2a7 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec @@ -3,10 +3,10 @@ EntityFramework5.Npgsql Npgsql for Entity Framework 5 - 0.0.0 + 3.0.8 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/npgsql/blob/develop/LICENSE.txt + 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 @@ -16,7 +16,7 @@ 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 new file mode 100644 index 0000000..23250b4 --- /dev/null +++ b/src/EntityFramework5.Npgsql/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/EntityFramework5.Npgsql/project.json b/src/EntityFramework5.Npgsql/project.json deleted file mode 100644 index 383ec1b..0000000 --- a/src/EntityFramework5.Npgsql/project.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "version": "3.1.0-*", - "packOptions": { - "owners": [ - "Shay Rojansky", - "Emil Lenngren", - "Francisco Figueiredo Jr.", - "Kenji Uno" - ], - "authors": [ - "Shay Rojansky", - "Emil Lenngren", - "Francisco Figueiredo Jr.", - "Kenji Uno", - "Jon Asher", - "Josh Cooley", - "Federico Di Gregorio", - "Jon Hanna", - "Chris Morgan", - "Dave Page", - "Glen Parker", - "Brar Piening", - "Hiroshi Saito" - ], - "description" : "PostgreSQL provider for Entity Framework 5", - "iconUrl": "http://www.npgsql.org/img/postgresql.gif", - "licenseUrl": "https://raw.githubusercontent.com/npgsql/npgsql/develop/LICENSE.txt", - "repository": { - "type": "git", - "url": "git://github.com/npgsql/npgsql" - } - }, - "buildOptions": { - "keyFile": "../../Npgsql.snk" - }, - "dependencies" : { - "Npgsql": "3.1.0-*" - }, - "frameworks": { - "net451": { - "frameworkAssemblies": { - "System.Collections": { "version": "4.0.0.0", "type": "build" }, - "System.Data": { "version": "4.0.0.0", "type": "build" }, - "System.Data.Entity": { "version": "4.0.0.0", "type": "build" }, - "System.Reflection": { "version": "4.0.0.0", "type": "build" }, - "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, - "System.Linq.Expressions": { "version": "4.0.0.0", "type": "build" }, - "System.Runtime": { "version": "4.0.0.0", "type": "build" } - } - } - } -} diff --git a/src/EntityFramework6.Npgsql/App.config b/src/EntityFramework6.Npgsql/App.config new file mode 100644 index 0000000..7e1d79c --- /dev/null +++ b/src/EntityFramework6.Npgsql/App.config @@ -0,0 +1,17 @@ + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index ff27fd8..a6f8acd 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -14,17 +14,14 @@ ..\ true - v4.5.1 - - false + v4.5 true full false bin\Debug\ - TRACE;DEBUG;NET451;ENTITIES6 + TRACE;DEBUG;NET45;ENTITIES6 prompt 4 bin\Debug\EntityFramework6.Npgsql.xml @@ -33,12 +30,24 @@ pdbonly true bin\Release\ - TRACE;NET451;ENTITIES6 + TRACE;NET45;ENTITIES6 prompt 4 bin\Release\EntityFramework6.Npgsql.xml + + ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll + True + + + ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll + True + + + ..\..\packages\Npgsql.3.1.0-beta0001\lib\net45\Npgsql.dll + True + @@ -78,10 +87,8 @@ - - {9d13b739-62b1-4190-b386-7a9547304eb3} - Npgsql - + + - + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index 7d550c1..ffd8ea5 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -3,10 +3,10 @@ EntityFramework6.Npgsql Npgsql for Entity Framework 6 - 0.0.0 + 3.0.8 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/npgsql/blob/develop/LICENSE.txt + 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 @@ -16,7 +16,7 @@ en-US npgsql postgresql postgres data database entity framework ef orm - + diff --git a/src/EntityFramework6.Npgsql/packages.config b/src/EntityFramework6.Npgsql/packages.config new file mode 100644 index 0000000..17a7531 --- /dev/null +++ b/src/EntityFramework6.Npgsql/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/project.json b/src/EntityFramework6.Npgsql/project.json deleted file mode 100644 index fc9f7a1..0000000 --- a/src/EntityFramework6.Npgsql/project.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "version": "3.1.0-*", - "packOptions": { - "owners": [ - "Shay Rojansky", - "Emil Lenngren", - "Francisco Figueiredo Jr.", - "Kenji Uno" - ], - "authors": [ - "Shay Rojansky", - "Emil Lenngren", - "Francisco Figueiredo Jr.", - "Kenji Uno", - "Jon Asher", - "Josh Cooley", - "Federico Di Gregorio", - "Jon Hanna", - "Chris Morgan", - "Dave Page", - "Glen Parker", - "Brar Piening", - "Hiroshi Saito" - ], - "description" : "PostgreSQL provider for Entity Framework 6", - "iconUrl": "http://www.npgsql.org/img/postgresql.gif", - "licenseUrl": "https://raw.githubusercontent.com/npgsql/npgsql/develop/LICENSE.txt", - "repository": { - "type": "git", - "url": "git://github.com/npgsql/npgsql" - } - }, - "buildOptions": { - "define": [ "ENTITIES6" ], - "keyFile": "../../Npgsql.snk" - }, - "dependencies" : { - "EntityFramework": "6.1.3", - "Npgsql": "3.1.0-*" - }, - "frameworks": { - "net451": { - "frameworkAssemblies": { - "System.Collections": { "version": "4.0.0.0", "type": "build" }, - "System.Data": { "version": "4.0.0.0", "type": "build" }, - "System.Data.Entity": { "version": "4.0.0.0", "type": "build" }, - "System.Reflection": { "version": "4.0.0.0", "type": "build" }, - "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, - "System.Linq.Expressions": { "version": "4.0.0.0", "type": "build" }, - "System.Runtime": { "version": "4.0.0.0", "type": "build" } - } - } - } -} diff --git a/test/EntityFramework6.Npgsql.Tests/App.config b/test/EntityFramework6.Npgsql.Tests/App.config index bc096b3..79c8fa4 100644 --- a/test/EntityFramework6.Npgsql.Tests/App.config +++ b/test/EntityFramework6.Npgsql.Tests/App.config @@ -1,42 +1,44 @@ - + -
+
+ - + + - + - - + + - - + + - - + + - - + + - + \ 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 c3246a7..c3a8574 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -13,9 +13,6 @@ true v4.6 - - false bin\Debug\ @@ -38,6 +35,26 @@ 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.3.3\lib\net45\NLog.dll + True + + + ..\..\packages\Npgsql.3.1.0-beta0001\lib\net451\Npgsql.dll + True + + + ..\..\packages\NUnit.3.2.1\lib\net45\nunit.framework.dll + True + 3.5 @@ -55,13 +72,18 @@ - + + + + + + Always @@ -77,14 +99,6 @@ {3ec85cba-5b79-11e3-8104-0022198ab089} EntityFramework6.Npgsql - - {9D13B739-62B1-4190-B386-7A9547304EB3} - Npgsql - - - {e9c258d7-0d8e-4e6a-9857-5c6438591755} - Npgsql.Tests - - + \ No newline at end of file diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index ec12f4f..e1e30fc 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -33,7 +33,6 @@ using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; -using Npgsql.Tests; using NpgsqlTypes; namespace EntityFramework6.Npgsql.Tests @@ -45,7 +44,7 @@ public void InsertAndSelect() { var varbitVal = "10011"; - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var blog = new Blog() { @@ -65,7 +64,7 @@ public void InsertAndSelect() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts = from p in context.Posts select p; @@ -86,7 +85,7 @@ public void InsertAndSelect() [Test] public void SelectWithWhere() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var blog = new Blog() { @@ -104,7 +103,7 @@ public void SelectWithWhere() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts = from p in context.Posts where p.Rating < 3 @@ -121,7 +120,7 @@ where p.Rating < 3 public void SelectWithWhere_Ef_TruncateTime() { DateTime createdOnDate = new DateTime(2014, 05, 08); - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var blog = new Blog() { @@ -141,7 +140,7 @@ public void SelectWithWhere_Ef_TruncateTime() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts = from p in context.Posts let datePosted = DbFunctions.TruncateTime(p.CreationDate) @@ -159,7 +158,7 @@ public void SelectWithWhere_Ef_TruncateTime() public void SelectWithLike_SpecialCharacters() { DateTime createdOnDate = new DateTime(2014, 05, 08); - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var blog = new Blog() { @@ -192,7 +191,7 @@ public void SelectWithLike_SpecialCharacters() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts1 = from p in context.Posts where p.Content.Contains("_") @@ -214,7 +213,7 @@ where p.Content.StartsWith("%") [Test] public void OrderBy() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { Random random = new Random(); var blog = new Blog() @@ -234,7 +233,7 @@ public void OrderBy() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts = from p in context.Posts orderby p.Rating @@ -252,7 +251,7 @@ orderby p.Rating [Test] public void OrderByThenBy() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { Random random = new Random(); var blog = new Blog() @@ -272,7 +271,7 @@ public void OrderByThenBy() context.SaveChanges(); } - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var posts = context.Posts.AsQueryable().OrderBy((p) => p.Title).ThenByDescending((p) => p.Rating); Assert.AreEqual(10, posts.Count()); @@ -287,7 +286,7 @@ public void OrderByThenBy() [Test] public void TestComputedValue() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { var blog = new Blog() { @@ -306,7 +305,7 @@ public void TestComputedValue() [Test] public void Operators() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -331,7 +330,7 @@ public void Operators() [Test] public void DataTypes() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -400,7 +399,7 @@ public void DataTypes() [Test] public void SByteTest() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); @@ -413,7 +412,7 @@ public void SByteTest() [Test] public void DateFunctions() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { IQueryable oneRow = context.Posts.Where(p => false).Select(p => 1).Concat(new int[] { 1 }); @@ -468,7 +467,7 @@ public void DateFunctions() [Test] public void TestComplicatedQueries() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -529,7 +528,7 @@ public void TestComplicatedQueries() [MonoIgnore("Probably bug in mono. See https://github.com/npgsql/Npgsql/issues/289.")] public void TestComplicatedQueriesMonoFails() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -552,9 +551,9 @@ public void TestComplicatedQueriesMonoFails() [Test] public void TestComplicatedQueriesWithApply() { - using (var conn = OpenConnection(ConnectionStringEF)) + using (var conn = OpenConnection(ConnectionString)) TestUtil.MinimumPgVersion(conn, "9.3.0"); - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -579,7 +578,7 @@ from t2 in context.Posts.Where(p => p.BlogId == t1.BlogId).Take(1) [Test] public void TestScalarValuedStoredFunctions() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; @@ -626,7 +625,7 @@ public void TestScalarValuedStoredFunctions() [Test] public void TestScalarValuedStoredFunctions_with_null_StoreFunctionName() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Database.Log = Console.Out.WriteLine; diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs index 95b79b8..a0b768c 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkMigrationTests.cs @@ -29,15 +29,8 @@ using System.Data.Common; using System.Data.Entity; using System.Data.Entity.Core.Metadata.Edm; -using System.Data.Entity.Migrations; -using System.Data.Entity.Migrations.History; using System.Data.Entity.Migrations.Model; -using System.Data.Entity.Spatial; -using System.Globalization; using System.Linq; -using System.Text; -using System.Threading; -using Npgsql.Tests; namespace EntityFramework6.Npgsql.Tests { @@ -71,7 +64,7 @@ private void PrintCode(IEnumerable + /// Indicates that the value of the marked element could be null sometimes, + /// so the check for null is necessary before its usage. + /// + /// + /// [CanBeNull] public object Test() { return null; } + /// public void UseTest() { + /// var p = Test(); + /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' + /// } + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] + internal sealed class CanBeNullAttribute : Attribute + { + // ReSharper disable once EmptyConstructor + public CanBeNullAttribute() { } + } + + /// + /// Indicates that the value of the marked element could never be null. + /// + /// + /// [NotNull] public object Foo() { + /// return null; // Warning: Possible 'null' assignment + /// } + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] + internal sealed class NotNullAttribute : Attribute { } + + /// + /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property + /// or of the Lazy.Value property can never be null. + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field)] + internal sealed class ItemNotNullAttribute : Attribute { } + + /// + /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property + /// or of the Lazy.Value property can be null. + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field)] + internal sealed class ItemCanBeNullAttribute : Attribute { } + + /// + /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), + /// so this symbol will not be marked as unused (as well as by other usage inspections). + /// + [AttributeUsage(AttributeTargets.All)] + internal sealed class UsedImplicitlyAttribute : Attribute + { + public UsedImplicitlyAttribute() + : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) + { } + + public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) + : this(useKindFlags, ImplicitUseTargetFlags.Default) + { } + + public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) + : this(ImplicitUseKindFlags.Default, targetFlags) + { } + + public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) + { + UseKindFlags = useKindFlags; + TargetFlags = targetFlags; + } + + public ImplicitUseKindFlags UseKindFlags { get; private set; } + public ImplicitUseTargetFlags TargetFlags { get; private set; } + } + + /// + /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes + /// as unused (as well as by other usage inspections) + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)] + internal sealed class MeansImplicitUseAttribute : Attribute + { + public MeansImplicitUseAttribute() + : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) + { } + + public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) + : this(useKindFlags, ImplicitUseTargetFlags.Default) + { } + + public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) + : this(ImplicitUseKindFlags.Default, targetFlags) + { } + + public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) + { + UseKindFlags = useKindFlags; + TargetFlags = targetFlags; + } + + [UsedImplicitly] + public ImplicitUseKindFlags UseKindFlags { get; private set; } + [UsedImplicitly] + public ImplicitUseTargetFlags TargetFlags { get; private set; } + } + + [Flags] + internal enum ImplicitUseKindFlags + { + Default = Access | Assign | InstantiatedWithFixedConstructorSignature, + /// Only entity marked with attribute considered used. + Access = 1, + /// Indicates implicit assignment to a member. + Assign = 2, + /// + /// Indicates implicit instantiation of a type with fixed constructor signature. + /// That means any unused constructor parameters won't be reported as such. + /// + InstantiatedWithFixedConstructorSignature = 4, + /// Indicates implicit instantiation of a type. + InstantiatedNoFixedConstructorSignature = 8, + } + + /// + /// Specify what is considered used implicitly when marked + /// with or . + /// + [Flags] + internal enum ImplicitUseTargetFlags + { + Default = Itself, + Itself = 1, + /// Members of entity marked with attribute are considered used. + Members = 2, + /// Entity marked with attribute and all its members considered used. + WithMembers = Itself | Members + } + + /// + /// This attribute is intended to mark publicly available API + /// which should not be removed and so is treated as used. + /// + [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] + internal sealed class PublicAPIAttribute : Attribute + { + public PublicAPIAttribute() { } + public PublicAPIAttribute([NotNull] string comment) + { + Comment = comment; + } + + public string Comment { get; private set; } + } + + /// + /// Describes dependency between method input and output. + /// + /// + ///

Function Definition Table syntax:

+ /// + /// FDT ::= FDTRow [;FDTRow]* + /// FDTRow ::= Input => Output | Output <= Input + /// Input ::= ParameterName: Value [, Input]* + /// Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value} + /// Value ::= true | false | null | notnull | canbenull + /// + /// If method has single input parameter, it's name could be omitted.
+ /// Using halt (or void/nothing, which is the same) + /// for method output means that the methos doesn't return normally.
+ /// canbenull annotation is only applicable for output parameters.
+ /// You can use multiple [ContractAnnotation] for each FDT row, + /// or use single attribute with rows separated by semicolon.
+ ///
+ /// + /// + /// [ContractAnnotation("=> halt")] + /// public void TerminationMethod() + /// + /// + /// [ContractAnnotation("halt <= condition: false")] + /// public void Assert(bool condition, string text) // regular assertion method + /// + /// + /// [ContractAnnotation("s:null => true")] + /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() + /// + /// + /// // A method that returns null if the parameter is null, + /// // and not null if the parameter is not null + /// [ContractAnnotation("null => null; notnull => notnull")] + /// public object Transform(object data) + /// + /// + /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] + /// public bool TryParse(string s, out Person result) + /// + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + internal sealed class ContractAnnotationAttribute : Attribute + { + public ContractAnnotationAttribute([NotNull] string contract) + : this(contract, false) + { } + + public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates) + { + Contract = contract; + ForceFullStates = forceFullStates; + } + + public string Contract { get; private set; } + public bool ForceFullStates { get; private set; } + } + + /// + /// Indicates that the function argument should be string literal and match one + /// of the parameters of the caller function. For example, ReSharper annotates + /// the parameter of . + /// + /// + /// public void Foo(string param) { + /// if (param == null) + /// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol + /// } + /// + [AttributeUsage(AttributeTargets.Parameter)] + internal sealed class InvokerParameterNameAttribute : Attribute { } + + /// + /// Indicates that IEnumerable, passed as parameter, is not enumerated. + /// + [AttributeUsage(AttributeTargets.Parameter)] + internal sealed class NoEnumerationAttribute : Attribute { } +} diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs similarity index 99% rename from test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs rename to test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index 83ae561..54690b3 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -33,9 +33,9 @@ using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Core.Objects; using System.Data.Entity.Infrastructure; -using Npgsql.Tests; using NpgsqlTypes; +// ReSharper disable once CheckNamespace namespace EntityFramework6.Npgsql.Tests { public abstract class EntityFrameworkTestBase : TestBase @@ -44,7 +44,7 @@ public abstract class EntityFrameworkTestBase : TestBase public override void TestFixtureSetup() { base.TestFixtureSetup(); - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { if (context.Database.Exists()) context.Database.Delete();//We delete to be 100% schema is synced @@ -52,7 +52,7 @@ public override void TestFixtureSetup() } // Create sequence for the IntComputedValue property. - using (var createSequenceConn = OpenConnection(ConnectionStringEF)) + using (var createSequenceConn = OpenConnection(ConnectionString)) { createSequenceConn.ExecuteNonQuery("create sequence blog_int_computed_value_seq"); createSequenceConn.ExecuteNonQuery("alter table \"dbo\".\"Blogs\" alter column \"IntComputedValue\" set default nextval('blog_int_computed_value_seq');"); @@ -68,7 +68,7 @@ public override void TestFixtureSetup() [SetUp] protected void SetUp() { - using (var context = new BloggingContext(ConnectionStringEF)) + using (var context = new BloggingContext(ConnectionString)) { context.Blogs.RemoveRange(context.Blogs); context.Posts.RemoveRange(context.Posts); diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs new file mode 100644 index 0000000..d11f508 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestBase.cs @@ -0,0 +1,117 @@ +#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 NLog.Config; +using NLog.Targets; +using NLog; +using Npgsql; +using Npgsql.Logging; + +using NUnit.Framework; + +// ReSharper disable once CheckNamespace +namespace EntityFramework6.Npgsql.Tests +{ + public abstract class TestBase + { + static readonly Logger _log = LogManager.GetCurrentClassLogger(); + + /// + /// The connection string that will be used when opening the connection to the tests database. + /// May be overridden in fixtures, e.g. to set special connection parameters + /// + protected virtual string ConnectionString => + _connectionString ?? (_connectionString = Environment.GetEnvironmentVariable("NPGSQL_TEST_DB") ?? DefaultConnectionString); + + 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. + /// + const string DefaultConnectionString = "Server=localhost;User ID=npgsql_tests;Password=npgsql_tests;Database=npgsql_tests_ef6"; + + #region Setup / Teardown + + [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 + + protected NpgsqlConnection OpenConnection(string connectionString = null) + { + if (connectionString == null) + connectionString = ConnectionString; + var conn = new NpgsqlConnection(connectionString); + try + { + conn.Open(); + } + catch (PostgresException e) + { + if (e.SqlState == "3D000") + TestUtil.IgnoreExceptOnBuildServer("Please create a database npgsql_tests, owned by user npgsql_tests"); + else if (e.SqlState == "28P01") + TestUtil.IgnoreExceptOnBuildServer("Please create a user npgsql_tests as follows: create user npgsql_tests with password 'npgsql_tests'"); + else + throw; + } + + return conn; + } + + protected NpgsqlConnection OpenConnection(NpgsqlConnectionStringBuilder csb) + { + return OpenConnection(csb.ToString()); + } + + #endregion + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs b/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs new file mode 100644 index 0000000..b34eeab --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/Support/TestUtil.cs @@ -0,0 +1,144 @@ +#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.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using NUnit.Framework; +using NUnit.Framework.Interfaces; +using Npgsql; + +// ReSharper disable once CheckNamespace +namespace EntityFramework6.Npgsql.Tests +{ + public static class TestUtil + { + public static bool IsOnBuildServer => Environment.GetEnvironmentVariable("TEAMCITY_VERSION") != null; + + /// + /// Calls Assert.Ignore() unless we're on the build server, in which case calls + /// Assert.Fail(). We don't to miss any regressions just because something was misconfigured + /// at the build server and caused a test to be inconclusive. + /// + public static void IgnoreExceptOnBuildServer(string message) + { + if (IsOnBuildServer) + Assert.Fail(message); + else + Assert.Ignore(message); + } + + public static void IgnoreExceptOnBuildServer(string message, params object[] args) + => IgnoreExceptOnBuildServer(string.Format(message, args)); + + public static void MinimumPgVersion(NpgsqlConnection conn, string minVersion, string ignoreText = null) + { + var min = new Version(minVersion); + if (conn.PostgreSqlVersion < min) + { + var msg = $"Postgresql backend version {conn.PostgreSqlVersion} is less than the required {min}"; + if (ignoreText != null) + msg += ": " + ignoreText; + Assert.Ignore(msg); + } + } + + public static string GetUniqueIdentifier(string prefix) + => prefix + Interlocked.Increment(ref _counter); + + static int _counter; + } + + public static class NpgsqlConnectionExtensions + { + public static int ExecuteNonQuery(this NpgsqlConnection conn, string sql, NpgsqlTransaction tx = null) + { + var cmd = tx == null ? new NpgsqlCommand(sql, conn) : new NpgsqlCommand(sql, conn, tx); + using (cmd) + return cmd.ExecuteNonQuery(); + } + + [CanBeNull] + public static object ExecuteScalar(this NpgsqlConnection conn, string sql, NpgsqlTransaction tx = null) + { + var cmd = tx == null ? new NpgsqlCommand(sql, conn) : new NpgsqlCommand(sql, conn, tx); + using (cmd) + return cmd.ExecuteScalar(); + } + + public static async Task ExecuteNonQueryAsync(this NpgsqlConnection conn, string sql, NpgsqlTransaction tx = null) + { + var cmd = tx == null ? new NpgsqlCommand(sql, conn) : new NpgsqlCommand(sql, conn, tx); + using (cmd) + return await cmd.ExecuteNonQueryAsync(); + } + + [CanBeNull] + public static async Task ExecuteScalarAsync(this NpgsqlConnection conn, string sql, NpgsqlTransaction tx = null) + { + var cmd = tx == null ? new NpgsqlCommand(sql, conn) : new NpgsqlCommand(sql, conn, tx); + using (cmd) + return await cmd.ExecuteScalarAsync(); + } + } + + /// + /// Semantic attribute that points to an issue linked with this test (e.g. this + /// test reproduces the issue) + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class IssueLink : Attribute + { + public string LinkAddress { get; private set; } + public IssueLink(string linkAddress) + { + LinkAddress = linkAddress; + } + } + + /// + /// Causes the test to be ignored on mono + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] + public class MonoIgnore : Attribute, ITestAction + { + readonly string _ignoreText; + + public MonoIgnore(string ignoreText = null) { _ignoreText = ignoreText; } + + public void BeforeTest([NotNull] ITest test) + { + if (Type.GetType("Mono.Runtime") != null) + { + var msg = "Ignored on mono"; + if (_ignoreText != null) + msg += ": " + _ignoreText; + Assert.Ignore(msg); + } + } + + public void AfterTest([NotNull] ITest test) { } + public ActionTargets Targets => ActionTargets.Test; + } +} diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config new file mode 100644 index 0000000..5c69e79 --- /dev/null +++ b/test/EntityFramework6.Npgsql.Tests/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework6.Npgsql.Tests/project.json b/test/EntityFramework6.Npgsql.Tests/project.json deleted file mode 100644 index 52b1d64..0000000 --- a/test/EntityFramework6.Npgsql.Tests/project.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "0.0.0", - "buildOptions": { - "keyFile": "../../Npgsql.snk", - "emitEntryPoint": true - }, - "dependencies": { - "NUnit": "3.2.1", - "NUnitLite": "3.2.1", - "NLog": "3.2.0.0", - "EntityFramework6.Npgsql": "3.1.0-*", - "Npgsql.Tests": "0.0.0" - }, - "frameworks": { - "net46": { - "frameworkAssemblies": { - "System.Diagnostics.Contracts": { "version": "4.0.0.0", "type": "build" }, - "System.Runtime.Serialization": { "version": "4.0.0.0", "type": "build" }, - "System.Transactions": { "version": "4.0.0.0", "type": "build" }, - "System.DirectoryServices": { "version": "4.0.0.0", "type": "build" }, - "System.Data": { "version": "4.0.0.0", "type": "build" }, - "System.Xml": { "version": "4.0.0.0", "type": "build" }, - "System.Web": { "version": "4.0.0.0", "type": "build" } - } - } - } -} From 9ef384b46d03054208516cc39329ee058eeae8bd Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 18:36:20 +0300 Subject: [PATCH 3/8] Update to Npgsql 3.1.0 --- src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj | 4 ++-- src/EntityFramework5.Npgsql/packages.config | 2 +- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj | 4 ++-- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec | 2 +- src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs | 1 + src/EntityFramework6.Npgsql/packages.config | 2 +- .../EntityFramework6.Npgsql.Tests.csproj | 4 ++-- test/EntityFramework6.Npgsql.Tests/packages.config | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj index 493f266..df94040 100644 --- a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj +++ b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.csproj @@ -37,8 +37,8 @@ bin\Release\EntityFramework5.Npgsql.xml - - ..\..\packages\Npgsql.3.1.0-beta0001\lib\net45\Npgsql.dll + + ..\..\packages\Npgsql.3.1.2\lib\net45\Npgsql.dll True diff --git a/src/EntityFramework5.Npgsql/packages.config b/src/EntityFramework5.Npgsql/packages.config index 23250b4..a55205e 100644 --- a/src/EntityFramework5.Npgsql/packages.config +++ b/src/EntityFramework5.Npgsql/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj index a6f8acd..1d7fb7c 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.csproj @@ -44,8 +44,8 @@ ..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll True - - ..\..\packages\Npgsql.3.1.0-beta0001\lib\net45\Npgsql.dll + + ..\..\packages\Npgsql.3.1.2\lib\net45\Npgsql.dll True diff --git a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index ffd8ea5..303879e 100644 --- a/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec +++ b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec @@ -16,7 +16,7 @@ en-US npgsql postgresql postgres data database entity framework ef orm - + diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index ad76f38..dd6435e 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -33,6 +33,7 @@ using System.Data.Metadata.Edm; #endif using System.Linq; +using Npgsql; using NpgsqlTypes; namespace Npgsql.SqlGenerators diff --git a/src/EntityFramework6.Npgsql/packages.config b/src/EntityFramework6.Npgsql/packages.config index 17a7531..ef18161 100644 --- a/src/EntityFramework6.Npgsql/packages.config +++ b/src/EntityFramework6.Npgsql/packages.config @@ -1,5 +1,5 @@  - + \ 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 c3a8574..1d15360 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj +++ b/test/EntityFramework6.Npgsql.Tests/EntityFramework6.Npgsql.Tests.csproj @@ -47,8 +47,8 @@ ..\..\packages\NLog.4.3.3\lib\net45\NLog.dll True - - ..\..\packages\Npgsql.3.1.0-beta0001\lib\net451\Npgsql.dll + + ..\..\packages\Npgsql.3.1.2\lib\net451\Npgsql.dll True diff --git a/test/EntityFramework6.Npgsql.Tests/packages.config b/test/EntityFramework6.Npgsql.Tests/packages.config index 5c69e79..7c2a037 100644 --- a/test/EntityFramework6.Npgsql.Tests/packages.config +++ b/test/EntityFramework6.Npgsql.Tests/packages.config @@ -2,6 +2,6 @@ - + \ No newline at end of file From 79497e5eb0fcc485b71dfee10c21fd5e72760fcb Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 20:20:40 +0300 Subject: [PATCH 4/8] Fix PostGIS tests --- .../Spatial/PostgisServiceTests.cs | 21 +++++++++++++++++++ .../Support/EntityFrameworkTestBase.cs | 3 +-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs index 825519d..fbabd3b 100644 --- a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs @@ -1821,5 +1821,26 @@ public void InstanceTest() Assert.Fail(); } } + + [OneTimeSetUp] + public new void TestFixtureSetup() + { + using (var context = new BloggingContext(ConnectionString)) + { + if (!context.Database.Exists()) + context.Database.Create(); + } + + using (var conn = new NpgsqlConnection(ConnectionString)) + { + conn.Open(); + using (var cmd = new NpgsqlCommand("CREATE EXTENSION IF NOT EXISTS postgis", conn)) + cmd.ExecuteNonQuery(); + + // Need to also have Npgsql reload the types from the database + conn.ReloadTypes(); + NpgsqlConnection.ClearPool(conn); + } + } } } diff --git a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs index 54690b3..366a02f 100644 --- a/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs +++ b/test/EntityFramework6.Npgsql.Tests/Support/EntityFrameworkTestBase.cs @@ -41,9 +41,8 @@ namespace EntityFramework6.Npgsql.Tests public abstract class EntityFrameworkTestBase : TestBase { [OneTimeSetUp] - public override void TestFixtureSetup() + public new void TestFixtureSetup() { - base.TestFixtureSetup(); using (var context = new BloggingContext(ConnectionString)) { if (context.Database.Exists()) From f2964ff19203992db1af6fc1191ebcff035816df Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 20:30:06 +0300 Subject: [PATCH 5/8] Cleanup PostGIS tests --- .../Spatial/PostgisServiceTests.cs | 1710 ++++++----------- 1 file changed, 600 insertions(+), 1110 deletions(-) diff --git a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs index fbabd3b..0783539 100644 --- a/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/Spatial/PostgisServiceTests.cs @@ -3,39 +3,18 @@ using Npgsql.Spatial; using NpgsqlTypes; using NUnit.Framework; +// ReSharper disable RedundantExplicitArrayCreation namespace EntityFramework6.Npgsql.Tests.Spatial { public class PostgisServiceTests : TestBase { - NpgsqlConnection _conn; - NpgsqlConnection Conn - { - get - { - if (_conn == null) - { - _conn = new NpgsqlConnection(ConnectionString); - _conn.Open(); - } - return _conn; - } - } - [Test] public void AsBinaryTest() { var p = new PostgisPoint(1D, 1D); - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.AsBinary(svcs.GeometryFromProviderValue(p)); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.AsBinary(svcs.GeometryFromProviderValue(p)); } [Test] @@ -48,16 +27,8 @@ public void AsBinaryTestGeog() public void AsGmlTest() { var p = new PostgisPoint(1D, 1D); - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.AsGml(svcs.GeometryFromProviderValue(p)); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.AsGml(svcs.GeometryFromProviderValue(p)); } [Test] @@ -70,16 +41,8 @@ public void AsGmlTestGeog() public void AsTextTest() { var p = new PostgisPoint(1D, 1D); - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.AsText(svcs.GeometryFromProviderValue(p)); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.AsText(svcs.GeometryFromProviderValue(p)); } [Test] @@ -92,16 +55,8 @@ public void AsTextTestGeog() public void BufferTest() { var p = new PostgisPoint(1D, 1D); - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.Buffer(svcs.GeometryFromProviderValue(p), 19D); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.Buffer(svcs.GeometryFromProviderValue(p), 19D); } [Test] @@ -114,8 +69,7 @@ public void BufferTest1() public void ContainsTest() { var p = new PostgisPoint(1D, 1D); - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); + var svcs = CreatePostgisServices(); var pol = new PostgisPolygon(new Coordinate2D[1][] {new Coordinate2D[5] { @@ -126,31 +80,15 @@ public void ContainsTest() new Coordinate2D(0D,0D) } }); - try - { - Assert.True(svcs.Contains(svcs.GeometryFromProviderValue(pol), svcs.GeometryFromProviderValue(p))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + Assert.True(svcs.Contains(svcs.GeometryFromProviderValue(pol), svcs.GeometryFromProviderValue(p))); } [Test] public void CreateProviderValueTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.CreateProviderValue( - svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))) - ); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.CreateProviderValue( + svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)))); } [Test] @@ -162,16 +100,8 @@ public void CreateProviderValueTestGeog() [Test] public void CreateWellKnownValueTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.CreateWellKnownValue(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); } [Test] @@ -183,33 +113,17 @@ public void CreateWellKnownValueTestGeog() [Test] public void CrossesTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.Crosses(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), - svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.Crosses(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); } [Test] public void DifferenceTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.Difference(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), - svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.Difference(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); } [Test] @@ -220,18 +134,10 @@ public void DifferenceTestGeog() [Test] public void DisjointTest() - { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.Disjoint(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), - svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + { + var svcs = CreatePostgisServices(); + svcs.Disjoint(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); } [Test] @@ -243,17 +149,9 @@ public void DisjointTestGeog() [Test] public void DistanceTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.Distance(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), - svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.Distance(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D)), + svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); } [Test] @@ -265,18 +163,10 @@ public void DistanceTestGeog() [Test] public void ElementAtTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.ElementAt(svcs.GeometryFromProviderValue( - new PostgisGeometryCollection(new PostgisGeometry[1] { new PostgisPoint(0D, 0D) })), - 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.ElementAt(svcs.GeometryFromProviderValue( + new PostgisGeometryCollection(new PostgisGeometry[1] { new PostgisPoint(0D, 0D) })), + 1); } [Test] @@ -414,79 +304,48 @@ public void GeographyPolygonFromTextTest() [Test] public void GeometryCollectionFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); + var svcs = CreatePostgisServices(); try { var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisGeometryCollection (new PostgisGeometry[] { new PostgisPoint(0D, 0D) }))); svcs.GeometryCollectionFromBinary(b, 1); } - catch (NotImplementedException exi) + catch (NotImplementedException) { Assert.Ignore("not implemented"); } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } } [Test] public void GeometryCollectionFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisGeometryCollection - (new PostgisGeometry[] { new PostgisPoint(0D, 0D) }))); - svcs.GeometryCollectionFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisGeometryCollection + (new PostgisGeometry[] { new PostgisPoint(0D, 0D) }))); + svcs.GeometryCollectionFromText(b, 1); } [Test] public void GeometryFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - svcs.GeometryFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryFromBinary(b, 1); } [Test] public void GeometryFromBinaryTestGeog() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); Assert.Ignore("not implemented"); } [Test] public void GeometryFromGmlTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - svcs.GeometryCollectionFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryCollectionFromText(b, 1); } [Test] @@ -498,32 +357,16 @@ public void GeometryFromGmlTestGeog() [Test] public void GeometryFromProviderValueTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - svcs.GeometryFromProviderValue(new PostgisPoint(0d, 0d)); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + svcs.GeometryFromProviderValue(new PostgisPoint(0d, 0d)); } [Test] public void GeometryFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); - svcs.GeometryCollectionFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(0D, 0D))); + svcs.GeometryCollectionFromText(b, 1); } [Test] @@ -535,297 +378,193 @@ public void GeometryFromTextTestGeog() [Test] public void GeometryLineFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue( - new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) }))); - svcs.GeometryLineFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) }))); + svcs.GeometryLineFromBinary(b, 1); } [Test] public void GeometryLineFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue( - new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) }))); - svcs.GeometryLineFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisLineString(new Coordinate2D[] { new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) }))); + svcs.GeometryLineFromText(b, 1); } [Test] public void GeometryMultiLineFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue( - new PostgisMultiLineString( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) - } - }))); - svcs.GeometryMultiLineFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiLineString( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryMultiLineFromBinary(b, 1); } [Test] public void GeometryMultiLineFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue( - new PostgisMultiLineString( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) - } - }))); - svcs.GeometryMultiLineFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiLineString( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryMultiLineFromText(b, 1); } [Test] public void GeometryMultiPointFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue( - new PostgisMultiPoint( - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) - } - ))); - svcs.GeometryMultiPointFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiPoint( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + ))); + svcs.GeometryMultiPointFromBinary(b, 1); } [Test] public void GeometryMultiPointFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue( - new PostgisMultiPoint( - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,0d) - } - ))); - svcs.GeometryMultiPointFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiPoint( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,0d) + } + ))); + svcs.GeometryMultiPointFromText(b, 1); } [Test] public void GeometryMultiPolygonFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue( - new PostgisMultiPolygon(new PostgisPolygon[] - {new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisMultiPolygon(new PostgisPolygon[] + {new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) } - ) - } - ))); - svcs.GeometryMultiPolygonFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + } + ) + } + ))); + svcs.GeometryMultiPolygonFromBinary(b, 1); } [Test] public void GeometryMultiPolygonFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue( - new PostgisMultiPolygon(new PostgisPolygon[] - {new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisMultiPolygon(new PostgisPolygon[] + {new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) } - ) - } - ))); - svcs.GeometryMultiPolygonFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + } + ) + } + ))); + svcs.GeometryMultiPolygonFromText(b, 1); } [Test] public void GeometryPointFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); - svcs.GeometryPointFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); + svcs.GeometryPointFromBinary(b, 1); } [Test] public void GeometryPointFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); - svcs.GeometryPointFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue(new PostgisPoint(1D, 1D))); + svcs.GeometryPointFromText(b, 1); } [Test] public void GeometryPolygonFromBinaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsBinary(svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - }))); - svcs.GeometryPolygonFromBinary(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsBinary(svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryPolygonFromBinary(b, 1); } [Test] public void GeometryPolygonFromTextTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.AsText(svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - }))); - svcs.GeometryPolygonFromText(b, 1); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.AsText(svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }))); + svcs.GeometryPolygonFromText(b, 1); } [Test] public void GetAreaTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetArea(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetArea(b); } [Test] @@ -837,106 +576,74 @@ public void GetAreaTestGeom() [Test] public void GetBoundaryTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetBoundary(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetBoundary(b); } [Test] public void GetCentroidTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetCentroid(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetCentroid(b); } [Test] public void GetConvexHullTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetConvexHull(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetConvexHull(b); } [Test] public void GetCoordinateSystemIdTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - }) - { SRID = 3742 }); - svcs.GetCoordinateSystemId(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + }) + { SRID = 3742 }); + svcs.GetCoordinateSystemId(b); } [Test] @@ -948,27 +655,19 @@ public void GetCoordinateSystemIdTestGeog() [Test] public void GetDimensionTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetDimension(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetDimension(b); } [Test] @@ -980,31 +679,23 @@ public void GetDimensionTestGeog() [Test] public void GetElementCountTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisGeometryCollection( - new PostgisGeometry[] { - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - }) + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisGeometryCollection( + new PostgisGeometry[] { + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } }) - ); - svcs.GetElementCount(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + }) + ); + svcs.GetElementCount(b); } [Test] @@ -1028,27 +719,19 @@ public void GetElevationTest1() [Test] public void GetEndPointTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetEndPoint(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetEndPoint(b); } [Test] @@ -1060,105 +743,73 @@ public void GetEndPointTestGeog() [Test] public void GetEnvelopeTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetEnvelope(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetEnvelope(b); } [Test] public void GetExteriorRingTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetExteriorRing(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetExteriorRing(b); } [Test] public void GetInteriorRingCountTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetInteriorRingCount(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetInteriorRingCount(b); } [Test] public void GetIsClosedTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetIsClosed(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsClosed(b); } [Test] @@ -1170,27 +821,19 @@ public void GetIsClosedTestGeog() [Test] public void GetIsEmptyTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetIsEmpty(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsEmpty(b); } [Test] @@ -1202,77 +845,53 @@ public void GetIsEmptyTestGeog() [Test] public void GetIsRingTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisLineString( - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - })); - svcs.GetIsRing(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisLineString( + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + })); + svcs.GetIsRing(b); } [Test] public void GetIsSimpleTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetIsSimple(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsSimple(b); } [Test] public void GetIsValidTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetIsSimple(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetIsSimple(b); } [Test] @@ -1284,27 +903,19 @@ public void GetLatitudeTest() [Test] public void GetLengthTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetLength(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetLength(b); } [Test] @@ -1334,27 +945,19 @@ public void GetMeasureTestGeog() [Test] public void GetPointCountTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetPointCount(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetPointCount(b); } [Test] @@ -1366,53 +969,37 @@ public void GetPointCountTestGeog() [Test] public void GetPointOnSurfaceTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetPointOnSurface(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetPointOnSurface(b); } [Test] public void GetSpatialTypeNameTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - Assert.IsTrue(svcs.GetSpatialTypeName(b).ToLower() == "polygon"); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + Assert.IsTrue(svcs.GetSpatialTypeName(b).ToLower() == "polygon"); } [Test] @@ -1423,28 +1010,20 @@ public void GetSpatialTypeNameTestGeog() [Test] public void GetStartPointTest() - { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.GetStartPoint(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + { + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.GetStartPoint(b); } [Test] @@ -1456,94 +1035,62 @@ public void GetStartPointTestGeog() [Test] public void GetXCoordinateTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPoint(0D, 0D)); - svcs.GetXCoordinate(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPoint(0D, 0D)); + svcs.GetXCoordinate(b); } [Test] public void GetYCoordinateTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPoint(0D, 0D)); - svcs.GetYCoordinate(b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPoint(0D, 0D)); + svcs.GetYCoordinate(b); } [Test] public void InteriorRingAtTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - ,new Coordinate2D[] { - new Coordinate2D(0.5D, 0.5D), - new Coordinate2D(0.5d,0.8d), - new Coordinate2D(0.8d,0.8d), - new Coordinate2D(0.8d,0.5d), - new Coordinate2D(0.5d,0.5d) - } - })); - svcs.InteriorRingAt(b, 2); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + ,new Coordinate2D[] { + new Coordinate2D(0.5D, 0.5D), + new Coordinate2D(0.5d,0.8d), + new Coordinate2D(0.8d,0.8d), + new Coordinate2D(0.8d,0.5d), + new Coordinate2D(0.5d,0.5d) + } + })); + svcs.InteriorRingAt(b, 2); } [Test] public void IntersectionTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Intersection(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Intersection(b, b); } [Test] @@ -1555,27 +1102,19 @@ public void IntersectionTestGeog() [Test] public void IntersectsTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Intersection(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Intersection(b, b); } [Test] @@ -1587,27 +1126,19 @@ public void IntersectsTestGeog() [Test] public void OverlapsTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Overlaps(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Overlaps(b, b); } [Test] @@ -1625,53 +1156,37 @@ public void PointAtTestGeog() [Test] public void RelateTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Relate(b, b, "0FFFFF212"); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Relate(b, b, "0FFFFF212"); } [Test] public void SpatialEqualsTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.SpatialEquals(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.SpatialEquals(b, b); } [Test] @@ -1683,27 +1198,19 @@ public void SpatialEqualsTestGeog() [Test] public void SymmetricDifferenceTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.SymmetricDifference(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.SymmetricDifference(b, b); } [Test] @@ -1715,53 +1222,37 @@ public void SymmetricDifferenceTestGeog() [Test] public void TouchesTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Touches(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Touches(b, b); } [Test] public void UnionTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Union(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Union(b, b); } [Test] @@ -1773,34 +1264,25 @@ public void UnionTestGeog() [Test] public void WithinTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); - try - { - var b = svcs.GeometryFromProviderValue( - new PostgisPolygon( - new Coordinate2D[][] { - new Coordinate2D[] { - new Coordinate2D(0D, 0D), - new Coordinate2D(0d,1d), - new Coordinate2D(1d,1d), - new Coordinate2D(1d,0d), - new Coordinate2D(0d,0d) - } - })); - svcs.Within(b, b); - } - catch (Exception ex) - { - Assert.Fail(ex.Message); - } + var svcs = CreatePostgisServices(); + var b = svcs.GeometryFromProviderValue( + new PostgisPolygon( + new Coordinate2D[][] { + new Coordinate2D[] { + new Coordinate2D(0D, 0D), + new Coordinate2D(0d,1d), + new Coordinate2D(1d,1d), + new Coordinate2D(1d,0d), + new Coordinate2D(0d,0d) + } + })); + svcs.Within(b, b); } [Test] public void InstanceTest() { - var svcs = new PostgisServices(); - svcs.SetConnection(Conn); + var svcs = CreatePostgisServices(); var b = svcs.GeometryFromProviderValue( new PostgisPolygon( new Coordinate2D[][] { @@ -1812,14 +1294,20 @@ public void InstanceTest() new Coordinate2D(0d,0d) } })); - try - { - var x = b.Area; - } - catch (Exception) - { - Assert.Fail(); - } + var x = b.Area; + } + + #region Support + + // ReSharper disable once InconsistentNaming + PostgisServices CreatePostgisServices() + { + var conn = new NpgsqlConnection(ConnectionString); + conn.Open(); + + var svcs = new PostgisServices(); + svcs.SetConnection(conn); + return svcs; } [OneTimeSetUp] @@ -1842,5 +1330,7 @@ public void InstanceTest() NpgsqlConnection.ClearPool(conn); } } + + #endregion Support } } From a3315508bf306c9d3c3c8d6d05e5145daab121c1 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 19:34:33 +0300 Subject: [PATCH 6/8] Versioning --- bump.sh | 43 +++++++++++++++++++ .../EntityFramework6.Npgsql.nuspec | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 bump.sh diff --git a/bump.sh b/bump.sh new file mode 100644 index 0000000..3a46822 --- /dev/null +++ b/bump.sh @@ -0,0 +1,43 @@ +#!/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/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec b/src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec index 303879e..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.0.8 + $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 From c33daad86571080a2e85c8b2bafc4b1d8c774cab Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Mon, 23 May 2016 20:57:42 +0300 Subject: [PATCH 7/8] Bump version to 3.1.0 --- src/CommonAssemblyInfo.cs | 6 +++--- src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec | 2 +- src/EntityFramework6.Npgsql/EntityFramework6.Npgsql.nuspec | 2 +- teamcity_set_version.cmd | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 teamcity_set_version.cmd diff --git a/src/CommonAssemblyInfo.cs b/src/CommonAssemblyInfo.cs index 3a32f39..1a7f45e 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.0")] -[assembly: AssemblyFileVersion("3.1.0.0")] -[assembly: AssemblyInformationalVersion("3.1.0-beta7-1+Branch.develop.Sha.a017bfc066ce372041992d892423c34089090402")] +[assembly: AssemblyVersion("3.1.0")] +[assembly: AssemblyFileVersion("3.1.0")] +[assembly: AssemblyInformationalVersion("3.1.0")] diff --git a/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec b/src/EntityFramework5.Npgsql/EntityFramework5.Npgsql.nuspec index 239e2a7..07f54f7 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.0.8 + 3.1.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 2e493ab..a3aaaf4 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.1.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 new file mode 100644 index 0000000..f0f2e36 --- /dev/null +++ b/teamcity_set_version.cmd @@ -0,0 +1 @@ +echo ##teamcity[buildNumber '3.1.0-%1'] From 28472b2a1f2b228507ae73dd1ba40a42d29dd4a7 Mon Sep 17 00:00:00 2001 From: roji Date: Mon, 23 May 2016 13:18:42 -0500 Subject: [PATCH 8/8] TeamCity change in 'EntityFramework6.Npgsql' project: Synchronization with own VCS root is enabled --- .../EntityFramework6Npgsql_Build.xml | 136 ++++++++++++++++++ .../pluginData/plugin-settings.xml | 5 + .../EntityFramework6Npgsql/project-config.xml | 10 ++ .../EntityFramework6Npgsql_Github.xml | 19 +++ 4 files changed, 170 insertions(+) create mode 100644 .teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml create mode 100644 .teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml create mode 100644 .teamcity/EntityFramework6Npgsql/project-config.xml create mode 100644 .teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml diff --git a/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml b/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml new file mode 100644 index 0000000..80b1396 --- /dev/null +++ b/.teamcity/EntityFramework6Npgsql/buildTypes/EntityFramework6Npgsql_Build.xml @@ -0,0 +1,136 @@ + + + Build + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml b/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml new file mode 100644 index 0000000..784b770 --- /dev/null +++ b/.teamcity/EntityFramework6Npgsql/pluginData/plugin-settings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.teamcity/EntityFramework6Npgsql/project-config.xml b/.teamcity/EntityFramework6Npgsql/project-config.xml new file mode 100644 index 0000000..6c2ccfb --- /dev/null +++ b/.teamcity/EntityFramework6Npgsql/project-config.xml @@ -0,0 +1,10 @@ + + + EntityFramework6.Npgsql + Entity Framework 6/5 for PostgreSQL + + + + + + diff --git a/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml b/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml new file mode 100644 index 0000000..7c55983 --- /dev/null +++ b/.teamcity/EntityFramework6Npgsql/vcsRoots/EntityFramework6Npgsql_Github.xml @@ -0,0 +1,19 @@ + + + https://github.com/npgsql/EntityFramework6.Npgsql.git + + + + + + + + + + + + + +