All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.dialect.Cache71Dialect Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.ConditionalParenthesisFunction;
import org.hibernate.dialect.function.ConvertFunction;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardJDBCEscapeFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy;
import org.hibernate.dialect.lock.OptimisticLockingStrategy;
import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy;
import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy;
import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.dialect.lock.UpdateLockingStrategy;
import org.hibernate.exception.internal.CacheSQLExceptionConversionDelegate;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.sql.CacheJoinFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.StandardBasicTypes;

/**
 * Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Caché SQL.
*
* Compatible with Caché 2007.1. *
* * Caché and Hibernate * * *

Caché and Hibernate

*

PREREQUISITES

* These setup instructions assume that both Caché and Hibernate are installed and operational. *
*

HIBERNATE DIRECTORIES AND FILES

* JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.1 * For earlier versions of Hibernate please contact * InterSystems Worldwide Response Center (WRC) * for the appropriate source files. *
*

CACHÉ DOCUMENTATION

* Documentation for Caché is available online when Caché is running. * It can also be obtained from the * InterSystems website. * The book, "Object-oriented Application Development Using the Caché Post-relational Database: * is also available from Springer-Verlag. *
*

HIBERNATE DOCUMENTATION

* Hibernate comes with extensive electronic documentation. * In addition, several books on Hibernate are available from * Manning Publications Co. * Three available titles are "Hibernate Quickly", "Hibernate in Action", and "Java Persistence with Hibernate". *
*

TO SET UP HIBERNATE FOR USE WITH CACHÉ

* The following steps assume that the directory where Caché was installed is C:\CacheSys. * This is the default installation directory for Caché. * The default installation directory for Hibernate is assumed to be C:\Hibernate. *

* If either product is installed in a different location, the pathnames that follow should be modified appropriately. *

* Caché version 2007.1 and above is recommended for use with * Hibernate. The next step depends on the location of your * CacheDB.jar depending on your version of Caché. *

    *
  1. Copy C:\CacheSys\dev\java\lib\JDK15\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.
  2. *

    *

  3. Insert the following files into your Java classpath: *

    *

      *
    • All jar files in the directory C:\Hibernate\lib
    • *
    • The directory (or directories) where hibernate.properties and/or hibernate.cfg.xml are kept.
    • *
    *
  4. *

    *

  5. In the file, hibernate.properties (or hibernate.cfg.xml), * specify the Caché dialect and the Caché version URL settings.
  6. *
*

* For example, in Hibernate 3.2, typical entries in hibernate.properties would have the following * "name=value" pairs: *

*

* * * * * * * * * * * * * * * * * * * * * * * * *
Property NameProperty Value
hibernate.dialectorg.hibernate.dialect.Cache71Dialect
hibernate.connection.driver_classcom.intersys.jdbc.CacheDriver
hibernate.connection.username(see note 1)
hibernate.connection.password(see note 1)
hibernate.connection.urljdbc:Cache://127.0.0.1:1972/USER
*

*

*
Note 1
*
Please contact your administrator for the userid and password you should use when attempting access via JDBC. * By default, these are chosen to be "_SYSTEM" and "SYS" respectively as noted in the SQL standard.
*
*
*

CACHÉ VERSION URL

* This is the standard URL for the JDBC driver. * For a JDBC driver on the machine hosting Caché, use the IP "loopback" address, 127.0.0.1. * For 1972, the default port, specify the super server port of your Caché instance. * For USER, substitute the NAMESPACE which contains your Caché database data. *
*

CACHÉ DIALECTS

* Choices for Dialect are: *
*

*

    *
  1. org.hibernate.dialect.Cache71Dialect (requires Caché * 2007.1 or above)
  2. *

    *

*
*

SUPPORT FOR IDENTITY COLUMNS

* Caché 2007.1 or later supports identity columns. For * Hibernate to use identity columns, specify "native" as the * generator. *
*

SEQUENCE DIALECTS SUPPORT SEQUENCES

*

* To use Hibernate sequence support with Caché in a namespace, you must FIRST load the following file into that namespace: *

 *     etc\CacheSequences.xml
 * 
* For example, at the COS terminal prompt in the namespace, run the * following command: *

* d LoadFile^%apiOBJ("c:\hibernate\etc\CacheSequences.xml","ck") *

* In your Hibernate mapping you can specify sequence use. *

* For example, the following shows the use of a sequence generator in a Hibernate mapping: *

 *     <id name="id" column="uid" type="long" unsaved-value="null">
 *         <generator class="sequence"/>
 *     </id>
 * 
*
*

* Some versions of Hibernate under some circumstances call * getSelectSequenceNextValString() in the dialect. If this happens * you will receive the error message: new MappingException( "Dialect * does not support sequences" ). *
*

HIBERNATE FILES ASSOCIATED WITH CACHÉ DIALECT

* The following files are associated with Caché dialect: *

*

    *
  1. src\org\hibernate\dialect\Cache71Dialect.java
  2. *
  3. src\org\hibernate\dialect\function\ConditionalParenthesisFunction.java
  4. *
  5. src\org\hibernate\dialect\function\ConvertFunction.java
  6. *
  7. src\org\hibernate\exception\CacheSQLStateConverter.java
  8. *
  9. src\org\hibernate\sql\CacheJoinFragment.java
  10. *
* Cache71Dialect ships with Hibernate 3.2. All other dialects are distributed by InterSystems and subclass Cache71Dialect. * * @author Jonathan Levinson */ public class Cache71Dialect extends Dialect { /** * Creates new Cache71Dialect instance. Sets up the JDBC / * Caché type mappings. */ public Cache71Dialect() { super(); commonRegistration(); register71Functions(); } protected final void commonRegistration() { // Note: For object <-> SQL datatype mappings see: // Configuration Manager | Advanced | SQL | System DDL Datatype Mappings // // TBD registerColumnType(Types.BINARY, "binary($1)"); // changed 08-11-2005, jsl registerColumnType( Types.BINARY, "varbinary($1)" ); registerColumnType( Types.BIGINT, "BigInt" ); registerColumnType( Types.BIT, "bit" ); registerColumnType( Types.CHAR, "char(1)" ); registerColumnType( Types.DATE, "date" ); registerColumnType( Types.DECIMAL, "decimal" ); registerColumnType( Types.DOUBLE, "double" ); registerColumnType( Types.FLOAT, "float" ); registerColumnType( Types.INTEGER, "integer" ); registerColumnType( Types.LONGVARBINARY, "longvarbinary" ); // binary %Stream registerColumnType( Types.LONGVARCHAR, "longvarchar" ); // character %Stream registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); registerColumnType( Types.REAL, "real" ); registerColumnType( Types.SMALLINT, "smallint" ); registerColumnType( Types.TIMESTAMP, "timestamp" ); registerColumnType( Types.TIME, "time" ); registerColumnType( Types.TINYINT, "tinyint" ); // TBD should this be varbinary($1)? // registerColumnType(Types.VARBINARY, "binary($1)"); registerColumnType( Types.VARBINARY, "longvarbinary" ); registerColumnType( Types.VARCHAR, "varchar($l)" ); registerColumnType( Types.BLOB, "longvarbinary" ); registerColumnType( Types.CLOB, "longvarchar" ); getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" ); getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); //getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); getDefaultProperties().setProperty( Environment.USE_SQL_COMMENTS, "false" ); registerFunction( "abs", new StandardSQLFunction( "abs" ) ); registerFunction( "acos", new StandardJDBCEscapeFunction( "acos", StandardBasicTypes.DOUBLE ) ); registerFunction( "%alphaup", new StandardSQLFunction( "%alphaup", StandardBasicTypes.STRING ) ); registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.STRING ) ); registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", StandardBasicTypes.DOUBLE ) ); registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", StandardBasicTypes.DOUBLE ) ); registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "($length(?1)*8)" ) ); // hibernate impelemnts cast in Dialect.java registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.INTEGER ) ); registerFunction( "char", new StandardJDBCEscapeFunction( "char", StandardBasicTypes.CHARACTER ) ); registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.INTEGER ) ); registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.INTEGER ) ); registerFunction( "cos", new StandardJDBCEscapeFunction( "cos", StandardBasicTypes.DOUBLE ) ); registerFunction( "cot", new StandardJDBCEscapeFunction( "cot", StandardBasicTypes.DOUBLE ) ); registerFunction( "coalesce", new VarArgsSQLFunction( "coalesce(", ",", ")" ) ); registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) ); registerFunction( "convert", new ConvertFunction() ); registerFunction( "curdate", new StandardJDBCEscapeFunction( "curdate", StandardBasicTypes.DATE ) ); registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) ); registerFunction( "current_timestamp", new ConditionalParenthesisFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP ) ); registerFunction( "curtime", new StandardJDBCEscapeFunction( "curtime", StandardBasicTypes.TIME ) ); registerFunction( "database", new StandardJDBCEscapeFunction( "database", StandardBasicTypes.STRING ) ); registerFunction( "dateadd", new VarArgsSQLFunction( StandardBasicTypes.TIMESTAMP, "dateadd(", ",", ")" ) ); registerFunction( "datediff", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "datediff(", ",", ")" ) ); registerFunction( "datename", new VarArgsSQLFunction( StandardBasicTypes.STRING, "datename(", ",", ")" ) ); registerFunction( "datepart", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "datepart(", ",", ")" ) ); registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); registerFunction( "dayname", new StandardJDBCEscapeFunction( "dayname", StandardBasicTypes.STRING ) ); registerFunction( "dayofmonth", new StandardJDBCEscapeFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); registerFunction( "dayofweek", new StandardJDBCEscapeFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); registerFunction( "dayofyear", new StandardJDBCEscapeFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); // is it necessary to register %exact since it can only appear in a where clause? registerFunction( "%exact", new StandardSQLFunction( "%exact", StandardBasicTypes.STRING ) ); registerFunction( "exp", new StandardJDBCEscapeFunction( "exp", StandardBasicTypes.DOUBLE ) ); registerFunction( "%external", new StandardSQLFunction( "%external", StandardBasicTypes.STRING ) ); registerFunction( "$extract", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "$extract(", ",", ")" ) ); registerFunction( "$find", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "$find(", ",", ")" ) ); registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.INTEGER ) ); registerFunction( "getdate", new StandardSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP ) ); registerFunction( "hour", new StandardJDBCEscapeFunction( "hour", StandardBasicTypes.INTEGER ) ); registerFunction( "ifnull", new VarArgsSQLFunction( "ifnull(", ",", ")" ) ); registerFunction( "%internal", new StandardSQLFunction( "%internal" ) ); registerFunction( "isnull", new VarArgsSQLFunction( "isnull(", ",", ")" ) ); registerFunction( "isnumeric", new StandardSQLFunction( "isnumeric", StandardBasicTypes.INTEGER ) ); registerFunction( "lcase", new StandardJDBCEscapeFunction( "lcase", StandardBasicTypes.STRING ) ); registerFunction( "left", new StandardJDBCEscapeFunction( "left", StandardBasicTypes.STRING ) ); registerFunction( "len", new StandardSQLFunction( "len", StandardBasicTypes.INTEGER ) ); registerFunction( "$length", new VarArgsSQLFunction( "$length(", ",", ")" ) ); // aggregate functions shouldn't be registered, right? //registerFunction( "list", new StandardSQLFunction("list",StandardBasicTypes.STRING) ); // stopped on $list registerFunction( "$list", new VarArgsSQLFunction( "$list(", ",", ")" ) ); registerFunction( "$listdata", new VarArgsSQLFunction( "$listdata(", ",", ")" ) ); registerFunction( "$listfind", new VarArgsSQLFunction( "$listfind(", ",", ")" ) ); registerFunction( "$listget", new VarArgsSQLFunction( "$listget(", ",", ")" ) ); registerFunction( "$listlength", new StandardSQLFunction( "$listlength", StandardBasicTypes.INTEGER ) ); registerFunction( "locate", new StandardSQLFunction( "$FIND", StandardBasicTypes.INTEGER ) ); registerFunction( "log", new StandardJDBCEscapeFunction( "log", StandardBasicTypes.DOUBLE ) ); registerFunction( "log10", new StandardJDBCEscapeFunction( "log", StandardBasicTypes.DOUBLE ) ); registerFunction( "lower", new StandardSQLFunction( "lower" ) ); registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); registerFunction( "minute", new StandardJDBCEscapeFunction( "minute", StandardBasicTypes.INTEGER ) ); registerFunction( "mod", new StandardJDBCEscapeFunction( "mod", StandardBasicTypes.DOUBLE ) ); registerFunction( "month", new StandardJDBCEscapeFunction( "month", StandardBasicTypes.INTEGER ) ); registerFunction( "monthname", new StandardJDBCEscapeFunction( "monthname", StandardBasicTypes.STRING ) ); registerFunction( "now", new StandardJDBCEscapeFunction( "monthname", StandardBasicTypes.TIMESTAMP ) ); registerFunction( "nullif", new VarArgsSQLFunction( "nullif(", ",", ")" ) ); registerFunction( "nvl", new NvlFunction() ); registerFunction( "%odbcin", new StandardSQLFunction( "%odbcin" ) ); registerFunction( "%odbcout", new StandardSQLFunction( "%odbcin" ) ); registerFunction( "%pattern", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "%pattern", "" ) ); registerFunction( "pi", new StandardJDBCEscapeFunction( "pi", StandardBasicTypes.DOUBLE ) ); registerFunction( "$piece", new VarArgsSQLFunction( StandardBasicTypes.STRING, "$piece(", ",", ")" ) ); registerFunction( "position", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "position(", " in ", ")" ) ); registerFunction( "power", new VarArgsSQLFunction( StandardBasicTypes.STRING, "power(", ",", ")" ) ); registerFunction( "quarter", new StandardJDBCEscapeFunction( "quarter", StandardBasicTypes.INTEGER ) ); registerFunction( "repeat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "repeat(", ",", ")" ) ); registerFunction( "replicate", new VarArgsSQLFunction( StandardBasicTypes.STRING, "replicate(", ",", ")" ) ); registerFunction( "right", new StandardJDBCEscapeFunction( "right", StandardBasicTypes.STRING ) ); registerFunction( "round", new VarArgsSQLFunction( StandardBasicTypes.FLOAT, "round(", ",", ")" ) ); registerFunction( "rtrim", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) ); registerFunction( "second", new StandardJDBCEscapeFunction( "second", StandardBasicTypes.INTEGER ) ); registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); registerFunction( "sin", new StandardJDBCEscapeFunction( "sin", StandardBasicTypes.DOUBLE ) ); registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); registerFunction( "%sqlstring", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%sqlstring(", ",", ")" ) ); registerFunction( "%sqlupper", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%sqlupper(", ",", ")" ) ); registerFunction( "sqrt", new StandardJDBCEscapeFunction( "SQRT", StandardBasicTypes.DOUBLE ) ); registerFunction( "%startswith", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "%startswith", "" ) ); // below is for Cache' that don't have str in 2007.1 there is str and we register str directly registerFunction( "str", new SQLFunctionTemplate( StandardBasicTypes.STRING, "cast(?1 as char varying)" ) ); registerFunction( "string", new VarArgsSQLFunction( StandardBasicTypes.STRING, "string(", ",", ")" ) ); // note that %string is deprecated registerFunction( "%string", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%string(", ",", ")" ) ); registerFunction( "substr", new VarArgsSQLFunction( StandardBasicTypes.STRING, "substr(", ",", ")" ) ); registerFunction( "substring", new VarArgsSQLFunction( StandardBasicTypes.STRING, "substring(", ",", ")" ) ); registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) ); registerFunction( "tan", new StandardJDBCEscapeFunction( "tan", StandardBasicTypes.DOUBLE ) ); registerFunction( "timestampadd", new StandardJDBCEscapeFunction( "timestampadd", StandardBasicTypes.DOUBLE ) ); registerFunction( "timestampdiff", new StandardJDBCEscapeFunction( "timestampdiff", StandardBasicTypes.DOUBLE ) ); registerFunction( "tochar", new VarArgsSQLFunction( StandardBasicTypes.STRING, "tochar(", ",", ")" ) ); registerFunction( "to_char", new VarArgsSQLFunction( StandardBasicTypes.STRING, "to_char(", ",", ")" ) ); registerFunction( "todate", new VarArgsSQLFunction( StandardBasicTypes.STRING, "todate(", ",", ")" ) ); registerFunction( "to_date", new VarArgsSQLFunction( StandardBasicTypes.STRING, "todate(", ",", ")" ) ); registerFunction( "tonumber", new StandardSQLFunction( "tonumber" ) ); registerFunction( "to_number", new StandardSQLFunction( "tonumber" ) ); // TRIM(end_keyword string-expression-1 FROM string-expression-2) // use Hibernate implementation "From" is one of the parameters they pass in position ?3 //registerFunction( "trim", new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1 ?2 from ?3)") ); registerFunction( "truncate", new StandardJDBCEscapeFunction( "truncate", StandardBasicTypes.STRING ) ); registerFunction( "ucase", new StandardJDBCEscapeFunction( "ucase", StandardBasicTypes.STRING ) ); registerFunction( "upper", new StandardSQLFunction( "upper" ) ); // %upper is deprecated registerFunction( "%upper", new StandardSQLFunction( "%upper" ) ); registerFunction( "user", new StandardJDBCEscapeFunction( "user", StandardBasicTypes.STRING ) ); registerFunction( "week", new StandardJDBCEscapeFunction( "user", StandardBasicTypes.INTEGER ) ); registerFunction( "xmlconcat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "xmlconcat(", ",", ")" ) ); registerFunction( "xmlelement", new VarArgsSQLFunction( StandardBasicTypes.STRING, "xmlelement(", ",", ")" ) ); // xmlforest requires a new kind of function constructor registerFunction( "year", new StandardJDBCEscapeFunction( "year", StandardBasicTypes.INTEGER ) ); } protected final void register71Functions() { this.registerFunction( "str", new VarArgsSQLFunction( StandardBasicTypes.STRING, "str(", ",", ")" ) ); } // DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean hasAlterTable() { // Does this dialect support the ALTER TABLE syntax? return true; } public boolean qualifyIndexName() { // Do we need to qualify index names with the schema name? return false; } /** * The syntax used to add a foreign key constraint to a table. * * @return String */ public String getAddForeignKeyConstraintString( String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) { // The syntax used to add a foreign key constraint to a table. return new StringBuilder( 300 ) .append( " ADD CONSTRAINT " ) .append( constraintName ) .append( " FOREIGN KEY " ) .append( constraintName ) .append( " (" ) .append( StringHelper.join( ", ", foreignKey ) ) // identifier-commalist .append( ") REFERENCES " ) .append( referencedTable ) .append( " (" ) .append( StringHelper.join( ", ", primaryKey ) ) // identifier-commalist .append( ") " ) .toString(); } public boolean supportsCheck() { // Does this dialect support check constraints? return false; } public String getAddColumnString() { // The syntax used to add a column to a table return " add column"; } public String getCascadeConstraintsString() { // Completely optional cascading drop clause. return ""; } public boolean dropConstraints() { // Do we need to drop constraints before dropping tables in this dialect? return true; } public boolean supportsCascadeDelete() { return true; } public boolean hasSelfReferentialForeignKeyBug() { return true; } // temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsTemporaryTables() { return true; } public String generateTemporaryTableName(String baseTableName) { String name = super.generateTemporaryTableName( baseTableName ); return name.length() > 25 ? name.substring( 1, 25 ) : name; } public String getCreateTemporaryTableString() { return "create global temporary table"; } public Boolean performTemporaryTableDDLInIsolation() { return Boolean.FALSE; } public String getCreateTemporaryTablePostfix() { return ""; } public boolean dropTemporaryTableAfterUse() { return true; } // IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsIdentityColumns() { return true; } public Class getNativeIdentifierGeneratorClass() { return IdentityGenerator.class; } public boolean hasDataTypeInIdentityColumn() { // Whether this dialect has an Identity clause added to the data type or a completely seperate identity // data type return true; } public String getIdentityColumnString() throws MappingException { // The keyword used to specify an identity column, if identity column key generation is supported. return "identity"; } public String getIdentitySelectString() { return "SELECT LAST_IDENTITY() FROM %TSQL_sys.snf"; } // SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsSequences() { return false; } // It really does support sequences, but InterSystems elects to suggest usage of IDENTITY instead :/ // Anyway, below are the actual support overrides for users wanting to use this combo... // // public String getSequenceNextValString(String sequenceName) { // return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')"; // } // // public String getSelectSequenceNextValString(String sequenceName) { // return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))"; // } // // public String getCreateSequenceString(String sequenceName) { // return "insert into InterSystems.Sequences(Name) values (ucase('" + sequenceName + "'))"; // } // // public String getDropSequenceString(String sequenceName) { // return "delete from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')"; // } // // public String getQuerySequencesString() { // return "select name from InterSystems.Sequences"; // } // lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsForUpdate() { // Does this dialect support the FOR UPDATE syntax? return false; } public boolean supportsForUpdateOf() { // Does this dialect support FOR UPDATE OF, allowing particular rows to be locked? return false; } public boolean supportsForUpdateNowait() { // Does this dialect support the Oracle-style FOR UPDATE NOWAIT syntax? return false; } public boolean supportsOuterJoinForUpdate() { return false; } public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // InterSystems Cache' does not current support "SELECT ... FOR UPDATE" syntax... // Set your transaction mode to READ_COMMITTED before using if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) { return new PessimisticForceIncrementLockingStrategy( lockable, lockMode); } else if ( lockMode==LockMode.PESSIMISTIC_WRITE) { return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode); } else if ( lockMode==LockMode.PESSIMISTIC_READ) { return new PessimisticReadUpdateLockingStrategy( lockable, lockMode); } else if ( lockMode==LockMode.OPTIMISTIC) { return new OptimisticLockingStrategy( lockable, lockMode); } else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) { return new OptimisticForceIncrementLockingStrategy( lockable, lockMode); } else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { return new SelectLockingStrategy( lockable, lockMode ); } } // LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsLimit() { return true; } public boolean supportsLimitOffset() { return false; } public boolean supportsVariableLimit() { return true; } public boolean bindLimitParametersFirst() { // Does the LIMIT clause come at the start of the SELECT statement, rather than at the end? return true; } public boolean useMaxForLimit() { // Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows? return true; } public String getLimitString(String sql, boolean hasOffset) { if ( hasOffset ) { throw new UnsupportedOperationException( "query result offset is not supported" ); } // This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions, // but this extension is not supported through Hibernate anyway. int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6; return new StringBuilder( sql.length() + 8 ) .append( sql ) .insert( insertionPoint, " TOP ? " ) .toString(); } // callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { return col; } public ResultSet getResultSet(CallableStatement ps) throws SQLException { ps.execute(); return ( ResultSet ) ps.getObject( 1 ); } // miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public String getLowercaseFunction() { // The name of the SQL function that transforms a string to lowercase return "lower"; } public String getNullColumnString() { // The keyword used to specify a nullable column. return " null"; } public JoinFragment createOuterJoinFragment() { // Create an OuterJoinGenerator for this dialect. return new CacheJoinFragment(); } public String getNoColumnsInsertString() { // The keyword used to insert a row without specifying // any column values return " default values"; } public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { return new CacheSQLExceptionConversionDelegate( this ); } public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { return EXTRACTER; } public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { /** * Extract the name of the violated constraint from the given SQLException. * * @param sqle The exception that was the result of the constraint violation. * @return The extracted constraint name. */ public String extractConstraintName(SQLException sqle) { return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() ); } }; // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean supportsEmptyInList() { return false; } public boolean areStringComparisonsCaseInsensitive() { return true; } public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() { return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy