From d070e5f489e48d8601969192e04b3b4632f592ab Mon Sep 17 00:00:00 2001 From: windcloud Date: Fri, 4 Oct 2013 16:01:45 +0800 Subject: [PATCH 1/5] Initial DDEX support (Entity Model) --- Npgsql2012.sln | 122 +-- NpgsqlDdexProvider/GlobalSuppressions.cs | 11 + NpgsqlDdexProvider/Guids.cs | 15 + NpgsqlDdexProvider/Key.snk | Bin 0 -> 596 bytes .../NpgsqlDataObjectSelector.cs | 39 + .../NpgsqlDataObjectSupport.xml | 500 ++++++++++++ .../NpgsqlDataProviderRegistration.cs | 52 ++ NpgsqlDdexProvider/NpgsqlDataViewSupport.xml | 107 +++ NpgsqlDdexProvider/NpgsqlDdexProvider.csproj | 249 ++++++ .../NpgsqlDdexProviderPackage.cs | 63 ++ .../NpgsqlProviderObjectFactory.cs | 25 + NpgsqlDdexProvider/Properties/AssemblyInfo.cs | 36 + NpgsqlDdexProvider/Resources.Designer.cs | 135 ++++ NpgsqlDdexProvider/Resources.resx | 144 ++++ NpgsqlDdexProvider/Resources/Package.ico | Bin 0 -> 2998 bytes NpgsqlDdexProvider/VSPackage.resx | 140 ++++ .../source.extension.vsixmanifest | 18 + src/Npgsql.csproj | 7 +- src/Npgsql/NpgsqlConnection.cs | 9 +- src/Npgsql/NpgsqlConnectionStringBuilder.cs | 1 + src/Npgsql/NpgsqlProviderManifest.cs | 6 + src/Npgsql/NpgsqlSchema.cs | 93 ++- src/Npgsql/NpgsqlSchemaV3.ssdl | 724 ++++++++++++++++++ src/Npgsql/SqlGenerators/VisitedExpression.cs | 2 +- 24 files changed, 2435 insertions(+), 63 deletions(-) create mode 100644 NpgsqlDdexProvider/GlobalSuppressions.cs create mode 100644 NpgsqlDdexProvider/Guids.cs create mode 100644 NpgsqlDdexProvider/Key.snk create mode 100644 NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs create mode 100644 NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml create mode 100644 NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs create mode 100644 NpgsqlDdexProvider/NpgsqlDataViewSupport.xml create mode 100644 NpgsqlDdexProvider/NpgsqlDdexProvider.csproj create mode 100644 NpgsqlDdexProvider/NpgsqlDdexProviderPackage.cs create mode 100644 NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs create mode 100644 NpgsqlDdexProvider/Properties/AssemblyInfo.cs create mode 100644 NpgsqlDdexProvider/Resources.Designer.cs create mode 100644 NpgsqlDdexProvider/Resources.resx create mode 100644 NpgsqlDdexProvider/Resources/Package.ico create mode 100644 NpgsqlDdexProvider/VSPackage.resx create mode 100644 NpgsqlDdexProvider/source.extension.vsixmanifest create mode 100644 src/Npgsql/NpgsqlSchemaV3.ssdl diff --git a/Npgsql2012.sln b/Npgsql2012.sln index dfa0fed6c4..e7f24c96ff 100644 --- a/Npgsql2012.sln +++ b/Npgsql2012.sln @@ -5,60 +5,82 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npgsql", "src\Npgsql.csproj EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NpgsqlTests", "tests\NpgsqlTests.csproj", "{E9C258D7-0D8E-4E6A-9857-5C6438591755}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NpgsqlDdexProvider", "NpgsqlDdexProvider\NpgsqlDdexProvider.csproj", "{249C6185-C3B5-4D28-A508-ABD975702A0B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug-net20|AnyCPU = Debug-net20|AnyCPU - Debug-net35|AnyCPU = Debug-net35|AnyCPU - Debug-net40|AnyCPU = Debug-net40|AnyCPU - Debug-net45|AnyCPU = Debug-net45|AnyCPU - Debug-net45-EF6|AnyCPU = Debug-net45-EF6|AnyCPU - Release-net20|AnyCPU = Release-net20|AnyCPU - Release-net35|AnyCPU = Release-net35|AnyCPU - Release-net40|AnyCPU = Release-net40|AnyCPU - Release-net45|AnyCPU = Release-net45|AnyCPU - Release-net45-EF6|AnyCPU = Release-net45-EF6|AnyCPU + Debug-net20|Any CPU = Debug-net20|Any CPU + Debug-net35|Any CPU = Debug-net35|Any CPU + Debug-net40|Any CPU = Debug-net40|Any CPU + Debug-net45|Any CPU = Debug-net45|Any CPU + Debug-net45-EF6|Any CPU = Debug-net45-EF6|Any CPU + Release-net20|Any CPU = Release-net20|Any CPU + Release-net35|Any CPU = Release-net35|Any CPU + Release-net40|Any CPU = Release-net40|Any CPU + Release-net45|Any CPU = Release-net45|Any CPU + Release-net45-EF6|Any CPU = Release-net45-EF6|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net20|AnyCPU.ActiveCfg = Debug-net20|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net20|AnyCPU.Build.0 = Debug-net20|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net35|AnyCPU.ActiveCfg = Debug-net35|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net35|AnyCPU.Build.0 = Debug-net35|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net40|AnyCPU.ActiveCfg = Debug-net40|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net40|AnyCPU.Build.0 = Debug-net40|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45|AnyCPU.ActiveCfg = Debug-net45|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45|AnyCPU.Build.0 = Debug-net45|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45-EF6|AnyCPU.ActiveCfg = Debug-net45-EF6|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45-EF6|AnyCPU.Build.0 = Debug-net45-EF6|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net20|AnyCPU.ActiveCfg = Release-net20|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net20|AnyCPU.Build.0 = Release-net20|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net35|AnyCPU.ActiveCfg = Release-net35|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net35|AnyCPU.Build.0 = Release-net35|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net40|AnyCPU.ActiveCfg = Release-net40|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net40|AnyCPU.Build.0 = Release-net40|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45|AnyCPU.ActiveCfg = Release-net45|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45|AnyCPU.Build.0 = Release-net45|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45-EF6|AnyCPU.ActiveCfg = Release-net45-EF6|Any CPU - {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45-EF6|AnyCPU.Build.0 = Release-net45-EF6|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net20|AnyCPU.ActiveCfg = Debug-net20|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net20|AnyCPU.Build.0 = Debug-net20|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net35|AnyCPU.ActiveCfg = Debug-net35|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net35|AnyCPU.Build.0 = Debug-net35|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net40|AnyCPU.ActiveCfg = Debug-net40|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net40|AnyCPU.Build.0 = Debug-net40|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45|AnyCPU.ActiveCfg = Debug-net45|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45|AnyCPU.Build.0 = Debug-net45|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45-EF6|AnyCPU.ActiveCfg = Debug-net45-EF6|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45-EF6|AnyCPU.Build.0 = Debug-net45-EF6|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net20|AnyCPU.ActiveCfg = Release-net20|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net20|AnyCPU.Build.0 = Release-net20|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net35|AnyCPU.ActiveCfg = Release-net35|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net35|AnyCPU.Build.0 = Release-net35|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net40|AnyCPU.ActiveCfg = Release-net40|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net40|AnyCPU.Build.0 = Release-net40|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45|AnyCPU.ActiveCfg = Release-net45|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45|AnyCPU.Build.0 = Release-net45|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45-EF6|AnyCPU.ActiveCfg = Release-net45-EF6|Any CPU - {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45-EF6|AnyCPU.Build.0 = Release-net45-EF6|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net20|Any CPU.ActiveCfg = Debug-net20|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net20|Any CPU.Build.0 = Debug-net20|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net35|Any CPU.ActiveCfg = Debug-net35|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net35|Any CPU.Build.0 = Debug-net35|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net40|Any CPU.ActiveCfg = Debug-net40|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net40|Any CPU.Build.0 = Debug-net40|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45|Any CPU.ActiveCfg = Debug-net45|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45|Any CPU.Build.0 = Debug-net45|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45-EF6|Any CPU.ActiveCfg = Debug-net45-EF6|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Debug-net45-EF6|Any CPU.Build.0 = Debug-net45-EF6|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net20|Any CPU.ActiveCfg = Release-net20|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net20|Any CPU.Build.0 = Release-net20|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net35|Any CPU.ActiveCfg = Release-net35|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net35|Any CPU.Build.0 = Release-net35|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net40|Any CPU.ActiveCfg = Release-net40|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net40|Any CPU.Build.0 = Release-net40|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45|Any CPU.ActiveCfg = Release-net45|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45|Any CPU.Build.0 = Release-net45|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45-EF6|Any CPU.ActiveCfg = Release-net45-EF6|Any CPU + {9D13B739-62B1-4190-B386-7A9547304EB3}.Release-net45-EF6|Any CPU.Build.0 = Release-net45-EF6|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net20|Any CPU.ActiveCfg = Debug-net20|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net20|Any CPU.Build.0 = Debug-net20|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net35|Any CPU.ActiveCfg = Debug-net35|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net35|Any CPU.Build.0 = Debug-net35|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net40|Any CPU.ActiveCfg = Debug-net40|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net40|Any CPU.Build.0 = Debug-net40|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45|Any CPU.ActiveCfg = Debug-net45|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45|Any CPU.Build.0 = Debug-net45|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45-EF6|Any CPU.ActiveCfg = Debug-net45-EF6|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Debug-net45-EF6|Any CPU.Build.0 = Debug-net45-EF6|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net20|Any CPU.ActiveCfg = Release-net20|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net20|Any CPU.Build.0 = Release-net20|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net35|Any CPU.ActiveCfg = Release-net35|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net35|Any CPU.Build.0 = Release-net35|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net40|Any CPU.ActiveCfg = Release-net40|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net40|Any CPU.Build.0 = Release-net40|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45|Any CPU.ActiveCfg = Release-net45|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45|Any CPU.Build.0 = Release-net45|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45-EF6|Any CPU.ActiveCfg = Release-net45-EF6|Any CPU + {E9C258D7-0D8E-4E6A-9857-5C6438591755}.Release-net45-EF6|Any CPU.Build.0 = Release-net45-EF6|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net20|Any CPU.ActiveCfg = Debug-net20|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net20|Any CPU.Build.0 = Debug-net20|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net35|Any CPU.ActiveCfg = Debug-net35|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net35|Any CPU.Build.0 = Debug-net35|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net40|Any CPU.ActiveCfg = Debug-net40|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net40|Any CPU.Build.0 = Debug-net40|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net45|Any CPU.ActiveCfg = Debug-net45|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net45|Any CPU.Build.0 = Debug-net45|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net45-EF6|Any CPU.ActiveCfg = Debug-net45-EF6|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Debug-net45-EF6|Any CPU.Build.0 = Debug-net45-EF6|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net20|Any CPU.ActiveCfg = Release-net20|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net20|Any CPU.Build.0 = Release-net20|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net35|Any CPU.ActiveCfg = Release-net35|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net35|Any CPU.Build.0 = Release-net35|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net40|Any CPU.ActiveCfg = Release-net40|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net40|Any CPU.Build.0 = Release-net40|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net45|Any CPU.ActiveCfg = Release-net45|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net45|Any CPU.Build.0 = Release-net45|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net45-EF6|Any CPU.ActiveCfg = Release-net45-EF6|Any CPU + {249C6185-C3B5-4D28-A508-ABD975702A0B}.Release-net45-EF6|Any CPU.Build.0 = Release-net45-EF6|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NpgsqlDdexProvider/GlobalSuppressions.cs b/NpgsqlDdexProvider/GlobalSuppressions.cs new file mode 100644 index 0000000000..a893f9d250 --- /dev/null +++ b/NpgsqlDdexProvider/GlobalSuppressions.cs @@ -0,0 +1,11 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. Project-level +// suppressions either have no target or are given a specific target +// and scoped to a namespace, type, member, etc. +// +// To add a suppression to this file, right-click the message in the +// Error List, point to "Suppress Message(s)", and click "In Project +// Suppression File". You do not need to add suppressions to this +// file manually. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] diff --git a/NpgsqlDdexProvider/Guids.cs b/NpgsqlDdexProvider/Guids.cs new file mode 100644 index 0000000000..6112848853 --- /dev/null +++ b/NpgsqlDdexProvider/Guids.cs @@ -0,0 +1,15 @@ +// Guids.cs +// MUST match guids.h +using System; + +namespace Npgsql.VisualStudio.Provider +{ + static class GuidList + { + public const string guidNpgsqlDdexProviderPkgString = "958b9481-2712-4670-9a62-8fe65e5beea7"; + //stringpublic const string guidNpgsqlDdexProviderCmdSetString = "095c8e0d-0072-4599-95b8-ade172bfd544"; + public const string guidNpgsqlDdexProviderDataProviderString = "70ba90f8-3027-4aF1-9b15-37abbd48744c"; + public const string guidNpgsqlDdexProviderDataSourceString = "7931728a-ebfb-4677-ad6b-995e29AA15c2"; + public const string guidNpgsqlDdexProviderObjectFactoryString = "555cd66B-3393-4bab-84d9-3f2caa639699"; + }; +} \ No newline at end of file diff --git a/NpgsqlDdexProvider/Key.snk b/NpgsqlDdexProvider/Key.snk new file mode 100644 index 0000000000000000000000000000000000000000..211cdc6adbe18f18dd011de77b20e50b11d4944d GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096Eq?lCZfV6=fVAOD9f6c<|^AY-I!}gbQ z;O3dHX_*3j7uCwUl%6Qv9$Ad^!~_a`iw(bukyW6r=ZU)gfgs=H4>NVs!v!gt!YPL{ zb-<@m+V5Z8V!W?8e?m`bvdgVp>l9;0j3lf3H#8W`XyeG>q3W_F$GWsB<%Hjz=&7@@ zv{tpKVsp$&FA`V35Z|)FZoS)Nz+yV3KBxA);URHhGxxd}Pas{uK&D{AK*>Ko67^|_ zaPKeT&+(XgC`sfU>?2pp;y4+xc^7J)PN2D7iCiM@&JS#&0=Pt}T4Z_lJb+Jj4k;x# zm#!Xg9hr08L{hq*+mHI}sjS-LqIt>jBO;?H>wpv2FwI}tMlBbULha$|GB?p5U%vdr z2Ch!_O^??eABO38*=k*%xcr5D^n+cK2||Kia^}qeTOyVf1+G6t|9DE@z=1lGGr>wW zzn*uWRO`yv$Ww3m1V!*!_aWQB@L?bn-VZKFLmVGOb=w60FN!5QJMd$r?3yROsVlk# z=3ueKZREC=W`(-j-Ujy_*BKTVS#S@pEYV*|-%zbz^SyA`qO2P3=C!uTaw z!n6s@`ZcKhNtSfw)7yVd-Nf;NMYpOTzritElNj4fLX~}W<0Zcsx(^Fq+cE(YBx8wX iwWG}clPBrzVr>(ZhOnn1s$O(l@Zs`MQa{hnNeM*l!Ya}L literal 0 HcmV?d00001 diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs b/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs new file mode 100644 index 0000000000..8ea7596f9e --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs @@ -0,0 +1,39 @@ +using Microsoft.VisualStudio.Data.Framework; +using Microsoft.VisualStudio.Data.Framework.AdoDotNet; +using Microsoft.VisualStudio.Data.Services.SupportEntities; +using System; +using System.Data; +using System.Data.Common; +using System.Collections.Generic; +using System.Linq; + +namespace Npgsql.VisualStudio.Provider +{ + class NpgsqlDataObjectSelector : AdoDotNetRootObjectSelector + { + protected override IVsDataReader SelectObjects(string typeName, object[] restrictions, string[] properties, object[] parameters) + { + + if (Site != null) + { + IVsDataReader reader = null; + DbConnection conn = (DbConnection)Site.GetLockedProviderObject(); + if ("".Equals(typeName)) + { + DbConnectionStringBuilder builder = DbProviderFactories.GetFactory("Npgsql").CreateConnectionStringBuilder(); + builder.ConnectionString = conn.ConnectionString; + DataTable table = new DataTable(); + table.Columns.AddRange(builder.Keys.Cast().Select((String k) => new DataColumn(k, builder[k].GetType())).ToArray()); + DataRow row = table.NewRow(); + row.ItemArray = builder.Values.Cast().ToArray(); + table.Rows.Add(row); + reader = new AdoDotNetTableReader(table); + } + Site.UnlockProviderObject(); + if (reader != null) + return reader; + } + throw new NotImplementedException(); + } + } +} diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml new file mode 100644 index 0000000000..af1e19b79f --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs new file mode 100644 index 0000000000..072503eded --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs @@ -0,0 +1,52 @@ +using Microsoft.VisualStudio.Shell; +using System; + +namespace Npgsql.VisualStudio.Provider +{ + class NpgsqlDataProviderRegistration : RegistrationAttribute + { + public override void Register(RegistrationAttribute.RegistrationContext context) + { + Key providerKey = null; + try + { + providerKey = context.CreateKey(@"DataProviders\{" + GuidList.guidNpgsqlDdexProviderDataProviderString + @"}"); + providerKey.SetValue(null, ".NET Framework Data Provider for PostgreSQL"); + providerKey.SetValue("AssociatedSource", "{" + GuidList.guidNpgsqlDdexProviderDataSourceString + "}"); + providerKey.SetValue("Description", "Provider_Description, " + this.GetType().Namespace + ".Resources"); + providerKey.SetValue("DisplayName", "Provider_DisplayName, " + this.GetType().Namespace + ".Resources"); + providerKey.SetValue("FactoryService", "{" + GuidList.guidNpgsqlDdexProviderObjectFactoryString + "}"); + providerKey.SetValue("InvariantName", "Npgsql"); + providerKey.SetValue("PlatformVersion", "2.0"); + providerKey.SetValue("ShortDisplayName", "Provider_ShortDisplayName, " + this.GetType().Namespace + ".Resources"); + providerKey.SetValue("Technology", "{77AB9A9D-78B9-4ba7-91AC-873F5338F1D2}"); + + providerKey = providerKey.CreateSubkey("SupportedObjects"); + providerKey.CreateSubkey("IVsDataConnectionProperties"); + providerKey.CreateSubkey("IVsDataConnectionUIProperties"); + providerKey.CreateSubkey("IVsDataConnectionSupport"); + providerKey.CreateSubkey("IVsDataObjectSupport"); + providerKey.CreateSubkey("IVsDataViewSupport"); + + providerKey = context.CreateKey(@"DataSources\{" + GuidList.guidNpgsqlDdexProviderDataSourceString + @"}"); + providerKey.SetValue(null, "PostgreSQL Database"); + providerKey.SetValue("DefaultProvider", "{" + GuidList.guidNpgsqlDdexProviderDataProviderString + "}"); + providerKey = providerKey.CreateSubkey("SupportingProviders"); + providerKey = providerKey.CreateSubkey("{" + GuidList.guidNpgsqlDdexProviderDataProviderString + "}"); + providerKey.SetValue("Description", "Provider_Description, " + this.GetType().Namespace + ".Resources"); + providerKey.SetValue("DisplayName", "Provider_DisplayName, " + this.GetType().Namespace + ".Resources"); + } + finally + { + if (providerKey != null) + providerKey.Close(); + } + } + + public override void Unregister(RegistrationAttribute.RegistrationContext context) + { + context.RemoveKey(@"DataProviders\{" + GuidList.guidNpgsqlDdexProviderDataProviderString + @"}"); + context.RemoveKey(@"DataSources\{" + GuidList.guidNpgsqlDdexProviderDataSourceString + @"}"); + } + } +} diff --git a/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml b/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml new file mode 100644 index 0000000000..dc1bbe763e --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml @@ -0,0 +1,107 @@ + + + + + PostgreSQL Server + + {Root.Host} ({Root.Database}) + + + + + + + + + + + {schema_name} + + + + + + + + + + + + {table_name} + + + + + + + + + + + + {column_name} + + + + + + + + + + + + {constraint_name} + + + + + + + + + + + + + + + + + + + + {table_name} + + + + + + + + + + + + {column_name} + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj b/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj new file mode 100644 index 0000000000..480de752f9 --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj @@ -0,0 +1,249 @@ + + + + 11.0 + 11.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + Debug + AnyCPU + 2.0 + {249C6185-C3B5-4D28-A508-ABD975702A0B} + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + Npgsql.VisualStudio.Provider + NpgsqlDdexProvider + True + Key.snk + v4.5 + + + true + full + false + bin\Debug-net45\ + TRACE;DEBUG;WINDOWS;UNMANAGED;NET35;NET40;NET45;ENTITIES + prompt + 4 + bin\Debug-net45\Npgsql.xml + v4.5 + + + pdbonly + true + bin\Release-net45\ + TRACE;WINDOWS;UNMANAGED;NET35;NET40;NET45;ENTITIES + prompt + 4 + bin\Release-net45\Npgsql.xml + v4.5 + + + true + full + false + bin\Debug-net40\ + TRACE;DEBUG;WINDOWS;UNMANAGED;NET35;NET40;ENTITIES + prompt + 4 + bin\Debug-net40\Npgsql.xml + v4.0 + + + pdbonly + true + bin\Release-net40\ + TRACE;WINDOWS;UNMANAGED;NET35;NET40;ENTITIES + prompt + 4 + bin\Release-net40\Npgsql.xml + v4.0 + + + true + full + false + bin\Debug-net35\ + TRACE;DEBUG;WINDOWS;UNMANAGED;NET35;ENTITIES + prompt + 4 + bin\Debug-net35\Npgsql.xml + v3.5 + + + pdbonly + true + bin\Release-net35\ + TRACE;WINDOWS;UNMANAGED;NET35;ENTITIES + prompt + 4 + bin\Release-net35\Npgsql.xml + v3.5 + + + true + full + false + bin\Debug-net20\ + TRACE;DEBUG;WINDOWS;UNMANAGED + prompt + 4 + bin\Debug-net20\Npgsql.xml + v2.0 + + + pdbonly + true + bin\Release-net20\ + TRACE;WINDOWS;UNMANAGED + prompt + 4 + bin\Release-net20\Npgsql.xml + v2.0 + + + true + full + false + bin\Debug-net45-EF6\ + TRACE;DEBUG;WINDOWS;UNMANAGED;NET35;NET40;NET45;ENTITIES;ENTITIES6 + prompt + 4 + bin\Debug-net45-EF6\Npgsql.xml + v4.5 + + + pdbonly + true + bin\Release-net45-EF6\ + TRACE;WINDOWS;UNMANAGED;NET35;NET40;NET45;ENTITIES;ENTITIES6 + prompt + 4 + bin\Release-net45-EF6\Npgsql.xml + v4.5 + + + + + + + + + + + + + true + + + + + + + + + + + + {80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2} + 8 + 0 + 0 + primary + False + False + + + {26AD1324-4B7C-44BC-84F8-B86AED45729F} + 10 + 0 + 0 + primary + False + False + + + {1A31287A-4D7D-413E-8E32-3B374931BD89} + 8 + 0 + 0 + primary + False + False + + + {2CE2370E-D744-4936-A090-3FFFE667B0E1} + 9 + 0 + 0 + primary + False + False + + + {00020430-0000-0000-C000-000000000046} + 2 + 0 + 0 + primary + False + False + + + + + + + + + True + True + Resources.resx + + + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + Designer + + + true + VSPackage + + + + + Designer + + + + + + + + + + + + + + + true + + + + + \ No newline at end of file diff --git a/NpgsqlDdexProvider/NpgsqlDdexProviderPackage.cs b/NpgsqlDdexProvider/NpgsqlDdexProviderPackage.cs new file mode 100644 index 0000000000..d2945ebfce --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlDdexProviderPackage.cs @@ -0,0 +1,63 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; +using System.ComponentModel.Design; +using Microsoft.Win32; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell; + +namespace Npgsql.VisualStudio.Provider +{ + /// + /// This is the class that implements the package exposed by this assembly. + /// + /// The minimum requirement for a class to be considered a valid package for Visual Studio + /// is to implement the IVsPackage interface and register itself with the shell. + /// This package uses the helper classes defined inside the Managed Package Framework (MPF) + /// to do it: it derives from the Package class that provides the implementation of the + /// IVsPackage interface and uses the registration attributes defined in the framework to + /// register itself and its components with the shell. + /// + // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is + // a package. + [PackageRegistration(UseManagedResourcesOnly = true)] + // This attribute is used to register the information needed to show this package + // in the Help/About dialog of Visual Studio. + [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] + [ProvideService(typeof(NpgsqlProviderObjectFactory), ServiceName = "PostgreSQL Provider Object Factory")] + [NpgsqlDataProviderRegistration] + [Guid(GuidList.guidNpgsqlDdexProviderPkgString)] + public sealed class NpgsqlDdexProviderPackage : Package + { + /// + /// Default constructor of the package. + /// Inside this method you can place any initialization code that does not require + /// any Visual Studio service because at this point the package object is created but + /// not sited yet inside Visual Studio environment. The place to do all the other + /// initialization is the Initialize method. + /// + public NpgsqlDdexProviderPackage() + { + + } + + + + ///////////////////////////////////////////////////////////////////////////// + // Overridden Package Implementation + #region Package Members + + /// + /// Initialization of the package; this method is called right after the package is sited, so this is the place + /// where you can put all the initialization code that rely on services provided by VisualStudio. + /// + protected override void Initialize() + { + ((IServiceContainer)this).AddService(typeof(NpgsqlProviderObjectFactory), new NpgsqlProviderObjectFactory(), true); + base.Initialize(); + } + #endregion + + } +} diff --git a/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs b/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs new file mode 100644 index 0000000000..7af65e4ef1 --- /dev/null +++ b/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs @@ -0,0 +1,25 @@ +using Microsoft.VisualStudio.Data.Framework; +using Microsoft.VisualStudio.Data.Framework.AdoDotNet; +using Microsoft.VisualStudio.Data.Services.SupportEntities; +using System; +using System.Runtime.InteropServices; + +namespace Npgsql.VisualStudio.Provider +{ + [Guid(GuidList.guidNpgsqlDdexProviderObjectFactoryString)] + class NpgsqlProviderObjectFactory : DataProviderObjectFactory + { + public override object CreateObject(Type objType) + { + if (objType == typeof(IVsDataConnectionProperties) || objType == typeof(IVsDataConnectionUIProperties)) + return new AdoDotNetConnectionProperties(); + else if (objType == typeof(IVsDataConnectionSupport)) + return new AdoDotNetConnectionSupport(); + else if (objType == typeof(IVsDataObjectSupport)) + return new DataObjectSupport(this.GetType().Namespace + ".NpgsqlDataObjectSupport", System.Reflection.Assembly.GetExecutingAssembly()); + else if (objType == typeof(IVsDataViewSupport)) + return new DataViewSupport(this.GetType().Namespace + ".NpgsqlDataViewSupport", System.Reflection.Assembly.GetExecutingAssembly()); + return null; + } + } +} diff --git a/NpgsqlDdexProvider/Properties/AssemblyInfo.cs b/NpgsqlDdexProvider/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f265c0da70 --- /dev/null +++ b/NpgsqlDdexProvider/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Npgsql Ddex Provider")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: CLSCompliant(false)] +[assembly: NeutralResourcesLanguage("en-US")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + + + diff --git a/NpgsqlDdexProvider/Resources.Designer.cs b/NpgsqlDdexProvider/Resources.Designer.cs new file mode 100644 index 0000000000..f4e7361ff9 --- /dev/null +++ b/NpgsqlDdexProvider/Resources.Designer.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18052 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Npgsql.VisualStudio.Provider { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Npgsql.VisualStudio.Provider.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Columns. + /// + public static string Node_Columns { + get { + return ResourceManager.GetString("Node_Columns", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Constraints. + /// + public static string Node_Constraints { + get { + return ResourceManager.GetString("Node_Constraints", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Schemata. + /// + public static string Node_Schemata { + get { + return ResourceManager.GetString("Node_Schemata", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tables. + /// + public static string Node_Tables { + get { + return ResourceManager.GetString("Node_Tables", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Views. + /// + public static string Node_Views { + get { + return ResourceManager.GetString("Node_Views", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Npgsql Ddex Provider. + /// + public static string Provider_Description { + get { + return ResourceManager.GetString("Provider_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Npgsql Ddex Provider. + /// + public static string Provider_Display { + get { + return ResourceManager.GetString("Provider_Display", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Npgsql Ddex Provider. + /// + public static string Provider_ShortDisplayName { + get { + return ResourceManager.GetString("Provider_ShortDisplayName", resourceCulture); + } + } + } +} diff --git a/NpgsqlDdexProvider/Resources.resx b/NpgsqlDdexProvider/Resources.resx new file mode 100644 index 0000000000..9c9b13362d --- /dev/null +++ b/NpgsqlDdexProvider/Resources.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Columns + + + Constraints + + + Schemata + + + Tables + + + Views + + + Npgsql Ddex Provider + + + Npgsql Ddex Provider + + + Npgsql Ddex Provider + + \ No newline at end of file diff --git a/NpgsqlDdexProvider/Resources/Package.ico b/NpgsqlDdexProvider/Resources/Package.ico new file mode 100644 index 0000000000000000000000000000000000000000..449296f495af26f2b41bb1626a28de7432145472 GIT binary patch literal 2998 zcmeHJIc@?$5G;1VEan=&z(kgxVUhCya&kft2^&G^5AXoz*K%ZEh6^mKRC)SN;9Ie2I^4EsEuJm3ak4(0(K0-)vtx2mz-v5Du5+`|?E{2~nF zj-DY~i1~a@z`8H2Rm8@RN^*7j%+?3;*Is5r;m32z^?Gs%|GV@5y&h|~@doa#jn6yX zPm+(*yf56oD($=C(DJ(6=%K6Llfe5Uo;dPV7%T5PITm!!YhANqXLaS`0ufOBi8crP zkWX22ZGmf>3$1+|+x>UW$1lsro%1<*HCnUTM61<8yWK{o(?Pe}#b7YNXf(oPGQo5@ z#cVdiVzIz-xkMC2Sglrgd0u0)* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + NpgsqlDdexProvider + + + Npgsql Ddex Provider + + + Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/NpgsqlDdexProvider/source.extension.vsixmanifest b/NpgsqlDdexProvider/source.extension.vsixmanifest new file mode 100644 index 0000000000..9973cc610a --- /dev/null +++ b/NpgsqlDdexProvider/source.extension.vsixmanifest @@ -0,0 +1,18 @@ + + + + + NpgsqlDdexProvider + Npgsql Ddex Provider + + + + + + + + + + + + diff --git a/src/Npgsql.csproj b/src/Npgsql.csproj index 5527112fc6..f8e7568682 100644 --- a/src/Npgsql.csproj +++ b/src/Npgsql.csproj @@ -1,4 +1,4 @@ - + Debug @@ -139,7 +139,7 @@ v4.5 - + @@ -172,6 +172,7 @@ + @@ -656,4 +657,4 @@ --> - + \ No newline at end of file diff --git a/src/Npgsql/NpgsqlConnection.cs b/src/Npgsql/NpgsqlConnection.cs index f8ef238fc4..c6b4d8f32e 100644 --- a/src/Npgsql/NpgsqlConnection.cs +++ b/src/Npgsql/NpgsqlConnection.cs @@ -1143,6 +1143,8 @@ public override DataTable GetSchema(string collectionName, string[] restrictions // custom collections for npgsql case "Databases": return NpgsqlSchema.GetDatabases(tempConn, restrictions); + case "Schemata": + return NpgsqlSchema.GetSchemata(tempConn, restrictions); case "Tables": return NpgsqlSchema.GetTables(tempConn, restrictions); case "Columns": @@ -1155,8 +1157,13 @@ public override DataTable GetSchema(string collectionName, string[] restrictions return NpgsqlSchema.GetIndexes(tempConn, restrictions); case "IndexColumns": return NpgsqlSchema.GetIndexColumns(tempConn, restrictions); + case "Constraints": + case "PrimaryKey": + case "UniqueKeys": case "ForeignKeys": - return NpgsqlSchema.GetForeignKeys(tempConn, restrictions); + return NpgsqlSchema.GetConstraints(tempConn, restrictions, collectionName); + case "ConstraintColumns": + return NpgsqlSchema.GetConstraintColumns(tempConn, restrictions); default: throw new ArgumentOutOfRangeException("collectionName", collectionName); } diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.cs b/src/Npgsql/NpgsqlConnectionStringBuilder.cs index e85642b8cd..108f6ad3d3 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.cs +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.cs @@ -294,6 +294,7 @@ public byte[] PasswordAsByteArray } public string Password { + get { return String.Empty; } set { SetValue(GetKeyName(Keywords.Password), value); } } diff --git a/src/Npgsql/NpgsqlProviderManifest.cs b/src/Npgsql/NpgsqlProviderManifest.cs index 8b7a6dd39b..2a7f783d7a 100644 --- a/src/Npgsql/NpgsqlProviderManifest.cs +++ b/src/Npgsql/NpgsqlProviderManifest.cs @@ -29,6 +29,12 @@ protected override XmlReader GetDbInformation(string informationType) { xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.ssdl"); } +#if NET45 + else if (informationType == StoreSchemaDefinitionVersion3) + { + xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchemaV3.ssdl"); + } +#endif else if (informationType == StoreSchemaMapping) { xmlReader = CreateXmlReaderForResource("Npgsql.NpgsqlSchema.msl"); diff --git a/src/Npgsql/NpgsqlSchema.cs b/src/Npgsql/NpgsqlSchema.cs index a7d8ce292c..a2e6583734 100644 --- a/src/Npgsql/NpgsqlSchema.cs +++ b/src/Npgsql/NpgsqlSchema.cs @@ -142,6 +142,35 @@ internal static DataTable GetDatabases(NpgsqlConnection conn, string[] restricti return databases; } + internal static DataTable GetSchemata(NpgsqlConnection conn, string[] restrictions) + { + DataTable schemata = new DataTable("Schemata"); + schemata.Locale = CultureInfo.InvariantCulture; + + schemata.Columns.AddRange( + new DataColumn[] + { + new DataColumn("catalog_name"), new DataColumn("schema_name"), new DataColumn("schema_owner") + }); + + StringBuilder getSchemata = new StringBuilder(); + + getSchemata.Append("SELECT catalog_name, schema_name, schema_owner FROM information_schema.schemata"); + + using ( + NpgsqlCommand command = + BuildCommand(conn, getSchemata, restrictions, "catalog_name", "schema_name", "schema_owner")) + { + using (NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(command)) + { + adapter.Fill(schemata); + } + } + + return schemata; + + } + /// /// Returns the Tables that contains table and view names and the database and schema they come from. /// @@ -373,11 +402,11 @@ and pg_catalog.pg_table_is_visible(i.oid) return indexColumns; } - internal static DataTable GetForeignKeys(NpgsqlConnection conn, string[] restrictions) + internal static DataTable GetConstraints(NpgsqlConnection conn, string[] restrictions, string constraint_type) { - StringBuilder getForeignKeys = new StringBuilder(); + StringBuilder getConstraints = new StringBuilder(); - getForeignKeys.Append( + getConstraints.Append( @"select current_database() as ""CONSTRAINT_CATALOG"", pgn.nspname as ""CONSTRAINT_SCHEMA"", @@ -385,23 +414,71 @@ internal static DataTable GetForeignKeys(NpgsqlConnection conn, string[] restric current_database() as ""TABLE_CATALOG"", pgtn.nspname as ""TABLE_SCHEMA"", pgt.relname as ""TABLE_NAME"", - 'FOREIGN KEY' as ""CONSTRAINT_TYPE"", + ""CONSTRAINT_TYPE"", pgc.condeferrable as ""IS_DEFERRABLE"", pgc.condeferred as ""INITIALLY_DEFERRED"" from pg_catalog.pg_constraint pgc inner join pg_catalog.pg_namespace pgn on pgc.connamespace = pgn.oid inner join pg_catalog.pg_class pgt on pgc.conrelid = pgt.oid inner join pg_catalog.pg_namespace pgtn on pgt.relnamespace = pgtn.oid -where pgc.contype='f' -"); +inner join ( +select 'PRIMARY KEY' ""CONSTRAINT_TYPE"", 'p' as ""contype"" union all +select 'FOREIGN KEY' ""CONSTRAINT_TYPE"", 'f' as ""contype"" union all +select 'UNIQUE KEY' ""CONSTRAINT_TYPE"", 'u' as ""contype"" +) mapping_table on mapping_table.contype = pgc.contype"); + if ("ForeignKeys".Equals(constraint_type)) + getConstraints.Append("where pgc.contype='f'"); + else if ("PrimaryKey".Equals(constraint_type)) + getConstraints.Append("where pgc.contype='p'"); + else if ("UniqueKeys".Equals(constraint_type)) + getConstraints.Append("where pgc.contype='u'"); + else + constraint_type = "Constraints"; + using ( + NpgsqlCommand command = + BuildCommand(conn, getConstraints, restrictions, false, "current_database()", "pgtn.nspname", "pgt.relname", "pgc.conname")) + { + using (NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(command)) + { + DataTable table = new DataTable(constraint_type); + adapter.Fill(table); + return table; + } + } + } + + internal static DataTable GetConstraintColumns(NpgsqlConnection conn, string[] restrictions) + { + StringBuilder getConstraintColumns = new StringBuilder(); + + getConstraintColumns.Append( +@"select current_database() as constraint_catalog, + n.nspname as constraint_schema, + c.conname as constraint_name, + current_database() as table_catalog, + n.nspname as table_schema, + t.relname as table_name, + a.attname as column_name, + a.attnum as ordinal_number, + mapping_table.constraint_type +from pg_constraint c +inner join pg_namespace n on n.oid = c.connamespace +inner join pg_class t on t.oid = c.conrelid and t.relkind = 'r' +inner join pg_attribute a on t.oid = a.attrelid and a.attnum = ANY(c.conkey) +inner join ( +select 'PRIMARY KEY' constraint_type, 'p' as contype union all +select 'FOREIGN KEY' constraint_type, 'f' as contype union all +select 'UNIQUE KEY' constraint_type, 'u' as contype +) mapping_table on mapping_table.contype = c.contype +where n.nspname not in ('pg_catalog', 'pg_toast')"); using ( NpgsqlCommand command = - BuildCommand(conn, getForeignKeys, restrictions, false, "current_database()", "pgtn.nspname", "pgt.relname", "pgc.conname")) + BuildCommand(conn, getConstraintColumns, restrictions, false, "current_database()", "n.nspname", "t.relname", "c.conname", "a.attname")) { using (NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(command)) { - DataTable table = new DataTable("ForeignKeys"); + DataTable table = new DataTable("ConstraintColumns"); adapter.Fill(table); return table; } diff --git a/src/Npgsql/NpgsqlSchemaV3.ssdl b/src/Npgsql/NpgsqlSchemaV3.ssdl new file mode 100644 index 0000000000..9c295da653 --- /dev/null +++ b/src/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' 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' 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/Npgsql/SqlGenerators/VisitedExpression.cs b/src/Npgsql/SqlGenerators/VisitedExpression.cs index d1e5760a06..e3e50fa404 100644 --- a/src/Npgsql/SqlGenerators/VisitedExpression.cs +++ b/src/Npgsql/SqlGenerators/VisitedExpression.cs @@ -147,7 +147,7 @@ internal override void WriteSql(StringBuilder sqlText) // Check https://github.com/franciscojunior/Npgsql2/pull/10 for more info. // NativeToBackendTypeConverterOptions.Default should provide the correct // formatting rules for any backend >= 8.0. - sqlText.Append(typeInfo.ConvertToBackend(_value, false)); + sqlText.Append(System.Text.Encoding.ASCII.GetChars(typeInfo.ConvertToBackend(_value, false))); break; case PrimitiveTypeKind.Time: sqlText.AppendFormat(ni, "TIME '{0:T}'", _value); From 9002845dd2f5b9f60b653be3307418b2f1b6c94e Mon Sep 17 00:00:00 2001 From: windcloud Date: Thu, 10 Oct 2013 16:20:03 +0800 Subject: [PATCH 2/5] DDEX: Remove NpgsqlDataObjectSelector, use default one, no longer need customization DDEX: Make copy/paste drag/drop work Npgsql: Rework NpgsqlConnectionStringBuilder to be more consistent Npgsql: Fix bug in NpgsqlMetaData.xml, wrong CompositeIdentifierSeparatorPattern Npgsql: Fix GetSchema for tables to return TABLE only --- .../NpgsqlDataObjectSelector.cs | 39 - .../NpgsqlDataObjectSupport.xml | 12 +- .../NpgsqlDataProviderRegistration.cs | 13 +- NpgsqlDdexProvider/NpgsqlDataViewSupport.xml | 6 +- NpgsqlDdexProvider/NpgsqlDdexProvider.csproj | 4 +- .../NpgsqlProviderObjectFactory.cs | 2 +- src/Npgsql/NpgsqlCommandBuilder.cs | 22 +- src/Npgsql/NpgsqlConnection.cs | 4 +- src/Npgsql/NpgsqlConnectionStringBuilder.cs | 877 ++++++++---------- src/Npgsql/NpgsqlConnectionStringBuilder.resx | 303 ++++-- src/Npgsql/NpgsqlConnector.cs | 4 +- src/Npgsql/NpgsqlMetaData.xml | 5 +- src/Npgsql/NpgsqlSchema.cs | 2 +- 13 files changed, 685 insertions(+), 608 deletions(-) delete mode 100644 NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs b/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs deleted file mode 100644 index 8ea7596f9e..0000000000 --- a/NpgsqlDdexProvider/NpgsqlDataObjectSelector.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.VisualStudio.Data.Framework; -using Microsoft.VisualStudio.Data.Framework.AdoDotNet; -using Microsoft.VisualStudio.Data.Services.SupportEntities; -using System; -using System.Data; -using System.Data.Common; -using System.Collections.Generic; -using System.Linq; - -namespace Npgsql.VisualStudio.Provider -{ - class NpgsqlDataObjectSelector : AdoDotNetRootObjectSelector - { - protected override IVsDataReader SelectObjects(string typeName, object[] restrictions, string[] properties, object[] parameters) - { - - if (Site != null) - { - IVsDataReader reader = null; - DbConnection conn = (DbConnection)Site.GetLockedProviderObject(); - if ("".Equals(typeName)) - { - DbConnectionStringBuilder builder = DbProviderFactories.GetFactory("Npgsql").CreateConnectionStringBuilder(); - builder.ConnectionString = conn.ConnectionString; - DataTable table = new DataTable(); - table.Columns.AddRange(builder.Keys.Cast().Select((String k) => new DataColumn(k, builder[k].GetType())).ToArray()); - DataRow row = table.NewRow(); - row.ItemArray = builder.Values.Cast().ToArray(); - table.Rows.Add(row); - reader = new AdoDotNetTableReader(table); - } - Site.UnlockProviderObject(); - if (reader != null) - return reader; - } - throw new NotImplementedException(); - } - } -} diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml index af1e19b79f..a18462c762 100644 --- a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml +++ b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml @@ -7,7 +7,11 @@ - + + + + + @@ -325,7 +329,7 @@ - + @@ -434,11 +438,11 @@ - + diff --git a/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs index 072503eded..6557b257c7 100644 --- a/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs +++ b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs @@ -1,4 +1,5 @@ -using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Data.Services.SupportEntities; +using Microsoft.VisualStudio.Shell; using System; namespace Npgsql.VisualStudio.Provider @@ -22,11 +23,11 @@ public override void Register(RegistrationAttribute.RegistrationContext context) providerKey.SetValue("Technology", "{77AB9A9D-78B9-4ba7-91AC-873F5338F1D2}"); providerKey = providerKey.CreateSubkey("SupportedObjects"); - providerKey.CreateSubkey("IVsDataConnectionProperties"); - providerKey.CreateSubkey("IVsDataConnectionUIProperties"); - providerKey.CreateSubkey("IVsDataConnectionSupport"); - providerKey.CreateSubkey("IVsDataObjectSupport"); - providerKey.CreateSubkey("IVsDataViewSupport"); + providerKey.CreateSubkey(typeof(IVsDataConnectionProperties).Name); + providerKey.CreateSubkey(typeof(IVsDataConnectionUIProperties).Name); + providerKey.CreateSubkey(typeof(IVsDataConnectionSupport).Name); + providerKey.CreateSubkey(typeof(IVsDataObjectSupport).Name); + providerKey.CreateSubkey(typeof(IVsDataViewSupport).Name); providerKey = context.CreateKey(@"DataSources\{" + GuidList.guidNpgsqlDdexProviderDataSourceString + @"}"); providerKey.SetValue(null, "PostgreSQL Database"); diff --git a/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml b/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml index dc1bbe763e..44bb48399d 100644 --- a/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml +++ b/NpgsqlDdexProvider/NpgsqlDataViewSupport.xml @@ -25,7 +25,7 @@ - + {table_name} @@ -70,7 +70,7 @@ - + {table_name} @@ -81,7 +81,7 @@ - + {column_name} diff --git a/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj b/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj index 480de752f9..1ed35f1b03 100644 --- a/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj +++ b/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj @@ -30,6 +30,7 @@ 4 bin\Debug-net45\Npgsql.xml v4.5 + true pdbonly @@ -40,6 +41,7 @@ 4 bin\Release-net45\Npgsql.xml v4.5 + true true @@ -144,6 +146,7 @@ + @@ -195,7 +198,6 @@ - diff --git a/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs b/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs index 7af65e4ef1..eacfd66037 100644 --- a/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs +++ b/NpgsqlDdexProvider/NpgsqlProviderObjectFactory.cs @@ -10,7 +10,7 @@ namespace Npgsql.VisualStudio.Provider class NpgsqlProviderObjectFactory : DataProviderObjectFactory { public override object CreateObject(Type objType) - { + { if (objType == typeof(IVsDataConnectionProperties) || objType == typeof(IVsDataConnectionUIProperties)) return new AdoDotNetConnectionProperties(); else if (objType == typeof(IVsDataConnectionSupport)) diff --git a/src/Npgsql/NpgsqlCommandBuilder.cs b/src/Npgsql/NpgsqlCommandBuilder.cs index a2caec8904..e80e03744a 100644 --- a/src/Npgsql/NpgsqlCommandBuilder.cs +++ b/src/Npgsql/NpgsqlCommandBuilder.cs @@ -303,31 +303,25 @@ public override string QuoteIdentifier(string unquotedIdentifier) { throw new ArgumentNullException("Unquoted identifier parameter cannot be null"); } + if (this.QuotePrefix != this.QuoteSuffix) + throw new ArgumentException("Specified QuotePrefix and QuoteSuffix values do not match"); - return String.Format("{0}{1}{2}", this.QuotePrefix, unquotedIdentifier, this.QuoteSuffix); + return this.QuotePrefix + unquotedIdentifier.Replace(this.QuotePrefix, this.QuotePrefix + this.QuotePrefix) + this.QuoteSuffix; } public override string UnquoteIdentifier(string quotedIdentifier) - { if (quotedIdentifier == null) - - { throw new ArgumentNullException("Quoted identifier parameter cannot be null"); - } + if (this.QuotePrefix != this.QuoteSuffix) + throw new ArgumentException("Specified QuotePrefix and QuoteSuffix values do not match"); string unquotedIdentifier = quotedIdentifier.Trim(); - if (unquotedIdentifier.StartsWith(this.QuotePrefix)) - - { - unquotedIdentifier = unquotedIdentifier.Remove(0, 1); - } - - if (unquotedIdentifier.EndsWith(this.QuoteSuffix)) - + if (unquotedIdentifier.Length > 2 && unquotedIdentifier.StartsWith(this.QuotePrefix) && unquotedIdentifier.EndsWith(this.QuoteSuffix)) { - unquotedIdentifier = unquotedIdentifier.Remove(unquotedIdentifier.Length - 1, 1); + unquotedIdentifier = unquotedIdentifier.Substring(1, unquotedIdentifier.Length - 2); + unquotedIdentifier = unquotedIdentifier.Replace(this.QuotePrefix + this.QuotePrefix, this.QuotePrefix); } return unquotedIdentifier; diff --git a/src/Npgsql/NpgsqlConnection.cs b/src/Npgsql/NpgsqlConnection.cs index c6b4d8f32e..885f1311f6 100644 --- a/src/Npgsql/NpgsqlConnection.cs +++ b/src/Npgsql/NpgsqlConnection.cs @@ -591,12 +591,12 @@ public override void Open() if (!settings.ContainsKey(Keywords.Host)) { throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), - NpgsqlConnectionStringBuilder.GetKeyName(Keywords.Host)); + Keywords.Host.ToString()); } if (!settings.ContainsKey(Keywords.UserName) && !settings.ContainsKey(Keywords.IntegratedSecurity)) { throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), - NpgsqlConnectionStringBuilder.GetKeyName(Keywords.UserName)); + Keywords.Host.ToString()); } // Get a Connector, either from the pool or creating one ourselves. diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.cs b/src/Npgsql/NpgsqlConnectionStringBuilder.cs index 108f6ad3d3..e41551d1c4 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.cs +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.cs @@ -29,7 +29,9 @@ // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. using System; +using System.Collections; using System.Collections.Generic; +using System.ComponentModel; using System.Data.Common; using System.Reflection; using System.Resources; @@ -40,127 +42,169 @@ namespace Npgsql public sealed class NpgsqlConnectionStringBuilder : DbConnectionStringBuilder { private static readonly ResourceManager resman = new ResourceManager(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly Dictionary defaults = new Dictionary(); - - private string originalConnectionString; + private static readonly IDictionary defaults = new Dictionary(); + private static readonly IDictionary keyword_mappings = new Dictionary(); + private static readonly IDictionary underlying_keywords = new Dictionary(); + private static readonly IDictionary props = new Dictionary(); + private static readonly IDictionary prop_key = new Dictionary(); private const int POOL_SIZE_LIMIT = 1024; private const int TIMEOUT_LIMIT = 1024; - static NpgsqlConnectionStringBuilder() + [AttributeUsage(AttributeTargets.Property)] + private sealed class NpgsqlConnectionStringKeywordAttribute : Attribute { - defaults.Add(Keywords.Host, string.Empty); - defaults.Add(Keywords.Port, 5432); - defaults.Add(Keywords.Protocol, ProtocolVersion.Version3); - defaults.Add(Keywords.Database, string.Empty); - defaults.Add(Keywords.UserName, string.Empty); - defaults.Add(Keywords.Password, string.Empty); - defaults.Add(Keywords.SSL, false); - defaults.Add(Keywords.SslMode, SslMode.Disable); - defaults.Add(Keywords.Timeout, 15); - defaults.Add(Keywords.SearchPath, string.Empty); - defaults.Add(Keywords.Pooling, true); - defaults.Add(Keywords.ConnectionLifeTime, 15); - defaults.Add(Keywords.MinPoolSize, 1); - defaults.Add(Keywords.MaxPoolSize, 20); - defaults.Add(Keywords.SyncNotification, false); - defaults.Add(Keywords.CommandTimeout, 20); - defaults.Add(Keywords.Enlist, false); - defaults.Add(Keywords.PreloadReader, false); - defaults.Add(Keywords.UseExtendedTypes, false); - defaults.Add(Keywords.IntegratedSecurity, false); - defaults.Add(Keywords.Compatible, THIS_VERSION); - defaults.Add(Keywords.ApplicationName, string.Empty); + public Keywords Keyword; + public string UnderlyingConnectionKeyword; + public bool IsInternal = false; + public NpgsqlConnectionStringKeywordAttribute(Keywords keyword, bool is_internal = false) + { + this.Keyword = keyword; + this.UnderlyingConnectionKeyword = keyword.ToString().ToUpperInvariant(); + this.IsInternal = is_internal; + } + public NpgsqlConnectionStringKeywordAttribute(Keywords keyword, string underlying_connection_keyword) + { + this.Keyword = keyword; + this.UnderlyingConnectionKeyword = underlying_connection_keyword; + } } - public NpgsqlConnectionStringBuilder() + [AttributeUsage(AttributeTargets.Property, AllowMultiple=true)] + private sealed class NpgsqlConnectionStringAcceptableKeywordAttribute : Attribute { - this.Clear(); + public string Keyword; + public NpgsqlConnectionStringAcceptableKeywordAttribute(string keyword) + { + this.Keyword = keyword; + } } - public NpgsqlConnectionStringBuilder(string connectionString) + private sealed class NpgsqlConnectionStringCategoryAttribute : CategoryAttribute { - this.Clear(); - this.originalConnectionString = connectionString; - base.ConnectionString = connectionString; - CheckValues(); + public NpgsqlConnectionStringCategoryAttribute(String category) : base(category) { } + protected override string GetLocalizedString(string value) + { + return resman.GetString(value); + } } - - /// - /// Return an exact copy of this NpgsqlConnectionString. - /// - public NpgsqlConnectionStringBuilder Clone() + private sealed class NpgsqlConnectionStringDisplayNameAttribute : DisplayNameAttribute { - NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(); - - foreach (string key in this.Keys) + public NpgsqlConnectionStringDisplayNameAttribute(string resourceName) : base(resourceName) { - builder[key] = this[key]; + try + { + string value = resman.GetString(resourceName); + if (value != null) + DisplayNameValue = value; + } + catch (Exception e) + { + } } - - return builder; } - private void CheckValues() + private sealed class NpgsqlConnectionStringDescriptionAttribute : DescriptionAttribute { - if ((MaxPoolSize > 0) && (MinPoolSize > MaxPoolSize)) + public NpgsqlConnectionStringDescriptionAttribute(string resourceName) : base(resourceName) { - string key = GetKeyName(Keywords.MinPoolSize); - throw new ArgumentOutOfRangeException( - key, String.Format(resman.GetString("Exception_IntegerKeyValMax"), key, MaxPoolSize)); + try + { + string value = resman.GetString(resourceName); + if (value != null) + DescriptionValue = value; + } + catch (Exception e) + { + } } } - #region Parsing Functions - - private static SslMode ToSslMode(object value) + private sealed class NpgsqlEnumConverter : EnumConverter { - if (value is SslMode) + public NpgsqlEnumConverter() : base(typeof(T)) { } + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { - return (SslMode) value; + return value.ToString(); } - else + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { - return (SslMode) Enum.Parse(typeof (SslMode), value.ToString(), true); + return value.ToString(); } } - private static ProtocolVersion ToProtocolVersion(object value) + static NpgsqlConnectionStringBuilder() { - if (value is ProtocolVersion) - { - return (ProtocolVersion) value; - } - else + try { - int ver = Convert.ToInt32(value); - - switch (ver) + foreach (PropertyInfo prop in typeof(NpgsqlConnectionStringBuilder).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { - case 2: - return ProtocolVersion.Version2; - case 3: - return ProtocolVersion.Version3; - default: - throw new InvalidCastException(value.ToString()); + NpgsqlConnectionStringKeywordAttribute current_keywordattr = null; + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringKeywordAttribute))) + current_keywordattr = (NpgsqlConnectionStringKeywordAttribute)attr; + if (current_keywordattr == null) + continue; + if (!current_keywordattr.IsInternal) + props[current_keywordattr.Keyword] = prop; + keyword_mappings[current_keywordattr.Keyword.ToString()] = current_keywordattr.Keyword; + keyword_mappings[current_keywordattr.Keyword.ToString().ToUpperInvariant()] = current_keywordattr.Keyword; + keyword_mappings[current_keywordattr.Keyword.ToString().ToLowerInvariant()] = current_keywordattr.Keyword; + keyword_mappings[current_keywordattr.UnderlyingConnectionKeyword] = current_keywordattr.Keyword; + keyword_mappings[current_keywordattr.UnderlyingConnectionKeyword.ToUpperInvariant()] = current_keywordattr.Keyword; + keyword_mappings[current_keywordattr.UnderlyingConnectionKeyword.ToLowerInvariant()] = current_keywordattr.Keyword; + underlying_keywords[current_keywordattr.Keyword] = current_keywordattr.UnderlyingConnectionKeyword; + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringAcceptableKeywordAttribute))) + keyword_mappings[((NpgsqlConnectionStringAcceptableKeywordAttribute)attr).Keyword] = current_keywordattr.Keyword; + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringDisplayNameAttribute))) + { + keyword_mappings[((NpgsqlConnectionStringDisplayNameAttribute)attr).DisplayName] = current_keywordattr.Keyword; + prop_key[current_keywordattr.UnderlyingConnectionKeyword] = ((NpgsqlConnectionStringDisplayNameAttribute)attr).DisplayName; + } + foreach (Attribute attr in prop.GetCustomAttributes(typeof(DefaultValueAttribute))) + defaults[current_keywordattr.Keyword] = ((DefaultValueAttribute)attr).Value; } + defaults[Keywords.Protocol] = ProtocolVersion.Version3.ToString(); + defaults[Keywords.SslMode] = SslMode.Disable.ToString(); + defaults[Keywords.Compatible] = THIS_VERSION.ToString(); + } + catch (Exception ex) + { } } - private static string ToString(ProtocolVersion protocolVersion) + public NpgsqlConnectionStringBuilder() { - switch (protocolVersion) + this.Clear(); + } + + public NpgsqlConnectionStringBuilder(string connectionString) + { + this.Clear(); + base.ConnectionString = connectionString; + CheckValues(); + } + + /// + /// Return an exact copy of this NpgsqlConnectionString. + /// + public NpgsqlConnectionStringBuilder Clone() + { + return new NpgsqlConnectionStringBuilder(this.ConnectionString); + } + + private void CheckValues() + { + if ((MaxPoolSize > 0) && (MinPoolSize > MaxPoolSize)) { - case ProtocolVersion.Version2: - return "2"; - case ProtocolVersion.Version3: - return "3"; - default: - return string.Empty; + string key = underlying_keywords[Keywords.MinPoolSize]; + throw new ArgumentOutOfRangeException( + key, String.Format(resman.GetString("Exception_IntegerKeyValMax"), key, MaxPoolSize)); } } + #region Parsing Functions + private static int ToInt32(object value, int min, int max, string key) { int v = Convert.ToInt32(value); @@ -179,139 +223,141 @@ private static int ToInt32(object value, int min, int max, string key) return v; } - private static Boolean ToBoolean(object value) - { - string text = value as string; - - if (text != null) - { - switch (text.ToLowerInvariant()) - { - case "t": - case "true": - case "y": - case "yes": - return true; - case "f": - case "false": - case "n": - case "no": - return false; - default: - throw new InvalidCastException(value.ToString()); - } - } - else - { - return Convert.ToBoolean(value); - } - } - - private Boolean ToIntegratedSecurity(object value) - { - string text = value as string; - if (text != null) - { - switch (text.ToLowerInvariant()) - { - case "t": - case "true": - case "y": - case "yes": - case "sspi": - return true; - - case "f": - case "false": - case "n": - case "no": - return false; - - default: - throw new InvalidCastException(value.ToString()); - } - } - else - { - return Convert.ToBoolean(value); - } - } - #endregion #region Properties - private string _host; + [NpgsqlConnectionStringCategory("DataCategory_Source")] + [NpgsqlConnectionStringKeyword(Keywords.Host)] + [NpgsqlConnectionStringAcceptableKeyword("SERVER")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Host")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Host")] + [RefreshProperties(RefreshProperties.All)] public string Host { - get { return _host; } - set { SetValue(GetKeyName(Keywords.Host), value); } + get { return (string) GetValue(Keywords.Host); } + set { SetValue(Keywords.Host, value); } } - private int _port; + [NpgsqlConnectionStringCategory("DataCategory_Source")] + [NpgsqlConnectionStringKeyword(Keywords.Port)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Port")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Port")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(5432)] public int Port { - get { return _port; } - set { SetValue(GetKeyName(Keywords.Port), value); } + get { return (int)GetValue(Keywords.Port); } + set { SetValue(Keywords.Port, value); } + } + + [Browsable(false)] + internal ProtocolVersion Protocol + { + get { return (ProtocolVersion)Enum.Parse(typeof(ProtocolVersion), ProtocolAsString); } + set { ProtocolAsString = value.ToString(); } } - private ProtocolVersion _protocol; - public ProtocolVersion Protocol + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.Protocol)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Protocol")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Protocol")] + [RefreshProperties(RefreshProperties.All)] + [TypeConverter(typeof(NpgsqlEnumConverter))] + public string ProtocolAsString { - get { return _protocol; } - set { SetValue(GetKeyName(Keywords.Protocol), value); } + get { return (string)base[underlying_keywords[Keywords.Protocol]]; } + set { SetValue(Keywords.Protocol, value); } } - private string _database; + [NpgsqlConnectionStringCategory("DataCategory_Source")] + [NpgsqlConnectionStringKeyword(Keywords.Database)] + [NpgsqlConnectionStringAcceptableKeyword("DB")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Database")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Database")] + [RefreshProperties(RefreshProperties.All)] public string Database { - get { return _database; } - set { SetValue(GetKeyName(Keywords.Database), value); } + get { return (string)GetValue(Keywords.Database); } + set { SetValue(Keywords.Database, value); } } - private string _username; + [NpgsqlConnectionStringCategory("DataCategory_Security")] + [NpgsqlConnectionStringKeyword(Keywords.UserName, "USER ID")] + [NpgsqlConnectionStringAcceptableKeyword("USER NAME")] + [NpgsqlConnectionStringAcceptableKeyword("USERID")] + [NpgsqlConnectionStringAcceptableKeyword("USER ID")] + [NpgsqlConnectionStringAcceptableKeyword("UID")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_UserName")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_UserName")] + [RefreshProperties(RefreshProperties.All)] public string UserName { get { - if ((_integrated_security) && (String.IsNullOrEmpty(_username))) + if (IntegratedSecurity && (String.IsNullOrEmpty((string)GetValue(Keywords.UserName)))) { System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); - _username = identity.Name.Split('\\')[1]; + return identity.Name.Split('\\')[1]; } - return _username; + return (string) GetValue(Keywords.UserName); } - - set { SetValue(GetKeyName(Keywords.UserName), value); } + set { SetValue(Keywords.UserName, value); } } - private byte[] _password; + [Browsable(false)] public byte[] PasswordAsByteArray { - get { return _password; } - set { _password = value; } + get { return System.Text.Encoding.UTF8.GetBytes((string)base[Keywords.Password.ToString()]); } } + + [NpgsqlConnectionStringCategory("DataCategory_Security")] + [NpgsqlConnectionStringKeyword(Keywords.Password)] + [NpgsqlConnectionStringAcceptableKeyword("PSW")] + [NpgsqlConnectionStringAcceptableKeyword("PWD")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Password")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Password")] + [RefreshProperties(RefreshProperties.All)] + [PasswordPropertyText(true)] public string Password { - get { return String.Empty; } - set { SetValue(GetKeyName(Keywords.Password), value); } + get { return (string)GetValue(Keywords.Password); } + set { SetValue(Keywords.Password, value); } } - private bool _ssl; + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.SSL)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_SSL")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_SSL")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(false)] public bool SSL { - get { return _ssl; } - set { SetValue(GetKeyName(Keywords.SSL), value); } + get { return (bool)GetValue(Keywords.SSL); } + set { SetValue(Keywords.SSL, value); } + } + + [Browsable(false)] + internal SslMode SslMode + { + get { return (SslMode)Enum.Parse(typeof(SslMode), SslModeAsString); } + set { SslModeAsString = value.ToString(); } } - private SslMode _sslmode; - public SslMode SslMode + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.SslMode)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_SslMode")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_SslMode")] + [RefreshProperties(RefreshProperties.All)] + [TypeConverter(typeof(NpgsqlEnumConverter))] + public string SslModeAsString { - get { return _sslmode; } - set { SetValue(GetKeyName(Keywords.SslMode), value); } + get { return (string)base[underlying_keywords[Keywords.SslMode]]; } + set { SetValue(Keywords.SslMode, value); } } + [Browsable(false)] [Obsolete("UTF-8 is always used regardless of this setting.")] public string Encoding { @@ -319,92 +365,152 @@ public string Encoding //set { } } - private int _timeout; + [NpgsqlConnectionStringCategory("DataCategory_Initialization")] + [NpgsqlConnectionStringKeyword(Keywords.Timeout)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Timeout")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Timeout")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(15)] public int Timeout { - get { return _timeout; } - set { SetValue(GetKeyName(Keywords.Timeout), value); } + get { return (int)GetValue(Keywords.Timeout); } + set { SetValue(Keywords.Timeout, ToInt32(value, 0, TIMEOUT_LIMIT, Keywords.Timeout.ToString())); } } - private string _searchpath; + [NpgsqlConnectionStringCategory("DataCategory_Context")] + [NpgsqlConnectionStringKeyword(Keywords.SearchPath)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_SearchPath")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_SearchPath")] + [RefreshProperties(RefreshProperties.All)] public string SearchPath { - get { return _searchpath; } - set { SetValue(GetKeyName(Keywords.SearchPath), value); } + get { return (string)GetValue(Keywords.SearchPath); } + set { SetValue(Keywords.SearchPath, value); } } - private bool _pooling; + [NpgsqlConnectionStringCategory("DataCategory_Pooling")] + [NpgsqlConnectionStringKeyword(Keywords.Pooling)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Pooling")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Pooling")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(true)] public bool Pooling { - get { return _pooling; } - set { SetValue(GetKeyName(Keywords.Pooling), value); } + get { return (bool)GetValue(Keywords.Pooling); } + set { SetValue(Keywords.Pooling, value); } } - private int _connection_life_time; + [NpgsqlConnectionStringCategory("DataCategory_Pooling")] + [NpgsqlConnectionStringKeyword(Keywords.ConnectionLifeTime)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_ConnectionLifeTime")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_ConnectionLifeTime")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(15)] public int ConnectionLifeTime { - get { return _connection_life_time; } - set { SetValue(GetKeyName(Keywords.ConnectionLifeTime), value); } + get { return (int)GetValue(Keywords.ConnectionLifeTime); } + set { SetValue(Keywords.ConnectionLifeTime, value); } } - private int _min_pool_size; + [NpgsqlConnectionStringCategory("DataCategory_Pooling")] + [NpgsqlConnectionStringKeyword(Keywords.MinPoolSize)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_MinPoolSize")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_MinPoolSize")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(1)] public int MinPoolSize { - get { return _min_pool_size; } - set { SetValue(GetKeyName(Keywords.MinPoolSize), value); } + get { return (int)GetValue(Keywords.MinPoolSize); } + set { SetValue(Keywords.MinPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MinPoolSize.ToString())); } } - private int _max_pool_size; + [NpgsqlConnectionStringCategory("DataCategory_Pooling")] + [NpgsqlConnectionStringKeyword(Keywords.MaxPoolSize)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_MaxPoolSize")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_MaxPoolSize")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(20)] public int MaxPoolSize { - get { return _max_pool_size; } - set { SetValue(GetKeyName(Keywords.MaxPoolSize), value); } + get { return (int)GetValue(Keywords.MaxPoolSize); } + set { SetValue(Keywords.MaxPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MaxPoolSize.ToString())); } } - private bool _sync_notification; + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.SyncNotification)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_SyncNotification")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_SyncNotification")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(false)] public bool SyncNotification { - get { return _sync_notification; } - set { SetValue(GetKeyName(Keywords.SyncNotification), value); } + get { return (bool)GetValue(Keywords.SyncNotification); } + set { SetValue(Keywords.SyncNotification, value); } } - private int _command_timeout; + [NpgsqlConnectionStringCategory("DataCategory_Initialization")] + [NpgsqlConnectionStringKeyword(Keywords.CommandTimeout)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_CommandTimeout")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_CommandTimeout")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(20)] public int CommandTimeout { - get { return _command_timeout; } - set { SetValue(GetKeyName(Keywords.CommandTimeout), value); } + get { return (int)GetValue(Keywords.CommandTimeout); } + set { SetValue(Keywords.CommandTimeout, value); } } - private bool _enlist; + [NpgsqlConnectionStringCategory("DataCategory_Pooling")] + [NpgsqlConnectionStringKeyword(Keywords.Enlist)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Enlist")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Enlist")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(true)] public bool Enlist { - get { return _enlist; } - set { SetValue(GetKeyName(Keywords.Enlist), value); } + get { return (bool)GetValue(Keywords.Enlist); } + set { SetValue(Keywords.Enlist, value); } } - private bool _preloadReader; + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.PreloadReader)] + [NpgsqlConnectionStringAcceptableKeyword("PRELOAD READER")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_PreloadReader")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_PreloadReader")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(true)] public bool PreloadReader { - get { return _preloadReader; } - set { SetValue(GetKeyName(Keywords.PreloadReader), value); } + get { return (bool)GetValue(Keywords.PreloadReader); } + set { SetValue(Keywords.PreloadReader, value); } } - private bool _useExtendedTypes; + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.UseExtendedTypes)] + [NpgsqlConnectionStringAcceptableKeyword("USE EXTENDED TYPES")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_UseExtendedTypes")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_UseExtendedTypes")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(true)] public bool UseExtendedTypes { - get { return _useExtendedTypes; } - set { SetValue(GetKeyName(Keywords.UseExtendedTypes), value); } + get { return (bool)GetValue(Keywords.UseExtendedTypes); } + set { SetValue(Keywords.UseExtendedTypes, value); } } - private bool _integrated_security; + [NpgsqlConnectionStringCategory("DataCategory_Security")] + [NpgsqlConnectionStringKeyword(Keywords.IntegratedSecurity)] + [NpgsqlConnectionStringAcceptableKeyword("INTEGRATED SECURITY")] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_IntegratedSecurity")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_IntegratedSecurity")] + [RefreshProperties(RefreshProperties.All)] + [DefaultValue(false)] public bool IntegratedSecurity { - get { return _integrated_security; } - set { SetValue(GetKeyName(Keywords.IntegratedSecurity), value); } + get { return (bool)GetValue(Keywords.IntegratedSecurity); } + set { SetValue(Keywords.IntegratedSecurity, value); } } - private Version _compatible; - private static readonly Version THIS_VERSION = MethodBase.GetCurrentMethod().DeclaringType.Assembly.GetName().Version; @@ -412,308 +518,145 @@ public bool IntegratedSecurity /// Compatibilty version. When possible, behaviour caused by breaking changes will be preserved /// if this version is less than that where the breaking change was introduced. /// - public Version Compatible - { - get { return _compatible; } - set { SetValue(GetKeyName(Keywords.Compatible), value); } - } - - - private string _application_name; + [Browsable(false)] + internal Version Compatible + { + get { return Version.Parse(CompatibleAsString); } + set { CompatibleAsString = value.ToString(); } + } + + [NpgsqlConnectionStringCategory("DataCategory_Advanced")] + [NpgsqlConnectionStringKeyword(Keywords.Compatible)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_Compatible")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_Compatible")] + [RefreshProperties(RefreshProperties.All)] + [ReadOnly(true)] + internal string CompatibleAsString + { + get { return (string)base[underlying_keywords[Keywords.Compatible]]; } + set { SetValue(Keywords.Compatible, value); } + } + + [NpgsqlConnectionStringCategory("DataCategory_Context")] + [NpgsqlConnectionStringKeyword(Keywords.ApplicationName)] + [NpgsqlConnectionStringDisplayName("ConnectionProperty_Display_ApplicationName")] + [NpgsqlConnectionStringDescription("ConnectionProperty_Description_ApplicationName")] + [RefreshProperties(RefreshProperties.All)] public string ApplicationName { - get { return _application_name; } - set { SetValue(GetKeyName(Keywords.ApplicationName), value); } + get { return (string)GetValue(Keywords.ApplicationName); } + set { SetValue(Keywords.ApplicationName, value); } } #endregion - private static Keywords GetKey(string key) + internal static object GetDefaultValue(Keywords keyword) { - switch (key.ToUpperInvariant()) - { - case "HOST": - case "SERVER": - return Keywords.Host; - case "PORT": - return Keywords.Port; - case "PROTOCOL": - return Keywords.Protocol; - case "DATABASE": - case "DB": - return Keywords.Database; - case "USERNAME": - case "USER NAME": - case "USER": - case "USERID": - case "USER ID": - case "UID": - return Keywords.UserName; - case "PASSWORD": - case "PSW": - case "PWD": - return Keywords.Password; - case "SSL": - return Keywords.SSL; - case "SSLMODE": - return Keywords.SslMode; - case "ENCODING": -#pragma warning disable 618 - return Keywords.Encoding; -#pragma warning restore 618 - case "TIMEOUT": - return Keywords.Timeout; - case "SEARCHPATH": - return Keywords.SearchPath; - case "POOLING": - return Keywords.Pooling; - case "CONNECTIONLIFETIME": - return Keywords.ConnectionLifeTime; - case "MINPOOLSIZE": - return Keywords.MinPoolSize; - case "MAXPOOLSIZE": - return Keywords.MaxPoolSize; - case "SYNCNOTIFICATION": - return Keywords.SyncNotification; - case "COMMANDTIMEOUT": - return Keywords.CommandTimeout; - case "ENLIST": - return Keywords.Enlist; - case "PRELOADREADER": - case "PRELOAD READER": - return Keywords.PreloadReader; - case "USEEXTENDEDTYPES": - case "USE EXTENDED TYPES": - return Keywords.UseExtendedTypes; - case "INTEGRATED SECURITY": - return Keywords.IntegratedSecurity; - case "COMPATIBLE": - return Keywords.Compatible; - case "APPLICATIONNAME": - return Keywords.ApplicationName; - default: - throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), key); - } + object obj; + defaults.TryGetValue(keyword, out obj); + return obj; } - internal static string GetKeyName(Keywords keyword) + /// + /// Case insensative accessor for indivual connection string values. + /// + public override object this[string keyword] { - switch (keyword) + get { - case Keywords.Host: - return "HOST"; - case Keywords.Port: - return "PORT"; - case Keywords.Protocol: - return "PROTOCOL"; - case Keywords.Database: - return "DATABASE"; - case Keywords.UserName: - return "USER ID"; - case Keywords.Password: - return "PASSWORD"; - case Keywords.SSL: - return "SSL"; - case Keywords.SslMode: - return "SSLMODE"; -#pragma warning disable 618 - case Keywords.Encoding: -#pragma warning restore 618 - return "ENCODING"; - case Keywords.Timeout: - return "TIMEOUT"; - case Keywords.SearchPath: - return "SEARCHPATH"; - case Keywords.Pooling: - return "POOLING"; - case Keywords.ConnectionLifeTime: - return "CONNECTIONLIFETIME"; - case Keywords.MinPoolSize: - return "MINPOOLSIZE"; - case Keywords.MaxPoolSize: - return "MAXPOOLSIZE"; - case Keywords.SyncNotification: - return "SYNCNOTIFICATION"; - case Keywords.CommandTimeout: - return "COMMANDTIMEOUT"; - case Keywords.Enlist: - return "ENLIST"; - case Keywords.PreloadReader: - return "PRELOADREADER"; - case Keywords.UseExtendedTypes: - return "USEEXTENDEDTYPES"; - case Keywords.IntegratedSecurity: - return "INTEGRATED SECURITY"; - case Keywords.Compatible: - return "COMPATIBLE"; - default: - return keyword.ToString().ToUpperInvariant(); + if (!keyword_mappings.ContainsKey(keyword)) + throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword); + return this[keyword_mappings[keyword]]; + } + set + { + if (!keyword_mappings.ContainsKey(keyword)) + throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword); + this[keyword_mappings[keyword]] = value; } } - internal static object GetDefaultValue(Keywords keyword) + public object this[Keywords keyword] { - return defaults[keyword]; + get { return props[keyword].GetValue(this); } + set { + try + { + if (props[keyword].PropertyType == value.GetType()) + props[keyword].SetValue(this, value); + else + props[keyword].SetValue(this, TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(value)); + } + catch (Exception ex) + { + ex = ex; + } + } } - /// - /// Case insensative accessor for indivual connection string values. - /// - public override object this[string keyword] + public override bool Remove(string keyword) { - get { return this[GetKey(keyword)]; } - set { this[GetKey(keyword)] = value; } + Keywords k; + if (keyword_mappings.TryGetValue(keyword, out k)) + Remove(k); + return false; } - public object this[Keywords keyword] + public bool Remove(Keywords keyword) { - get { return base[GetKeyName(keyword)]; } - set { SetValue(GetKeyName(keyword), value); } + return base.Remove(underlying_keywords[keyword]); } - public override bool Remove(string keyword) + public override bool ContainsKey(string keyword) { - Keywords key = GetKey(keyword); - SetValue(key, defaults[key]); - return base.Remove(keyword); + if (keyword_mappings.ContainsKey(keyword)) + return ContainsKey(keyword_mappings[keyword]); + return false; } public bool ContainsKey(Keywords keyword) { - return base.ContainsKey(GetKeyName(keyword)); + return base.ContainsKey(underlying_keywords[keyword]); } - /// - /// This function will set value for known key, both private member and base[key]. - /// - /// - /// - private void SetValue(string keyword, object value) + /*public override ICollection Keys { - if (value == null) - { - Remove(keyword); - return; - } - - string strValue = value as string; - if (strValue != null) + get { - // .NET's DbConnectionStringBuilder trims whitespace and discards empty values, - // so we do the same - strValue = strValue.Trim(); - if (strValue.Length == 0) - { - Remove(keyword); - return; - } - value = strValue; + ICollection list = new List(); + foreach (object o in base.Keys) + list.Add(prop_key[o.ToString()]); + return (ICollection) list; } + }*/ - Keywords key = GetKey(keyword); - SetValue(key, value); - if (key == Keywords.Protocol) - { - base[GetKeyName(key)] = ToString(this.Protocol); - } - else if (key == Keywords.Compatible) - { - base[GetKeyName(key)] = ((Version) this.Compatible).ToString(); - } - else - { - base[GetKeyName(key)] = value; - } + public override bool TryGetValue(string keyword, out object value) + { + value = null; + if (keyword_mappings.ContainsKey(keyword)) + return base.TryGetValue(underlying_keywords[keyword_mappings[keyword]], out value); + return false; } /// - /// The function will modify private member only, not base[key]. /// /// /// private void SetValue(Keywords keyword, object value) { - string key_name = GetKeyName(keyword); - + string key_name = underlying_keywords[keyword]; try { - switch (keyword) + string value2 = value as string; + if (value2 != null) { - case Keywords.Host: - this._host = Convert.ToString(value); - break; - case Keywords.Port: - this._port = Convert.ToInt32(value); - break; - case Keywords.Protocol: - this._protocol = ToProtocolVersion(value); - break; - case Keywords.Database: - this._database = Convert.ToString(value); - break; - case Keywords.UserName: - this._username = Convert.ToString(value); - break; - case Keywords.Password: - this._password = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(value)); - break; - case Keywords.SSL: - this._ssl = ToBoolean(value); - break; - case Keywords.SslMode: - this._sslmode = ToSslMode(value); - break; -#pragma warning disable 618 - case Keywords.Encoding: - break; -#pragma warning restore 618 - case Keywords.Timeout: - this._timeout = ToInt32(value, 0, TIMEOUT_LIMIT, key_name); - break; - case Keywords.SearchPath: - this._searchpath = Convert.ToString(value); - break; - case Keywords.Pooling: - this._pooling = ToBoolean(value); - break; - case Keywords.ConnectionLifeTime: - this._connection_life_time = Convert.ToInt32(value); - break; - case Keywords.MinPoolSize: - this._min_pool_size = ToInt32(value, 0, POOL_SIZE_LIMIT, key_name); - break; - case Keywords.MaxPoolSize: - this._max_pool_size = ToInt32(value, 0, POOL_SIZE_LIMIT, key_name); - break; - case Keywords.SyncNotification: - this._sync_notification = ToBoolean(value); - break; - case Keywords.CommandTimeout: - this._command_timeout = Convert.ToInt32(value); - break; - case Keywords.Enlist: - this._enlist = ToBoolean(value); - break; - case Keywords.PreloadReader: - this._preloadReader = ToBoolean(value); - break; - case Keywords.UseExtendedTypes: - this._useExtendedTypes = ToBoolean(value); - break; - case Keywords.IntegratedSecurity: - this._integrated_security = ToIntegratedSecurity(value); - break; - case Keywords.Compatible: - Version ver = new Version(value.ToString()); - if (ver > THIS_VERSION) - throw new ArgumentException("Attempt to set compatibility with version " + value + - " when using version " + THIS_VERSION); - _compatible = ver; - break; - case Keywords.ApplicationName: - this._application_name = Convert.ToString(value); - break; + value2 = value2.Trim(); + if (String.IsNullOrEmpty(value2)) + value = null; + else + value = value2; } + base[key_name] = value; } catch (InvalidCastException exception) { @@ -748,6 +691,10 @@ private void SetValue(Keywords keyword, object value) } } + private object GetValue(Keywords keyword) + { + return TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(base[underlying_keywords[keyword]]); + } /// /// Clear the member and assign them to the default value. @@ -756,10 +703,8 @@ public override void Clear() { base.Clear(); - foreach (Keywords keyword in defaults.Keys) - { - SetValue(GetKeyName(keyword), defaults[keyword]); - } + foreach (KeyValuePair pair in defaults) + this[pair.Key] = pair.Value; } } diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.resx b/src/Npgsql/NpgsqlConnectionStringBuilder.resx index d9bd0d2da4..4c8a493f0c 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.resx +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.resx @@ -1,9 +1,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - key=value argument incorrect in ConnectionString - - - expecting {0}=[True/False] value in ConnectionString - - - expecting {0}=[Numeric] value in ConnectionString - - - numeric value {0} in ConnectionString exceeds maximum value {1} - - - numeric value {0} in ConnectionString is below minimum value {1} - - - expecting {0}=[Protocol Version] value in ConnectionString - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + key=value argument incorrect in ConnectionString + + + expecting {0}=[True/False] value in ConnectionString + + + expecting {0}=[Numeric] value in ConnectionString + + + numeric value {0} in ConnectionString exceeds maximum value {1} + + + numeric value {0} in ConnectionString is below minimum value {1} + + + expecting {0}=[Protocol Version] value in ConnectionString + + + Advanced + + + Context + + + Initialization + + + Pooling + + + Security + + + Data Source + + + Host + + + Host + + + Port + + + Port + + + Protocol Version + + + Protocol Version + + + Database + + + Database + + + Username + + + Username + + + Password + + + Password + + + SSL + + + SSL + + + SSL Mode + + + SSL Mode + + + Timeout + + + Timeout + + + SearchPath + + + SearchPath + + + Pooling + + + Pooling + + + ConnectionLifeTime + + + ConnectionLifeTime + + + MinPoolSize + + + MinPoolSize + + + MaxPoolSize + + + MaxPoolSize + + + SyncNotification + + + SyncNotification + + + CommandTimeout + + + CommandTimeout + + + Enlist + + + Enlist + + + PreloadReader + + + PreloadReader + + + UseExtendedTypes + + + UseExtendedTypes + + + IntegratedSecurity + + + IntegratedSecurity + + + Npgsql Compatibility + + + Npgsql Compatibility + + + ApplicationName + + + ApplicationName + + \ No newline at end of file diff --git a/src/Npgsql/NpgsqlConnector.cs b/src/Npgsql/NpgsqlConnector.cs index 6855898063..025088f5e0 100644 --- a/src/Npgsql/NpgsqlConnector.cs +++ b/src/Npgsql/NpgsqlConnector.cs @@ -789,7 +789,7 @@ internal void Open() ) new NpgsqlCommand("SET CLIENT_ENCODING TO UTF8", this).ExecuteBlind(); - if (!string.IsNullOrEmpty(settings.SearchPath)) + if (settings.ContainsKey(Keywords.SearchPath)) { /*NpgsqlParameter p = new NpgsqlParameter("p", DbType.String); p.Value = settings.SearchPath; @@ -817,7 +817,7 @@ internal void Open() commandSearchPath.ExecuteBlind(); } - if (!string.IsNullOrEmpty(settings.ApplicationName)) + if (settings.ContainsKey(Keywords.ApplicationName)) { if (!SupportsApplicationName) { diff --git a/src/Npgsql/NpgsqlMetaData.xml b/src/Npgsql/NpgsqlMetaData.xml index 5c8b3ae5b4..780f5cea00 100644 --- a/src/Npgsql/NpgsqlMetaData.xml +++ b/src/Npgsql/NpgsqlMetaData.xml @@ -8,6 +8,7 @@ + @@ -51,7 +52,7 @@ - . + \. Npgsql 2 (^\[\p{Lo}\p{Lu}\p{Ll}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Nd}@$#_]*$)|(^\[[^\]\0]|\]\]+\]$)|(^\"[^\"\0]|\"\"+\"$) @@ -61,7 +62,7 @@ @[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$) 128 ^[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$) - "^(([^"]|"")*)$" + (^"([^"]|"")*"$) 2 ; '(([^']|'')*)' diff --git a/src/Npgsql/NpgsqlSchema.cs b/src/Npgsql/NpgsqlSchema.cs index a2e6583734..681e0cb952 100644 --- a/src/Npgsql/NpgsqlSchema.cs +++ b/src/Npgsql/NpgsqlSchema.cs @@ -191,7 +191,7 @@ internal static DataTable GetTables(NpgsqlConnection conn, string[] restrictions StringBuilder getTables = new StringBuilder(); - getTables.Append("SELECT table_catalog, table_schema, table_name, table_type FROM information_schema.tables"); + getTables.Append("SELECT * FROM (SELECT table_catalog, table_schema, table_name, table_type FROM information_schema.tables WHERE table_type = 'BASE TABLE') tmp"); using ( NpgsqlCommand command = From 2155b09510da20fc8a7340c9d198e60d0de8185c Mon Sep 17 00:00:00 2001 From: windcloud Date: Thu, 10 Oct 2013 22:52:22 +0800 Subject: [PATCH 3/5] DDEX: TableForeignKeyColumn ReferencedColumn not support yet, have to change GetSchema() Npgsql: Revert NpgsqlConnectionStringBuilder.resx to using 2.0 assembly Npgsql: Fix typo Keywords.Host to Keywords.UserName --- NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml | 4 ++-- src/Npgsql/NpgsqlConnection.cs | 2 +- src/Npgsql/NpgsqlConnectionStringBuilder.resx | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml index a18462c762..f9a8290b37 100644 --- a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml +++ b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml @@ -438,11 +438,11 @@ - + diff --git a/src/Npgsql/NpgsqlConnection.cs b/src/Npgsql/NpgsqlConnection.cs index 885f1311f6..5e0a2f905a 100644 --- a/src/Npgsql/NpgsqlConnection.cs +++ b/src/Npgsql/NpgsqlConnection.cs @@ -596,7 +596,7 @@ public override void Open() if (!settings.ContainsKey(Keywords.UserName) && !settings.ContainsKey(Keywords.IntegratedSecurity)) { throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"), - Keywords.Host.ToString()); + Keywords.UserName.ToString()); } // Get a Connector, either from the pool or creating one ourselves. diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.resx b/src/Npgsql/NpgsqlConnectionStringBuilder.resx index 4c8a493f0c..10d451e886 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.resx +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.resx @@ -87,9 +87,10 @@ - + + @@ -111,10 +112,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 key=value argument incorrect in ConnectionString From 0c27be513e2f33a1147a9da184876372145c1282 Mon Sep 17 00:00:00 2001 From: windcloud Date: Tue, 15 Oct 2013 14:43:25 +0800 Subject: [PATCH 4/5] Npgsql - Fix NpgsqlConnectionStringBuilder to be compilable in .NET 2.0 Npgsql - Make it so that custom property (Protocol, SslMode, Compatible, etc) to throw an error if invalid string is passed. --- src/Npgsql/NpgsqlConnectionStringBuilder.cs | 33 +++++++-------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.cs b/src/Npgsql/NpgsqlConnectionStringBuilder.cs index e41551d1c4..88cdb03c62 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.cs +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.cs @@ -141,7 +141,7 @@ static NpgsqlConnectionStringBuilder() foreach (PropertyInfo prop in typeof(NpgsqlConnectionStringBuilder).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { NpgsqlConnectionStringKeywordAttribute current_keywordattr = null; - foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringKeywordAttribute))) + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringKeywordAttribute), false)) current_keywordattr = (NpgsqlConnectionStringKeywordAttribute)attr; if (current_keywordattr == null) continue; @@ -154,14 +154,14 @@ static NpgsqlConnectionStringBuilder() keyword_mappings[current_keywordattr.UnderlyingConnectionKeyword.ToUpperInvariant()] = current_keywordattr.Keyword; keyword_mappings[current_keywordattr.UnderlyingConnectionKeyword.ToLowerInvariant()] = current_keywordattr.Keyword; underlying_keywords[current_keywordattr.Keyword] = current_keywordattr.UnderlyingConnectionKeyword; - foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringAcceptableKeywordAttribute))) + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringAcceptableKeywordAttribute), false)) keyword_mappings[((NpgsqlConnectionStringAcceptableKeywordAttribute)attr).Keyword] = current_keywordattr.Keyword; - foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringDisplayNameAttribute))) + foreach (Attribute attr in prop.GetCustomAttributes(typeof(NpgsqlConnectionStringDisplayNameAttribute), false)) { keyword_mappings[((NpgsqlConnectionStringDisplayNameAttribute)attr).DisplayName] = current_keywordattr.Keyword; prop_key[current_keywordattr.UnderlyingConnectionKeyword] = ((NpgsqlConnectionStringDisplayNameAttribute)attr).DisplayName; } - foreach (Attribute attr in prop.GetCustomAttributes(typeof(DefaultValueAttribute))) + foreach (Attribute attr in prop.GetCustomAttributes(typeof(DefaultValueAttribute), true)) defaults[current_keywordattr.Keyword] = ((DefaultValueAttribute)attr).Value; } defaults[Keywords.Protocol] = ProtocolVersion.Version3.ToString(); @@ -267,7 +267,7 @@ internal ProtocolVersion Protocol public string ProtocolAsString { get { return (string)base[underlying_keywords[Keywords.Protocol]]; } - set { SetValue(Keywords.Protocol, value); } + set { SetValue(Keywords.Protocol, Enum.Parse(typeof(ProtocolVersion), value).ToString()); } } [NpgsqlConnectionStringCategory("DataCategory_Source")] @@ -354,7 +354,7 @@ internal SslMode SslMode public string SslModeAsString { get { return (string)base[underlying_keywords[Keywords.SslMode]]; } - set { SetValue(Keywords.SslMode, value); } + set { SetValue(Keywords.SslMode, Enum.Parse(typeof(SslMode), value).ToString()); } } [Browsable(false)] @@ -521,7 +521,7 @@ public bool IntegratedSecurity [Browsable(false)] internal Version Compatible { - get { return Version.Parse(CompatibleAsString); } + get { return new Version(CompatibleAsString); } set { CompatibleAsString = value.ToString(); } } @@ -534,7 +534,7 @@ internal Version Compatible internal string CompatibleAsString { get { return (string)base[underlying_keywords[Keywords.Compatible]]; } - set { SetValue(Keywords.Compatible, value); } + set { SetValue(Keywords.Compatible, new Version(value).ToString()); } } [NpgsqlConnectionStringCategory("DataCategory_Context")] @@ -578,14 +578,14 @@ public override object this[string keyword] public object this[Keywords keyword] { - get { return props[keyword].GetValue(this); } + get { return props[keyword].GetValue(this, null); } set { try { if (props[keyword].PropertyType == value.GetType()) - props[keyword].SetValue(this, value); + props[keyword].SetValue(this, value, null); else - props[keyword].SetValue(this, TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(value)); + props[keyword].SetValue(this, TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(value), null); } catch (Exception ex) { @@ -619,17 +619,6 @@ public bool ContainsKey(Keywords keyword) return base.ContainsKey(underlying_keywords[keyword]); } - /*public override ICollection Keys - { - get - { - ICollection list = new List(); - foreach (object o in base.Keys) - list.Add(prop_key[o.ToString()]); - return (ICollection) list; - } - }*/ - public override bool TryGetValue(string keyword, out object value) { value = null; From 27d7c6f1de6cec8dc27905fe58c4020ff5998fc5 Mon Sep 17 00:00:00 2001 From: windcloud Date: Sun, 27 Oct 2013 11:45:12 +0800 Subject: [PATCH 5/5] Make NpgsqlConnectionBuilder to throw the inner exception instead of TargetInvokeException when parsing invalid value Fix MinPoolSize/MaxPoolSize check Make NpgsqlConnectionBuilder keyword case insensitive Fix GetSchema SQL on Contraints and ConstraintColumns when using restriction --- src/Npgsql/NpgsqlConnectionStringBuilder.cs | 52 ++++++++++++++------- src/Npgsql/NpgsqlSchema.cs | 8 ++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/Npgsql/NpgsqlConnectionStringBuilder.cs b/src/Npgsql/NpgsqlConnectionStringBuilder.cs index 88cdb03c62..4e108fa9e3 100644 --- a/src/Npgsql/NpgsqlConnectionStringBuilder.cs +++ b/src/Npgsql/NpgsqlConnectionStringBuilder.cs @@ -51,6 +51,8 @@ public sealed class NpgsqlConnectionStringBuilder : DbConnectionStringBuilder private const int POOL_SIZE_LIMIT = 1024; private const int TIMEOUT_LIMIT = 1024; + private bool SuppressCheckValues = false; + [AttributeUsage(AttributeTargets.Property)] private sealed class NpgsqlConnectionStringKeywordAttribute : Attribute { @@ -181,8 +183,19 @@ public NpgsqlConnectionStringBuilder() public NpgsqlConnectionStringBuilder(string connectionString) { this.Clear(); - base.ConnectionString = connectionString; - CheckValues(); + this.ConnectionString = connectionString; + } + + new public string ConnectionString + { + get { return base.ConnectionString; } + set + { + SuppressCheckValues = true; + base.ConnectionString = value; + SuppressCheckValues = false; + CheckValues(); + } } /// @@ -195,6 +208,10 @@ public NpgsqlConnectionStringBuilder Clone() private void CheckValues() { + // At Initialization, not all default properties are set, ignore for the moment + if (SuppressCheckValues || !ContainsKey(Keywords.MinPoolSize) || !ContainsKey(Keywords.MaxPoolSize)) + return; + if ((MaxPoolSize > 0) && (MinPoolSize > MaxPoolSize)) { string key = underlying_keywords[Keywords.MinPoolSize]; @@ -421,7 +438,7 @@ public int ConnectionLifeTime public int MinPoolSize { get { return (int)GetValue(Keywords.MinPoolSize); } - set { SetValue(Keywords.MinPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MinPoolSize.ToString())); } + set { SetValue(Keywords.MinPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MinPoolSize.ToString())); CheckValues(); } } [NpgsqlConnectionStringCategory("DataCategory_Pooling")] @@ -433,7 +450,7 @@ public int MinPoolSize public int MaxPoolSize { get { return (int)GetValue(Keywords.MaxPoolSize); } - set { SetValue(Keywords.MaxPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MaxPoolSize.ToString())); } + set { SetValue(Keywords.MaxPoolSize, ToInt32(value, 0, POOL_SIZE_LIMIT, Keywords.MaxPoolSize.ToString())); CheckValues(); } } [NpgsqlConnectionStringCategory("DataCategory_Advanced")] @@ -564,22 +581,23 @@ public override object this[string keyword] { get { - if (!keyword_mappings.ContainsKey(keyword)) + if (!keyword_mappings.ContainsKey(keyword.ToUpperInvariant())) throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword); - return this[keyword_mappings[keyword]]; + return this[keyword_mappings[keyword.ToUpperInvariant()]]; } set { - if (!keyword_mappings.ContainsKey(keyword)) + if (!keyword_mappings.ContainsKey(keyword.ToUpperInvariant())) throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword); - this[keyword_mappings[keyword]] = value; + this[keyword_mappings[keyword.ToUpperInvariant()]] = value; } } public object this[Keywords keyword] { get { return props[keyword].GetValue(this, null); } - set { + set + { try { if (props[keyword].PropertyType == value.GetType()) @@ -587,9 +605,9 @@ public object this[Keywords keyword] else props[keyword].SetValue(this, TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(value), null); } - catch (Exception ex) + catch (TargetInvocationException ex) { - ex = ex; + throw ex.InnerException; } } } @@ -597,8 +615,8 @@ public object this[Keywords keyword] public override bool Remove(string keyword) { Keywords k; - if (keyword_mappings.TryGetValue(keyword, out k)) - Remove(k); + if (keyword_mappings.TryGetValue(keyword.ToUpperInvariant(), out k)) + return Remove(k); return false; } @@ -609,8 +627,8 @@ public bool Remove(Keywords keyword) public override bool ContainsKey(string keyword) { - if (keyword_mappings.ContainsKey(keyword)) - return ContainsKey(keyword_mappings[keyword]); + if (keyword_mappings.ContainsKey(keyword.ToUpperInvariant())) + return ContainsKey(keyword_mappings[keyword.ToUpperInvariant()]); return false; } @@ -622,8 +640,8 @@ public bool ContainsKey(Keywords keyword) public override bool TryGetValue(string keyword, out object value) { value = null; - if (keyword_mappings.ContainsKey(keyword)) - return base.TryGetValue(underlying_keywords[keyword_mappings[keyword]], out value); + if (keyword_mappings.ContainsKey(keyword.ToUpperInvariant())) + return base.TryGetValue(underlying_keywords[keyword_mappings[keyword.ToUpperInvariant()]], out value); return false; } diff --git a/src/Npgsql/NpgsqlSchema.cs b/src/Npgsql/NpgsqlSchema.cs index 681e0cb952..2d7981bcce 100644 --- a/src/Npgsql/NpgsqlSchema.cs +++ b/src/Npgsql/NpgsqlSchema.cs @@ -427,11 +427,11 @@ inner join ( select 'UNIQUE KEY' ""CONSTRAINT_TYPE"", 'u' as ""contype"" ) mapping_table on mapping_table.contype = pgc.contype"); if ("ForeignKeys".Equals(constraint_type)) - getConstraints.Append("where pgc.contype='f'"); + getConstraints.Append(" and pgc.contype='f'"); else if ("PrimaryKey".Equals(constraint_type)) - getConstraints.Append("where pgc.contype='p'"); + getConstraints.Append(" and pgc.contype='p'"); else if ("UniqueKeys".Equals(constraint_type)) - getConstraints.Append("where pgc.contype='u'"); + getConstraints.Append(" and pgc.contype='u'"); else constraint_type = "Constraints"; using ( @@ -470,7 +470,7 @@ inner join ( select 'FOREIGN KEY' constraint_type, 'f' as contype union all select 'UNIQUE KEY' constraint_type, 'u' as contype ) mapping_table on mapping_table.contype = c.contype -where n.nspname not in ('pg_catalog', 'pg_toast')"); +and n.nspname not in ('pg_catalog', 'pg_toast')"); using ( NpgsqlCommand command =