11using System ;
22using System . Data . SqlClient ;
3- using System . Text ;
43using System . Threading ;
54using System . Threading . Tasks ;
65using MySql . Data . MySqlClient ;
76using Npgsql ;
87using Serilog ;
98using SqlStreamStore . Infrastructure ;
10- using static SqlStreamStore . Server . Constants ;
119
1210namespace SqlStreamStore . Server
1311{
1412 internal class DatabaseInitializer
1513 {
1614 private readonly SqlStreamStoreServerConfiguration _configuration ;
17- private readonly SqlStreamStoreFactory _streamStoreFactory ;
1815
1916 public DatabaseInitializer ( SqlStreamStoreServerConfiguration configuration )
2017 {
@@ -24,156 +21,101 @@ public DatabaseInitializer(SqlStreamStoreServerConfiguration configuration)
2421 }
2522
2623 _configuration = configuration ;
27- _streamStoreFactory = new SqlStreamStoreFactory ( configuration ) ;
2824 }
2925
3026 public Task Initialize ( CancellationToken cancellationToken = default )
3127 {
3228 switch ( _configuration . Provider )
3329 {
34- case mssql :
35- return InitializeMsSqlStreamStore ( cancellationToken ) ;
36- case mysql :
37- return InitializeMySqlStreamStore ( cancellationToken ) ;
38- case postgres :
39- return InitializePostgresStreamStore ( cancellationToken ) ;
30+ case Constants . mssql :
31+ return InitializeMsSql ( cancellationToken ) ;
32+ case Constants . mysql :
33+ return InitializeMySql ( cancellationToken ) ;
34+ case Constants . postgres :
35+ return InitializePostgres ( cancellationToken ) ;
4036 default :
41- Log . Warning ( "Provider {provider} has no initialization ." , _configuration . Provider ) ;
37+ Log . Warning ( "Provider {provider} has no database initializer ." , _configuration . Provider ) ;
4238 return Task . CompletedTask ;
4339 }
4440 }
4541
46- private async Task InitializeMySqlStreamStore ( CancellationToken cancellationToken )
42+ private async Task InitializeMySql ( CancellationToken cancellationToken )
4743 {
4844 var connectionStringBuilder = new MySqlConnectionStringBuilder ( _configuration . ConnectionString ) ;
49-
50- using ( var streamStore = _streamStoreFactory . CreateMySqlStreamStore ( ) )
51- {
52- try
45+ using ( var connection = new MySqlConnection (
46+ new MySqlConnectionStringBuilder ( _configuration . ConnectionString )
5347 {
54- using ( var connection = new MySqlConnection (
55- new MySqlConnectionStringBuilder ( _configuration . ConnectionString )
56- {
57- Database = null
58- } . ConnectionString ) )
59- {
60- await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
61-
62- using ( var command = new MySqlCommand (
63- $ "CREATE DATABASE IF NOT EXISTS `{ connectionStringBuilder . Database } `",
64- connection ) )
65- {
66- await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
67- }
68- }
48+ Database = null
49+ } . ConnectionString ) )
50+ {
51+ await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
6952
70- await streamStore . CreateSchemaIfNotExists ( cancellationToken ) ;
71- }
72- catch ( SqlException ex )
53+ using ( var command = new MySqlCommand (
54+ $ "CREATE DATABASE IF NOT EXISTS ` { connectionStringBuilder . Database } `" ,
55+ connection ) )
7356 {
74- SchemaCreationFailed ( streamStore . GetSchemaCreationScript , ex ) ;
75- throw ;
57+ await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
7658 }
7759 }
7860 }
7961
80- private async Task InitializeMsSqlStreamStore ( CancellationToken cancellationToken )
62+ private async Task InitializeMsSql ( CancellationToken cancellationToken )
8163 {
8264 var connectionStringBuilder = new SqlConnectionStringBuilder ( _configuration . ConnectionString ) ;
83-
84- using ( var streamStore = _streamStoreFactory . CreateMsSqlStreamStore ( ) )
85- {
86- try
65+ using ( var connection = new SqlConnection (
66+ new SqlConnectionStringBuilder ( _configuration . ConnectionString )
8767 {
88- using ( var connection = new SqlConnection (
89- new SqlConnectionStringBuilder ( _configuration . ConnectionString )
90- {
91- InitialCatalog = "master"
92- } . ConnectionString ) )
93- {
94- await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
68+ InitialCatalog = "master"
69+ } . ConnectionString ) )
70+ {
71+ await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
9572
96- using ( var command = new SqlCommand (
97- $@ "
73+ using ( var command = new SqlCommand (
74+ $@ "
9875IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'{ connectionStringBuilder . InitialCatalog } ')
9976BEGIN
10077 CREATE DATABASE [{ connectionStringBuilder . InitialCatalog } ]
10178END;
10279" ,
103- connection ) )
104- {
105- await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
106- }
107- }
108-
109- await streamStore . CreateSchemaIfNotExists ( cancellationToken ) ;
110- }
111- catch ( SqlException ex )
80+ connection ) )
11281 {
113- SchemaCreationFailed ( streamStore . GetSchemaCreationScript , ex ) ;
114- throw ;
82+ await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
11583 }
11684 }
11785 }
11886
119- private async Task InitializePostgresStreamStore ( CancellationToken cancellationToken )
87+ private async Task InitializePostgres ( CancellationToken cancellationToken )
12088 {
12189 var connectionStringBuilder = new NpgsqlConnectionStringBuilder ( _configuration . ConnectionString ) ;
122- using ( var streamStore = _streamStoreFactory . CreatePostgresStreamStore ( ) )
90+ using ( var connection = new NpgsqlConnection (
91+ new NpgsqlConnectionStringBuilder ( _configuration . ConnectionString )
92+ {
93+ Database = null
94+ } . ConnectionString ) )
12395 {
124- try
96+ await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
97+
98+ async Task < bool > DatabaseExists ( )
12599 {
126- using ( var connection = new NpgsqlConnection (
127- new NpgsqlConnectionStringBuilder ( _configuration . ConnectionString )
128- {
129- Database = null
130- } . ConnectionString ) )
100+ using ( var command = new NpgsqlCommand (
101+ $ "SELECT 1 FROM pg_database WHERE datname = '{ connectionStringBuilder . Database } '",
102+ connection ) )
131103 {
132- await connection . OpenAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
133-
134- async Task < bool > DatabaseExists ( )
135- {
136- using ( var command = new NpgsqlCommand (
137- $ "SELECT 1 FROM pg_database WHERE datname = '{ connectionStringBuilder . Database } '",
138- connection ) )
139- {
140- return await command . ExecuteScalarAsync ( cancellationToken ) . NotOnCapturedContext ( )
141- != null ;
142- }
143- }
144-
145- if ( ! await DatabaseExists ( ) )
146- {
147- using ( var command = new NpgsqlCommand (
148- $ "CREATE DATABASE { connectionStringBuilder . Database } ",
149- connection ) )
150- {
151- await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
152- }
153- }
154-
155- await streamStore . CreateSchemaIfNotExists ( cancellationToken ) ;
104+ return await command . ExecuteScalarAsync ( cancellationToken ) . NotOnCapturedContext ( )
105+ != null ;
156106 }
157107 }
158- catch ( NpgsqlException ex )
108+
109+ if ( ! await DatabaseExists ( ) )
159110 {
160- SchemaCreationFailed ( streamStore . GetSchemaCreationScript , ex ) ;
161- throw ;
111+ using ( var command = new NpgsqlCommand (
112+ $ "CREATE DATABASE { connectionStringBuilder . Database } ",
113+ connection ) )
114+ {
115+ await command . ExecuteNonQueryAsync ( cancellationToken ) . NotOnCapturedContext ( ) ;
116+ }
162117 }
163118 }
164119 }
165-
166- private static void SchemaCreationFailed ( Func < string > getSchemaCreationScript , Exception ex )
167- => Log . Error (
168- new StringBuilder ( )
169- . Append ( "Could not create schema: {ex}" )
170- . AppendLine ( )
171- . Append (
172- "Does your connection string have enough permissions? If not, run the following sql script as a privileged user:" )
173- . AppendLine ( )
174- . Append ( "{script}" )
175- . ToString ( ) ,
176- ex ,
177- getSchemaCreationScript ( ) ) ;
178120 }
179121}
0 commit comments