Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2008-09-12 05:20:22 +0000
committerbvosburgh2008-09-12 05:20:22 +0000
commit9a4a93e9c623edf8b2fa8f12eda4af78e94c96ac (patch)
treea91e196bd31cdf40278555bdf4ce5b739dc6d68f /jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db
parent3c751de5e716860007a8c030215d623a1897ca40 (diff)
downloadwebtools.dali-9a4a93e9c623edf8b2fa8f12eda4af78e94c96ac.tar.gz
webtools.dali-9a4a93e9c623edf8b2fa8f12eda4af78e94c96ac.tar.xz
webtools.dali-9a4a93e9c623edf8b2fa8f12eda4af78e94c96ac.zip
[242321] database case-sensitivity
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db')
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfile.java2
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfileFactory.java3
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Database.java56
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseFinder.java18
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseObject.java25
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Schema.java45
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/SchemaContainer.java28
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Table.java20
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPCatalogWrapper.java5
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java28
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseObjectWrapper.java73
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java1059
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPForeignKeyWrapper.java4
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaContainerWrapper.java28
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaWrapper.java52
-rw-r--r--jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTableWrapper.java25
16 files changed, 1044 insertions, 427 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfile.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfile.java
index 95a9ad4460..6dd625a783 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfile.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfile.java
@@ -99,7 +99,7 @@ public interface ConnectionProfile
/**
* Return the name of the Driver instance
*/
- public String getDriverName();
+ String getDriverName();
// ********** connection **********
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfileFactory.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfileFactory.java
index 4bff72eae2..e44773953a 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfileFactory.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/ConnectionProfileFactory.java
@@ -48,7 +48,8 @@ public interface ConnectionProfileFactory {
* Clients should use this method when a JPA platform is unavailable
* (e.g. during project creation). The returned connection profile will
* not be able to search for database objects by any names other than
- * those supplied by the factory.
+ * those supplied by the factory (i.e. lookups cannot be performed with
+ * "identifiers").
*/
ConnectionProfile buildConnectionProfile(String name);
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Database.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Database.java
index d4f3c1b9e1..c101d40f59 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Database.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Database.java
@@ -29,22 +29,15 @@ public interface Database
// ********** properties **********
/**
- * Return the database's vendor.
+ * Return the name of the database's vendor.
*/
- String getVendor();
+ String getVendorName();
/**
* Return the database's version.
*/
String getVersion();
- /**
- * Return the database's default schema.
- * In most cases the default schema's name will match the user name.
- * It may be null.
- */
- Schema getDefaultSchema();
-
// ********** catalogs **********
@@ -55,40 +48,59 @@ public interface Database
/**
* Return the database's catalogs.
+ * @see #supportsCatalogs()
*/
Iterator<Catalog> catalogs();
/**
* Return the number of catalogs the database contains.
+ * @see #supportsCatalogs()
*/
int catalogsSize();
/**
- * Return the names of the database's catalogs.
+ * Return the catalog with specified name. The name must be an exact match
+ * of the catalog's name.
+ * @see #supportsCatalogs()
+ * @see #getCatalogForIdentifier(String)
+ */
+ Catalog getCatalogNamed(String name);
+
+ /**
+ * Return the database's catalog identifiers, sorted by name.
*/
- Iterator<String> catalogNames();
+ Iterator<String> sortedCatalogIdentifiers();
+
+ /**
+ * Return the catalog for the specified identifier. The identifier should
+ * be an SQL identifier (i.e. quoted when case-sensitive or containing
+ * special characters, unquoted otherwise).
+ * @see #supportsCatalogs()
+ * @see #getCatalogNamed(String)
+ */
+ Catalog getCatalogForIdentifier(String identifier);
/**
* Return the database's "default" catalog.
* Return null if the database does not support catalogs.
+ * @see #supportsCatalogs()
*/
Catalog getDefaultCatalog();
- /**
- * Return the catalog with specified name. The name should be an SQL
- * identifier (i.e. quoted when case-sensitive, unquoted when
- * case-insensitive).
- */
- Catalog getCatalogNamed(String name);
+ // ********** utility methods **********
- // ********** search utility **********
+ /**
+ * Select and return from the specified list of database objects the
+ * database object identified by the specified identifier.
+ * The identifier should be an SQL identifier (i.e. delimited when
+ * non-"normal").
+ */
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier);
/**
- * Return the database object from the specified list with specified name.
- * The name should be an SQL identifier (i.e. quoted when case-sensitive,
- * unquoted when case-insensitive).
+ * Convert the specified name to a database-appropriate SQL identifier.
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name);
+ String convertNameToIdentifier(String name);
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseFinder.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseFinder.java
index d8cf20e36f..e7806e7933 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseFinder.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseFinder.java
@@ -25,9 +25,10 @@ package org.eclipse.jpt.db;
public interface DatabaseFinder {
/**
- * Return the database object with the specified name from the specified list.
+ * Select and return from the specified list of database objects the
+ * database object identified by the specified identifier.
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name, DefaultCallback defaultCallback);
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier, DefaultCallback defaultCallback);
/**
* The platform-provided finder is passed a "default" callback that can be
@@ -36,9 +37,10 @@ public interface DatabaseFinder {
interface DefaultCallback {
/**
- * Return the database object with the specified name from the specified list.
+ * Select and return from the specified list of database objects the
+ * database object identified by the specified identifier.
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name);
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier);
}
@@ -55,9 +57,9 @@ public interface DatabaseFinder {
super();
}
// search for an exact match on the name
- public <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name, DefaultCallback defaultCallback) {
+ public <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier, DefaultCallback defaultCallback) {
for (T databaseObject : databaseObjects) {
- if (databaseObject.getName().equals(name)) {
+ if (databaseObject.getName().equals(identifier)) {
return databaseObject;
}
}
@@ -82,8 +84,8 @@ public interface DatabaseFinder {
super();
}
// simply use the callback
- public <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name, DefaultCallback defaultCallback) {
- return defaultCallback.getDatabaseObjectNamed(databaseObjects, name);
+ public <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier, DefaultCallback defaultCallback) {
+ return defaultCallback.selectDatabaseObjectForIdentifier(databaseObjects, identifier);
}
@Override
public String toString() {
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseObject.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseObject.java
index 5b25256f3a..e9f755dbb0 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseObject.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/DatabaseObject.java
@@ -28,18 +28,27 @@ public interface DatabaseObject {
String getName();
/**
- * Given the name of a Java member and the database object to which it is
- * mapped, build and return a string to be used as the value for the member's
- * database object annotation's 'name' element. Return null if the member
- * maps to the database object by default.
+ * Return the database object's "identifier", which is the object's name
+ * modified so it can be used in an SQL statement (e.g. if the name contains
+ * special characters or is mixed case, it will be delimited, typically by
+ * double-quotes).
+ * Return null if the database object's identifier matches the specified
+ * "default name".
*/
- String getAnnotationIdentifier(String javaIdentifier);
+ String getIdentifier(String defaultName);
/**
- * Return a string to be used as the value for the member's
- * database object annotation's 'name' element.
+ * Return the database object's "identifier", which is the object's name
+ * modified so it can be used in an SQL statement (e.g. if the name contains
+ * special characters or is mixed case, it will be delimited, typically by
+ * double-quotes).
*/
- String getAnnotationIdentifier();
+ String getIdentifier();
+
+ /**
+ * Return the database object's database.
+ */
+ Database getDatabase();
/**
* Return the database object's connection profile.
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Schema.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Schema.java
index 7d82c9e0ce..984dfb537a 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Schema.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Schema.java
@@ -27,10 +27,9 @@ public interface Schema
extends DatabaseObject, Comparable<Schema>
{
/**
- * Return the schema's catalog. Return null if the schema's database does
- * not support catalogs.
+ * Return the schema's container; either a catalog or a database.
*/
- Catalog getCatalog();
+ SchemaContainer getContainer();
// ********** tables **********
@@ -46,16 +45,24 @@ public interface Schema
int tablesSize();
/**
- * Return the names of the schema's tables.
+ * Return the table with specified name. The name must be an exact match
+ * of the table's name.
+ * @see #getTableForIdentifier(String)
*/
- Iterator<String> tableNames();
+ Table getTableNamed(String name);
/**
- * Return the table with specified name. The name should be an SQL
- * identifier (i.e. quoted when case-sensitive, unquoted when
- * case-insensitive).
+ * Return the schema's table identifiers, sorted by name.
*/
- Table getTableNamed(String name);
+ Iterator<String> sortedTableIdentifiers();
+
+ /**
+ * Return the table for the specified identifier. The identifier should
+ * be an SQL identifier (i.e. quoted when case-sensitive or containing
+ * special characters, unquoted otherwise).
+ * @see #getTableNamed(String)
+ */
+ Table getTableForIdentifier(String identifier);
// ********** sequences **********
@@ -71,15 +78,23 @@ public interface Schema
int sequencesSize();
/**
- * Return the names of the schema's sequences.
+ * Return the sequence with specified name. The name must be an exact match
+ * of the sequence's name.
+ * @see #getSequenceForIdentifier(String)
+ */
+ Sequence getSequenceNamed(String name);
+
+ /**
+ * Return the schema's sequence identifers, sorted by name.
*/
- Iterator<String> sequenceNames();
+ Iterator<String> sortedSequenceIdentifiers();
/**
- * Return the sequence with specified name. The name should be an SQL
- * identifier (i.e. quoted when case-sensitive, unquoted when
- * case-insensitive).
+ * Return the sequence for the specified identifier. The identifier should
+ * be an SQL identifier (i.e. quoted when case-sensitive or containing
+ * special characters, unquoted otherwise).
+ * @see #getSequenceNamed(String)
*/
- Sequence getSequenceNamed(String name);
+ Sequence getSequenceForIdentifier(String identifier);
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/SchemaContainer.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/SchemaContainer.java
index c814945bc2..26372f4a03 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/SchemaContainer.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/SchemaContainer.java
@@ -37,15 +37,31 @@ public interface SchemaContainer
int schemataSize();
/**
- * Return the names of the container's schemata.
+ * Return the schema with specified name. The name must be an exact match
+ * of the schema's name.
+ * @see #schemaNames()
+ * @see #getSchemaForIdentifier(String)
*/
- Iterator<String> schemaNames();
+ Schema getSchemaNamed(String name);
/**
- * Return the schema with specified name. The name should be an SQL
- * identifier (i.e. quoted when case-sensitive, unquoted when
- * case-insensitive).
+ * Return the container's schema identifiers, sorted by name.
*/
- Schema getSchemaNamed(String name);
+ Iterator<String> sortedSchemaIdentifiers();
+
+ /**
+ * Return the schema for the specified identifier. The identifier should
+ * be an SQL identifier (i.e. quoted when case-sensitive or containing
+ * special characters, unquoted otherwise).
+ * @see #schemaIdentifiers()
+ * @see #getSchemaNamed(String)
+ */
+ Schema getSchemaForIdentifier(String identifier);
+
+ /**
+ * Return the container's default schema, as defined by the database vendor.
+ * In most cases the default schema's name will match the user name.
+ */
+ Schema getDefaultSchema();
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Table.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Table.java
index 4ea223d068..ef4d334af0 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Table.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/Table.java
@@ -45,16 +45,24 @@ public interface Table
int columnsSize();
/**
- * Return the names of the table's columns.
+ * Return the column with specified name. The name must be an exact match
+ * of the column's name.
+ * @see #getColumnForIdentifier(String)
*/
- Iterator<String> columnNames();
+ Column getColumnNamed(String name);
/**
- * Return the column with specified name. The name should be an SQL
- * identifier (i.e. quoted when case-sensitive, unquoted when
- * case-insensitive).
+ * Return the table's column identifers, sorted by name.
*/
- Column getColumnNamed(String name);
+ Iterator<String> sortedColumnIdentifiers();
+
+ /**
+ * Return the column for the specified identifier. The identifier should
+ * be an SQL identifier (i.e. quoted when case-sensitive or containing
+ * special characters, unquoted otherwise).
+ * @see #getColumnNamed(String)
+ */
+ Column getColumnForIdentifier(String identifier);
// ********** primary key columns **********
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPCatalogWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPCatalogWrapper.java
index 63414ca0f9..d1182e5f11 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPCatalogWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPCatalogWrapper.java
@@ -51,11 +51,6 @@ final class DTPCatalogWrapper
}
@Override
- DTPCatalogWrapper getCatalog() {
- return this;
- }
-
- @Override
DTPSchemaWrapper getSchema(org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema) {
return this.wraps(dtpSchema.getCatalog()) ?
this.getSchema_(dtpSchema)
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java
index 10332afe88..ef0b0eec35 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java
@@ -90,13 +90,13 @@ final class DTPConnectionProfileWrapper
return this.dtpConnectionProfile.getName();
}
- public String getAnnotationIdentifier(String javaIdentifier) {
- // connection profiles should not be in Java annotations
+ public String getIdentifier(String javaIdentifier) {
+ // connection profiles do not have "identifiers"
throw new UnsupportedOperationException();
}
- public String getAnnotationIdentifier() {
- // connection profiles should not be in Java annotations
+ public String getIdentifier() {
+ // connection profiles do not have "identifiers"
throw new UnsupportedOperationException();
}
@@ -307,22 +307,22 @@ final class DTPConnectionProfileWrapper
}
/**
- * This is called by whenever we need to find a component by name
- * (e.g. Table.getColumnNamed(String)). We channel all the calls to here
+ * This is called whenever we need to find a component by identifier
+ * (e.g. Table.getColumnForIdentifier(String)). We channel all the calls to here
* and then we delegate to the JPA platform-supplied "database finder".
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name) {
- return this.finder.getDatabaseObjectNamed(databaseObjects, name, this.databaseFinderCallback);
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier) {
+ return this.finder.selectDatabaseObjectForIdentifier(databaseObjects, identifier, this.databaseFinderCallback);
}
/**
* The default "database finder" calls back to here so we can delegate to
- * the database, which contains all the state necessary to properly match
- * identifiers.
+ * the database, which contains all the information necessary to properly
+ * match identifiers.
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed_(T[] databaseObjects, String name) {
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier_(T[] databaseObjects, String identifier) {
// the database should not be null here - call its internal method
- return this.database.getDatabaseObjectNamed_(databaseObjects, name);
+ return this.database.selectDatabaseObjectForIdentifier_(databaseObjects, identifier);
}
void databaseChanged(DTPDatabaseWrapper db) {
@@ -540,9 +540,9 @@ final class DTPConnectionProfileWrapper
// ********** default DatabaseFinder **********
class DatabaseFinderCallback implements DatabaseFinder.DefaultCallback {
- public <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name) {
+ public <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier) {
// call back to the internal method
- return DTPConnectionProfileWrapper.this.getDatabaseObjectNamed_(databaseObjects, name);
+ return DTPConnectionProfileWrapper.this.selectDatabaseObjectForIdentifier_(databaseObjects, identifier);
}
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseObjectWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseObjectWrapper.java
index bed57df93b..a4cfae644c 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseObjectWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseObjectWrapper.java
@@ -88,13 +88,25 @@ abstract class DTPDatabaseObjectWrapper
}
/**
- * This is called by whenever we need to find a component by name
- * (e.g. Table.getColumnNamed(String)). We channel all the calls to the
- * connection profile, which then delegates to the JPA platform-
- * supplied "database finder".
+ * This is called by whenever we need to find a component by identifier
+ * (e.g. Table.getColumnForIdentifier(String)). We channel all the calls to the
+ * connection profile, which then delegates to the JPA platform-supplied
+ * "database finder".
*/
- <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name) {
- return this.getConnectionProfile().getDatabaseObjectNamed(databaseObjects, name);
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier) {
+ return this.getConnectionProfile().selectDatabaseObjectForIdentifier(databaseObjects, identifier);
+ }
+
+ /**
+ * Convenience method.
+ */
+ <T extends DatabaseObject> T selectDatabaseObjectNamed(T[] databaseObjects, String name) {
+ for (T dbObject : databaseObjects) {
+ if (dbObject.getName().equals(name)) {
+ return dbObject;
+ }
+ }
+ return null;
}
/**
@@ -117,27 +129,8 @@ abstract class DTPDatabaseObjectWrapper
* Table(bar) vs. "Foo" => "bar"
* Table(Bar) vs. "Foo" => "Bar"
*/
- public String getAnnotationIdentifier(String javaIdentifier) {
- return this.getAnnotationIdentifier(javaIdentifier, this.getName());
- }
-
- String getAnnotationIdentifier(String javaIdentifier, String dbIdentifier) {
- if (this.getDatabase().vendorFoldsToUppercase()) {
- if (StringTools.stringIsUppercase(dbIdentifier)) {
- return dbIdentifier.equalsIgnoreCase(javaIdentifier) ? null : dbIdentifier;
- }
- return this.getDatabase().delimitIdentifier(dbIdentifier);
- }
- if (this.getDatabase().vendorFoldsToLowercase()) {
- if (StringTools.stringIsLowercase(dbIdentifier)) {
- return dbIdentifier.equalsIgnoreCase(javaIdentifier) ? null : dbIdentifier;
- }
- return this.getDatabase().delimitIdentifier(dbIdentifier);
- }
- if (this.getDatabase().vendorDoesNotFold()) {
- return dbIdentifier.equals(javaIdentifier) ? null : dbIdentifier;
- }
- throw new IllegalStateException("unknown vendor folding: " + this.getDatabase().getVendor()); //$NON-NLS-1$
+ public String getIdentifier(String defaultName) {
+ return this.getDatabase().convertNameToIdentifier(this.getName(), defaultName);
}
/**
@@ -146,29 +139,25 @@ abstract class DTPDatabaseObjectWrapper
* Table(FOO) => "FOO"
* Table(Foo) => "\"Foo\""
* Table(foo) => "\"foo\""
+ * Table(foo++) => "\"foo++\""
+ * Table(f"o) => "\"f\"\"o++\"" (i.e. "f""o")
*
* PostgreSQL etc.
- * Table(foo) => "foo"
- * Table(Foo) => "\"Foo\""
* Table(FOO) => "\"FOO\""
+ * Table(Foo) => "\"Foo\""
+ * Table(foo) => "foo"
+ * Table(foo++) => "\"foo++\""
+ * Table(f"o) => "\"f\"\"o++\"" (i.e. "f""o")
*
* SQL Server etc.
+ * Table(FOO) => "FOO"
* Table(Foo) => "Foo"
* Table(foo) => "foo"
- * Table(FOO) => "FOO"
+ * Table(foo++) => "\"foo++\""
+ * Table(f"o) => "\"f\"\"o++\"" (i.e. "f""o")
*/
- public String getAnnotationIdentifier() {
- String name = this.getName();
- if (this.getDatabase().vendorFoldsToUppercase()) {
- return StringTools.stringIsUppercase(name) ? name : this.getDatabase().delimitIdentifier(name);
- }
- if (this.getDatabase().vendorFoldsToLowercase()) {
- return StringTools.stringIsLowercase(name) ? name : this.getDatabase().delimitIdentifier(name);
- }
- if (this.getDatabase().vendorDoesNotFold()) {
- return name;
- }
- throw new IllegalStateException("unknown vendor folding: " + this.getDatabase().getVendor()); //$NON-NLS-1$
+ public String getIdentifier() {
+ return this.getDatabase().convertNameToIdentifier(this.getName());
}
@Override
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java
index e7da680987..04b9870ab0 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java
@@ -10,6 +10,7 @@
package org.eclipse.jpt.db.internal;
import java.text.Collator;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -18,15 +19,25 @@ import org.eclipse.datatools.connectivity.sqm.internal.core.RDBCorePlugin;
import org.eclipse.jpt.db.Catalog;
import org.eclipse.jpt.db.Database;
import org.eclipse.jpt.db.DatabaseObject;
+import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
/**
* Wrap a DTP Database.
+ *
* Sometimes the database will directly hold schemata; but if the database
* supports catalogs, it will not hold the schemata directly, but will delegate
* to the "default" catalog.
+ *
+ * Note:
+ * We use "name" when dealing with the unmodified name of a database object
+ * as supplied by the database itself (i.e. it is not delimited and it is always
+ * case-sensitive).
+ * We use "identifier" when dealing with a string representation of a database
+ * object name (i.e. it may be delimited and, depending on the vendor, it may
+ * be case-insensitive).
*/
final class DTPDatabaseWrapper
extends DTPSchemaContainerWrapper
@@ -35,7 +46,7 @@ final class DTPDatabaseWrapper
// the wrapped DTP database
private final org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase;
- // lazy-initialized
+ // lazy-initialized, sorted
private DTPCatalogWrapper[] catalogs;
// lazy-initialized - but it can be 'null' so we use a flag
@@ -46,28 +57,6 @@ final class DTPDatabaseWrapper
private static final DTPCatalogWrapper[] EMPTY_CATALOGS = new DTPCatalogWrapper[0];
- // ********** constants **********
-
- private static final String POSTGRESQL_PUBLIC_SCHEMA_NAME = "public"; //$NON-NLS-1$
-
-
- // ********** vendors **********
-
- static final String DERBY_VENDOR = "Derby"; //$NON-NLS-1$
- static final String HSQLDB_VENDOR = "HSQLDB"; //$NON-NLS-1$
- static final String DB2_UDB_I_SERIES_VENDOR = "DB2 UDB iSeries"; //$NON-NLS-1$
- static final String DB2_UDB_VENDOR = "DB2 UDB"; //$NON-NLS-1$
- static final String DB2_UDB_Z_SERIES_VENDOR = "DB2 UDB zSeries"; //$NON-NLS-1$
- static final String INFORMIX_VENDOR = "Informix"; //$NON-NLS-1$
- static final String SQL_SERVER_VENDOR = "SQL Server"; //$NON-NLS-1$
- static final String MYSQL_VENDOR = "MySql"; //$NON-NLS-1$
- static final String ORACLE_VENDOR = "Oracle"; //$NON-NLS-1$
- static final String POSTGRES_VENDOR = "postgres"; //$NON-NLS-1$
- static final String MAXDB_VENDOR = "MaxDB"; //$NON-NLS-1$
- static final String SYBASE_ASA_VENDOR = "Sybase_ASA"; //$NON-NLS-1$
- static final String SYBASE_ASE_VENDOR = "Sybase_ASE"; //$NON-NLS-1$
-
-
// ********** constructor **********
DTPDatabaseWrapper(DTPConnectionProfileWrapper connectionProfile, org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase) {
@@ -99,11 +88,6 @@ final class DTPDatabaseWrapper
}
@Override
- DTPCatalogWrapper getCatalog() {
- return null; // catalog not supported
- }
-
- @Override
DTPSchemaWrapper getSchema(org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema) {
return this.getSchema_(dtpSchema);
}
@@ -128,7 +112,7 @@ final class DTPDatabaseWrapper
// ********** Database implementation **********
- public String getVendor() {
+ public String getVendorName() {
return this.dtpDatabase.getVendor();
}
@@ -138,8 +122,8 @@ final class DTPDatabaseWrapper
// override to make method public since it's in the Database interface
@Override
- public <T extends DatabaseObject> T getDatabaseObjectNamed(T[] databaseObjects, String name) {
- return super.getDatabaseObjectNamed(databaseObjects, name);
+ public <T extends DatabaseObject> T selectDatabaseObjectForIdentifier(T[] databaseObjects, String identifier) {
+ return super.selectDatabaseObjectForIdentifier(databaseObjects, identifier);
}
// ***** catalogs
@@ -154,6 +138,10 @@ final class DTPDatabaseWrapper
return new ArrayIterator<Catalog>(this.getCatalogs());
}
+ private Iterator<DTPCatalogWrapper> catalogWrappers() {
+ return new ArrayIterator<DTPCatalogWrapper>(this.getCatalogs());
+ }
+
private synchronized DTPCatalogWrapper[] getCatalogs() {
if (this.catalogs == null) {
this.catalogs = this.buildCatalogs();
@@ -170,7 +158,7 @@ final class DTPDatabaseWrapper
for (int i = result.length; i-- > 0;) {
result[i] = new DTPCatalogWrapper(this, dtpCatalogs.get(i));
}
- return result;
+ return CollectionTools.sort(result);
}
// minimize scope of suppressed warnings
@@ -183,42 +171,6 @@ final class DTPDatabaseWrapper
return this.getCatalogs().length;
}
- public Iterator<String> catalogNames() {
- return new TransformationIterator<Catalog, String>(this.catalogs()) {
- @Override
- protected String transform(Catalog catalog) {
- return catalog.getName();
- }
- };
- }
-
- public synchronized DTPCatalogWrapper getDefaultCatalog() {
- if ( ! this.defaultCatalogCalculated) {
- this.defaultCatalogCalculated = true;
- this.defaultCatalog = this.buildDefaultCatalog();
- }
- return this.defaultCatalog;
- }
-
- private DTPCatalogWrapper buildDefaultCatalog() {
- if ( ! this.supportsCatalogs()) {
- return null;
- }
- for (DTPCatalogWrapper catalog : this.getCatalogs()) {
- String catalogName = catalog.getName();
- if (catalogName.length() == 0) {
- return catalog; // special catalog that contains all schemata (Derby)
- }
- if (catalogName.equals(this.getConnectionProfile().getUserName())) {
- return catalog; // user name is default catalog
- }
- if (catalogName.equals(this.getName())) {
- return catalog; // special catalog with same name as DB (PostgreSQL)
- }
- }
- throw new IllegalStateException("unknown default catalog"); //$NON-NLS-1$
- }
-
/**
* return the catalog for the specified DTP catalog
*/
@@ -232,223 +184,84 @@ final class DTPDatabaseWrapper
}
public DTPCatalogWrapper getCatalogNamed(String name) {
- return this.getDatabaseObjectNamed(this.getCatalogs(), name);
+ return this.selectDatabaseObjectNamed(this.getCatalogs(), name);
}
- // ***** schemata
-
- @Override
- synchronized DTPSchemaWrapper[] getSchemata() {
- DTPCatalogWrapper cat = this.getDefaultCatalog();
- return (cat == null) ? super.getSchemata() : cat.getSchemata();
- }
-
- public DTPSchemaWrapper getDefaultSchema() {
- DTPSchemaWrapper schema = this.getSchemaNamed(this.getConnectionProfile().getUserName());
- if (schema != null) {
- return schema;
- }
- // PostgreSQL has a "schema search path" - the default is:
- // "$user",public
- // so if "$user" is not found, return public
- if (this.getVendor().equals(POSTGRES_VENDOR)) {
- return this.getSchemaNamed(POSTGRESQL_PUBLIC_SCHEMA_NAME);
- }
- // MySQL database has a single schema with the same name as the database
- if (this.getVendor().equals(MYSQL_VENDOR)) {
- return this.getSchemaNamed(this.getName());
- }
- return null;
- }
-
-
- // ********** identifiers **********
-
- /**
- * Return the database object with the specified name. If the name is
- * "delimited" (typically with double-quotes), it will be used without any
- * folding. If the name is "normal" (i.e. not delimited), it will be
- * folded to the appropriate case (typically uppercase).
- * @see #identifierIsDelimited(String)
- * @see #foldIdentifier(String)
- *
- * Since the database has the appropriate state to compare identifiers,
- * the connection profile delegates to here when using the default
- * "database finder".
- */
- // TODO convert embedded quotes?
- <T extends DatabaseObject> T getDatabaseObjectNamed_(T[] databaseObjects, String name) {
- name = this.normalizeIdentifier(name);
- for (T dbObject : databaseObjects) {
- if (dbObject.getName().equals(name)) {
- return dbObject;
+ public Iterator<String> sortedCatalogIdentifiers() {
+ // the catalogs are already sorted
+ return new TransformationIterator<DTPCatalogWrapper, String>(this.catalogWrappers()) {
+ @Override
+ protected String transform(DTPCatalogWrapper next) {
+ return next.getIdentifier();
}
- }
- return null;
+ };
}
- private String normalizeIdentifier(String identifier) {
- if (this.identifierIsDelimited(identifier)) {
- return StringTools.unwrap(identifier);
- }
- return this.foldIdentifier(identifier);
+ public DTPCatalogWrapper getCatalogForIdentifier(String identifier) {
+ return this.selectDatabaseObjectForIdentifier(this.getCatalogs(), identifier);
}
- /**
- * Return whether the specified identifier is "delimited" for the current
- * database (typically with double-quotes).
- */
- private boolean identifierIsDelimited(String identifier) {
- if (this.vendorAllowsQuoteDelimiters()
- && StringTools.stringIsQuoted(identifier)) {
- return true;
- }
- if (this.vendorAllowsBracketDelimiters()
- && StringTools.stringIsBracketed(identifier)) {
- return true;
- }
- if (this.vendorAllowsBacktickDelimiters()
- && StringTools.stringIsDelimited(identifier, BACKTICK)) {
- return true;
+ public synchronized DTPCatalogWrapper getDefaultCatalog() {
+ if ( ! this.defaultCatalogCalculated) {
+ this.defaultCatalogCalculated = true;
+ this.defaultCatalog = this.buildDefaultCatalog();
}
- return false;
- }
-
- /**
- * Return whether the database allows identifiers to delimited with
- * quotes: "FOO".
- */
- boolean vendorAllowsQuoteDelimiters() {
- // all platforms allow identifiers to be delimited by quotes
- return true;
- }
-
- /**
- * Return whether the database allows identifiers to delimited with
- * brackets: [FOO].
- */
- boolean vendorAllowsBracketDelimiters() {
- String vendor = this.getVendor();
- return vendor.equals(SQL_SERVER_VENDOR)
- || vendor.equals(SYBASE_ASE_VENDOR)
- || vendor.equals(SYBASE_ASA_VENDOR);
+ return this.defaultCatalog;
}
- /**
- * Return whether the database allows identifiers to delimited with
- * backticks: `FOO`.
- */
- boolean vendorAllowsBacktickDelimiters() {
- String vendor = this.getVendor();
- return vendor.equals(MYSQL_VENDOR);
+ private DTPCatalogWrapper buildDefaultCatalog() {
+ return this.supportsCatalogs() ? this.getVendor().getDefaultCatalog(this) : null;
}
- private static final char BACKTICK = '`';
+ // ***** schemata
- /**
- * Fold the specified identifier to the appropriate case.
- * The SQL-92 spec says a "normal" (non-delimited) identifier should be
- * folded to uppercase; but some databases do otherwise (e.g. PostgreSQL).
- *
- * According to on-line documentation I could find: ~bjv
- * The following databases fold to uppercase:
- * Derby
- * Oracle
- * DB2
- * HSQLDB
- * MaxDB
- * The following databases fold to lowercase:
- * PostgreSQL
- * Informix
- * MySQL (sorta - depends on underlying O/S file system and env var)
- * The following databases do not fold:
- * MS SQL Server (might depend on collation setting...)
- * Sybase (might depend on collation setting...)
- */
- private String foldIdentifier(String identifier) {
- if (this.vendorFoldsToLowercase()) {
- return identifier.toLowerCase();
- }
- if (this.vendorFoldsToUppercase()) {
- return identifier.toUpperCase();
- }
- if (this.vendorDoesNotFold()) {
- return identifier;
- }
- throw new IllegalStateException("unknown vendor folding: " + this.getVendor()); //$NON-NLS-1$
+ @Override
+ synchronized DTPSchemaWrapper[] getSchemata() {
+ DTPCatalogWrapper cat = this.getDefaultCatalog();
+ return (cat == null) ? super.getSchemata() : cat.getSchemata();
}
- /**
- * Return whether the database folds non-delimited identifiers to lowercase.
- */
- boolean vendorFoldsToLowercase() {
- String vendor = this.getVendor();
- return vendor.equals(POSTGRES_VENDOR)
- || vendor.equals(INFORMIX_VENDOR);
+ DTPSchemaWrapper getDefaultSchema(DTPSchemaContainerWrapper schemaContainer) {
+ return this.getVendor().getDefaultSchema(schemaContainer);
}
- /**
- * Return whether the database does not fold non-delimited identifiers to
- * lowercase.
- */
- boolean vendorDoesNotFoldToLowercase() {
- return ! this.vendorFoldsToLowercase();
- }
- /**
- * Return whether the database folds non-delimited identifiers to uppercase.
- */
- boolean vendorFoldsToUppercase() {
- return this.vendorFolds()
- && this.vendorDoesNotFoldToLowercase();
- }
+ // ********** names vs. identifiers **********
/**
- * Return whether the database does not fold non-delimited identifiers to
- * uppercase.
+ * Convert the specified name to an identifier. Return null if the resulting
+ * identifier matches the specified default name.
*/
- boolean vendorDoesNotFoldToUppercase() {
- return ! this.vendorFoldsToUppercase();
+ String convertNameToIdentifier(String name, String defaultName) {
+ return this.getVendor().convertNameToIdentifier(name, defaultName);
}
/**
- * Return whether the database folds non-delimited identifiers to either
- * uppercase or lowercase.
+ * Convert the specified name to an identifier.
*/
- boolean vendorFolds() {
- return ! this.vendorDoesNotFold();
+ public String convertNameToIdentifier(String name) {
+ return this.getVendor().convertNameToIdentifier(name);
}
/**
- * Return whether the database does not fold non-delimited identifiers to
- * either uppercase or lowercase (i.e. the identifier is used unmodified).
- * These guys are bit flaky, so we force an exact match.
- * (e.g. MySQL folds database and table names to lowercase on Windows
- * by default; but that default can be changed by the
- * 'lower_case_table_names' system variable. This because databases are
- * stored as directories and tables are stored as files in the underlying
- * O/S, and the case-sensitivity of the names is determined by the behavior
- * of filenames on the O/S. Then, to complicate things,
- * none of the other identifiers, like table and column names, are folded;
- * but they are case-insensitive, unless delimited. See
- * http://dev.mysql.com/doc/refman/6.0/en/identifier-case-sensitivity.html.)
+ * Return the database object identified by the specified identifier. If
+ * the identifier is "delimited" (typically with double-quotes), it will be
+ * used without any folding. If the name is "normal" (i.e. not delimited),
+ * it will be folded to the appropriate case (typically uppercase).
+ *
+ * Since the database has the appropriate state to compare identifiers and
+ * names, the connection profile delegates to here when using the default
+ * "database finder".
*/
- boolean vendorDoesNotFold() {
- String vendor = this.getVendor();
- return vendor.equals(SQL_SERVER_VENDOR)
- || vendor.equals(SYBASE_ASE_VENDOR)
- || vendor.equals(SYBASE_ASA_VENDOR)
- || vendor.equals(MYSQL_VENDOR);
+ <T extends DatabaseObject> T selectDatabaseObjectForIdentifier_(T[] databaseObjects, String identifier) {
+ return this.selectDatabaseObjectNamed(databaseObjects, this.convertIdentifierToName(identifier));
}
/**
- * Delimit the specified identifier in a vendor-appropriate fashion.
+ * Convert the specified identifier to a name.
*/
- String delimitIdentifier(String identifier) {
- if (this.vendorAllowsQuoteDelimiters()) {
- return StringTools.quote(identifier);
- }
- throw new IllegalStateException("unknown vendor delimiters: " + this.getVendor()); //$NON-NLS-1$
+ String convertIdentifierToName(String identifier) {
+ return this.getVendor().convertIdentifierToName(identifier);
}
@@ -465,6 +278,10 @@ final class DTPDatabaseWrapper
return RDBCorePlugin.getDefault().getDatabaseDefinitionRegistry().getDefinition(this.dtpDatabase);
}
+ private Vendor getVendor() {
+ return getVendor(this.getVendorName());
+ }
+
// ********** listening **********
@@ -517,4 +334,742 @@ final class DTPDatabaseWrapper
this.catalogs = null;
}
+
+ // ********** vendors **********
+
+ private static Vendor getVendor(String name) {
+ Vendor vendor = getVendors().get(name);
+ return (vendor != null) ? vendor : Default.INSTANCE;
+ }
+
+ /**
+ * keyed by vendor name
+ */
+ private static HashMap<String, Vendor> Vendors;
+
+ private static synchronized HashMap<String, Vendor> getVendors() {
+ if (Vendors == null) {
+ Vendors = buildVendors();
+ }
+ return Vendors;
+ }
+
+ private static HashMap<String, Vendor> buildVendors() {
+ HashMap<String, Vendor> map = new HashMap<String, Vendor>(20);
+ putVendor(map, Derby.INSTANCE);
+ putVendor(map, HSQLDB.INSTANCE);
+ putVendor(map, DB2.UDB);
+ putVendor(map, DB2.UDB_I_SERIES);
+ putVendor(map, DB2.UDB_Z_SERIES);
+ putVendor(map, Informix.INSTANCE);
+ putVendor(map, SQLServer.INSTANCE);
+ putVendor(map, MySQL.INSTANCE);
+ putVendor(map, Oracle.INSTANCE);
+ putVendor(map, Postgres.INSTANCE);
+ putVendor(map, MaxDB.INSTANCE);
+ putVendor(map, Sybase.ASA);
+ putVendor(map, Sybase.ASE);
+ return map;
+ }
+
+ private static void putVendor(HashMap<String, Vendor> map, Vendor vendor) {
+ String name = vendor.getName();
+ if (map.put(name, vendor) != null) {
+ throw new IllegalArgumentException("Duplicate vendor: " + name); //$NON-NLS-1$
+ }
+ }
+
+
+ // ********** vendor classes **********
+
+ /**
+ * Delegate vendor-specific behavior to implementations of this class"
+ * - default catalog and schema
+ * - converting names to identifiers and vice-versa
+ *
+ * Note:
+ * We use "name" when dealing with the unmodified name of a database object
+ * as supplied by the database itself (i.e. it is not delimited and it is always
+ * case-sensitive).
+ * We use "identifier" when dealing with a string representation of a database
+ * object name (i.e. it may be delimited and, depending on the vendor, it may
+ * be case-insensitive).
+ */
+ private abstract static class Vendor {
+
+ Vendor() {
+ super();
+ }
+
+ /**
+ * Return the vendor's name. This must match the name specified by the
+ * DTP connection profile.
+ */
+ abstract String getName();
+
+ /**
+ * The SQL spec says a "normal" (non-delimited) identifier should be
+ * folded to uppercase; but some databases do otherwise (e.g. Sybase).
+ */
+ Folder getFolder() {
+ return Folder.UPPER;
+ }
+
+
+ // ********** default catalog and schema **********
+
+ DTPCatalogWrapper getDefaultCatalog(DTPDatabaseWrapper database) {
+ return database.getCatalogForIdentifier(this.getDefaultCatalogIdentifier(database));
+ }
+
+ /**
+ * Typically, the name of the default catalog is the user name.
+ */
+ String getDefaultCatalogIdentifier(DTPDatabaseWrapper database) {
+ return database.getConnectionProfile().getUserName();
+ }
+
+ DTPSchemaWrapper getDefaultSchema(DTPSchemaContainerWrapper sc) {
+ return sc.getSchemaForIdentifier(this.getDefaultSchemaIdentifier(sc));
+ }
+
+ /**
+ * Typically, the name of the default schema is the user name.
+ */
+ String getDefaultSchemaIdentifier(DTPSchemaContainerWrapper sc) {
+ return sc.getDatabase().getConnectionProfile().getUserName();
+ }
+
+
+ // ********** name -> identifier **********
+
+ /**
+ * @see DTPDatabaseWrapper#convertNameToIdentifier(String, String)
+ */
+ final String convertNameToIdentifier(String name, String defaultName) {
+ return this.nameRequiresDelimiters(name) ? this.delimitName(name)
+ : this.normalNamesMatch(name, defaultName) ? null : name;
+ }
+
+ /**
+ * @see DTPDatabaseWrapper#convertNameToIdentifier(String)
+ */
+ final String convertNameToIdentifier(String name) {
+ return this.nameRequiresDelimiters(name) ? this.delimitName(name) : name;
+ }
+
+ /**
+ * Return whether the specified database object name must be delimited
+ * when used in an SQL statement.
+ * If the name has any "special" characters (as opposed to letters,
+ * digits, and other allowed characters [e.g. underscores]), it requires
+ * delimiters.
+ * If the name is mixed case and the database folds undelimited names
+ * (to either uppercase or lowercase), it requires delimiters.
+ */
+ final boolean nameRequiresDelimiters(String name) {
+ return (name.length() == 0) // an empty string must be delimited(?)
+ || this.nameContainsAnySpecialCharacters(name)
+ || this.nameIsNotFolded(name);
+ }
+
+ /**
+ * Return whether the specified name contains any "special" characters
+ * that require the name to be delimited.
+ * Pre-condition: the specified name is not empty
+ */
+ final boolean nameContainsAnySpecialCharacters(String name) {
+ char[] string = name.toCharArray();
+ if (this.characterIsSpecialNameStart(string[0])) {
+ return true;
+ }
+ for (int i = string.length; i-- > 1; ) { // note: stop at 1
+ if (this.characterIsSpecialNamePart(string[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified character is "special" for the first
+ * character of a name.
+ * Typically, databases are more restrictive about what characters can
+ * be used to *start* an identifier (as opposed to the characters
+ * allowed for the remainder of the identifier).
+ */
+ final boolean characterIsSpecialNameStart(char c) {
+ return ! this.characterIsNormalNameStart(c);
+ }
+
+ /**
+ * Return whether the specified character is "normal" for the first
+ * character of a name.
+ * The first character of an identifier can be:
+ * - a letter
+ * - any of the other, vendor-specific, "normal" start characters
+ */
+ boolean characterIsNormalNameStart(char c) {
+ // all vendors allow a letter
+ return Character.isLetter(c)
+ || this.characterIsNormalNameStart_(c);
+ }
+
+ private boolean characterIsNormalNameStart_(char c) {
+ return arrayContains(this.getNormalNameStartCharacters(), c);
+ }
+
+ /**
+ * Return the "normal" characters, beyond letters, for the
+ * first character of a name.
+ * Return null if there are no additional characters.
+ */
+ char[] getNormalNameStartCharacters() {
+ return null;
+ }
+
+ /**
+ * Return whether the specified character is "special" for the second and
+ * subsequent characters of a name.
+ */
+ final boolean characterIsSpecialNamePart(char c) {
+ return ! this.characterIsNormalNamePart(c);
+ }
+
+ /**
+ * Return whether the specified character is "normal" for the second and
+ * subsequent characters of a name.
+ * The second and subsequent characters of a "normal" name can be:
+ * - a letter
+ * - a digit
+ * - any of the other, vendor-specific, "normal" start characters
+ * - any of the other, vendor-specific, "normal" part characters
+ */
+ boolean characterIsNormalNamePart(char c) {
+ // all vendors allow a letter or digit
+ return Character.isLetterOrDigit(c)
+ || this.characterIsNormalNameStart_(c)
+ || this.characterIsNormalNamePart_(c);
+ }
+
+ private boolean characterIsNormalNamePart_(char c) {
+ return arrayContains(this.getNormalNamePartCharacters(), c);
+ }
+
+ /**
+ * Return the "normal" characters, beyond letters and digits and the
+ * "normal" first characters, for the second and subsequent characters
+ * of an identifier. Return null if there are no additional characters.
+ */
+ char[] getNormalNamePartCharacters() {
+ return null;
+ }
+
+ /**
+ * Return whether the specified name is not folded to the database's
+ * case, requiring it to be delimited.
+ */
+ final boolean nameIsNotFolded(String name) {
+ return ! this.getFolder().stringIsFolded(name);
+ }
+
+ /**
+ * Return whether the specified "normal" names match.
+ */
+ final boolean normalNamesMatch(String name1, String name2) {
+ return this.normalIdentifiersAreCaseSensitive() ?
+ name1.equals(name2)
+ :
+ name1.equalsIgnoreCase(name2);
+ }
+
+ /**
+ * Typically, "normal" identifiers are case-insensitive.
+ */
+ final boolean normalIdentifiersAreCaseSensitive() {
+ return this.getFolder().isCaseSensitive();
+ }
+
+ /**
+ * Wrap the specified name in delimiters (typically double-quotes),
+ * converting it to an identifier.
+ */
+ String delimitName(String name) {
+ return StringTools.quote(name);
+ }
+
+
+ // ********** identifier -> name **********
+
+ /**
+ * @see DTPDatabaseWrapper#selectDatabaseObjectForIdentifier_(DatabaseObject[], String)
+ */
+ // not sure how to handle an empty string:
+ // both "" and "\"\"" are converted to "" ...
+ // convert "" to 'null' since empty strings must be delimited?
+ final String convertIdentifierToName(String identifier) {
+ return (identifier == null) ? null :
+ this.identifierIsDelimited(identifier) ?
+ StringTools.undelimit(identifier)
+ :
+ this.getFolder().fold(identifier);
+ }
+
+ /**
+ * Return whether the specified identifier is "delimited".
+ * The SQL-92 spec says identifiers should be delimited by
+ * double-quotes; but some databases allow otherwise (e.g. Sybase).
+ */
+ boolean identifierIsDelimited(String identifier) {
+ return StringTools.stringIsQuoted(identifier);
+ }
+
+
+ // ********** misc **********
+
+ @Override
+ public String toString() {
+ return this.getName();
+ }
+
+ /**
+ * static convenience method - array null check
+ */
+ static boolean arrayContains(char[] array, char c) {
+ return (array != null) && CollectionTools.contains(array, c);
+ }
+
+ /**
+ * Handle database-specific case-folding issues.
+ */
+ enum Folder {
+ UPPER {
+ @Override String fold(String string) { return string.toUpperCase(); }
+ @Override boolean stringIsFolded(String string) { return StringTools.stringIsUppercase(string); }
+ @Override boolean isCaseSensitive() { return false; }
+ },
+ LOWER {
+ @Override String fold(String string) { return string.toLowerCase(); }
+ @Override boolean stringIsFolded(String string) { return StringTools.stringIsLowercase(string); }
+ @Override boolean isCaseSensitive() { return false; }
+ },
+ NONE {
+ @Override String fold(String string) { return string; }
+ @Override boolean stringIsFolded(String string) { return true; }
+ @Override boolean isCaseSensitive() { return true; }
+ };
+ abstract String fold(String string);
+ abstract boolean stringIsFolded(String string);
+ abstract boolean isCaseSensitive();
+ }
+
+ }
+
+ private static class Default extends Vendor {
+ static final Vendor INSTANCE = new Default();
+
+ private Default() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "Default Vendor"; //$NON-NLS-1$
+ }
+
+ }
+
+ private static class Derby extends Vendor {
+ static final Vendor INSTANCE = new Derby();
+
+ private Derby() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "Derby"; //$NON-NLS-1$
+ }
+
+ /**
+ * Derby has a single, unnamed catalog that contains all the schemata.
+ */
+ @Override
+ String getDefaultCatalogIdentifier(DTPDatabaseWrapper database) {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * The default user name on Derby is "APP".
+ */
+ @Override
+ String getDefaultSchemaIdentifier(DTPSchemaContainerWrapper sc) {
+ String user = super.getDefaultSchemaIdentifier(sc);
+ return ((user == null) || (user.length() == 0)) ?
+ DEFAULT_USER_NAME
+ :
+ user;
+ }
+ private static final String DEFAULT_USER_NAME = "APP"; //$NON-NLS-1$
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '_' };
+
+ }
+
+ private static class HSQLDB extends Vendor {
+ static final Vendor INSTANCE = new HSQLDB();
+
+ private HSQLDB() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "HSQLDB"; //$NON-NLS-1$
+ }
+
+ }
+
+ private static class DB2 extends Vendor {
+ static final Vendor UDB_I_SERIES = new DB2("DB2 UDB iSeries"); //$NON-NLS-1$
+ static final Vendor UDB = new DB2("DB2 UDB"); //$NON-NLS-1$
+ static final Vendor UDB_Z_SERIES = new DB2("DB2 UDB zSeries"); //$NON-NLS-1$
+
+ private final String name;
+
+ private DB2(String name) {
+ super();
+ this.name = name;
+ }
+
+ @Override
+ String getName() {
+ return this.name;
+ }
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '_' };
+
+ }
+
+ private static class Informix extends Vendor {
+ static final Vendor INSTANCE = new Informix();
+
+ private Informix() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "Informix"; //$NON-NLS-1$
+ }
+
+ @Override
+ Folder getFolder() {
+ return Folder.LOWER;
+ }
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '_' };
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '$' };
+
+ }
+
+ private static class SQLServer extends Vendor {
+ static final Vendor INSTANCE = new SQLServer();
+
+ private SQLServer() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "SQL Server"; //$NON-NLS-1$
+ }
+
+ /**
+ * The default schema on SQL Server for any database (catalog) is 'dbo'.
+ */
+ @Override
+ String getDefaultSchemaIdentifier(DTPSchemaContainerWrapper sc) {
+ return DEFAULT_SCHEMA_NAME;
+ }
+ private static final String DEFAULT_SCHEMA_NAME = "dbo"; //$NON-NLS-1$
+
+ /**
+ * By default, SQL Server identifiers are case-sensitive, even without
+ * delimiters. This can depend on the collation setting....
+ */
+ @Override
+ Folder getFolder() {
+ return Folder.NONE;
+ }
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '_', '@', '#' };
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '$' };
+
+ /**
+ * By default, SQL Server delimits identifiers with brackets ([]); but it
+ * can also be configured to use double-quotes.
+ */
+ @Override
+ boolean identifierIsDelimited(String identifier) {
+ return StringTools.stringIsBracketed(identifier)
+ || super.identifierIsDelimited(identifier);
+ }
+
+ }
+
+ private static class MySQL extends Vendor {
+ static final Vendor INSTANCE = new MySQL();
+
+ private MySQL() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "MySql"; //$NON-NLS-1$
+ }
+
+ /**
+ * MySQL is a bit unusual, so we force exact matches.
+ * (e.g. MySQL folds database and table names to lowercase on Windows
+ * by default; but that default can be changed by the
+ * 'lower_case_table_names' system variable. This is because databases are
+ * stored as directories and tables are stored as files in the underlying
+ * O/S; and the case-sensitivity of the names is determined by the behavior
+ * of filenames on the O/S. Then, to complicate things,
+ * none of the other identifiers, like table and column names, are folded;
+ * but they are case-insensitive, unless delimited. See
+ * http://dev.mysql.com/doc/refman/6.0/en/identifier-case-sensitivity.html.)
+ */
+ @Override
+ Folder getFolder() {
+ return Folder.NONE;
+ }
+
+ /**
+ * MySQL has a single schema with the same name as the database.
+ */
+ @Override
+ String getDefaultSchemaIdentifier(DTPSchemaContainerWrapper sc) {
+ return sc.getDatabase().getName();
+ }
+
+ /**
+ * MySQL is the only vendor that allows a digit.
+ * Although, the name cannnot be *all* digits.
+ */
+ @Override
+ boolean characterIsNormalNameStart(char c) {
+ return Character.isDigit(c) || super.characterIsNormalNameStart(c);
+ }
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '_', '$' };
+
+ /**
+ * By default, MySQL delimits identifiers with backticks (`); but it
+ * can also be configured to use double-quotes.
+ */
+ @Override
+ boolean identifierIsDelimited(String identifier) {
+ return StringTools.stringIsDelimited(identifier, BACKTICK)
+ || super.identifierIsDelimited(identifier);
+ }
+ private static final char BACKTICK = '`';
+
+ }
+
+ private static class Oracle extends Vendor {
+ static final Vendor INSTANCE = new Oracle();
+
+ private Oracle() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "Oracle"; //$NON-NLS-1$
+ }
+
+ /**
+ * Oracle has a single, unnamed catalog that contains all the schemata.
+ */
+ @Override
+ String getDefaultCatalogIdentifier(DTPDatabaseWrapper database) {
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '_', '$', '#' };
+
+ }
+
+ private static class Postgres extends Vendor {
+ static final Vendor INSTANCE = new Postgres();
+
+ private Postgres() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "postgres"; //$NON-NLS-1$
+ }
+
+ @Override
+ Folder getFolder() {
+ return Folder.LOWER;
+ }
+
+ /**
+ * PostgreSQL has a single, unnamed catalog that contains all the schemata.
+ */
+ @Override
+ String getDefaultCatalogIdentifier(DTPDatabaseWrapper database) {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * PostgreSQL has a "schema search path". The default is:
+ * "$user",public
+ * If "$user" is not found, return "public".
+ */
+ @Override
+ DTPSchemaWrapper getDefaultSchema(DTPSchemaContainerWrapper sc) {
+ DTPSchemaWrapper schema = super.getDefaultSchema(sc);
+ return (schema != null) ? schema : sc.getSchemaNamed(PUBLIC_SCHEMA_NAME);
+ }
+ private static final String PUBLIC_SCHEMA_NAME = "public"; //$NON-NLS-1$
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '_' };
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '$' };
+
+ }
+
+ private static class MaxDB extends Vendor {
+ static final Vendor INSTANCE = new MaxDB();
+
+ private MaxDB() {
+ super();
+ }
+
+ @Override
+ String getName() {
+ return "MaxDB"; //$NON-NLS-1$
+ }
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '#', '@', '$' };
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '_' };
+
+ }
+
+ private static class Sybase extends Vendor {
+ static final Vendor ASA = new Sybase("Sybase_ASA"); //$NON-NLS-1$
+ static final Vendor ASE = new Sybase("Sybase_ASE"); //$NON-NLS-1$
+
+ private final String name;
+
+ private Sybase(String name) {
+ super();
+ this.name = name;
+ }
+
+ @Override
+ String getName() {
+ return this.name;
+ }
+
+ /**
+ * The default schema on Sybase for any database (catalog) is 'dbo'.
+ */
+ @Override
+ String getDefaultSchemaIdentifier(DTPSchemaContainerWrapper sc) {
+ return DEFAULT_SCHEMA_NAME;
+ }
+ private static final String DEFAULT_SCHEMA_NAME = "dbo"; //$NON-NLS-1$
+
+ /**
+ * By default, Sybase identifiers are case-sensitive, even without
+ * delimiters. This can depend on the collation setting....
+ */
+ @Override
+ Folder getFolder() {
+ return Folder.NONE;
+ }
+
+ @Override
+ char[] getNormalNameStartCharacters() {
+ return NORMAL_NAME_START_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_START_CHARACTERS = new char[] { '_', '@' };
+
+ @Override
+ char[] getNormalNamePartCharacters() {
+ return NORMAL_NAME_PART_CHARACTERS;
+ }
+ private static final char[] NORMAL_NAME_PART_CHARACTERS = new char[] { '$', '¥', '£', '#' };
+
+ /**
+ * By default, Sybase delimits identifiers with brackets ([]); but it
+ * can also be configured to use double-quotes.
+ */
+ @Override
+ boolean identifierIsDelimited(String identifier) {
+ return StringTools.stringIsBracketed(identifier)
+ || super.identifierIsDelimited(identifier);
+ }
+
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPForeignKeyWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPForeignKeyWrapper.java
index a605046f62..8317bb926e 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPForeignKeyWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPForeignKeyWrapper.java
@@ -273,9 +273,9 @@ final class DTPForeignKeyWrapper
* ForeignKey(Foo_ID => ID) vs. "foo" => "Foo_ID"
*/
public String getJoinColumnAnnotationIdentifier(String attributeName) {
- String defaultBaseColumnName = attributeName + '_' + this.getReferencedTable().getPrimaryKeyColumn().getName();
String baseColumnName = this.getColumnPair().getBaseColumn().getName();
- return this.getAnnotationIdentifier(defaultBaseColumnName, baseColumnName);
+ String defaultBaseColumnName = attributeName + '_' + this.getReferencedTable().getPrimaryKeyColumn().getName();
+ return this.getDatabase().convertNameToIdentifier(baseColumnName, defaultBaseColumnName);
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaContainerWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaContainerWrapper.java
index 0323456f89..3ac1595aee 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaContainerWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaContainerWrapper.java
@@ -14,6 +14,7 @@ import java.util.List;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.SchemaContainer;
+import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
@@ -51,12 +52,6 @@ abstract class DTPSchemaContainerWrapper
abstract List<org.eclipse.datatools.modelbase.sql.schema.Schema> getDTPSchemata();
/**
- * return the schema container's catalog,
- * null if the database does not support catalogs
- */
- abstract DTPCatalogWrapper getCatalog();
-
- /**
* return the schema for the specified DTP schema
*/
abstract DTPSchemaWrapper getSchema(org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema);
@@ -122,24 +117,33 @@ abstract class DTPSchemaContainerWrapper
for (int i = result.length; i-- > 0;) {
result[i] = new DTPSchemaWrapper(this, dtpSchemata.get(i));
}
- return result;
+ return CollectionTools.sort(result);
}
public int schemataSize() {
return this.getSchemata().length;
}
- public Iterator<String> schemaNames() {
+ public DTPSchemaWrapper getSchemaNamed(String name) {
+ return this.selectDatabaseObjectNamed(this.getSchemata(), name);
+ }
+
+ public Iterator<String> sortedSchemaIdentifiers() {
+ // the schemata are already sorted
return new TransformationIterator<DTPSchemaWrapper, String>(this.schemaWrappers()) {
@Override
- protected String transform(DTPSchemaWrapper schema) {
- return schema.getName();
+ protected String transform(DTPSchemaWrapper next) {
+ return next.getIdentifier();
}
};
}
- public DTPSchemaWrapper getSchemaNamed(String name) {
- return this.getDatabaseObjectNamed(this.getSchemata(), name);
+ public DTPSchemaWrapper getSchemaForIdentifier(String identifier) {
+ return this.selectDatabaseObjectForIdentifier(this.getSchemata(), identifier);
+ }
+
+ public DTPSchemaWrapper getDefaultSchema() {
+ return this.getDatabase().getDefaultSchema(this);
}
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaWrapper.java
index 3d3a2938d3..08382c69d7 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPSchemaWrapper.java
@@ -13,10 +13,10 @@ import java.text.Collator;
import java.util.Iterator;
import java.util.List;
-import org.eclipse.jpt.db.Catalog;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.Sequence;
import org.eclipse.jpt.db.Table;
+import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
@@ -60,8 +60,8 @@ final class DTPSchemaWrapper
return this.dtpSchema.getName();
}
- public Catalog getCatalog() {
- return this.getContainer().getCatalog();
+ public DTPSchemaContainerWrapper getContainer() {
+ return (DTPSchemaContainerWrapper) this.getParent();
}
// ***** tables
@@ -87,7 +87,7 @@ final class DTPSchemaWrapper
for (int i = result.length; i-- > 0;) {
result[i] = new DTPTableWrapper(this, dtpTables.get(i));
}
- return result;
+ return CollectionTools.sort(result);
}
// minimize scope of suppressed warnings
@@ -100,15 +100,6 @@ final class DTPSchemaWrapper
return this.getTables().length;
}
- public Iterator<String> tableNames() {
- return new TransformationIterator<DTPTableWrapper, String>(this.tableWrappers()) {
- @Override
- protected String transform(DTPTableWrapper table) {
- return table.getName();
- }
- };
- }
-
/**
* return the table for the specified DTP table
*/
@@ -133,7 +124,21 @@ final class DTPSchemaWrapper
}
public DTPTableWrapper getTableNamed(String name) {
- return this.getDatabaseObjectNamed(this.getTables(), name);
+ return this.selectDatabaseObjectNamed(this.getTables(), name);
+ }
+
+ public Iterator<String> sortedTableIdentifiers() {
+ // the tables are already sorted
+ return new TransformationIterator<DTPTableWrapper, String>(this.tableWrappers()) {
+ @Override
+ protected String transform(DTPTableWrapper table) {
+ return table.getIdentifier();
+ }
+ };
+ }
+
+ public DTPTableWrapper getTableForIdentifier(String identifier) {
+ return this.selectDatabaseObjectForIdentifier(this.getTables(), identifier);
}
// ***** sequences
@@ -159,7 +164,7 @@ final class DTPSchemaWrapper
for (int i = result.length; i-- > 0;) {
result[i] = new DTPSequenceWrapper(this, dtpSequences.get(i));
}
- return result;
+ return CollectionTools.sort(result);
}
// minimize scope of suppressed warnings
@@ -172,17 +177,22 @@ final class DTPSchemaWrapper
return this.getSequences().length;
}
- public Iterator<String> sequenceNames() {
+ public DTPSequenceWrapper getSequenceNamed(String name) {
+ return this.selectDatabaseObjectNamed(this.getSequences(), name);
+ }
+
+ public Iterator<String> sortedSequenceIdentifiers() {
+ // the sequences are already sorted
return new TransformationIterator<DTPSequenceWrapper, String>(this.sequenceWrappers()) {
@Override
protected String transform(DTPSequenceWrapper sequence) {
- return sequence.getName();
+ return sequence.getIdentifier();
}
};
}
- public DTPSequenceWrapper getSequenceNamed(String name) {
- return this.getDatabaseObjectNamed(this.getSequences(), name);
+ public DTPSequenceWrapper getSequenceForIdentifier(String identifier) {
+ return this.selectDatabaseObjectForIdentifier(this.getSequences(), identifier);
}
@@ -216,10 +226,6 @@ final class DTPSchemaWrapper
return this.getTable_(dtpColumn.getTable()).getColumn_(dtpColumn);
}
- private DTPSchemaContainerWrapper getContainer() {
- return (DTPSchemaContainerWrapper) this.getParent();
- }
-
// ********** listening **********
diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTableWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTableWrapper.java
index fc50bc4913..3dab7266df 100644
--- a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTableWrapper.java
+++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTableWrapper.java
@@ -96,7 +96,7 @@ final class DTPTableWrapper
for (int i = result.length; i-- > 0;) {
result[i] = new DTPColumnWrapper(this, dtpColumns.get(i));
}
- return result;
+ return CollectionTools.sort(result);
}
// minimize scope of suppressed warnings
@@ -109,13 +109,8 @@ final class DTPTableWrapper
return this.getColumns().length;
}
- public Iterator<String> columnNames() {
- return new TransformationIterator<DTPColumnWrapper, String>(this.columnWrappers()) {
- @Override
- protected String transform(DTPColumnWrapper next) {
- return next.getName();
- }
- };
+ public DTPColumnWrapper getColumnNamed(String name) {
+ return this.selectDatabaseObjectNamed(this.getColumns(), name);
}
/**
@@ -141,8 +136,18 @@ final class DTPTableWrapper
throw new IllegalArgumentException("invalid DTP column: " + dtpColumn); //$NON-NLS-1$
}
- public DTPColumnWrapper getColumnNamed(String name) {
- return this.getDatabaseObjectNamed(this.getColumns(), name);
+ public Iterator<String> sortedColumnIdentifiers() {
+ // the columns are already sorted
+ return new TransformationIterator<DTPColumnWrapper, String>(this.columnWrappers()) {
+ @Override
+ protected String transform(DTPColumnWrapper next) {
+ return next.getIdentifier();
+ }
+ };
+ }
+
+ public DTPColumnWrapper getColumnForIdentifier(String identifier) {
+ return this.selectDatabaseObjectForIdentifier(this.getColumns(), identifier);
}
// ***** primaryKeyColumns

Back to the top