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 0000000000..211cdc6adb
Binary files /dev/null and b/NpgsqlDdexProvider/Key.snk differ
diff --git a/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml
new file mode 100644
index 0000000000..f9a8290b37
--- /dev/null
+++ b/NpgsqlDdexProvider/NpgsqlDataObjectSupport.xml
@@ -0,0 +1,504 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs
new file mode 100644
index 0000000000..6557b257c7
--- /dev/null
+++ b/NpgsqlDdexProvider/NpgsqlDataProviderRegistration.cs
@@ -0,0 +1,53 @@
+using Microsoft.VisualStudio.Data.Services.SupportEntities;
+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(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");
+ 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..44bb48399d
--- /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..1ed35f1b03
--- /dev/null
+++ b/NpgsqlDdexProvider/NpgsqlDdexProvider.csproj
@@ -0,0 +1,251 @@
+
+
+
+ 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
+ true
+
+
+ pdbonly
+ true
+ bin\Release-net45\
+ TRACE;WINDOWS;UNMANAGED;NET35;NET40;NET45;ENTITIES
+ prompt
+ 4
+ bin\Release-net45\Npgsql.xml
+ v4.5
+ true
+
+
+ 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..eacfd66037
--- /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 0000000000..449296f495
Binary files /dev/null and b/NpgsqlDdexProvider/Resources/Package.ico differ
diff --git a/NpgsqlDdexProvider/VSPackage.resx b/NpgsqlDdexProvider/VSPackage.resx
new file mode 100644
index 0000000000..98a411c49c
--- /dev/null
+++ b/NpgsqlDdexProvider/VSPackage.resx
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 0eef897b71..a0375cc87e 100644
--- a/src/Npgsql.csproj
+++ b/src/Npgsql.csproj
@@ -176,6 +176,7 @@
+
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 f8ef238fc4..5e0a2f905a 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.UserName.ToString());
}
// Get a Connector, either from the pool or creating one ourselves.
@@ -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..4e108fa9e3 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,186 @@ 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()
+ private bool SuppressCheckValues = false;
+
+ [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)
+ try
{
- return (ProtocolVersion) value;
+ 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), false))
+ 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), false))
+ keyword_mappings[((NpgsqlConnectionStringAcceptableKeywordAttribute)attr).Keyword] = current_keywordattr.Keyword;
+ 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), true))
+ 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();
}
- else
+ catch (Exception ex)
{
- int ver = Convert.ToInt32(value);
+ }
+ }
- switch (ver)
- {
- case 2:
- return ProtocolVersion.Version2;
- case 3:
- return ProtocolVersion.Version3;
- default:
- throw new InvalidCastException(value.ToString());
- }
+ public NpgsqlConnectionStringBuilder()
+ {
+ this.Clear();
+ }
+
+ public NpgsqlConnectionStringBuilder(string connectionString)
+ {
+ this.Clear();
+ this.ConnectionString = connectionString;
+ }
+
+ new public string ConnectionString
+ {
+ get { return base.ConnectionString; }
+ set
+ {
+ SuppressCheckValues = true;
+ base.ConnectionString = value;
+ SuppressCheckValues = false;
+ CheckValues();
}
}
- private static string ToString(ProtocolVersion protocolVersion)
+ ///
+ /// Return an exact copy of this NpgsqlConnectionString.
+ ///
+ public NpgsqlConnectionStringBuilder Clone()
+ {
+ return new NpgsqlConnectionStringBuilder(this.ConnectionString);
+ }
+
+ private void CheckValues()
{
- switch (protocolVersion)
+ // 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))
{
- 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,138 +240,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, Enum.Parse(typeof(ProtocolVersion), value).ToString()); }
}
- 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
{
- 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, Enum.Parse(typeof(SslMode), value).ToString()); }
}
+ [Browsable(false)]
[Obsolete("UTF-8 is always used regardless of this setting.")]
public string Encoding
{
@@ -318,92 +382,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())); CheckValues(); }
}
- 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())); CheckValues(); }
}
- 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;
@@ -411,148 +535,43 @@ 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 new Version(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, new Version(value).ToString()); }
+ }
+
+ [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)
- {
- 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);
- }
- }
-
- internal static string GetKeyName(Keywords keyword)
- {
- switch (keyword)
- {
- 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();
- }
- }
-
internal static object GetDefaultValue(Keywords keyword)
{
- return defaults[keyword];
+ object obj;
+ defaults.TryGetValue(keyword, out obj);
+ return obj;
}
///
@@ -560,159 +579,91 @@ internal static object GetDefaultValue(Keywords keyword)
///
public override object this[string keyword]
{
- get { return this[GetKey(keyword)]; }
- set { this[GetKey(keyword)] = value; }
+ get
+ {
+ if (!keyword_mappings.ContainsKey(keyword.ToUpperInvariant()))
+ throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword);
+ return this[keyword_mappings[keyword.ToUpperInvariant()]];
+ }
+ set
+ {
+ if (!keyword_mappings.ContainsKey(keyword.ToUpperInvariant()))
+ throw new ArgumentException(resman.GetString("Exception_WrongKeyVal"), keyword);
+ this[keyword_mappings[keyword.ToUpperInvariant()]] = value;
+ }
}
public object this[Keywords keyword]
{
- get { return base[GetKeyName(keyword)]; }
- set { SetValue(GetKeyName(keyword), value); }
+ get { return props[keyword].GetValue(this, null); }
+ set
+ {
+ try
+ {
+ if (props[keyword].PropertyType == value.GetType())
+ props[keyword].SetValue(this, value, null);
+ else
+ props[keyword].SetValue(this, TypeDescriptor.GetConverter(props[keyword].PropertyType).ConvertFrom(value), null);
+ }
+ catch (TargetInvocationException ex)
+ {
+ throw ex.InnerException;
+ }
+ }
}
public override bool Remove(string keyword)
{
- Keywords key = GetKey(keyword);
- SetValue(key, defaults[key]);
- return base.Remove(keyword);
+ Keywords k;
+ if (keyword_mappings.TryGetValue(keyword.ToUpperInvariant(), out k))
+ return Remove(k);
+ return false;
}
- public bool ContainsKey(Keywords keyword)
+ public bool Remove(Keywords keyword)
{
- return base.ContainsKey(GetKeyName(keyword));
+ return base.Remove(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 bool ContainsKey(string keyword)
{
- if (value == null)
- {
- Remove(keyword);
- return;
- }
+ if (keyword_mappings.ContainsKey(keyword.ToUpperInvariant()))
+ return ContainsKey(keyword_mappings[keyword.ToUpperInvariant()]);
+ return false;
+ }
- string strValue = value as string;
- if (strValue != null)
- {
- // .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;
- }
+ public bool ContainsKey(Keywords keyword)
+ {
+ return base.ContainsKey(underlying_keywords[keyword]);
+ }
- 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.ToUpperInvariant()))
+ return base.TryGetValue(underlying_keywords[keyword_mappings[keyword.ToUpperInvariant()]], 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)
{
@@ -747,6 +698,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.
@@ -755,10 +710,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..10d451e886 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=2.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
+
+
+ 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 264085dd22..1ddaeb7991 100644
--- a/src/Npgsql/NpgsqlConnector.cs
+++ b/src/Npgsql/NpgsqlConnector.cs
@@ -794,7 +794,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;
@@ -822,7 +822,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/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..2d7981bcce 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.
///
@@ -162,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 =
@@ -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(" and pgc.contype='f'");
+ else if ("PrimaryKey".Equals(constraint_type))
+ getConstraints.Append(" and pgc.contype='p'");
+ else if ("UniqueKeys".Equals(constraint_type))
+ getConstraints.Append(" and 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
+and 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