Skip to content

Commit c3f9c20

Browse files
authored
Merge pull request #203 from bgrainger/change-database
Implement ChangeDatabase.
2 parents 82b6f13 + 9a025d9 commit c3f9c20

17 files changed

+274
-20
lines changed

.ci/config/config.compression+ssl.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=127.0.0.1;user id=ssltest;password=test;port=3306;database=mysqltest;ssl mode=required;use compression=true;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

.ci/config/config.compression.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=127.0.0.1;user id=mysqltest;password='test;key=\"val';port=3306;database=mysqltest;ssl mode=none;UseCompression=true;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

.ci/config/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=127.0.0.1;user id=mysqltest;password='test;key=\"val';port=3306;database=mysqltest;ssl mode=none;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

.ci/config/config.ssl.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=127.0.0.1;user id=ssltest;password=test;port=3306;database=mysqltest;ssl mode=required;certificate file=../../../../../.ci/server/certs/ssl-client.pfx;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

.ci/config/config.uds+ssl.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=./../../../../../.ci/mysqld/mysqld.sock;user id=ssltest;password=test;database=mysqltest;ssl mode=required;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

.ci/config/config.uds.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Data": {
33
"ConnectionString": "server=./../../../../../.ci/mysqld/mysqld.sock;user id=mysqltest;password='test;key=\"val';database=mysqltest;ssl mode=none;Use Affected Rows=true",
44
"PasswordlessUser": "no_password",
5+
"SecondaryDatabase": "testdb2",
56
"SupportsCachedProcedures": true,
67
"SupportsJson": true,
78
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",

src/MySqlConnector/MySqlClient/ConnectionPool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void Return(MySqlSession session)
5858
{
5959
try
6060
{
61-
if (session.PoolGeneration == m_generation)
61+
if (session.PoolGeneration == m_generation && session.DatabaseOverride == null)
6262
m_sessions.Enqueue(session);
6363
else
6464
session.DisposeAsync(IOBehavior.Synchronous, CancellationToken.None).ConfigureAwait(false);

src/MySqlConnector/MySqlClient/MySqlConnection.cs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,24 @@ public override void EnlistTransaction(System.Transactions.Transaction transacti
8686

8787
public override void Close() => DoClose();
8888

89-
public override void ChangeDatabase(string databaseName)
89+
public override void ChangeDatabase(string databaseName) => ChangeDatabaseAsync(IOBehavior.Synchronous, databaseName, CancellationToken.None).GetAwaiter().GetResult();
90+
public Task ChangeDatabaseAsync(string databaseName) => ChangeDatabaseAsync(IOBehavior.Asynchronous, databaseName, CancellationToken.None);
91+
public Task ChangeDatabaseAsync(string databaseName, CancellationToken cancellationToken) => ChangeDatabaseAsync(IOBehavior.Asynchronous, databaseName, CancellationToken.None);
92+
93+
private async Task ChangeDatabaseAsync(IOBehavior ioBehavior, string databaseName, CancellationToken cancellationToken)
9094
{
91-
throw new NotImplementedException();
95+
if (string.IsNullOrWhiteSpace(databaseName))
96+
throw new ArgumentException("Database name is not valid.", nameof(databaseName));
97+
98+
if (State != ConnectionState.Open)
99+
throw new InvalidOperationException("Connection is not open.");
100+
101+
CloseDatabase();
102+
103+
await m_session.SendAsync(InitDatabasePayload.Create(databaseName), ioBehavior, cancellationToken).ConfigureAwait(false);
104+
var payload = await m_session.ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
105+
OkPayload.Create(payload);
106+
m_session.DatabaseOverride = databaseName;
92107
}
93108

94109
public override void Open() => OpenAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
@@ -142,7 +157,7 @@ public override string ConnectionString
142157
}
143158
}
144159

145-
public override string Database => m_connectionSettings.Database;
160+
public override string Database => m_session.DatabaseOverride ?? m_connectionSettings.Database;
146161

147162
public override ConnectionState State => m_connectionState;
148163

@@ -281,16 +296,7 @@ private void DoClose()
281296
{
282297
if (m_connectionState != ConnectionState.Closed)
283298
{
284-
m_cachedProcedures = null;
285-
if (ActiveReader != null){
286-
ActiveReader.Dispose();
287-
ActiveReader = null;
288-
}
289-
if (CurrentTransaction != null)
290-
{
291-
CurrentTransaction.Dispose();
292-
CurrentTransaction = null;
293-
}
299+
CloseDatabase();
294300
if (m_session != null)
295301
{
296302
if (m_connectionSettings.Pooling)
@@ -303,6 +309,21 @@ private void DoClose()
303309
}
304310
}
305311

312+
private void CloseDatabase()
313+
{
314+
m_cachedProcedures = null;
315+
if (ActiveReader != null)
316+
{
317+
ActiveReader.Dispose();
318+
ActiveReader = null;
319+
}
320+
if (CurrentTransaction != null)
321+
{
322+
CurrentTransaction.Dispose();
323+
CurrentTransaction = null;
324+
}
325+
}
326+
306327
MySqlConnectionStringBuilder m_connectionStringBuilder;
307328
ConnectionSettings m_connectionSettings;
308329
MySqlSession m_session;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace MySql.Data.Serialization
5+
{
6+
internal class InitDatabasePayload
7+
{
8+
public static PayloadData Create(string databaseName)
9+
{
10+
var writer = new PayloadWriter();
11+
12+
writer.WriteByte((byte) CommandKind.InitDatabase);
13+
writer.Write(Encoding.UTF8.GetBytes(databaseName));
14+
15+
return new PayloadData(new ArraySegment<byte>(writer.ToBytes()));
16+
}
17+
}
18+
}

src/MySqlConnector/Serialization/MySqlSession.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public MySqlSession(ConnectionPool pool, int poolGeneration)
3232
public byte[] AuthPluginData { get; set; }
3333
public ConnectionPool Pool { get; }
3434
public int PoolGeneration { get; }
35+
public string DatabaseOverride { get; set; }
3536

3637
public void ReturnToPool() => Pool?.Return(this);
3738

0 commit comments

Comments
 (0)