Skip to content

Commit e4a2721

Browse files
Merge pull request #131 from dotnetprojects/add-primary-key
Add primary key
2 parents f6bd5b1 + c595fda commit e4a2721

File tree

36 files changed

+1303
-1243
lines changed

36 files changed

+1303
-1243
lines changed

src/Migrator.Tests/Database/DerivedDatabaseIntegrationTestServices/PostgreSqlDatabaseIntegrationTestService.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Threading;
55
using System.Threading.Tasks;
66
using LinqToDB;
7-
using LinqToDB.Async;
87
using LinqToDB.Data;
98
using Mapster;
109
using Migrator.Tests.Database.DatabaseName.Interfaces;
Lines changed: 111 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,111 @@
1-
using System;
2-
using System.Data.Common;
3-
using System.Linq;
4-
using System.Threading;
5-
using System.Threading.Tasks;
6-
using LinqToDB;
7-
using LinqToDB.Async;
8-
using LinqToDB.Data;
9-
using Mapster;
10-
using Microsoft.Data.SqlClient;
11-
using Migrator.Tests.Database.DatabaseName.Interfaces;
12-
using Migrator.Tests.Database.Interfaces;
13-
using Migrator.Tests.Database.Models;
14-
using Migrator.Tests.Settings.Models;
15-
16-
namespace Migrator.Tests.Database.DerivedDatabaseIntegrationTestServices;
17-
18-
public class SqlServerDatabaseIntegrationTestService(TimeProvider timeProvider, IDatabaseNameService databaseNameService)
19-
: DatabaseIntegrationTestServiceBase(databaseNameService), IDatabaseIntegrationTestService
20-
{
21-
private const string SqlServerInitialCatalogString = "Initial Catalog";
22-
23-
public override async Task<DatabaseInfo> CreateTestDatabaseAsync(DatabaseConnectionConfig databaseConnectionConfig, CancellationToken cancellationToken)
24-
{
25-
using var context = new DataConnection(new DataOptions().UseSqlServer(databaseConnectionConfig.ConnectionString));
26-
await context.ExecuteAsync("use master", cancellationToken);
27-
28-
var databaseNames = context.Query<string>($"SELECT name FROM sys.databases WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb')").ToList();
29-
30-
var toBeDeletedDatabaseNames = databaseNames.Where(x =>
31-
{
32-
var creationDate = DatabaseNameService.ReadTimeStampFromString(x);
33-
return creationDate.HasValue && creationDate.Value < timeProvider.GetUtcNow().Subtract(MinTimeSpanBeforeDatabaseDeletion);
34-
}).ToList();
35-
36-
foreach (var databaseName in toBeDeletedDatabaseNames)
37-
{
38-
var databaseInfoToBeDeleted = new DatabaseInfo { DatabaseConnectionConfig = databaseConnectionConfig, DatabaseName = databaseName };
39-
await DropDatabaseAsync(databaseInfoToBeDeleted, cancellationToken);
40-
}
41-
42-
var newDatabaseName = DatabaseNameService.CreateDatabaseName();
43-
44-
await context.ExecuteAsync($"CREATE DATABASE [{newDatabaseName}]", cancellationToken);
45-
46-
var clonedDatabaseConnectionConfig = databaseConnectionConfig.Adapt<DatabaseConnectionConfig>();
47-
48-
var builder = new DbConnectionStringBuilder
49-
{
50-
ConnectionString = clonedDatabaseConnectionConfig.ConnectionString
51-
};
52-
53-
if (builder.TryGetValue(SqlServerInitialCatalogString, out var value))
54-
{
55-
builder.Remove(SqlServerInitialCatalogString);
56-
builder.Add(SqlServerInitialCatalogString, newDatabaseName);
57-
}
58-
59-
clonedDatabaseConnectionConfig.ConnectionString = builder.ConnectionString;
60-
61-
var databaseInfo = new DatabaseInfo
62-
{
63-
DatabaseConnectionConfig = clonedDatabaseConnectionConfig,
64-
DatabaseName = newDatabaseName
65-
};
66-
67-
return databaseInfo;
68-
}
69-
70-
public override async Task DropDatabaseAsync(DatabaseInfo databaseInfo, CancellationToken cancellationToken)
71-
{
72-
var creationDate = DatabaseNameService.ReadTimeStampFromString(databaseInfo.DatabaseName);
73-
74-
if (!creationDate.HasValue)
75-
{
76-
throw new Exception("You tried to drop a database that was not created by this service. For safety reasons we deny your request.");
77-
}
78-
79-
using var context = new DataConnection(new DataOptions().UseSqlServer(databaseInfo.DatabaseConnectionConfig.ConnectionString));
80-
await context.ExecuteAsync("use master", cancellationToken);
81-
82-
try
83-
{
84-
await context.ExecuteAsync($"ALTER DATABASE [{databaseInfo.DatabaseName}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", cancellationToken);
85-
await context.ExecuteAsync($"DROP DATABASE [{databaseInfo.DatabaseName}]", cancellationToken);
86-
}
87-
catch (SqlException ex)
88-
{
89-
// 3701: "Cannot drop the database because it does not exist or you do not have permission"
90-
if (ex.Errors.Count > 0 && ex.Errors.Cast<SqlError>().Any(x => x.Number == 3701))
91-
{
92-
await Task.Delay(5000, cancellationToken);
93-
94-
var count = await context.ExecuteAsync<int>($"SELECT COUNT(*) FROM sys.databases WHERE name = '{databaseInfo.DatabaseName}'");
95-
96-
if (count == 1)
97-
{
98-
throw new UnauthorizedAccessException($"The database '{databaseInfo.DatabaseName}' cannot be dropped but it still exists so we assume you do not have sufficient privileges to drop databases or this database.", ex);
99-
}
100-
else
101-
{
102-
// The database was removed by another (asynchronously) running test that kicked in earlier.
103-
// That's ok for us as we have achieved the goal.
104-
}
105-
}
106-
else
107-
{
108-
throw;
109-
}
110-
}
111-
}
112-
}
1+
using System;
2+
using System.Data.Common;
3+
using System.Linq;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using LinqToDB;
7+
using LinqToDB.Data;
8+
using Mapster;
9+
using Microsoft.Data.SqlClient;
10+
using Migrator.Tests.Database.DatabaseName.Interfaces;
11+
using Migrator.Tests.Database.Interfaces;
12+
using Migrator.Tests.Database.Models;
13+
using Migrator.Tests.Settings.Models;
14+
15+
namespace Migrator.Tests.Database.DerivedDatabaseIntegrationTestServices;
16+
17+
public class SqlServerDatabaseIntegrationTestService(TimeProvider timeProvider, IDatabaseNameService databaseNameService)
18+
: DatabaseIntegrationTestServiceBase(databaseNameService), IDatabaseIntegrationTestService
19+
{
20+
private const string SqlServerInitialCatalogString = "Initial Catalog";
21+
22+
public override async Task<DatabaseInfo> CreateTestDatabaseAsync(DatabaseConnectionConfig databaseConnectionConfig, CancellationToken cancellationToken)
23+
{
24+
using var context = new DataConnection(new DataOptions().UseSqlServer(databaseConnectionConfig.ConnectionString));
25+
await context.ExecuteAsync("use master", cancellationToken);
26+
27+
var databaseNames = context.Query<string>($"SELECT name FROM sys.databases WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb')").ToList();
28+
29+
var toBeDeletedDatabaseNames = databaseNames.Where(x =>
30+
{
31+
var creationDate = DatabaseNameService.ReadTimeStampFromString(x);
32+
return creationDate.HasValue && creationDate.Value < timeProvider.GetUtcNow().Subtract(MinTimeSpanBeforeDatabaseDeletion);
33+
}).ToList();
34+
35+
foreach (var databaseName in toBeDeletedDatabaseNames)
36+
{
37+
var databaseInfoToBeDeleted = new DatabaseInfo { DatabaseConnectionConfig = databaseConnectionConfig, DatabaseName = databaseName };
38+
await DropDatabaseAsync(databaseInfoToBeDeleted, cancellationToken);
39+
}
40+
41+
var newDatabaseName = DatabaseNameService.CreateDatabaseName();
42+
43+
await context.ExecuteAsync($"CREATE DATABASE [{newDatabaseName}]", cancellationToken);
44+
45+
var clonedDatabaseConnectionConfig = databaseConnectionConfig.Adapt<DatabaseConnectionConfig>();
46+
47+
var builder = new DbConnectionStringBuilder
48+
{
49+
ConnectionString = clonedDatabaseConnectionConfig.ConnectionString
50+
};
51+
52+
if (builder.TryGetValue(SqlServerInitialCatalogString, out var value))
53+
{
54+
builder.Remove(SqlServerInitialCatalogString);
55+
builder.Add(SqlServerInitialCatalogString, newDatabaseName);
56+
}
57+
58+
clonedDatabaseConnectionConfig.ConnectionString = builder.ConnectionString;
59+
60+
var databaseInfo = new DatabaseInfo
61+
{
62+
DatabaseConnectionConfig = clonedDatabaseConnectionConfig,
63+
DatabaseName = newDatabaseName
64+
};
65+
66+
return databaseInfo;
67+
}
68+
69+
public override async Task DropDatabaseAsync(DatabaseInfo databaseInfo, CancellationToken cancellationToken)
70+
{
71+
var creationDate = DatabaseNameService.ReadTimeStampFromString(databaseInfo.DatabaseName);
72+
73+
if (!creationDate.HasValue)
74+
{
75+
throw new Exception("You tried to drop a database that was not created by this service. For safety reasons we deny your request.");
76+
}
77+
78+
using var context = new DataConnection(new DataOptions().UseSqlServer(databaseInfo.DatabaseConnectionConfig.ConnectionString));
79+
await context.ExecuteAsync("use master", cancellationToken);
80+
81+
try
82+
{
83+
await context.ExecuteAsync($"ALTER DATABASE [{databaseInfo.DatabaseName}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", cancellationToken);
84+
await context.ExecuteAsync($"DROP DATABASE [{databaseInfo.DatabaseName}]", cancellationToken);
85+
}
86+
catch (SqlException ex)
87+
{
88+
// 3701: "Cannot drop the database because it does not exist or you do not have permission"
89+
if (ex.Errors.Count > 0 && ex.Errors.Cast<SqlError>().Any(x => x.Number == 3701))
90+
{
91+
await Task.Delay(5000, cancellationToken);
92+
93+
var count = await context.ExecuteAsync<int>($"SELECT COUNT(*) FROM sys.databases WHERE name = '{databaseInfo.DatabaseName}'");
94+
95+
if (count == 1)
96+
{
97+
throw new UnauthorizedAccessException($"The database '{databaseInfo.DatabaseName}' cannot be dropped but it still exists so we assume you do not have sufficient privileges to drop databases or this database.", ex);
98+
}
99+
else
100+
{
101+
// The database was removed by another (asynchronously) running test that kicked in earlier.
102+
// That's ok for us as we have achieved the goal.
103+
}
104+
}
105+
else
106+
{
107+
throw;
108+
}
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)