From 5658b505bc46c2c9f8b50cfa73af2b88a31ccd23 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 15 Jul 2024 08:22:32 +0100 Subject: [PATCH 1/6] remove psql null db --- CHANGELOG.md | 4 ++++ .../PostgreSql/PostgreSqlServerHelper.cs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 427c41b9..10390784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +- Listing databases on Postgres now respects connection string database and timeout + ## [3.2.5] - 2024-06-07 - Bugfix for resource lifetime in ListDatabasesAsync, add unit tests diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs index 2be64744..8eaad2be 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs @@ -37,25 +37,25 @@ public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRunti using var con = new NpgsqlConnection(b.ConnectionString); con.Open(); - using var cmd = GetCommand($"CREATE DATABASE \"{newDatabaseName.GetRuntimeName()}\"",con); + using var cmd = GetCommand($"CREATE DATABASE \"{newDatabaseName.GetRuntimeName()}\"", con); cmd.CommandTimeout = CreateDatabaseTimeoutInSeconds; cmd.ExecuteNonQuery(); } public override Dictionary DescribeServer(DbConnectionStringBuilder builder) => throw new NotImplementedException(); - public override string? GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Username; + public override string? GetExplicitUsernameIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder)builder).Username; - public override string? GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder) builder).Password; + public override string? GetExplicitPasswordIfAny(DbConnectionStringBuilder builder) => ((NpgsqlConnectionStringBuilder)builder).Password; public override Version? GetVersion(DiscoveredServer server) { using var con = server.GetConnection(); con.Open(); - using var cmd = server.GetCommand("SHOW server_version",con); + using var cmd = server.GetCommand("SHOW server_version", con); using var r = cmd.ExecuteReader(); - if(r.Read()) - return r[0] == DBNull.Value ? null: CreateVersionFromString((string)r[0]); + if (r.Read()) + return r[0] == DBNull.Value ? null : CreateVersionFromString((string)r[0]); return null; } @@ -64,10 +64,10 @@ public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRunti public override IEnumerable ListDatabases(DbConnectionStringBuilder builder) { //create a copy so as not to corrupt the original + var b = new NpgsqlConnectionStringBuilder(builder.ConnectionString) { - Database = null, - Timeout = 5 + Timeout = builder.TryGetValue("Timeout", out var timeout) ? (int)timeout : 5 }; using var con = new NpgsqlConnection(b.ConnectionString); @@ -88,7 +88,7 @@ public override IEnumerable ListDatabases(DbConnection con) public override DbDataAdapter GetDataAdapter(DbCommand cmd) => new NpgsqlDataAdapter((NpgsqlCommand)cmd); - public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new NpgsqlCommandBuilder(new NpgsqlDataAdapter((NpgsqlCommand) cmd)); + public override DbCommandBuilder GetCommandBuilder(DbCommand cmd) => new NpgsqlCommandBuilder(new NpgsqlDataAdapter((NpgsqlCommand)cmd)); public override DbParameter GetParameter(string parameterName) => new NpgsqlParameter { ParameterName = parameterName }; From 4ccf74b624372c81f48b3eb1c4b8773aae6495c9 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 15 Jul 2024 09:25:49 +0100 Subject: [PATCH 2/6] update tests --- .../PostgreSql/PostgreSqlServerHelper.cs | 1 - Tests/FAnsiTests/DatabaseTests.cs | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs index 8eaad2be..38eac816 100644 --- a/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs +++ b/FAnsiSql/Implementations/PostgreSql/PostgreSqlServerHelper.cs @@ -33,7 +33,6 @@ public override DbConnectionStringBuilder EnableAsync(DbConnectionStringBuilder public override void CreateDatabase(DbConnectionStringBuilder builder, IHasRuntimeName newDatabaseName) { var b = (NpgsqlConnectionStringBuilder)GetConnectionStringBuilder(builder.ConnectionString); - b.Database = null; using var con = new NpgsqlConnection(b.ConnectionString); con.Open(); diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index c55ee824..15ec9d0a 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -20,7 +20,7 @@ namespace FAnsiTests; [NonParallelizable] public class DatabaseTests { - protected readonly Dictionary TestConnectionStrings = []; + protected readonly Dictionary TestConnectionStrings = []; private bool _allowDatabaseCreation; private string _testScratchDatabase; @@ -39,11 +39,11 @@ public void CheckFiles() var file = Path.Combine(TestContext.CurrentContext.TestDirectory, TestFilename); - Assert.That(File.Exists(file),"Could not find " + TestFilename); + Assert.That(File.Exists(file), "Could not find " + TestFilename); var doc = XDocument.Load(file); - var root = doc.Element("TestDatabases")??throw new Exception($"Missing element 'TestDatabases' in {TestFilename}"); + var root = doc.Element("TestDatabases") ?? throw new Exception($"Missing element 'TestDatabases' in {TestFilename}"); var settings = root.Element("Settings") ?? throw new Exception($"Missing element 'Settings' in {TestFilename}"); @@ -62,13 +62,22 @@ public void CheckFiles() { var type = element.Element("DatabaseType")?.Value; - if(!Enum.TryParse(type, out DatabaseType databaseType)) + if (!Enum.TryParse(type, out DatabaseType databaseType)) throw new Exception($"Could not parse DatabaseType {type}"); var constr = element.Element("ConnectionString")?.Value; - TestConnectionStrings.Add(databaseType,constr); + TestConnectionStrings.Add(databaseType, constr); + } + if (TestConnectionStrings.ContainsKey(DatabaseType.PostgreSql)) + { + //make the postgres test DB if it doesn't exist + var testDB = GetTestDatabase(DatabaseType.PostgreSql); + if (!testDB.Server.DiscoverDatabases().ToList().Any(db => db.GetWrappedName().Contains(_testScratchDatabase))) + { + testDB.Server.CreateDatabase(_testScratchDatabase); + } } } catch (Exception exception) @@ -85,19 +94,19 @@ protected IEnumerable TestServer() } protected DiscoveredServer GetTestServer(DatabaseType type) { - if(!TestConnectionStrings.ContainsKey(type)) + if (!TestConnectionStrings.ContainsKey(type)) Assert.Inconclusive("No connection string configured for that server"); return new DiscoveredServer(TestConnectionStrings[type], type); } - protected DiscoveredDatabase GetTestDatabase(DatabaseType type, bool cleanDatabase=true) + protected DiscoveredDatabase GetTestDatabase(DatabaseType type, bool cleanDatabase = true) { var server = GetTestServer(type); var db = server.ExpectDatabase(_testScratchDatabase); - if(!db.Exists()) - if(_allowDatabaseCreation) + if (!db.Exists()) + if (_allowDatabaseCreation) db.Create(); else Assert.Inconclusive( @@ -131,7 +140,7 @@ protected DiscoveredDatabase GetTestDatabase(DatabaseType type, bool cleanDataba protected void AssertCanCreateDatabases() { - if(!_allowDatabaseCreation) + if (!_allowDatabaseCreation) Assert.Inconclusive("Test cannot run when AllowDatabaseCreation is false"); } @@ -165,7 +174,7 @@ protected static void AssertAreEqual(DataTable dt1, DataTable dt2) foreach (DataRow row1 in dt1.Rows) { - var match = dt2.Rows.Cast().Any(row2=> dt1.Columns.Cast().All(c => AreBasicallyEquals(row1[c.ColumnName], row2[c.ColumnName]))); + var match = dt2.Rows.Cast().Any(row2 => dt1.Columns.Cast().All(c => AreBasicallyEquals(row1[c.ColumnName], row2[c.ColumnName]))); Assert.That(match, $"Couldn't find match for row:{string.Join(",", row1.ItemArray)}"); } From 88b2a02cb683fc451acee6fae017be9d8fff0677 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 15 Jul 2024 09:34:43 +0100 Subject: [PATCH 3/6] update github db settings --- Tests/FAnsiTests/TestDatabases-github.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FAnsiTests/TestDatabases-github.xml b/Tests/FAnsiTests/TestDatabases-github.xml index 1bd3e7eb..fffb74ed 100644 --- a/Tests/FAnsiTests/TestDatabases-github.xml +++ b/Tests/FAnsiTests/TestDatabases-github.xml @@ -18,6 +18,6 @@ PostgreSql - User ID=postgres;Password=pgpass4291;Host=127.0.0.1;Port=5432 + User ID=postgres;Password=pgpass4291;Host=127.0.0.1;Port=5432;Database=postgres From cccd72e719c5d1d143d96655f9307338b8702922 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 15 Jul 2024 15:10:43 +0100 Subject: [PATCH 4/6] update test --- Tests/FAnsiTests/CrossPlatformTests.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Tests/FAnsiTests/CrossPlatformTests.cs b/Tests/FAnsiTests/CrossPlatformTests.cs index d12a81ce..56bf6b7d 100644 --- a/Tests/FAnsiTests/CrossPlatformTests.cs +++ b/Tests/FAnsiTests/CrossPlatformTests.cs @@ -793,9 +793,15 @@ public void HorribleDatabaseAndTableNames(DatabaseType type,string horribleDatab var database = GetTestDatabase(type); SqlConnection.ClearAllPools(); + //var db = database.Server.ExpectDatabase(horribleTableName); + //if (db.Exists()) + // db.Drop(); + if (type == DatabaseType.PostgreSql) + database.Server.CreateDatabase(horribleDatabaseName); database = database.Server.ExpectDatabase(horribleDatabaseName); - database.Create(true); + if(type != DatabaseType.PostgreSql) + database.Create(true); SqlConnection.ClearAllPools(); @@ -918,9 +924,8 @@ public void HorribleColumnNames(DatabaseType type, string horribleDatabaseName, AssertCanCreateDatabases(); var database = GetTestDatabase(type); - + database.Server.CreateDatabase(horribleDatabaseName); database = database.Server.ExpectDatabase(horribleDatabaseName); - database.Create(true); Assert.That(database.GetRuntimeName(), Is.EqualTo(horribleDatabaseName).IgnoreCase); try From 6513d9f417d709923007f31c4d998d32f0948de6 Mon Sep 17 00:00:00 2001 From: James Friel Date: Mon, 15 Jul 2024 15:40:44 +0100 Subject: [PATCH 5/6] update test --- Tests/FAnsiTests/CrossPlatformTests.cs | 3 --- Tests/FAnsiTests/DatabaseTests.cs | 8 ++++---- Tests/FAnsiTests/Table/LongNamesTests.cs | 12 +++++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Tests/FAnsiTests/CrossPlatformTests.cs b/Tests/FAnsiTests/CrossPlatformTests.cs index 56bf6b7d..d2ea62d9 100644 --- a/Tests/FAnsiTests/CrossPlatformTests.cs +++ b/Tests/FAnsiTests/CrossPlatformTests.cs @@ -793,9 +793,6 @@ public void HorribleDatabaseAndTableNames(DatabaseType type,string horribleDatab var database = GetTestDatabase(type); SqlConnection.ClearAllPools(); - //var db = database.Server.ExpectDatabase(horribleTableName); - //if (db.Exists()) - // db.Drop(); if (type == DatabaseType.PostgreSql) database.Server.CreateDatabase(horribleDatabaseName); diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index 15ec9d0a..cae89701 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -13,6 +13,7 @@ using FAnsi.Implementations.MicrosoftSQL; using FAnsi.Implementations.PostgreSql; using NUnit.Framework; +using NUnit.Framework.Internal; namespace FAnsiTests; @@ -72,11 +73,10 @@ public void CheckFiles() } if (TestConnectionStrings.ContainsKey(DatabaseType.PostgreSql)) { - //make the postgres test DB if it doesn't exist - var testDB = GetTestDatabase(DatabaseType.PostgreSql); - if (!testDB.Server.DiscoverDatabases().ToList().Any(db => db.GetWrappedName().Contains(_testScratchDatabase))) + var server = GetTestServer(DatabaseType.PostgreSql); + if (!server.DiscoverDatabases().ToList().Any(db => db.GetWrappedName().Contains(_testScratchDatabase))) { - testDB.Server.CreateDatabase(_testScratchDatabase); + server.CreateDatabase(_testScratchDatabase); } } } diff --git a/Tests/FAnsiTests/Table/LongNamesTests.cs b/Tests/FAnsiTests/Table/LongNamesTests.cs index 1d66316b..50160052 100644 --- a/Tests/FAnsiTests/Table/LongNamesTests.cs +++ b/Tests/FAnsiTests/Table/LongNamesTests.cs @@ -8,7 +8,7 @@ namespace FAnsiTests.Table; internal sealed class LongNamesTests : DatabaseTests { - [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] + [TestCaseSource(typeof(All), nameof(All.DatabaseTypes))] public void Test_LongTableName_CreateAndReadBack(DatabaseType dbType) { var db = GetTestDatabase(dbType); @@ -16,7 +16,7 @@ public void Test_LongTableName_CreateAndReadBack(DatabaseType dbType) var tableName = new StringBuilder(db.Server.GetQuerySyntaxHelper().MaximumTableLength).Append('a', db.Server.GetQuerySyntaxHelper().MaximumTableLength).ToString(); var columnName = new StringBuilder(db.Server.GetQuerySyntaxHelper().MaximumColumnLength).Append('b', db.Server.GetQuerySyntaxHelper().MaximumColumnLength).ToString(); - var tbl = db.CreateTable(tableName,[new DatabaseColumnRequest(columnName,new DatabaseTypeRequest(typeof(string),100))]); + var tbl = db.CreateTable(tableName, [new DatabaseColumnRequest(columnName, new DatabaseTypeRequest(typeof(string), 100))]); Assert.Multiple(() => { @@ -29,7 +29,7 @@ public void Test_LongTableName_CreateAndReadBack(DatabaseType dbType) Assert.That(col.GetRuntimeName(), Is.EqualTo(columnName).IgnoreCase); } - [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] + [TestCaseSource(typeof(All), nameof(All.DatabaseTypes))] public void Test_LongDatabaseNames_CreateAndReadBack(DatabaseType dbType) { AssertCanCreateDatabases(); @@ -40,9 +40,11 @@ public void Test_LongDatabaseNames_CreateAndReadBack(DatabaseType dbType) for (var i = 0; i < db.Server.GetQuerySyntaxHelper().MaximumDatabaseLength; i++) sb.Append('a'); - + if (dbType == DatabaseType.PostgreSql) + db.Server.CreateDatabase(sb.ToString()); var db2 = db.Server.ExpectDatabase(sb.ToString()); - db2.Create(true); + if (dbType != DatabaseType.PostgreSql) + db2.Create(true); Assert.Multiple(() => { From fd047d3b14b9e047a6a56f3246a898ba6d9db22b Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 16 Jul 2024 09:16:36 -0500 Subject: [PATCH 6/6] Disused usings, tidy scratch db creation logic --- FAnsiSql/Discovery/DiscoveredColumn.cs | 3 +-- FAnsiSql/Discovery/DiscoveredServerHelper.cs | 1 - Tests/FAnsiTests/DatabaseTests.cs | 12 +++++------- Tests/FAnsiTests/Table/CreateIndexTest.cs | 5 +---- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/FAnsiSql/Discovery/DiscoveredColumn.cs b/FAnsiSql/Discovery/DiscoveredColumn.cs index a5b85e07..9a6f963a 100644 --- a/FAnsiSql/Discovery/DiscoveredColumn.cs +++ b/FAnsiSql/Discovery/DiscoveredColumn.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using FAnsi.Discovery.QuerySyntax; +using FAnsi.Discovery.QuerySyntax; using FAnsi.Naming; using TypeGuesser; diff --git a/FAnsiSql/Discovery/DiscoveredServerHelper.cs b/FAnsiSql/Discovery/DiscoveredServerHelper.cs index c4256ab0..07eb0662 100644 --- a/FAnsiSql/Discovery/DiscoveredServerHelper.cs +++ b/FAnsiSql/Discovery/DiscoveredServerHelper.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using System.Threading; diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index cae89701..6c4be06f 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -13,7 +13,6 @@ using FAnsi.Implementations.MicrosoftSQL; using FAnsi.Implementations.PostgreSql; using NUnit.Framework; -using NUnit.Framework.Internal; namespace FAnsiTests; @@ -70,13 +69,12 @@ public void CheckFiles() var constr = element.Element("ConnectionString")?.Value; TestConnectionStrings.Add(databaseType, constr); - } - if (TestConnectionStrings.ContainsKey(DatabaseType.PostgreSql)) - { - var server = GetTestServer(DatabaseType.PostgreSql); - if (!server.DiscoverDatabases().ToList().Any(db => db.GetWrappedName().Contains(_testScratchDatabase))) + + // Make sure our scratch db exists for PostgreSQL + if (databaseType == DatabaseType.PostgreSql) { - server.CreateDatabase(_testScratchDatabase); + var server = GetTestServer(DatabaseType.PostgreSql); + if (server.DiscoverDatabases().All(db => db.GetWrappedName()?.Contains(_testScratchDatabase) != true)) server.CreateDatabase(_testScratchDatabase); } } } diff --git a/Tests/FAnsiTests/Table/CreateIndexTest.cs b/Tests/FAnsiTests/Table/CreateIndexTest.cs index a323ad43..3f3be985 100644 --- a/Tests/FAnsiTests/Table/CreateIndexTest.cs +++ b/Tests/FAnsiTests/Table/CreateIndexTest.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; +using System.Data; using FAnsi; using FAnsi.Discovery; using FAnsi.Exceptions;