Skip to content

Commit 9a025d9

Browse files
committed
Implement ChangeDatabase. Fixes #201
1 parent e09fa1b commit 9a025d9

15 files changed

+270
-18
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

@@ -280,16 +295,7 @@ private void DoClose()
280295
{
281296
if (m_connectionState != ConnectionState.Closed)
282297
{
283-
m_cachedProcedures = null;
284-
if (ActiveReader != null){
285-
ActiveReader.Dispose();
286-
ActiveReader = null;
287-
}
288-
if (CurrentTransaction != null)
289-
{
290-
CurrentTransaction.Dispose();
291-
CurrentTransaction = null;
292-
}
298+
CloseDatabase();
293299
if (m_session != null)
294300
{
295301
if (m_connectionSettings.Pooling)
@@ -302,6 +308,21 @@ private void DoClose()
302308
}
303309
}
304310

311+
private void CloseDatabase()
312+
{
313+
m_cachedProcedures = null;
314+
if (ActiveReader != null)
315+
{
316+
ActiveReader.Dispose();
317+
ActiveReader = null;
318+
}
319+
if (CurrentTransaction != null)
320+
{
321+
CurrentTransaction.Dispose();
322+
CurrentTransaction = null;
323+
}
324+
}
325+
305326
MySqlConnectionStringBuilder m_connectionStringBuilder;
306327
ConnectionSettings m_connectionSettings;
307328
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)