Skip to content

Commit

Permalink
WL#12621, DevAPI: Handling of Default Schema.
Browse files Browse the repository at this point in the history
  • Loading branch information
fjssilva committed Nov 26, 2018
1 parent d4aa2dc commit b234a88
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

Version 8.0.14

- WL#12621, DevAPI: Handling of Default Schema.

- Fix for Bug#93340 (28970166), C/J BUILD SCRIPT IS TOO VERBOSE

- WL#12462, DevAPI: Be prepared for initial notice on connection.
Expand Down
5 changes: 2 additions & 3 deletions src/main/user-impl/java/com/mysql/cj/xdevapi/SessionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import com.mysql.cj.conf.PropertySet;
import com.mysql.cj.conf.RuntimeProperty;
import com.mysql.cj.exceptions.MysqlErrorNumbers;
import com.mysql.cj.exceptions.WrongArgumentException;
import com.mysql.cj.protocol.x.XMessage;
import com.mysql.cj.protocol.x.XMessageBuilder;
import com.mysql.cj.protocol.x.XProtocol;
Expand Down Expand Up @@ -100,8 +99,8 @@ public String getDefaultSchemaName() {
}

public Schema getDefaultSchema() {
if (this.defaultSchemaName == null) {
throw new WrongArgumentException("Default schema not provided");
if (this.defaultSchemaName == null || this.defaultSchemaName.length() == 0) {
return null;
}
return new SchemaImpl(this.session, this, this.defaultSchemaName);
}
Expand Down
161 changes: 161 additions & 0 deletions src/test/java/testsuite/x/devapi/SessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand All @@ -52,6 +53,7 @@
import org.junit.Test;

import com.mysql.cj.CoreSession;
import com.mysql.cj.ServerVersion;
import com.mysql.cj.conf.PropertyKey;
import com.mysql.cj.exceptions.CJCommunicationsException;
import com.mysql.cj.exceptions.CJPacketTooBigException;
Expand Down Expand Up @@ -104,6 +106,165 @@ private String getRandomTestSchemaName() {
return n;
}

@Test
public void urlWithDefaultSchema() {
if (!this.isSetForXTests) {
return;
}

try {
// Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms.
this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute();
this.session.sql("GRANT SELECT ON *.* TO 'testUserN'@'%'").execute();

final String testSchemaName = getRandomTestSchemaName();
this.session.createSchema(testSchemaName);

final SessionFactory testSessionFactory = new SessionFactory();
final String testUriPattern = "mysqlx://testUserN:testUserN@%s:%s/%s?xdevapi.auth=%s";

// Check if the default schema is correctly sent when using different authentication mechanisms.
String[] authMechs = mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4")) ? new String[] { "PLAIN", "MYSQL41", "SHA256_MEMORY" }
: new String[] { "PLAIN", "MYSQL41" };
for (String authMech : authMechs) {
final String testCase = "Testing default schema provided in authentication mecanism '" + authMech + "'.";

// Test using a connection String.
final String testUri = String.format(testUriPattern, getTestHost(), getTestPort(), testSchemaName, authMech);

Session testSession = testSessionFactory.getSession(testUri);
assertTrue(testCase, testSession.getUri().contains("/" + testSchemaName + "?"));
assertEquals(testCase, testSchemaName, testSession.getDefaultSchemaName());
assertNotNull(testCase, testSession.getDefaultSchema());
assertEquals(testCase, testSchemaName, testSession.getDefaultSchema().getName());
assertEquals(testCase, testSchemaName, testSession.sql("SELECT database()").execute().fetchOne().getString(0));
testSession.close();

// Test using a properties map.
final Properties testProps = new Properties();
testProps.setProperty(PropertyKey.USER.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.PASSWORD.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.HOST.getKeyName(), getTestHost());
testProps.setProperty(PropertyKey.PORT.getKeyName(), String.valueOf(getTestPort()));
testProps.setProperty(PropertyKey.DBNAME.getKeyName(), testSchemaName);
testProps.setProperty(PropertyKey.xdevapiAuth.getKeyName(), authMech);

testSession = testSessionFactory.getSession(testProps);
assertTrue(testCase, testSession.getUri().contains("/" + testSchemaName + "?"));
assertEquals(testCase, testSchemaName, testSession.getDefaultSchemaName());
assertNotNull(testCase, testSession.getDefaultSchema());
assertEquals(testCase, testSchemaName, testSession.getDefaultSchema().getName());
assertEquals(testCase, testSchemaName, testSession.sql("SELECT database()").execute().fetchOne().getString(0));
testSession.close();
}
} finally {
this.session.sql("DROP USER IF EXISTS testUserN").execute();
}
}

@Test
public void urlWithoutDefaultSchema() {
if (!this.isSetForXTests) {
return;
}

try {
// Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms.
this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute();
this.session.sql("GRANT SELECT ON *.* TO 'testUserN'@'%'").execute();

final SessionFactory testSessionFactory = new SessionFactory();
final String testUriPattern1 = "mysqlx://testUserN:testUserN@%s:%s/?xdevapi.auth=%s";
final String testUriPattern2 = "mysqlx://testUserN:testUserN@%s:%s?xdevapi.auth=%s";
final String testUriPattern3 = "mysqlx://testUserN:testUserN@address=(host=%s)(port=%s)(xdevapi.auth=%s)";

// Check if not setting a default schema works correctly when using different authentication mechanisms.
String[] authMechs = mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4")) ? new String[] { "PLAIN", "MYSQL41", "SHA256_MEMORY" }
: new String[] { "PLAIN", "MYSQL41" };
for (String authMech : authMechs) {
for (String testUriPattern : new String[] { testUriPattern1, testUriPattern2, testUriPattern3 }) {
// Test using a connection String.
final String testUri = String.format(testUriPattern, getTestHost(), getTestPort(), authMech);
final String testCase = "Testing no default schema with authentication mecanism '" + authMech + "' and URI '" + testUri + "'.";

Session testSession = testSessionFactory.getSession(testUri);
assertTrue(testCase, testSession.getUri().contains("/?"));
assertEquals(testCase, "", testSession.getDefaultSchemaName());
assertNull(testCase, testSession.getDefaultSchema());
assertNull(testCase, testSession.sql("SELECT database()").execute().fetchOne().getString(0));
testSession.close();
}

// Test using a properties map.
final String testCase = "Testing no default schema with authentication mecanism '" + authMech + "'.";
final Properties testProps = new Properties();
testProps.setProperty(PropertyKey.USER.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.PASSWORD.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.HOST.getKeyName(), getTestHost());
testProps.setProperty(PropertyKey.PORT.getKeyName(), String.valueOf(getTestPort()));
testProps.setProperty(PropertyKey.xdevapiAuth.getKeyName(), authMech);

Session testSession = testSessionFactory.getSession(testProps);
assertTrue(testCase, testSession.getUri().contains("/?"));
assertEquals(testCase, "", testSession.getDefaultSchemaName());
assertNull(testCase, testSession.getDefaultSchema());
assertNull(testCase, testSession.sql("SELECT database()").execute().fetchOne().getString(0));
testSession.close();
}
} finally {
this.session.sql("DROP USER IF EXISTS testUserN").execute();
}
}

@Test
public void invalidDefaultSchema() {
if (!this.isSetForXTests) {
return;
}

try {
// Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms.
this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute();
this.session.sql("GRANT SELECT ON *.* TO 'testUserN'@'%'").execute();

final String testSchemaName = getRandomTestSchemaName();

final SessionFactory testSessionFactory = new SessionFactory();
final String testUriPattern = "mysqlx://testUserN:testUserN@%s:%s/%s?xdevapi.auth=%s";

// Check if the default schema is correctly sent when using different authentication mechanisms.
String[] authMechs = mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4")) ? new String[] { "PLAIN", "MYSQL41", "SHA256_MEMORY" }
: new String[] { "PLAIN", "MYSQL41" };
for (String authMech : authMechs) {
final String testCase = "Testing missing default schema provided in authentication mecanism '" + authMech + "'.";

// Test using a connection String.
final String testUri = String.format(testUriPattern, getTestHost(), getTestPort(), testSchemaName, authMech);

assertThrows(testCase, XProtocolError.class, "ERROR \\d{4} \\(HY000\\) Unknown database '" + testSchemaName + "'", () -> {
testSessionFactory.getSession(testUri);
return null;
});

// Test using a properties map.
final Properties testProps = new Properties();
testProps.setProperty(PropertyKey.USER.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.PASSWORD.getKeyName(), "testUserN");
testProps.setProperty(PropertyKey.HOST.getKeyName(), getTestHost());
testProps.setProperty(PropertyKey.PORT.getKeyName(), String.valueOf(getTestPort()));
testProps.setProperty(PropertyKey.DBNAME.getKeyName(), testSchemaName);
testProps.setProperty(PropertyKey.xdevapiAuth.getKeyName(), authMech);

assertThrows(testCase, XProtocolError.class, "ERROR \\d{4} \\(HY000\\) Unknown database '" + testSchemaName + "'", () -> {
testSessionFactory.getSession(testUri);
return null;
});
}
} finally {
this.session.sql("DROP USER IF EXISTS testUserN").execute();
}
}

@Test
public void createDropSchema() {
if (!this.isSetForXTests) {
Expand Down

0 comments on commit b234a88

Please sign in to comment.