diff options
author | bvosburgh | 2011-03-22 15:49:10 +0000 |
---|---|---|
committer | bvosburgh | 2011-03-22 15:49:10 +0000 |
commit | 94f754ccfddeed4302d55cdd9555cdd3d2e1c4c6 (patch) | |
tree | 23847c37681254a31816276d7ae3bd68418a1e5f | |
parent | 18aef55f8ac7bf00d86f4bb657192bfceb8ea39d (diff) | |
download | webtools.dali-94f754ccfddeed4302d55cdd9555cdd3d2e1c4c6.tar.gz webtools.dali-94f754ccfddeed4302d55cdd9555cdd3d2e1c4c6.tar.xz webtools.dali-94f754ccfddeed4302d55cdd9555cdd3d2e1c4c6.zip |
add MySQL ANSI_QUOTES support; add check for SQL reserved words (that must be delimited)
6 files changed, 134 insertions, 115 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPDatabaseWrapper.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPDatabaseWrapper.java index 22bebaeaa2..ed7d51577a 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPDatabaseWrapper.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/DTPDatabaseWrapper.java @@ -301,6 +301,7 @@ final class DTPDatabaseWrapper return this.dtpDriverAdapter.selectTableForIdentifier(tables, identifier); } + // TODO add to interface? (so it can be used by AbstractDTPDriverAdapter) DatabaseDefinition getDTPDefinition() { return RDBCorePlugin.getDefault().getDatabaseDefinitionRegistry().getDefinition(this.dtpDatabase); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/AbstractDTPDriverAdapter.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/AbstractDTPDriverAdapter.java index ea1af7e5fe..6a3e845164 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/AbstractDTPDriverAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/AbstractDTPDriverAdapter.java @@ -19,6 +19,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.eclipse.datatools.connectivity.sqm.core.definition.DatabaseDefinition; +import org.eclipse.datatools.connectivity.sqm.internal.core.RDBCorePlugin; import org.eclipse.jpt.common.utility.internal.ArrayTools; import org.eclipse.jpt.common.utility.internal.CollectionTools; import org.eclipse.jpt.common.utility.internal.StringTools; @@ -87,7 +89,7 @@ abstract class AbstractDTPDriverAdapter return this.supportsCatalogs() ? this.getDefaultCatalogNames_() : Collections.<String>emptyList(); } - private final Iterable<String> getDefaultCatalogNames_() { + final Iterable<String> getDefaultCatalogNames_() { ArrayList<String> names = new ArrayList<String>(); this.addDefaultCatalogNamesTo(names); return names; @@ -162,9 +164,13 @@ abstract class AbstractDTPDriverAdapter || this.nameIsNotFolded(name); } - // TODO SQL reserved identifiers must be delimited - boolean nameIsReservedWord(@SuppressWarnings("unused") String name) { - return false; + boolean nameIsReservedWord(String name) { + return this.getDTPDefinition().isSQLKeyword(name); + } + + // TODO make Database.getDTPDefinition() public? + DatabaseDefinition getDTPDefinition() { + return RDBCorePlugin.getDefault().getDatabaseDefinitionRegistry().getDefinition(this.database.getDTPDatabase()); } /** diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/CatalogStrategy.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/CatalogStrategy.java index 3e29daf6bd..1fa345a172 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/CatalogStrategy.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/CatalogStrategy.java @@ -28,7 +28,6 @@ interface CatalogStrategy { /** * Return the DTP database's catalogs. This will be empty if the database * does <em>not</em> support catalogs. - * * @see #supportsCatalogs() */ List<Catalog> getCatalogs(); @@ -36,7 +35,6 @@ interface CatalogStrategy { /** * Return the DTP database's schemas. This will be empty if the database * supports catalogs. - * * @see #supportsCatalogs() */ List<Schema> getSchemas(); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/DTPDriverAdapter.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/DTPDriverAdapter.java index 509dddbf53..e94380b533 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/DTPDriverAdapter.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/DTPDriverAdapter.java @@ -46,7 +46,6 @@ public interface DTPDriverAdapter { /** * Return the DTP database's catalogs. * This will be empty if the database does not support catalogs. - * * @see #supportsCatalogs() */ List<org.eclipse.datatools.modelbase.sql.schema.Catalog> getDTPCatalogs(); @@ -65,7 +64,6 @@ public interface DTPDriverAdapter { /** * Return the DTP database's schemas. * This will be empty if the database supports catalogs. - * * @see #supportsCatalogs() */ List<org.eclipse.datatools.modelbase.sql.schema.Schema> getDTPSchemas(); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/MySQL.java b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/MySQL.java index a1f709e6fb..8d76aaf498 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/MySQL.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.db/src/org/eclipse/jpt/jpa/db/internal/driver/MySQL.java @@ -12,6 +12,7 @@ package org.eclipse.jpt.jpa.db.internal.driver; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.eclipse.jpt.common.utility.internal.ArrayTools; import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.jpt.common.utility.internal.Tools; import org.eclipse.jpt.jpa.db.Database; @@ -21,7 +22,7 @@ import org.eclipse.jpt.jpa.db.Table; /** * MySQL is a bit unusual in that it does <em>not</em> fold <em>regular</em> - * identifiers and most of its identifiers are <em>not</em> case-sensitive + * identifiers and its identifiers are <em>not</em> case-sensitive * (except in special cases, described below). Even <em>delimited</em> identifiers * are case-<em>in</em>sensitive. (Delimiters are only needed for identifiers * that contain special characters or are reserved words.) @@ -40,14 +41,19 @@ import org.eclipse.jpt.jpa.db.Table; * O/S; and the actual case-sensitivity of the names will ulimately be * determined by the behavior of filenames on the O/S. * <p> - * See http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html. + * See <a href=http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html> + * Identifier Case Sensitivity</a>. */ class MySQL extends AbstractDTPDriverAdapter { - /** lazy-initialized */ + /** lazy-initialized; value comes from the database server */ private int lower_case_table_names = -1; + /** lazy-initialized; value comes from the database server */ + private Boolean ANSI_QUOTES = null; + + MySQL(Database database) { super(database); } @@ -84,7 +90,7 @@ class MySQL * fine without any folding anyways. * <li>We only test whether a name is already folded when determining * whether it must be delimited; and MySQL ignores delimiters - * when it comes to case-sensitivity, so we can leave any "normal" + * when it comes to case-sensitivity, so we can leave any <em>regular</em> * mixed-case names undelimited. (MySQL only requires delimiters for * special characters and reserved words.) * </ul> @@ -127,11 +133,10 @@ class MySQL * By default, MySQL delimits identifiers with backticks (<code>`</code>); * but it can also be configured to use double-quotes. */ - //TODO query for ANSI_QUOTES setting @Override boolean identifierIsDelimited(String identifier) { return StringTools.stringIsDelimited(identifier, BACKTICK) - || super.identifierIsDelimited(identifier); + || (StringTools.stringIsQuoted(identifier) && this.doubleQuoteIsIdentifierDelimiter()); } private static final char BACKTICK = '`'; @@ -171,7 +176,7 @@ class MySQL super.selectTableForIdentifier(tables, identifier); } - <T extends DatabaseObject> T selectDatabaseObjectForIdentifierRespectCase(Iterable<T> databaseObjects, String identifier) { + private <T extends DatabaseObject> T selectDatabaseObjectForIdentifierRespectCase(Iterable<T> databaseObjects, String identifier) { return this.selectDatabaseObjectNamedRespectCase(databaseObjects, this.convertIdentifierToName(identifier)); } @@ -188,15 +193,15 @@ class MySQL } - // ********** misc ********** + // ********** lower_case_table_names ********** private boolean tableNamesAreCaseSensitive() { - return this.getLowerCaseTableNamesValue() == 0; + return this.getLowerCaseTableNames() == 0; } - private int getLowerCaseTableNamesValue() { + private int getLowerCaseTableNames() { if (this.lower_case_table_names == -1) { - this.lower_case_table_names = this.buildLowerCaseTableNamesValue(); + this.lower_case_table_names = this.buildLowerCaseTableNames(); } return this.lower_case_table_names; } @@ -205,17 +210,21 @@ class MySQL * If we don't have a live connection (i.e. we are working off-line), * use the current O/S default setting(?). */ - private int buildLowerCaseTableNamesValue() { - int dbValue = this.getLowerCaseTableNamesValueFromDatabase(); - return (dbValue != -1) ? dbValue : this.getLowerCaseTableNamesValueFromOS(); + private int buildLowerCaseTableNames() { + int dbValue = this.getLowerCaseTableNamesFromDatabase(); + return (dbValue != -1) ? dbValue : this.getLowerCaseTableNamesFromOS(); } - private int getLowerCaseTableNamesValueFromDatabase() { + /** + * See <a href=http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html> + * Identifier Case Sensitivity</a>. + */ + private int getLowerCaseTableNamesFromDatabase() { if (this.getConnectionProfile().isDisconnected()) { return -1; } // the underscore is a wild character on MySQL, so we need to escape it - List<Map<String, Object>> rows = this.execute("show variables like 'lower\\_case\\_table\\_names'"); //$NON-NLS-1$ + List<Map<String, Object>> rows = this.execute("SHOW VARIABLES LIKE 'lower\\_case\\_table\\_names'"); //$NON-NLS-1$ if (rows.isEmpty()) { return -1; } @@ -231,7 +240,7 @@ class MySQL * Return the default value for the current O/S (unfortunately this is the * client O/S, not the MySQL Server O/S...). */ - private int getLowerCaseTableNamesValueFromOS() { + private int getLowerCaseTableNamesFromOS() { if (Tools.osIsMac()) { return 2; } @@ -242,6 +251,50 @@ class MySQL } + // ********** ANSI_QUOTES ********** + + private boolean doubleQuoteIsIdentifierDelimiter() { + return this.getANSIQuotes().booleanValue(); + } + + private Boolean getANSIQuotes() { + if (this.ANSI_QUOTES == null) { + this.ANSI_QUOTES = this.buildANSIQuotes(); + } + return this.ANSI_QUOTES; + } + + /** + * If we don't have a live connection (i.e. we are working off-line), + * return <code>FALSE</code> (the default setting). + */ + private Boolean buildANSIQuotes() { + Boolean dbValue = this.getANSIQuotesFromDatabase(); + return (dbValue != null) ? dbValue : Boolean.FALSE; + } + + /** + * See <a href=http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_ansi_quotes> + * ANSI_QUOTES</a>. + */ + private Boolean getANSIQuotesFromDatabase() { + if (this.getConnectionProfile().isDisconnected()) { + return null; + } + List<Map<String, Object>> rows = this.execute("SELECT @@SESSION.sql_mode"); //$NON-NLS-1$ + if (rows.isEmpty()) { + return null; + } + Map<String, Object> row = rows.get(0); + String sql_mode = (String) row.get("@@SESSION.sql_mode"); //$NON-NLS-1$ + if (sql_mode == null) { + return null; + } + String[] modes = sql_mode.split(","); //$NON-NLS-1$ + return Boolean.valueOf(ArrayTools.contains(modes, "ANSI_QUOTES")); //$NON-NLS-1$ + } + + // ********** factory ********** static class Factory implements DTPDriverAdapterFactory { diff --git a/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/MySQLTests.java b/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/MySQLTests.java index 31c3dff1a6..e35b7e7fca 100644 --- a/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/MySQLTests.java +++ b/jpa/tests/org.eclipse.jpt.jpa.db.tests/src/org/eclipse/jpt/jpa/db/tests/internal/platforms/MySQLTests.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.Properties; import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCDriverDefinitionConstants; import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.jpt.common.utility.internal.ArrayTools; import org.eclipse.jpt.jpa.db.Column; import org.eclipse.jpt.jpa.db.ForeignKey; import org.eclipse.jpt.jpa.db.Schema; @@ -24,14 +25,15 @@ import org.eclipse.jpt.jpa.db.Table; /** * MySQL * - * Notes: - * - We can only get database objects from the database associated with our - * connection profile. - * - We can reference objects across multiple databases, so they are sorta like - * schemas.... - * - Foreign keys must be defined as table-level constraints; they cannot be - * defined as part of the column clause. - * - Case-sensitivity and -folding is whacked on MySQL.... + * Notes:<ul> + * <li>We can only get database objects from the database associated with our + * connection profile. + * <li>We can reference objects across multiple databases, so they are sorta like + * schemas.... + * <li>Foreign keys must be defined as table-level constraints; they cannot be + * defined as part of the column clause. + * <li>Case-sensitivity and -folding is whacked on MySQL.... + * </ul> */ @SuppressWarnings("nls") public class MySQLTests extends DTPPlatformTests { @@ -103,7 +105,7 @@ public class MySQLTests extends DTPPlatformTests { } private String getDatabaseName() { - return "dalitest"; + return this.getUserID(); // by convention... } @Override @@ -130,14 +132,12 @@ public class MySQLTests extends DTPPlatformTests { TestConnectionListener listener = new TestConnectionListener(); this.connectionProfile.addConnectionListener(listener); - this.dropDatabase(this.getDatabaseName()); - this.executeUpdate("CREATE DATABASE " + this.getDatabaseName()); this.getJDBCConnection().setCatalog(this.getDatabaseName()); - this.dropTable(this.getDatabaseName(), "foo_baz"); - this.dropTable(this.getDatabaseName(), "baz"); - this.dropTable(this.getDatabaseName(), "foo"); - this.dropTable(this.getDatabaseName(), "bar"); + this.dropTable("foo_baz"); + this.dropTable("baz"); + this.dropTable("foo"); + this.dropTable("bar"); this.executeUpdate(this.buildBarDDL()); this.executeUpdate(this.buildFooDDL()); @@ -154,6 +154,8 @@ public class MySQLTests extends DTPPlatformTests { Table fooTable = schema.getTableNamed("foo"); assertEquals(3, fooTable.getColumnsSize()); assertEquals(1, fooTable.getPrimaryKeyColumnsSize()); + // if the tables are created with MyISAM as the backing store + // there will be no foreign keys assertEquals(1, fooTable.getForeignKeysSize()); Column pkColumn = fooTable.getPrimaryKeyColumn(); @@ -207,18 +209,16 @@ public class MySQLTests extends DTPPlatformTests { assertTrue(foo_bazTable.joinTableNameIsDefault()); assertTrue(foo_bazTable.getColumnNamed("foo_id").isPartOfForeignKey()); - this.dropTable(this.getDatabaseName(), "foo_baz"); - this.dropTable(this.getDatabaseName(), "baz"); - this.dropTable(this.getDatabaseName(), "foo"); - this.dropTable(this.getDatabaseName(), "bar"); - - this.dropDatabase(this.getDatabaseName()); + this.dropTable("foo_baz"); + this.dropTable("baz"); + this.dropTable("foo"); + this.dropTable("bar"); this.connectionProfile.removeConnectionListener(listener); this.connectionProfile.disconnect(); } - private static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$ + private static final String CR = System.getProperty("line.separator"); private String buildBarDDL() { StringBuilder sb = new StringBuilder(200); @@ -235,7 +235,7 @@ public class MySQLTests extends DTPPlatformTests { sb.append(" id INTEGER PRIMARY KEY,").append(CR); sb.append(" name VARCHAR(20),").append(CR); sb.append(" bar_id INTEGER,").append(CR); - sb.append(" FOREIGN KEY (bar_id) REFERENCES bar(id)").append(CR); + sb.append(" CONSTRAINT BAR FOREIGN KEY (bar_id) REFERENCES bar(id)").append(CR); sb.append(")").append(CR); return sb.toString(); } @@ -269,13 +269,11 @@ public class MySQLTests extends DTPPlatformTests { TestConnectionListener listener = new TestConnectionListener(); this.connectionProfile.addConnectionListener(listener); - this.dropDatabase(this.getDatabaseName()); - this.executeUpdate("CREATE DATABASE " + this.getDatabaseName()); this.getJDBCConnection().setCatalog(this.getDatabaseName()); - this.dropTable(this.getDatabaseName(), "test1"); - this.dropTable(this.getDatabaseName(), "TEST2"); - this.dropTable(this.getDatabaseName(), "`TEST3`"); + this.dropTable("test1"); + this.dropTable("TEST2"); + this.dropTable("`TEST3`"); this.executeUpdate("CREATE TABLE test1 (id INTEGER, name VARCHAR(20))"); this.executeUpdate("CREATE TABLE TEST2 (id INTEGER, name VARCHAR(20))"); @@ -291,7 +289,7 @@ public class MySQLTests extends DTPPlatformTests { assertNotNull(test1Table); // if 'lctn' is 0 (UNIX), the table name is case-sensitive - int lctn = this.getLowerCaseTableNamesValueFromDatabase(); + int lctn = this.getLowerCaseTableNamesFromDatabase(); String test2Identifier = (lctn == 0) ? "TEST2" : "test2"; Table test2Table = schema.getTableForIdentifier(test2Identifier); @@ -301,17 +299,15 @@ public class MySQLTests extends DTPPlatformTests { Table test3Table = schema.getTableForIdentifier(test3Identifier); assertNotNull(test3Table); - this.dropTable(this.getDatabaseName(), "test1"); - this.dropTable(this.getDatabaseName(), "TEST2"); - this.dropTable(this.getDatabaseName(), "`TEST3`"); - - this.dropDatabase(this.getDatabaseName()); + this.dropTable("test1"); + this.dropTable("TEST2"); + this.dropTable("`TEST3`"); this.connectionProfile.removeConnectionListener(listener); this.connectionProfile.disconnect(); } - protected int getLowerCaseTableNamesValueFromDatabase() throws SQLException { + protected int getLowerCaseTableNamesFromDatabase() throws SQLException { // the underscore is a wild character on MySQL, so we need to escape it ArrayList<HashMap<String, Object>> rows = this.execute("show variables like 'lower\\_case\\_table\\_names'"); Map<String, Object> row = rows.get(0); @@ -328,11 +324,9 @@ public class MySQLTests extends DTPPlatformTests { TestConnectionListener listener = new TestConnectionListener(); this.connectionProfile.addConnectionListener(listener); - this.dropDatabase(this.getDatabaseName()); - this.executeUpdate("CREATE DATABASE " + this.getDatabaseName()); this.getJDBCConnection().setCatalog(this.getDatabaseName()); - this.dropTable(this.getDatabaseName(), "test"); + this.dropTable("test"); // lowercase this.executeUpdate("CREATE TABLE test (id INTEGER, name VARCHAR(20))"); @@ -347,7 +341,7 @@ public class MySQLTests extends DTPPlatformTests { assertNotNull(table.getColumnForIdentifier("id")); assertNotNull(table.getColumnForIdentifier("name")); - this.dropTable(this.getDatabaseName(), "test"); + this.dropTable("test"); // uppercase this.executeUpdate("CREATE TABLE test (ID INTEGER, NAME VARCHAR(20))"); @@ -362,7 +356,7 @@ public class MySQLTests extends DTPPlatformTests { assertNotNull(table.getColumnForIdentifier("id")); assertNotNull(table.getColumnForIdentifier("name")); - this.dropTable(this.getDatabaseName(), "test"); + this.dropTable("test"); // mixed case this.executeUpdate("CREATE TABLE test (Id INTEGER, Name VARCHAR(20))"); @@ -377,7 +371,7 @@ public class MySQLTests extends DTPPlatformTests { assertNotNull(table.getColumnForIdentifier("id")); assertNotNull(table.getColumnForIdentifier("name")); - this.dropTable(this.getDatabaseName(), "test"); + this.dropTable("test"); // delimited this.executeUpdate("CREATE TABLE test (`Id` INTEGER, `Name` VARCHAR(20))"); @@ -391,64 +385,33 @@ public class MySQLTests extends DTPPlatformTests { assertNotNull(table.getColumnNamed("Name")); assertNotNull(table.getColumnForIdentifier("id")); assertNotNull(table.getColumnForIdentifier("name")); - assertNotNull(table.getColumnForIdentifier("`Id`")); - assertNotNull(table.getColumnForIdentifier("\"Id\"")); - assertNotNull(table.getColumnForIdentifier("`Name`")); - assertNotNull(table.getColumnForIdentifier("\"Name\"")); - this.dropTable(this.getDatabaseName(), "test"); - - this.dropDatabase(this.getDatabaseName()); - - this.connectionProfile.removeConnectionListener(listener); - this.connectionProfile.disconnect(); - } - - /** - * We can only get a single "schema" per connection via DTP, - * so cross-schema references are not visible. - */ - public void testCrossSchemaReference() throws Exception { - this.connectionProfile.connect(); - TestConnectionListener listener = new TestConnectionListener(); - this.connectionProfile.addConnectionListener(listener); - - this.dropDatabase("xref_test2"); - this.dropDatabase("xref_test1"); - - this.executeUpdate("CREATE DATABASE xref_test1"); - this.getJDBCConnection().setCatalog("xref_test1"); - this.executeUpdate("CREATE TABLE org (id INTEGER PRIMARY KEY, name VARCHAR(20))"); - - this.executeUpdate("CREATE DATABASE xref_test2"); - this.getJDBCConnection().setCatalog("xref_test2"); - this.executeUpdate("CREATE TABLE emp (id INTEGER PRIMARY KEY, name VARCHAR(20), " + - "org_id INTEGER, FOREIGN KEY (org_id) REFERENCES xref_test1.org(id))"); + boolean quotes = this.getANSIQuotesFromDatabase(); + assertNotNull(table.getColumnForIdentifier("`Id`")); + if (quotes) { + assertNotNull(table.getColumnForIdentifier("\"Id\"")); + } - this.getJDBCConnection().setCatalog("xref_test2"); - // the MySQL database does NOT refresh - see bug 279721... - ((ICatalogObject) this.getDTPDatabase()).refresh(); - // ...refresh the single schema instead - ((ICatalogObject) getDTPSchema(this.getDefaultSchema())).refresh(); - Schema schema2 = this.getDefaultSchema(); - assertNotNull(schema2); - Table empTable = schema2.getTableNamed("emp"); - assertNotNull(empTable); - // no foreign keys... - assertEquals(0, empTable.getForeignKeysSize()); + assertNotNull(table.getColumnForIdentifier("`Name`")); + if (quotes) { + assertNotNull(table.getColumnForIdentifier("\"Name\"")); + } - this.dropDatabase("xref_test2"); - this.dropDatabase("xref_test1"); + this.dropTable("test"); this.connectionProfile.removeConnectionListener(listener); this.connectionProfile.disconnect(); } - private void dropTable(String dbName, String tableName) throws Exception { - this.executeUpdate("DROP TABLE IF EXISTS " + dbName + '.' + tableName); + protected boolean getANSIQuotesFromDatabase() throws SQLException { + ArrayList<HashMap<String, Object>> rows = this.execute("SELECT @@SESSION.sql_mode"); + Map<String, Object> row = rows.get(0); + String sql_mode = (String) row.get("@@SESSION.sql_mode"); + String[] modes = sql_mode.split(","); + return Boolean.valueOf(ArrayTools.contains(modes, "ANSI_QUOTES")).booleanValue(); } - private void dropDatabase(String name) throws Exception { - this.executeUpdate("DROP DATABASE IF EXISTS " + name); + private void dropTable(String tableName) throws Exception { + this.executeUpdate("DROP TABLE IF EXISTS " + tableName); } } |