You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [31/44] - in /incubator/openjpa/trunk: ./
openjpa-jdbc-5/ openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/
openjpa-jdbc-5/src/main/java/ openjpa-jdbc-5/src/main/java/org/
openjpa-jdbc-5/src/main/java/org/apache/ openjpa-jdbc-5/src/main/...
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import javax.sql.DataSource;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.StoreException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Factory class to instantiate a dictionary. It will use
+ * the following heuristic:
+ * <ul>
+ * <li>Check to see if there is a DictionaryClass property,
+ * and if so, use that to instantiate the dictionary.</li>
+ * <li>Check the URL in the JDBCConfiguration against a list
+ * of pre-defined URLs for various dictionaries.</li>
+ * <li>Check the driver in the JDBCConfiguration against a list of known
+ * patterns.</li>
+ * <li>Acquire a connection and check its database metadata.</li>
+ * <li>Return an instance of the generic DBDictionary.</li>
+ * </ul>
+ *
+ * @author Marc Prud'hommeaux
+ * @nojavadoc
+ */
+public class DBDictionaryFactory {
+
+ // pcl: can't use these classes directly because they rely on native libs
+ private static final String ORACLE_DICT_NAME =
+ "org.apache.openjpa.jdbc.sql.OracleDictionary";
+ private static final String HSQL_DICT_NAME =
+ "org.apache.openjpa.jdbc.sql.HSQLDictionary";
+
+ private static final Localizer _loc = Localizer.forPackage
+ (DBDictionaryFactory.class);
+
+ /**
+ * Create the dictionary for the given class name and properties.
+ */
+ public static DBDictionary newDBDictionary(JDBCConfiguration conf,
+ String dclass, String props) {
+ return newDBDictionary(conf, dclass, props, null);
+ }
+
+ /**
+ * Attempt to create the dictionary from the given connection URL and
+ * driver name, either or both of which may be null. If the dictionary
+ * cannot be calculated, returns null.
+ */
+ public static DBDictionary calculateDBDictionary(JDBCConfiguration conf,
+ String url, String driver, String props) {
+ String dclass = dictionaryClassForString(url);
+ if (dclass == null)
+ dclass = dictionaryClassForString(driver);
+ if (dclass == null)
+ return null;
+ return newDBDictionary(conf, dclass, props);
+ }
+
+ /**
+ * Create the dictionary using connection metadata to determine its type.
+ */
+ public static DBDictionary newDBDictionary(JDBCConfiguration conf,
+ DataSource ds, String props) {
+ Connection conn = null;
+ try {
+ conn = ds.getConnection();
+ DatabaseMetaData meta = conn.getMetaData();
+ String dclass = dictionaryClassForString(meta.getURL());
+ if (dclass == null)
+ dclass = dictionaryClassForString
+ (meta.getDatabaseProductName());
+ if (dclass == null)
+ dclass = DBDictionary.class.getName();
+ return newDBDictionary(conf, dclass, props, conn);
+ } catch (SQLException se) {
+ throw new StoreException(se).setFatal(true);
+ } finally {
+ if (conn != null)
+ try {
+ conn.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ /**
+ * Create the dictionary using the given class name and properties; the
+ * connection may be null if not supplied to the factory.
+ */
+ private static DBDictionary newDBDictionary(JDBCConfiguration conf,
+ String dclass, String props, Connection conn) {
+ DBDictionary dict = null;
+ try {
+ dict = (DBDictionary) Class.forName(dclass, true,
+ DBDictionary.class.getClassLoader()).newInstance();
+ } catch (Exception e) {
+ throw new UserException(e).setFatal(true);
+ }
+
+ // warn if we could not locate the appropriate dictionary
+ Log log = conf.getLog(JDBCConfiguration.LOG_JDBC);
+ if (log.isWarnEnabled() && dict.getClass() == DBDictionary.class)
+ log.warn(_loc.get("warn-generic"));
+
+ if (log.isInfoEnabled()) {
+ String infoString = "";
+ if (conn != null) {
+ try {
+ DatabaseMetaData meta = conn.getMetaData();
+ infoString = " (" + meta.getDatabaseProductName() + " "
+ + meta.getDatabaseProductVersion() + " ,"
+ + meta.getDriverName() + " "
+ + meta.getDriverVersion() + ")";
+ } catch (SQLException se) {
+ if (log.isTraceEnabled())
+ log.trace(se.toString(), se);
+ }
+ }
+
+ log.info(_loc.get("using-dict", dclass, infoString));
+ }
+
+ // set the dictionary's metadata
+ Configurations.configureInstance(dict, conf, props, "DBDictionary");
+ if (conn != null) {
+ try {
+ dict.connectedConfiguration(conn);
+ } catch (SQLException se) {
+ throw new StoreException(se).setFatal(true);
+ }
+ }
+ return dict;
+ }
+
+ /**
+ * Guess the dictionary class name to use based on the product string.
+ */
+ private static String dictionaryClassForString(String prod) {
+ if (prod == null || prod.length() == 0)
+ return null;
+ prod = prod.toLowerCase();
+
+ if (prod.indexOf("oracle") != -1)
+ return ORACLE_DICT_NAME;
+ if (prod.indexOf("sqlserver") != -1)
+ return SQLServerDictionary.class.getName();
+ if (prod.indexOf("jsqlconnect") != -1)
+ return SQLServerDictionary.class.getName();
+ if (prod.indexOf("mysql") != -1)
+ return MySQLDictionary.class.getName();
+ if (prod.indexOf("postgres") != -1)
+ return PostgresDictionary.class.getName();
+ if (prod.indexOf("sybase") != -1)
+ return SybaseDictionary.class.getName();
+ if (prod.indexOf("adaptive server") != -1)
+ return SybaseDictionary.class.getName();
+ if (prod.indexOf("informix") != -1)
+ return InformixDictionary.class.getName();
+ if (prod.indexOf("hsql") != -1)
+ return HSQL_DICT_NAME;
+ if (prod.indexOf("foxpro") != -1)
+ return FoxProDictionary.class.getName();
+ if (prod.indexOf("interbase") != -1)
+ return InterbaseDictionary.class.getName();
+ if (prod.indexOf("jdatastore") != -1)
+ return JDataStoreDictionary.class.getName();
+ if (prod.indexOf("borland") != -1)
+ return JDataStoreDictionary.class.getName();
+ if (prod.indexOf("access") != -1)
+ return AccessDictionary.class.getName();
+ if (prod.indexOf("pointbase") != -1)
+ return PointbaseDictionary.class.getName();
+ if (prod.indexOf("empress") != -1)
+ return EmpressDictionary.class.getName();
+ if (prod.indexOf("firebird") != -1)
+ return FirebirdDictionary.class.getName();
+ if (prod.indexOf("cache") != -1)
+ return CacheDictionary.class.getName();
+ if (prod.indexOf("derby") != -1)
+ return DerbyDictionary.class.getName();
+ // test db2 last, because there's a decent chance this string could
+ // appear in the URL of another database (like if the db is named
+ // "testdb2" or something)
+ if (prod.indexOf("db2") != -1 || prod.indexOf("as400") != -1)
+ return DB2Dictionary.class.getName();
+
+ // known dbs that we don't support
+ if (prod.indexOf("cloudscape") != -1)
+ return DBDictionary.class.getName();
+ if (prod.indexOf("daffodil") != -1)
+ return DBDictionary.class.getName();
+ if (prod.indexOf("sapdb") != -1)
+ return DBDictionary.class.getName();
+ if (prod.indexOf("idb") != -1) // instantdb
+ return DBDictionary.class.getName();
+
+ // give up
+ return null;
+ }
+
+ /**
+ * Return a string containing all the property values of the given
+ * database metadata.
+ */
+ public static String toString(DatabaseMetaData meta)
+ throws SQLException {
+ String lineSep = System.getProperty("line.separator");
+ StringBuffer buf = new StringBuffer();
+ try {
+ buf.append("catalogSeparator: ")
+ .append(meta.getCatalogSeparator())
+ .append(lineSep)
+ .append("catalogTerm: ")
+ .append(meta.getCatalogTerm())
+ .append(lineSep)
+ .append("databaseProductName: ")
+ .append(meta.getDatabaseProductName())
+ .append(lineSep)
+ .append("databaseProductVersion: ")
+ .append(meta.getDatabaseProductVersion())
+ .append(lineSep)
+ .append("driverName: ")
+ .append(meta.getDriverName())
+ .append(lineSep)
+ .append("driverVersion: ")
+ .append(meta.getDriverVersion())
+ .append(lineSep)
+ .append("extraNameCharacters: ")
+ .append(meta.getExtraNameCharacters())
+ .append(lineSep)
+ .append("identifierQuoteString: ")
+ .append(meta.getIdentifierQuoteString())
+ .append(lineSep)
+ .append("numericFunctions: ")
+ .append(meta.getNumericFunctions())
+ .append(lineSep)
+ .append("procedureTerm: ")
+ .append(meta.getProcedureTerm())
+ .append(lineSep)
+ .append("schemaTerm: ")
+ .append(meta.getSchemaTerm())
+ .append(lineSep)
+ .append("searchStringEscape: ")
+ .append(meta.getSearchStringEscape())
+ .append(lineSep)
+ .append("sqlKeywords: ")
+ .append(meta.getSQLKeywords())
+ .append(lineSep)
+ .append("stringFunctions: ")
+ .append(meta.getStringFunctions())
+ .append(lineSep)
+ .append("systemFunctions: ")
+ .append(meta.getSystemFunctions())
+ .append(lineSep)
+ .append("timeDateFunctions: ")
+ .append(meta.getTimeDateFunctions())
+ .append(lineSep)
+ .append("url: ")
+ .append(meta.getURL())
+ .append(lineSep)
+ .append("userName: ")
+ .append(meta.getUserName())
+ .append(lineSep)
+ .append("defaultTransactionIsolation: ")
+ .append(meta.getDefaultTransactionIsolation())
+ .append(lineSep)
+ .append("driverMajorVersion: ")
+ .append(meta.getDriverMajorVersion())
+ .append(lineSep)
+ .append("driverMinorVersion: ")
+ .append(meta.getDriverMinorVersion())
+ .append(lineSep)
+ .append("maxBinaryLiteralLength: ")
+ .append(meta.getMaxBinaryLiteralLength())
+ .append(lineSep)
+ .append("maxCatalogNameLength: ")
+ .append(meta.getMaxCatalogNameLength())
+ .append(lineSep)
+ .append("maxCharLiteralLength: ")
+ .append(meta.getMaxCharLiteralLength())
+ .append(lineSep)
+ .append("maxColumnNameLength: ")
+ .append(meta.getMaxColumnNameLength())
+ .append(lineSep)
+ .append("maxColumnsInGroupBy: ")
+ .append(meta.getMaxColumnsInGroupBy())
+ .append(lineSep)
+ .append("maxColumnsInIndex: ")
+ .append(meta.getMaxColumnsInIndex())
+ .append(lineSep)
+ .append("maxColumnsInOrderBy: ")
+ .append(meta.getMaxColumnsInOrderBy())
+ .append(lineSep)
+ .append("maxColumnsInSelect: ")
+ .append(meta.getMaxColumnsInSelect())
+ .append(lineSep)
+ .append("maxColumnsInTable: ")
+ .append(meta.getMaxColumnsInTable())
+ .append(lineSep)
+ .append("maxConnections: ")
+ .append(meta.getMaxConnections())
+ .append(lineSep)
+ .append("maxCursorNameLength: ")
+ .append(meta.getMaxCursorNameLength())
+ .append(lineSep)
+ .append("maxIndexLength: ")
+ .append(meta.getMaxIndexLength())
+ .append(lineSep)
+ .append("maxProcedureNameLength: ")
+ .append(meta.getMaxProcedureNameLength())
+ .append(lineSep)
+ .append("maxRowSize: ")
+ .append(meta.getMaxRowSize())
+ .append(lineSep)
+ .append("maxSchemaNameLength: ")
+ .append(meta.getMaxSchemaNameLength())
+ .append(lineSep)
+ .append("maxStatementLength: ")
+ .append(meta.getMaxStatementLength())
+ .append(lineSep)
+ .append("maxStatements: ")
+ .append(meta.getMaxStatements())
+ .append(lineSep)
+ .append("maxTableNameLength: ")
+ .append(meta.getMaxTableNameLength())
+ .append(lineSep)
+ .append("maxTablesInSelect: ")
+ .append(meta.getMaxTablesInSelect())
+ .append(lineSep)
+ .append("maxUserNameLength: ")
+ .append(meta.getMaxUserNameLength())
+ .append(lineSep)
+ .append("isCatalogAtStart: ")
+ .append(meta.isCatalogAtStart())
+ .append(lineSep)
+ .append("isReadOnly: ")
+ .append(meta.isReadOnly())
+ .append(lineSep)
+ .append("nullPlusNonNullIsNull: ")
+ .append(meta.nullPlusNonNullIsNull())
+ .append(lineSep)
+ .append("nullsAreSortedAtEnd: ")
+ .append(meta.nullsAreSortedAtEnd())
+ .append(lineSep)
+ .append("nullsAreSortedAtStart: ")
+ .append(meta.nullsAreSortedAtStart())
+ .append(lineSep)
+ .append("nullsAreSortedHigh: ")
+ .append(meta.nullsAreSortedHigh())
+ .append(lineSep)
+ .append("nullsAreSortedLow: ")
+ .append(meta.nullsAreSortedLow())
+ .append(lineSep)
+ .append("storesLowerCaseIdentifiers: ")
+ .append(meta.storesLowerCaseIdentifiers())
+ .append(lineSep)
+ .append("storesLowerCaseQuotedIdentifiers: ")
+ .append(meta.storesLowerCaseQuotedIdentifiers())
+ .append(lineSep)
+ .append("storesMixedCaseIdentifiers: ")
+ .append(meta.storesMixedCaseIdentifiers())
+ .append(lineSep)
+ .append("storesMixedCaseQuotedIdentifiers: ")
+ .append(meta.storesMixedCaseQuotedIdentifiers())
+ .append(lineSep)
+ .append("storesUpperCaseIdentifiers: ")
+ .append(meta.storesUpperCaseIdentifiers())
+ .append(lineSep)
+ .append("storesUpperCaseQuotedIdentifiers: ")
+ .append(meta.storesUpperCaseQuotedIdentifiers())
+ .append(lineSep)
+ .append("supportsAlterTableWithAddColumn: ")
+ .append(meta.supportsAlterTableWithAddColumn())
+ .append(lineSep)
+ .append("supportsAlterTableWithDropColumn: ")
+ .append(meta.supportsAlterTableWithDropColumn())
+ .append(lineSep)
+ .append("supportsANSI92EntryLevelSQL: ")
+ .append(meta.supportsANSI92EntryLevelSQL())
+ .append(lineSep)
+ .append("supportsANSI92FullSQL: ")
+ .append(meta.supportsANSI92FullSQL())
+ .append(lineSep)
+ .append("supportsANSI92IntermediateSQL: ")
+ .append(meta.supportsANSI92IntermediateSQL())
+ .append(lineSep)
+ .append("supportsCatalogsInDataManipulation: ")
+ .append(meta.supportsCatalogsInDataManipulation())
+ .append(lineSep)
+ .append("supportsCatalogsInIndexDefinitions: ")
+ .append(meta.supportsCatalogsInIndexDefinitions())
+ .append(lineSep)
+ .append("supportsCatalogsInPrivilegeDefinitions: ")
+ .append(meta.supportsCatalogsInPrivilegeDefinitions())
+ .append(lineSep)
+ .append("supportsCatalogsInProcedureCalls: ")
+ .append(meta.supportsCatalogsInProcedureCalls())
+ .append(lineSep)
+ .append("supportsCatalogsInTableDefinitions: ")
+ .append(meta.supportsCatalogsInTableDefinitions())
+ .append(lineSep)
+ .append("supportsColumnAliasing: ")
+ .append(meta.supportsColumnAliasing())
+ .append(lineSep)
+ .append("supportsConvert: ")
+ .append(meta.supportsConvert())
+ .append(lineSep)
+ .append("supportsCoreSQLGrammar: ")
+ .append(meta.supportsCoreSQLGrammar())
+ .append(lineSep)
+ .append("supportsCorrelatedSubqueries: ")
+ .append(meta.supportsCorrelatedSubqueries())
+ .append(lineSep)
+ .append(
+ "supportsDataDefinitionAndDataManipulationTransactions: ")
+ .append(meta.
+ supportsDataDefinitionAndDataManipulationTransactions())
+ .append(lineSep)
+ .append("supportsDataManipulationTransactionsOnly: ")
+ .append(meta.supportsDataManipulationTransactionsOnly())
+ .append(lineSep)
+ .append("supportsDifferentTableCorrelationNames: ")
+ .append(meta.supportsDifferentTableCorrelationNames())
+ .append(lineSep)
+ .append("supportsExpressionsInOrderBy: ")
+ .append(meta.supportsExpressionsInOrderBy())
+ .append(lineSep)
+ .append("supportsExtendedSQLGrammar: ")
+ .append(meta.supportsExtendedSQLGrammar())
+ .append(lineSep)
+ .append("supportsFullOuterJoins: ")
+ .append(meta.supportsFullOuterJoins())
+ .append(lineSep)
+ .append("supportsGroupBy: ")
+ .append(meta.supportsGroupBy())
+ .append(lineSep)
+ .append("supportsGroupByBeyondSelect: ")
+ .append(meta.supportsGroupByBeyondSelect())
+ .append(lineSep)
+ .append("supportsGroupByUnrelated: ")
+ .append(meta.supportsGroupByUnrelated())
+ .append(lineSep)
+ .append("supportsIntegrityEnhancementFacility: ")
+ .append(meta.supportsIntegrityEnhancementFacility())
+ .append(lineSep)
+ .append("supportsLikeEscapeClause: ")
+ .append(meta.supportsLikeEscapeClause())
+ .append(lineSep)
+ .append("supportsLimitedOuterJoins: ")
+ .append(meta.supportsLimitedOuterJoins())
+ .append(lineSep)
+ .append("supportsMinimumSQLGrammar: ")
+ .append(meta.supportsMinimumSQLGrammar())
+ .append(lineSep)
+ .append("supportsMixedCaseIdentifiers: ")
+ .append(meta.supportsMixedCaseIdentifiers())
+ .append(lineSep)
+ .append("supportsMixedCaseQuotedIdentifiers: ")
+ .append(meta.supportsMixedCaseQuotedIdentifiers())
+ .append(lineSep)
+ .append("supportsMultipleResultSets: ")
+ .append(meta.supportsMultipleResultSets())
+ .append(lineSep)
+ .append("supportsMultipleTransactions: ")
+ .append(meta.supportsMultipleTransactions())
+ .append(lineSep)
+ .append("supportsNonNullableColumns: ")
+ .append(meta.supportsNonNullableColumns())
+ .append(lineSep)
+ .append("supportsOpenCursorsAcrossCommit: ")
+ .append(meta.supportsOpenCursorsAcrossCommit())
+ .append(lineSep)
+ .append("supportsOpenCursorsAcrossRollback: ")
+ .append(meta.supportsOpenCursorsAcrossRollback())
+ .append(lineSep)
+ .append("supportsOpenStatementsAcrossCommit: ")
+ .append(meta.supportsOpenStatementsAcrossCommit())
+ .append(lineSep)
+ .append("supportsOpenStatementsAcrossRollback: ")
+ .append(meta.supportsOpenStatementsAcrossRollback())
+ .append(lineSep)
+ .append("supportsOrderByUnrelated: ")
+ .append(meta.supportsOrderByUnrelated())
+ .append(lineSep)
+ .append("supportsOuterJoins: ")
+ .append(meta.supportsOuterJoins())
+ .append(lineSep)
+ .append("supportsPositionedDelete: ")
+ .append(meta.supportsPositionedDelete())
+ .append(lineSep)
+ .append("supportsPositionedUpdate: ")
+ .append(meta.supportsPositionedUpdate())
+ .append(lineSep)
+ .append("supportsSchemasInDataManipulation: ")
+ .append(meta.supportsSchemasInDataManipulation())
+ .append(lineSep)
+ .append("supportsSchemasInIndexDefinitions: ")
+ .append(meta.supportsSchemasInIndexDefinitions())
+ .append(lineSep)
+ .append("supportsSchemasInPrivilegeDefinitions: ")
+ .append(meta.supportsSchemasInPrivilegeDefinitions())
+ .append(lineSep)
+ .append("supportsSchemasInProcedureCalls: ")
+ .append(meta.supportsSchemasInProcedureCalls())
+ .append(lineSep)
+ .append("supportsSchemasInTableDefinitions: ")
+ .append(meta.supportsSchemasInTableDefinitions())
+ .append(lineSep)
+ .append("supportsSelectForUpdate: ")
+ .append(meta.supportsSelectForUpdate())
+ .append(lineSep)
+ .append("supportsStoredProcedures: ")
+ .append(meta.supportsStoredProcedures())
+ .append(lineSep)
+ .append("supportsSubqueriesInComparisons: ")
+ .append(meta.supportsSubqueriesInComparisons())
+ .append(lineSep)
+ .append("supportsSubqueriesInExists: ")
+ .append(meta.supportsSubqueriesInExists())
+ .append(lineSep)
+ .append("supportsSubqueriesInIns: ")
+ .append(meta.supportsSubqueriesInIns())
+ .append(lineSep)
+ .append("supportsSubqueriesInQuantifieds: ")
+ .append(meta.supportsSubqueriesInQuantifieds())
+ .append(lineSep)
+ .append("supportsTableCorrelationNames: ")
+ .append(meta.supportsTableCorrelationNames())
+ .append(lineSep)
+ .append("supportsTransactions: ")
+ .append(meta.supportsTransactions())
+ .append(lineSep)
+ .append("supportsUnion: ")
+ .append(meta.supportsUnion())
+ .append(lineSep)
+ .append("supportsUnionAll: ")
+ .append(meta.supportsUnionAll())
+ .append(lineSep)
+ .append("usesLocalFilePerTable: ")
+ .append(meta.usesLocalFilePerTable())
+ .append(lineSep)
+ .append("usesLocalFiles: ")
+ .append(meta.usesLocalFiles())
+ .append(lineSep)
+ .append("allProceduresAreCallable: ")
+ .append(meta.allProceduresAreCallable())
+ .append(lineSep)
+ .append("allTablesAreSelectable: ")
+ .append(meta.allTablesAreSelectable())
+ .append(lineSep)
+ .append("dataDefinitionCausesTransactionCommit: ")
+ .append(meta.dataDefinitionCausesTransactionCommit())
+ .append(lineSep)
+ .append("dataDefinitionIgnoredInTransactions: ")
+ .append(meta.dataDefinitionIgnoredInTransactions())
+ .append(lineSep)
+ .append("doesMaxRowSizeIncludeBlobs: ")
+ .append(meta.doesMaxRowSizeIncludeBlobs())
+ .append(lineSep)
+ .append("supportsBatchUpdates: ")
+ .append(meta.supportsBatchUpdates());
+ } catch (Throwable t) {
+ // maybe abstract method error for jdbc 3 metadata method, or
+ // other error
+ buf.append(lineSep).append("Caught throwable: ").append(t);
+ }
+
+ return buf.toString();
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionaryFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Arrays;
+import javax.sql.DataSource;
+
+/**
+ * Dictionary for Apache Derby (formerly Cloudscape).
+ */
+public class DerbyDictionary
+ extends AbstractDB2Dictionary {
+
+ /**
+ * If true, we will shutdown the embedded database when closing
+ * the DataSource.
+ */
+ public boolean shutdownOnClose = true;
+
+ public DerbyDictionary() {
+ platform = "Apache Derby";
+ validationSQL = "VALUES(1)";
+ stringLengthFunction = "LENGTH({0})";
+ substringFunctionName = "SUBSTR";
+
+ maxConstraintNameLength = 18;
+ maxIndexNameLength = 18;
+ maxColumnNameLength = 30;
+ maxTableNameLength = 18;
+
+ useGetBytesForBlobs = true;
+ useSetBytesForBlobs = true;
+
+ allowsAliasInBulkClause = false;
+ supportsDeferredConstraints = false;
+ supportsSelectForUpdate = true;
+ supportsDefaultDeleteAction = false;
+ requiresCastForMathFunctions = true;
+ requiresCastForComparisons = true;
+
+ fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
+ "BIGINT", "INTEGER",
+ }));
+ reservedWordSet.addAll(Arrays.asList(new String[]{
+ "ALIAS", "BIGINT", "BOOLEAN", "CALL", "CLASS",
+ "COPY", "DB2J_DEBUG", "EXECUTE", "EXPLAIN",
+ "FILE", "FILTER", "GETCURRENTCONNECTION", "INDEX",
+ "INSTANCEOF", "METHOD", "NEW", "OFF", "OUT", "PROPERTIES",
+ "PUBLICATION", "RECOMPILE", "REFRESH", "RENAME",
+ "RUNTIMESTATISTICS", "STATEMENT", "STATISTICS",
+ "TIMING", "WAIT", "XML",
+ }));
+ }
+
+ public void closeDataSource(DataSource dataSource) {
+ super.closeDataSource(dataSource);
+
+ if (!shutdownOnClose)
+ return;
+
+ // as well as closing the DataSource, we also need to
+ // shut down the instance if we are using an embedded database, which
+ // can only be done by connecting to the same URL with the
+ // ";shutdown=true" string appended to the end
+ // see: http://db.apache.org/derby/docs/dev/devguide/tdevdvlp40464.html
+ if (conf != null && conf.getConnectionDriverName() != null &&
+ conf.getConnectionDriverName().indexOf("EmbeddedDriver") != -1) {
+ try {
+ DriverManager.getConnection(conf.getConnectionURL()
+ + ";shutdown=true");
+ } catch (SQLException e) {
+ // we actuall expect a SQLException to be thrown here:
+ // Derby strangely uses that as a mechanism to report
+ // a successful shutdown
+ }
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/EmpressDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/EmpressDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/EmpressDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/EmpressDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Table;
+
+/**
+ * Dictionary for Empress using ODBC server combined with their
+ * type 2 driver. This dictionary may issues with other
+ * driver/topology configurations.
+ * Empress does not allow multiple connections to read rows
+ * read in a transaction, effectively forcing pessimistic transactions
+ * regardless of the Optimistic setting. To allow users to use
+ * optimistic transactions in a multi-connection evironment, you
+ * must set the AllowConcurrentRead setting to true in addition
+ * to standard options.
+ * Empress has the following additional limitations:
+ * <ul>
+ * <li>Foreign keys are quite limited in Empress and it is recommended
+ * that these be created by hand.</li>
+ * <li>Batching can be unreliable. Using BatchLimit=0 is strongly
+ * recommended.</li>
+ * <li>Using AllowConcurrentRead should be accompanied by
+ * SimulateLocking=true</li>
+ * <li>Connections should be rolled back on return to ensure locks
+ * are released (see OpenJPA default DataSource documentation.</li>
+ * <li>Certain outer joins requiring parameters in a subselect is not
+ * supported by Empress and may under certain configurations cause
+ * size () calls on query results and LRS fields to throw an exception.</li>
+ * <li>Certain aggregate functions are not supported.</li>
+ * </ul>
+ */
+public class EmpressDictionary
+ extends DBDictionary {
+
+ /**
+ * This setting inserts "BYPASS" after every "SELECT". This
+ * allows for multiple transactional reads of the same row
+ * from different connections at the expense of loss of
+ * pessimistic locking. Defaults to false.
+ */
+ public boolean allowConcurrentRead = false;
+
+ public EmpressDictionary() {
+ platform = "Empress";
+
+ validationSQL = "SELECT DISTINCT today FROM sys_tables";
+ joinSyntax = SYNTAX_TRADITIONAL;
+ toUpperCaseFunction = "TOUPPER({0})";
+ toLowerCaseFunction = "TOLOWER({0})";
+
+ supportsDeferredConstraints = false;
+ requiresAliasForSubselect = true;
+ maxTableNameLength = 28;
+ maxColumnNameLength = 28;
+ maxIndexNameLength = 28;
+ maxConstraintNameLength = 28;
+ schemaCase = SCHEMA_CASE_PRESERVE;
+
+ useGetBytesForBlobs = true;
+ useSetBytesForBlobs = true;
+ useGetStringForClobs = true;
+ useSetStringForClobs = true;
+
+ clobTypeName = "TEXT";
+ blobTypeName = "BULK";
+ realTypeName = "FLOAT(8)";
+ bigintTypeName = "DECIMAL(38)";
+ timestampTypeName = "DATE";
+ varcharTypeName = "CHARACTER";
+ tinyintTypeName = "DOUBLE PRECISION";
+ doubleTypeName = "SMALLINT";
+ bitTypeName = "SMALLINT";
+
+ fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
+ "TEXT", "BULK", "LONGFLOAT", "INTEGER64", "SHORTINTEGER",
+ "LONGINTEGER",
+ }));
+ }
+
+ public boolean isSystemIndex(String name, Table table) {
+ return name.toUpperCase().startsWith("SYS_");
+ }
+
+ public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch,
+ SQLBuffer from, SQLBuffer where, SQLBuffer group,
+ SQLBuffer having, SQLBuffer order,
+ boolean distinct, boolean forUpdate, long startIdx, long endIdx) {
+ if (!allowConcurrentRead)
+ return super.toSelect(selects, fetch, from, where, group,
+ having, order, distinct, forUpdate, startIdx, endIdx);
+
+ // override to allow a "BYPASS" to be inserted post-"select"
+ // depending on allowConcurrentRead setting
+ SQLBuffer buf = new SQLBuffer(this);
+ buf.append("SELECT BYPASS ");
+ if (distinct)
+ buf.append("DISTINCT ");
+ buf.append(selects).append(" FROM ").append(from);
+
+ if (where != null && !where.isEmpty())
+ buf.append(" WHERE ").append(where);
+ if (group != null && !group.isEmpty())
+ buf.append(" GROUP BY ").append(group);
+ if (having != null && !having.isEmpty())
+ buf.append(" HAVING ").append(having);
+ if (order != null && !order.isEmpty())
+ buf.append(" ORDER BY ").append(order);
+ return buf;
+ }
+
+ public String[] getDropColumnSQL(Column column) {
+ // empress wants dropped columns in the form: ALTER TABLE foo
+ // DELETE columnToDrop
+ return new String[]{ "ALTER TABLE "
+ + getFullName(column.getTable(), false) + " DELETE " + column };
+ }
+
+ public void setFloat(PreparedStatement stmnt, int idx, float val,
+ Column col)
+ throws SQLException {
+ // empress seems to allow INFINITY to be stored, but not retrieved,
+ // which can prove to be difficult to handle
+ if (val == Float.POSITIVE_INFINITY) {
+ val = Float.MAX_VALUE;
+ storageWarning(new Float(Float.POSITIVE_INFINITY),
+ new Float(val));
+ } else if (val == Float.NEGATIVE_INFINITY) {
+ val = Float.MIN_VALUE + 1;
+ storageWarning(new Float(Float.NEGATIVE_INFINITY),
+ new Float(val));
+ }
+ super.setFloat(stmnt, idx, val, col);
+ }
+
+ public void setDouble(PreparedStatement stmnt, int idx, double val,
+ Column col)
+ throws SQLException {
+ // empress seems to allow INFINITY to be stored, but not retrieved,
+ // which can prove to be difficult to handle
+ if (val == Double.POSITIVE_INFINITY) {
+ val = Double.MAX_VALUE;
+ storageWarning(new Double(Double.POSITIVE_INFINITY),
+ new Double(val));
+ } else if (val == Double.NEGATIVE_INFINITY) {
+ val = Double.MIN_VALUE + 1;
+ storageWarning(new Double(Double.NEGATIVE_INFINITY),
+ new Double(val));
+ }
+ super.setDouble(stmnt, idx, val, col);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/EmpressDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FirebirdDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FirebirdDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FirebirdDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FirebirdDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.schema.Column;
+
+/**
+ * Dictionary for Firebird.
+ */
+public class FirebirdDictionary
+ extends InterbaseDictionary {
+
+ public FirebirdDictionary() {
+ platform = "Firebird";
+
+ // Firebird 1.5+ locking statement
+ supportsLockingWithMultipleTables = false;
+ forUpdateClause = "FOR UPDATE WITH LOCK";
+ }
+
+ public String getPlaceholderValueString(Column col) {
+ return super.getPlaceholderValueString(col)
+ + " AS " + getTypeName(col);
+ }
+
+ public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
+ FilterValue end) {
+ // SUBSTRING in Firebird is of the form:
+ // SELECT SUBSTRING(SOME_COLUMN FROM 1 FOR 5)
+ buf.append("SUBSTRING(");
+ str.appendTo(buf);
+ buf.append(" FROM ");
+ start.appendTo(buf);
+ buf.append(" + 1");
+ if (end != null) {
+ buf.append(" FOR ");
+ end.appendTo(buf);
+ buf.append(" - (");
+ start.appendTo(buf);
+ buf.append(")");
+ }
+ buf.append(")");
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FirebirdDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FoxProDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FoxProDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FoxProDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FoxProDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+
+/**
+ * Dictionary for Visual FoxPro via DataDirect SequeLink
+ * and DataDirect ODBC FoxPro driver. This will not
+ * work with any other combination of JDBC/ODBC server and ODBC driver.
+ * FoxPro has the following limitations:
+ * <ul>
+ * <li>Primary Keys and indexes cannot be created via JDBC</li>
+ * <li>Only has fixed-length char fields: all strings must be
+ * trimmed in result sets</li>
+ * <li>Does not have sufficient support for foreign keys</li>
+ * <li>ODBC driver cannot handle certain Aggregate functions.</li>
+ * <li>Locking is extremeley unreliable. Multiple clients
+ * accessing single datastore may result in concurrency
+ * data validity errors.</li>
+ * </ul>
+ */
+public class FoxProDictionary
+ extends DBDictionary {
+
+ public FoxProDictionary() {
+ platform = "Visual FoxPro";
+ joinSyntax = SYNTAX_TRADITIONAL;
+
+ supportsForeignKeys = false;
+ supportsDeferredConstraints = false;
+ maxTableNameLength = 30;
+ maxColumnNameLength = 30;
+ maxIndexNameLength = 8;
+ maxConstraintNameLength = 8;
+
+ binaryTypeName = "GENERAL";
+ blobTypeName = "GENERAL";
+ longVarbinaryTypeName = "GENERAL";
+ clobTypeName = "MEMO";
+ longVarcharTypeName = "MEMO";
+ dateTypeName = "TIMESTAMP";
+ timeTypeName = "TIMESTAMP";
+ varcharTypeName = "CHARACTER{0}";
+ bigintTypeName = "DOUBLE";
+ numericTypeName = "INTEGER";
+ smallintTypeName = "INTEGER";
+ bitTypeName = "NUMERIC(1)";
+ integerTypeName = "INTEGER";
+ tinyintTypeName = "INTEGER";
+ decimalTypeName = "DOUBLE";
+ doubleTypeName = "DOUBLE";
+ realTypeName = "DOUBLE";
+ floatTypeName = "NUMERIC(19,16)";
+
+ // the max character literal length is actually 254, but for primary
+ // keys, it is 240; default to that length so users can add PKs later
+ characterColumnSize = 240;
+ }
+
+ public String getString(ResultSet rs, int column)
+ throws SQLException {
+ // foxpro doesn't auto-truncate values.
+ String str = rs.getString(column);
+ if (str != null)
+ str = str.trim();
+ return str;
+ }
+
+ public void setNull(PreparedStatement stmnt, int idx, int colType,
+ Column col)
+ throws SQLException {
+ // ensure that blob/clob is handled with safe methods.
+ switch (colType) {
+ case Types.BLOB:
+ stmnt.setBytes(idx, null);
+ break;
+ case Types.CLOB:
+ stmnt.setString(idx, null);
+ break;
+ default:
+ super.setNull(stmnt, idx, colType, col);
+ }
+ }
+
+ protected String appendSize(Column col, String typeName) {
+ // foxpro does not like unsized column declarations.
+ if (col.getSize() == 0) {
+ if ("CHARACTER".equals(typeName))
+ col.setSize(240);
+ else if ("NUMERIC".equals(typeName))
+ col.setSize(19);
+ }
+ return super.appendSize(col, typeName);
+ }
+
+ protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) {
+ // this foxpro driver combination does not support primary keys
+ return null;
+ }
+
+ public String[] getCreateIndexSQL(Index index) {
+ // foxpro JDBC access does not allow the creation of indexes
+ return new String[0];
+ }
+
+ public Column[] getColumns(DatabaseMetaData meta, String catalog,
+ String schemaName, String tableName, String columnName, Connection conn)
+ throws SQLException {
+ try {
+ Column[] cols = super.getColumns(meta, catalog, schemaName,
+ tableName, columnName, conn);
+ for (int i = 0; cols != null && i < cols.length; i++) {
+ // foxpro returns an odd type "11" code for DATETIME fields
+ if (cols[i].getType() == 11)
+ cols[i].setType(Types.TIMESTAMP);
+ // MEMO maps to LONGVARCHAR during reverse analysis
+ else if ("MEMO".equals(cols[i].getTypeName()))
+ cols[i].setType(Types.CLOB);
+ }
+ return cols;
+ } catch (SQLException se) {
+ // foxpro throws an exception if the table specified in the
+ // column list is not found
+ if (se.getErrorCode() == 562)
+ return null;
+ throw se;
+ }
+ }
+
+ public PrimaryKey[] getPrimaryKeys(DatabaseMetaData meta, String catalog,
+ String schemaName, String tableName, Connection conn)
+ throws SQLException {
+ // this combination does not reliably return PK information
+ return null;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/FoxProDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+
+import org.hsqldb.Trace;
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.Unique;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.ReferentialIntegrityException;
+import serp.util.Numbers;
+
+/**
+ * Dictionary for Hypersonic SQL database.
+ */
+public class HSQLDictionary
+ extends DBDictionary {
+
+ /**
+ * Sets whether HSQL should use "CREATED CACHED TABLE" rather than
+ * "CREATE TABLE", which allows disk-based database operations.
+ */
+ public boolean cacheTables = false;
+
+ private SQLBuffer _oneBuffer = new SQLBuffer(this).append("1");
+
+ public HSQLDictionary() {
+ platform = "HSQL";
+ validationSQL = "CALL 1";
+ closePoolSQL = "SHUTDOWN";
+
+ supportsAutoAssign = true;
+ lastGeneratedKeyQuery = "CALL IDENTITY()";
+ autoAssignClause = "IDENTITY";
+ autoAssignTypeName = "INTEGER";
+ nextSequenceQuery = "SELECT NEXT VALUE FOR {0} FROM"
+ + " INFORMATION_SCHEMA.SYSTEM_SEQUENCES";
+ crossJoinClause = "JOIN";
+ requiresConditionForCrossJoin = true;
+ stringLengthFunction = "LENGTH({0})";
+ trimLeadingFunction = "LTRIM({0})";
+ trimTrailingFunction = "RTRIM({0})";
+ trimBothFunction = "LTRIM(RTRIM({0}))";
+
+ // HSQL 1.8.0 does support schema names in the table ("schema.table"),
+ // but doesn't support it for columns references ("schema.table.column")
+ useSchemaName = false;
+ supportsSelectForUpdate = false;
+ supportsSelectStartIndex = true;
+ supportsSelectEndIndex = true;
+ rangePosition = RANGE_PRE_DISTINCT;
+ supportsDeferredConstraints = false;
+
+ useGetObjectForBlobs = true;
+ blobTypeName = "VARBINARY";
+
+ supportsNullTableForGetPrimaryKeys = true;
+ supportsNullTableForGetIndexInfo = true;
+
+ requiresCastForMathFunctions = true;
+ requiresCastForComparisons = true;
+
+ reservedWordSet.addAll(Arrays.asList(new String[]{
+ "BEFORE", "BIGINT", "BINARY", "CACHED", "DATETIME", "LIMIT",
+ "LONGVARBINARY", "LONGVARCHAR", "OBJECT", "OTHER",
+ "SAVEPOINT", "TEMP", "TEXT", "TRIGGER", "TINYINT",
+ "VARBINARY", "VARCHAR_IGNORECASE",
+ }));
+ }
+
+ public int getJDBCType(int metaTypeCode, boolean lob) {
+ int type = super.getJDBCType(metaTypeCode, lob);
+ switch (type) {
+ case Types.BIGINT:
+ if (metaTypeCode == JavaTypes.BIGINTEGER)
+ return Types.NUMERIC;
+ break;
+ }
+ return type;
+ }
+
+ public int getPreferredType(int type) {
+ switch (type) {
+ case Types.CLOB:
+ return Types.VARCHAR;
+ case Types.BLOB:
+ return Types.VARBINARY;
+ default:
+ return super.getPreferredType(type);
+ }
+ }
+
+ public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
+ return new String[0];
+ }
+
+ public String[] getDropPrimaryKeySQL(PrimaryKey pk) {
+ return new String[0];
+ }
+
+ public String[] getAddColumnSQL(Column column) {
+ return new String[]{ "ALTER TABLE "
+ + getFullName(column.getTable(), false)
+ + " ADD COLUMN " + getDeclareColumnSQL(column, true) };
+ }
+
+ public String[] getCreateTableSQL(Table table) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("CREATE ");
+ if (cacheTables)
+ buf.append("CACHED ");
+ buf.append("TABLE ").append(getFullName(table, false)).append(" (");
+
+ Column[] cols = table.getColumns();
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ buf.append(", ");
+ buf.append(getDeclareColumnSQL(cols[i], false));
+ }
+
+ PrimaryKey pk = table.getPrimaryKey();
+ String pkStr;
+ if (pk != null) {
+ pkStr = getPrimaryKeyConstraintSQL(pk);
+ if (pkStr != null && pkStr.length() > 0)
+ buf.append(", ").append(pkStr);
+ }
+
+ Unique[] unqs = table.getUniques();
+ String unqStr;
+ for (int i = 0; i < unqs.length; i++) {
+ unqStr = getUniqueConstraintSQL(unqs[i]);
+ if (unqStr != null)
+ buf.append(", ").append(unqStr);
+ }
+
+ buf.append(")");
+ return new String[]{ buf.toString() };
+ }
+
+ protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) {
+ Column[] cols = pk.getColumns();
+ if (cols.length == 1 && cols[0].isAutoAssigned())
+ return null;
+ return super.getPrimaryKeyConstraintSQL(pk);
+ }
+
+ public boolean isSystemIndex(String name, Table table) {
+ return name.toUpperCase().startsWith("SYS_");
+ }
+
+ protected String getSequencesSQL(String schemaName, String sequenceName) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ").
+ append("INFORMATION_SCHEMA.SYSTEM_SEQUENCES");
+ if (schemaName != null || sequenceName != null)
+ buf.append(" WHERE ");
+ if (schemaName != null) {
+ buf.append("SEQUENCE_SCHEMA = ?");
+ if (sequenceName != null)
+ buf.append(" AND ");
+ }
+ if (sequenceName != null)
+ buf.append("SEQUENCE_NAME = ?");
+ return buf.toString();
+ }
+
+ public SQLBuffer toOperation(String op, SQLBuffer selects, SQLBuffer from,
+ SQLBuffer where, SQLBuffer group, SQLBuffer having, SQLBuffer order,
+ boolean distinct, boolean forUpdate, long start, long end) {
+ // hsql requires ordering when limit is used
+ if ((start != 0 || end != Long.MAX_VALUE)
+ && (order == null || order.isEmpty()))
+ order = _oneBuffer;
+ return super.toOperation(op, selects, from, where, group, having,
+ order, distinct, forUpdate, start, end);
+ }
+
+ public Column[] getColumns(DatabaseMetaData meta, String catalog,
+ String schemaName, String tableName, String columnName, Connection conn)
+ throws SQLException {
+ Column[] cols = super.getColumns(meta, catalog, schemaName, tableName,
+ columnName, conn);
+
+ for (int i = 0; cols != null && i < cols.length; i++)
+ if ("BOOLEAN".equalsIgnoreCase(cols[i].getTypeName()))
+ cols[i].setType(Types.BIT);
+ return cols;
+ }
+
+ public void setLong(PreparedStatement stmnt, int idx, long val, Column col)
+ throws SQLException {
+ if (val == Long.MIN_VALUE) {
+ val = Long.MIN_VALUE + 1;
+ storageWarning(Numbers.valueOf(Long.MIN_VALUE),
+ Numbers.valueOf(val));
+ }
+ super.setLong(stmnt, idx, val, col);
+ }
+
+ public void setBigDecimal(PreparedStatement stmnt, int idx, BigDecimal val,
+ Column col)
+ throws SQLException {
+ // hsql can't compare a BigDecimal equal to any other type, so try
+ // to set type based on column
+ int type = (val == null || col == null) ? JavaTypes.BIGDECIMAL
+ : col.getJavaType();
+ switch (type) {
+ case JavaTypes.DOUBLE:
+ case JavaTypes.DOUBLE_OBJ:
+ setDouble(stmnt, idx, val.doubleValue(), col);
+ break;
+ case JavaTypes.FLOAT:
+ case JavaTypes.FLOAT_OBJ:
+ setDouble(stmnt, idx, val.floatValue(), col);
+ break;
+ default:
+ super.setBigDecimal(stmnt, idx, val, col);
+ }
+ }
+
+ protected void appendSelectRange(SQLBuffer buf, long start, long end) {
+ // HSQL doesn't parameters in range
+ buf.append(" LIMIT ").append(String.valueOf(start)).append(" ");
+ if (end == Long.MAX_VALUE)
+ buf.append(String.valueOf(0));
+ else
+ buf.append(String.valueOf(end - start));
+ }
+
+ public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
+ FilterValue end) {
+ buf.append(substringFunctionName).append("((");
+ str.appendTo(buf);
+ buf.append("), (");
+ start.appendTo(buf);
+ buf.append(" + 1)");
+ if (end != null) {
+ buf.append(", (");
+ appendNumericCast(buf, end);
+ buf.append(" - (");
+ appendNumericCast(buf, start);
+ buf.append("))");
+ }
+ buf.append(")");
+ }
+
+ public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
+ FilterValue start) {
+ buf.append("(LOCATE(");
+ find.appendTo(buf);
+ buf.append(", ");
+ str.appendTo(buf);
+ if (start != null) {
+ buf.append(", (");
+ start.appendTo(buf);
+ buf.append(" + 1)");
+ }
+ buf.append(") - 1)");
+ }
+
+ public String getPlaceholderValueString(Column col) {
+ String type = getTypeName(col.getType());
+ int idx = type.indexOf("{0}");
+ if (idx != -1) {
+ String pre = type.substring(0, idx);
+ if (type.length() > idx + 3)
+ type = pre + type.substring(idx + 3);
+ else
+ type = pre;
+ }
+ return "NULL AS " + type;
+ }
+
+ public OpenJPAException newStoreException(String msg, SQLException[] causes,
+ Object failed) {
+ OpenJPAException ke = super.newStoreException(msg, causes, failed);
+ if (ke instanceof ReferentialIntegrityException
+ && causes[0].getErrorCode() == -Trace.VIOLATION_OF_UNIQUE_INDEX) {
+ ((ReferentialIntegrityException) ke).setIntegrityViolation
+ (ReferentialIntegrityException.IV_UNIQUE);
+ }
+ return ke;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+
+/**
+ * Dictionary for Informix database. Notable features:
+ * <ul>
+ * <li>Informix does not allow pessimistic locking on scrollable result
+ * sets.</li>
+ * <li>SET LOCK MODE TO WAIT N statements are issued to wait on locks. See
+ * {@link #lockWaitSeconds} and {@link #lockModeEnabled}.</li>
+ * <li>LOCK MODE ROW is used by default for table creation to allow the
+ * maximum concurrency.</li>
+ * </ul>
+ */
+public class InformixDictionary
+ extends DBDictionary {
+
+ /**
+ * If true, then we will issue a "SET LOCK MODE TO WAIT N"
+ * statement whenever we create a {@link Connection}, in order
+ * allow waiting on locks.
+ */
+ public boolean lockModeEnabled = false;
+
+ /**
+ * If {@link #lockModeEnabled} is <code>true</code>, then this
+ * parameter specifies the number of seconds we will wait to
+ * obtain a lock for inserts and pessimistic locking.
+ */
+ public int lockWaitSeconds = 30;
+
+ /**
+ * Informix JDBC metadata for all known drivers returns with the
+ * table catalog and the table schema name swapped. A <code>true</code>
+ * value for this property indicates that they should be reversed.
+ */
+ public boolean swapSchemaAndCatalog = true;
+
+ // weak set of connections we've already executed lock mode sql on
+ private final Collection _seenConnections = new ReferenceHashSet
+ (ReferenceHashSet.WEAK);
+
+ public InformixDictionary() {
+ platform = "Informix";
+ validationSQL = "SELECT FIRST 1 CURRENT TIMESTAMP "
+ + "FROM informix.systables";
+
+ supportsAutoAssign = true;
+ autoAssignTypeName = "serial";
+ lastGeneratedKeyQuery = "SELECT FIRST 1 DBINFO('sqlca.sqlerrd1') "
+ + "FROM informix.systables";
+
+ // informix actually does support deferred constraints, but not
+ // in the table definition; deferred constraints can be activated by
+ // invoking "set constraints all deferred" on the connection, which
+ // we don't do yet
+ supportsDeferredConstraints = false;
+ constraintNameMode = CONS_NAME_AFTER;
+
+ maxTableNameLength = 18;
+ maxColumnNameLength = 18;
+ maxIndexNameLength = 18;
+ maxConstraintNameLength = 18;
+
+ // Informix uses a non-standard ":" to separate schema and table names
+ catalogSeparator = ":";
+
+ // informix supports "CLOB" type, but any attempt to insert
+ // into them raises: "java.sql.SQLException: Can't convert fromnull"
+ useGetStringForClobs = true;
+ longVarcharTypeName = "TEXT";
+ clobTypeName = "TEXT";
+ smallintTypeName = "INT8";
+ tinyintTypeName = "INT8";
+ floatTypeName = "FLOAT";
+ bitTypeName = "BOOLEAN";
+ blobTypeName = "BYTE";
+ doubleTypeName = "NUMERIC(32,20)";
+ dateTypeName = "DATE";
+ timestampTypeName = "DATE";
+ doubleTypeName = "NUMERIC(32,20)";
+ floatTypeName = "REAL";
+ bigintTypeName = "NUMERIC(32,0)";
+ doubleTypeName = "DOUBLE PRECISION";
+ fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
+ "BYTE", "DOUBLE PRECISION", "INTERVAL", "SMALLFLOAT", "TEXT",
+ "INT8",
+ }));
+
+ supportsQueryTimeout = false;
+ supportsMultipleNontransactionalResultSets = false;
+ supportsLockingWithDistinctClause = false;
+ supportsLockingWithMultipleTables = false;
+ supportsLockingWithOrderClause = false;
+
+ // the informix JDBC drivers have problems with using the
+ // schema name in reflection on columns and tables
+ supportsSchemaForGetColumns = false;
+ supportsSchemaForGetTables = false;
+ }
+
+ public void connectedConfiguration(Connection conn)
+ throws SQLException {
+ super.connectedConfiguration(conn);
+ if (driverVendor == null) {
+ DatabaseMetaData meta = conn.getMetaData();
+ if ("Informix".equalsIgnoreCase(meta.getDriverName()))
+ driverVendor = VENDOR_DATADIRECT;
+ else
+ driverVendor = VENDOR_OTHER;
+ }
+ }
+
+ public Column[] getColumns(DatabaseMetaData meta, String catalog,
+ String schemaName, String tableName, String columnName, Connection conn)
+ throws SQLException {
+ Column[] cols = super.getColumns(meta, catalog, schemaName, tableName,
+ columnName, conn);
+
+ // treat logvarchar as clob
+ for (int i = 0; cols != null && i < cols.length; i++)
+ if (cols[i].getType() == Types.LONGVARCHAR)
+ cols[i].setType(Types.CLOB);
+ return cols;
+ }
+
+ public Column newColumn(ResultSet colMeta)
+ throws SQLException {
+ Column col = super.newColumn(colMeta);
+ if (swapSchemaAndCatalog)
+ col.setSchemaName(colMeta.getString("TABLE_CAT"));
+ return col;
+ }
+
+ public PrimaryKey newPrimaryKey(ResultSet pkMeta)
+ throws SQLException {
+ PrimaryKey pk = super.newPrimaryKey(pkMeta);
+ if (swapSchemaAndCatalog)
+ pk.setSchemaName(pkMeta.getString("TABLE_CAT"));
+ return pk;
+ }
+
+ public Index newIndex(ResultSet idxMeta)
+ throws SQLException {
+ Index idx = super.newIndex(idxMeta);
+ if (swapSchemaAndCatalog)
+ idx.setSchemaName(idxMeta.getString("TABLE_CAT"));
+ return idx;
+ }
+
+ public void setBoolean(PreparedStatement stmnt, int idx, boolean val,
+ Column col)
+ throws SQLException {
+ // informix actually requires that a boolean be set: it cannot
+ // handle a numeric argument
+ stmnt.setBoolean(idx, val);
+ }
+
+ public String[] getCreateTableSQL(Table table) {
+ String[] create = super.getCreateTableSQL(table);
+ create[0] = create[0] + " LOCK MODE ROW";
+ return create;
+ }
+
+ public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
+ String pksql = getPrimaryKeyConstraintSQL(pk);
+ if (pksql == null)
+ return new String[0];
+ return new String[]{ "ALTER TABLE "
+ + getFullName(pk.getTable(), false) + " ADD CONSTRAINT " + pksql };
+ }
+
+ public String[] getAddForeignKeySQL(ForeignKey fk) {
+ String fksql = getForeignKeyConstraintSQL(fk);
+ if (fksql == null)
+ return new String[0];
+ return new String[]{ "ALTER TABLE "
+ + getFullName(fk.getTable(), false) + " ADD CONSTRAINT " + fksql };
+ }
+
+ public boolean supportsRandomAccessResultSet(Select sel,
+ boolean forUpdate) {
+ return !forUpdate && !sel.isLob()
+ && super.supportsRandomAccessResultSet(sel, forUpdate);
+ }
+
+ public Connection decorate(Connection conn)
+ throws SQLException {
+ conn = super.decorate(conn);
+
+ // if we haven't already done so, initialize the lock mode of the
+ // connection
+ if (lockModeEnabled && _seenConnections.add(conn)) {
+ String sql = "SET LOCK MODE TO WAIT";
+ if (lockWaitSeconds > 0)
+ sql = sql + " " + lockWaitSeconds;
+
+ Statement stmnt = null;
+ try {
+ stmnt = conn.createStatement();
+ stmnt.executeUpdate(sql);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, this);
+ } finally {
+ if (stmnt != null)
+ try {
+ stmnt.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ // the datadirect driver requires that we issue a rollback before using
+ // each connection
+ if (VENDOR_DATADIRECT.equalsIgnoreCase(driverVendor))
+ try {
+ conn.rollback();
+ } catch (SQLException se) {
+ }
+ return conn;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InterbaseDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InterbaseDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InterbaseDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InterbaseDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.Types;
+
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.StoreException;
+
+/**
+ * Dictionary for Borland Interbase.
+ */
+public class InterbaseDictionary
+ extends DBDictionary {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (InterbaseDictionary.class);
+
+ public InterbaseDictionary() {
+ platform = "Borland Interbase";
+ validationSQL = "SELECT 1 FROM RDB$DATABASE";
+ supportsDeferredConstraints = false;
+
+ useGetStringForClobs = true;
+ useSetStringForClobs = true;
+ useGetBytesForBlobs = true;
+ useSetBytesForBlobs = true;
+
+ // the JDBC driver claims 31, but that causes exceptions
+ maxTableNameLength = 30;
+
+ bigintTypeName = "NUMERIC(18,0)";
+ integerTypeName = "INTEGER";
+ doubleTypeName = "DOUBLE PRECISION";
+ charTypeName = "CHAR(1)";
+ blobTypeName = "BLOB";
+ clobTypeName = "BLOB SUB_TYPE 1";
+ bitTypeName = "SMALLINT";
+ smallintTypeName = "SMALLINT";
+ tinyintTypeName = "SMALLINT";
+
+ // no support for lower-casing or finding the length of strings
+ // (although it can be added to the database; see
+ // http://bdn.borland.com/article/0,1410,27563,00.html )
+ toLowerCaseFunction = null;
+ stringLengthFunction = null;
+ }
+
+ protected String getTableNameForMetadata(String tableName) {
+ return (tableName == null) ? "%"
+ : super.getTableNameForMetadata(tableName);
+ }
+
+ protected String getColumnNameForMetadata(String columnName) {
+ return (columnName == null) ? "%"
+ : super.getColumnNameForMetadata(columnName);
+ }
+
+ protected String appendSize(Column col, String typeName) {
+ if (col.isPrimaryKey() && col.getType() == Types.VARCHAR) {
+ // reduce size of varchar primary key cols proportional to the
+ // number of cols, because interbase caps the total pk size
+ int numKeys = 1;
+ if (col.getTable() != null
+ && col.getTable().getPrimaryKey() != null)
+ numKeys = col.getTable().getPrimaryKey().getColumns().length;
+ col.setSize(Math.min(col.getSize(), 200 / numKeys));
+ } else if (col.getType() == Types.VARCHAR && col.getSize() > 200
+ && col.getTable() != null) {
+ // indexed varchar cols have to be <= 250 chars
+ Index[] idx = col.getTable().getIndexes();
+ for (int i = 0; i < idx.length; i++) {
+ if (idx[i].containsColumn(col)) {
+ col.setSize(Math.min(col.getSize(), 200));
+ break;
+ }
+ }
+ }
+ return super.appendSize(col, typeName);
+ }
+
+ public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
+ FilterValue start) {
+ throw new StoreException(_loc.get("indexof-not-supported", platform));
+ }
+
+ public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
+ FilterValue end) {
+ throw new StoreException(_loc.get("substring-not-supported",
+ platform));
+ }
+
+ public String[] getDropColumnSQL(Column column) {
+ // Interbase uses "ALTER TABLE DROP <COLUMN_NAME>" rather than the
+ // usual "ALTER TABLE DROP COLUMN <COLUMN_NAME>"
+ return new String[]{ "ALTER TABLE "
+ + getFullName(column.getTable(), false) + " DROP " + column };
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InterbaseDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+
+import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
+import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.ReferentialIntegrityException;
+
+/**
+ * Dictionary for Borland JDataStore
+ */
+public class JDataStoreDictionary
+ extends DBDictionary {
+
+ public JDataStoreDictionary() {
+ platform = "Borland JDataStore";
+ joinSyntax = SYNTAX_TRADITIONAL;
+
+ supportsDeferredConstraints = false;
+ allowsAliasInBulkClause = false;
+
+ maxTableNameLength = 31;
+ maxColumnNameLength = 31;
+ maxIndexNameLength = 31;
+ maxConstraintNameLength = 31;
+
+ useGetStringForClobs = true;
+ useSetStringForClobs = true;
+ useGetBytesForBlobs = true;
+ blobTypeName = "VARBINARY";
+ clobTypeName = "VARCHAR";
+
+ // it is possible to use a FOR UPDATE clause with JDataStore,
+ // but the actual row won't wind up being locked
+ supportsLockingWithDistinctClause = false;
+ supportsQueryTimeout = false;
+
+ // there is no build-in function for getting the last generated
+ // key in JDataStore; using MAX will have to suffice
+ supportsAutoAssign = true;
+ lastGeneratedKeyQuery = "SELECT MAX({0}) FROM {1}";
+ autoAssignClause = "AUTOINCREMENT";
+
+ fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
+ "SHORT", "INT", "LONG", "DOUBLE PRECISION", "BOOLEAN",
+ }));
+
+ searchStringEscape = "";
+ }
+
+ public void substring(SQLBuffer buf, FilterValue str, FilterValue start,
+ FilterValue end) {
+ buf.append("SUBSTRING(");
+ str.appendTo(buf);
+ buf.append(" FROM (");
+ start.appendTo(buf);
+ buf.append(" + 1) FOR (");
+ if (end == null) {
+ buf.append("CHAR_LENGTH(");
+ str.appendTo(buf);
+ buf.append(")");
+ } else
+ end.appendTo(buf);
+ buf.append(" - (");
+ start.appendTo(buf);
+ buf.append(")))");
+ }
+
+ public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
+ FilterValue start) {
+ buf.append("(POSITION(");
+ find.appendTo(buf);
+ buf.append(" IN ");
+ if (start != null)
+ substring(buf, str, start, null);
+ else
+ str.appendTo(buf);
+ buf.append(") - 1");
+ if (start != null) {
+ buf.append(" + ");
+ start.appendTo(buf);
+ }
+ buf.append(")");
+ }
+
+ public OpenJPAException newStoreException(String msg, SQLException[] causes,
+ Object failed) {
+ OpenJPAException ke = super.newStoreException(msg, causes, failed);
+ if (ke instanceof ReferentialIntegrityException
+ && causes[0].getMessage().indexOf("Duplicate key value for") > -1) {
+ ((ReferentialIntegrityException) ke).setIntegrityViolation
+ (ReferentialIntegrityException.IV_UNIQUE);
+ }
+ return ke;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.sql;
+
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+
+/**
+ * Represents a SQL join.
+ *
+ * @author Abe White
+ */
+public class Join
+ implements Cloneable, JoinSyntaxes {
+
+ public static final int TYPE_INNER = 0;
+ public static final int TYPE_OUTER = 1;
+ public static final int TYPE_CROSS = 2;
+
+ private int _type = TYPE_INNER;
+
+ private int _alias1;
+ private int _alias2;
+ private Table _table1;
+ private Table _table2;
+ private ForeignKey _fk;
+ private boolean _inverse;
+
+ /**
+ * Constructor for inner and outer joins.
+ */
+ Join(Table table1, int alias1, Table table2, int alias2, ForeignKey fk,
+ boolean inverse) {
+ _table1 = table1;
+ _alias1 = alias1;
+ _table2 = table2;
+ _alias2 = alias2;
+ _fk = fk;
+ _inverse = inverse;
+ }
+
+ /**
+ * Private default constructor.
+ */
+ private Join() {
+ }
+
+ public int getType() {
+ return _type;
+ }
+
+ public void setType(int type) {
+ _type = type;
+ }
+
+ public String getAlias1() {
+ return SelectImpl.toAlias(_alias1);
+ }
+
+ public String getAlias2() {
+ return SelectImpl.toAlias(_alias2);
+ }
+
+ int getIndex1() {
+ return _alias1;
+ }
+
+ int getIndex2() {
+ return _alias2;
+ }
+
+ public Table getTable1() {
+ return _table1;
+ }
+
+ public Table getTable2() {
+ return _table2;
+ }
+
+ public ForeignKey getForeignKey() {
+ return _fk;
+ }
+
+ public boolean isForeignKeyInversed() {
+ return _inverse;
+ }
+
+ /**
+ * Return a join that is this join in reverse.
+ */
+ public Join reverse() {
+ Join join = new Join();
+ join._type = _type;
+ join._table1 = _table2;
+ join._alias1 = _alias2;
+ join._table2 = _table1;
+ join._alias2 = _alias1;
+ join._fk = _fk;
+ join._inverse = !_inverse;
+ return join;
+ }
+
+ public int hashCode() {
+ return _alias1 ^ _alias2;
+ }
+
+ public boolean equals(Object other) {
+ if (other == this)
+ return true;
+ if (!(other instanceof Join))
+ return false;
+
+ Join j = (Join) other;
+ return (_alias1 == j._alias1 && _alias2 == j._alias2)
+ || (_alias1 == j._alias2 && _alias2 == j._alias1);
+ }
+
+ public String toString() {
+ String typeString;
+ if (_type == TYPE_CROSS)
+ typeString = "cross";
+ else if (_type == TYPE_INNER)
+ typeString = "inner";
+ else
+ typeString = "outer";
+ return "<" + System.identityHashCode(this) + "> t"
+ + _alias1 + "->t" + _alias2 + " (" + typeString + ")";
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java
------------------------------------------------------------------------------
svn:executable = *