Skip to content

Commit b666fc8

Browse files
committed
Moved PostgreSqlEnsureClean code to internal class
1 parent 402a593 commit b666fc8

File tree

2 files changed

+59
-44
lines changed

2 files changed

+59
-44
lines changed

TestSupport/EfHelpers/CleanDatabaseExtensions.cs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System;
66
using Microsoft.EntityFrameworkCore;
77
using Microsoft.EntityFrameworkCore.Infrastructure;
8-
using Npgsql;
98
using TestSupport.EfHelpers.Internal;
109

1110
namespace TestSupport.EfHelpers
@@ -34,48 +33,5 @@ public static void EnsureClean(this DatabaseFacade databaseFacade, bool setUpSch
3433
else
3534
throw new InvalidOperationException("The EnsureClean method only works with SQL Server or PostgreSQL databases.");
3635
}
37-
38-
private static void FasterPostgreSqlEnsureClean(this DatabaseFacade databaseFacade, bool setUpSchema = true)
39-
{
40-
var connectionString = databaseFacade.GetDbConnection().ConnectionString;
41-
if (connectionString.DatabaseExists())
42-
{
43-
var conn = new NpgsqlConnection(connectionString);
44-
conn.Open();
45-
46-
var dropPublicSchemaCommand = new NpgsqlCommand
47-
{
48-
Connection = conn,
49-
CommandText = @"
50-
DO $$
51-
DECLARE
52-
r RECORD;
53-
BEGIN
54-
FOR r IN (SELECT nspname FROM pg_namespace WHERE nspname NOT IN ('pg_toast', 'pg_catalog', 'information_schema'))
55-
LOOP
56-
EXECUTE 'DROP SCHEMA ' || quote_ident(r.nspname) || ' CASCADE';
57-
END LOOP;
58-
EXECUTE 'CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public';
59-
END $$"
60-
};
61-
dropPublicSchemaCommand.ExecuteNonQuery();
62-
}
63-
64-
if (setUpSchema)
65-
databaseFacade.EnsureCreated();
66-
}
67-
68-
private static bool DatabaseExists(this string connectionString)
69-
{
70-
var builder = new NpgsqlConnectionStringBuilder(connectionString);
71-
var orgDbStartsWith = builder.Database;
72-
builder.Database = "postgres";
73-
var newConnectionString = builder.ToString();
74-
using var conn = new NpgsqlConnection(newConnectionString);
75-
conn.Open();
76-
77-
using var cmd = new NpgsqlCommand($"SELECT COUNT(*) FROM pg_catalog.pg_database WHERE datname='{orgDbStartsWith}'", conn);
78-
return (long)cmd.ExecuteScalar() == 1;
79-
}
8036
}
8137
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Infrastructure;
3+
using Npgsql;
4+
5+
namespace TestSupport.EfHelpers.Internal
6+
{
7+
internal static class PostgreSqlDropSchemaEnsureClean
8+
{
9+
/// <summary>
10+
/// This uses the "DROP SCHEMA" approach (see https://stackoverflow.com/a/13823560/1434764)
11+
/// to remove all the tables, extensions, functions, collations.
12+
/// The SQL in this method was provided by Shay Rojansky, github @roji
13+
/// </summary>
14+
/// <param name="databaseFacade"></param>
15+
/// <param name="setUpSchema"></param>
16+
public static void FasterPostgreSqlEnsureClean(this DatabaseFacade databaseFacade, bool setUpSchema = true)
17+
{
18+
var connectionString = databaseFacade.GetDbConnection().ConnectionString;
19+
if (connectionString.DatabaseExists())
20+
{
21+
var conn = new NpgsqlConnection(connectionString);
22+
conn.Open();
23+
24+
var dropPublicSchemaCommand = new NpgsqlCommand
25+
{
26+
Connection = conn,
27+
CommandText = @"
28+
DO $$
29+
DECLARE
30+
r RECORD;
31+
BEGIN
32+
FOR r IN (SELECT nspname FROM pg_namespace WHERE nspname NOT IN ('pg_toast', 'pg_catalog', 'information_schema'))
33+
LOOP
34+
EXECUTE 'DROP SCHEMA ' || quote_ident(r.nspname) || ' CASCADE';
35+
END LOOP;
36+
EXECUTE 'CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public';
37+
END $$"
38+
};
39+
dropPublicSchemaCommand.ExecuteNonQuery();
40+
}
41+
42+
if (setUpSchema)
43+
databaseFacade.EnsureCreated();
44+
}
45+
46+
private static bool DatabaseExists(this string connectionString)
47+
{
48+
var builder = new NpgsqlConnectionStringBuilder(connectionString);
49+
var orgDbStartsWith = builder.Database;
50+
builder.Database = "postgres";
51+
var newConnectionString = builder.ToString();
52+
using var conn = new NpgsqlConnection(newConnectionString);
53+
conn.Open();
54+
55+
using var cmd = new NpgsqlCommand($"SELECT COUNT(*) FROM pg_catalog.pg_database WHERE datname='{orgDbStartsWith}'", conn);
56+
return (long)cmd.ExecuteScalar() == 1;
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)