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