From: <ste...@us...> - 2006-02-23 17:30:46
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25533/src/org/hibernate/dialect Modified Files: Dialect.java FrontBaseDialect.java HSQLDialect.java MckoiDialect.java PointbaseDialect.java RDMSOS2200Dialect.java SQLServerDialect.java TimesTenDialect.java Log Message: HHH-1518 : locking strategies Index: Dialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/Dialect.java,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- Dialect.java 28 Jan 2006 12:07:25 -0000 1.66 +++ Dialect.java 23 Feb 2006 17:30:39 -0000 1.67 @@ -18,11 +18,14 @@ import org.hibernate.LockMode; import org.hibernate.MappingException; import org.hibernate.QueryException; +import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.CastFunction; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; import org.hibernate.engine.Mapping; import org.hibernate.exception.SQLExceptionConverter; import org.hibernate.exception.SQLStateConverter; @@ -1010,5 +1013,16 @@ return "current_timestamp"; } - + /** + * Get a strategy instance which knows how to acquire a database-level lock + * of the specified mode for this dialect. + * + * @param lockable The persister for the entity to be locked. + * @param lockMode The type of lock to be acquired. + * @return The appropriate locking strategy. + * @since 3.2 + */ + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + return new SelectLockingStrategy( lockable, lockMode ); + } } Index: FrontBaseDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/FrontBaseDialect.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- FrontBaseDialect.java 12 Aug 2005 01:57:48 -0000 1.7 +++ FrontBaseDialect.java 23 Feb 2006 17:30:39 -0000 1.8 @@ -1,6 +1,12 @@ //$Id$ package org.hibernate.dialect; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.persister.entity.Lockable; +import org.hibernate.LockMode; + import java.sql.Types; /** @@ -72,4 +78,14 @@ public boolean isCurrentTimestampSelectStringCallable() { return true; } + + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax... + if ( lockMode.greaterThan( LockMode.READ ) ) { + return new UpdateLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } + } } Index: HSQLDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/HSQLDialect.java,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- HSQLDialect.java 27 Nov 2005 22:42:03 -0000 1.36 +++ HSQLDialect.java 23 Feb 2006 17:30:39 -0000 1.37 @@ -3,16 +3,27 @@ import java.sql.SQLException; import java.sql.Types; +import java.io.Serializable; import org.hibernate.Hibernate; +import org.hibernate.LockMode; +import org.hibernate.StaleObjectStateException; +import org.hibernate.JDBCException; +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.persister.entity.Lockable; import org.hibernate.util.ReflectHelper; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; import org.hibernate.exception.ViolatedConstraintNameExtracter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * An SQL dialect compatible with HSQLDB (Hypersonic SQL). @@ -23,6 +34,8 @@ */ public class HSQLDialect extends Dialect { + private static final Log log = LogFactory.getLog( HSQLDialect.class ); + private boolean schemaSupport; public HSQLDialect() { @@ -185,8 +198,8 @@ public String[] getCreateSequenceStrings(String sequenceName) { return new String[] { "create table dual_" + sequenceName + " (zero integer)", - "insert into dual_" + sequenceName + " values (0)", - "create sequence " + sequenceName + " start with 1" + "insert into dual_" + sequenceName + " values (0)", + "create sequence " + sequenceName + " start with 1" }; } @@ -273,4 +286,34 @@ return false; } + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // HSQLDB only supports READ_UNCOMMITTED transaction isolation + return new ReadUncommittedLockingStrategy( lockable, lockMode ); + } + + public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy { + public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) { + super( lockable, lockMode ); + } + + public void lock(Serializable id, Object version, Object object, SessionImplementor session) + throws StaleObjectStateException, JDBCException { + if ( getLockMode().greaterThan( LockMode.READ ) ) { + throw new HibernateException( "HSQLDB supports only READ_UNCOMMITTED isolation" ); + } + else { + super.lock( id, version, object, session ); + } + } + + protected String generateLockString() { + if ( getLockMode().greaterThan( LockMode.READ ) ) { + log.info( "generating locking strategy [" + getLockMode() + "]; HSQLDB supports only READ_UNCOMMITTED isolation" ); + return null; + } + else { + return super.generateLockString(); + } + } + } } Index: MckoiDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/MckoiDialect.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- MckoiDialect.java 7 Jul 2005 02:39:10 -0000 1.7 +++ MckoiDialect.java 23 Feb 2006 17:30:39 -0000 1.8 @@ -4,8 +4,13 @@ import java.sql.Types; import org.hibernate.Hibernate; +import org.hibernate.LockMode; +import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.MckoiCaseFragment; @@ -81,4 +86,13 @@ return new MckoiCaseFragment(); } + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax... + if ( lockMode.greaterThan( LockMode.READ ) ) { + return new UpdateLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } + } } Index: PointbaseDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/PointbaseDialect.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- PointbaseDialect.java 26 Oct 2004 15:41:00 -0000 1.3 +++ PointbaseDialect.java 23 Feb 2006 17:30:39 -0000 1.4 @@ -2,6 +2,12 @@ //Created on 04 February 2002, 17:35 package org.hibernate.dialect; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.persister.entity.Lockable; +import org.hibernate.LockMode; + import java.sql.Types; /** @@ -51,11 +57,13 @@ return ""; } + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax... + if ( lockMode.greaterThan( LockMode.READ ) ) { + return new UpdateLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } + } } - - - - - - - Index: RDMSOS2200Dialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/RDMSOS2200Dialect.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- RDMSOS2200Dialect.java 18 Nov 2005 22:08:05 -0000 1.1 +++ RDMSOS2200Dialect.java 23 Feb 2006 17:30:39 -0000 1.2 @@ -1,357 +1,322 @@ -/* - * Created on Aug 24, 2005 - * This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS). - * This dialect was developed for use with Hibernate 3.0.5. Other versions may - * require modifications to the dialect. - * - * Version History: - * Also change the version displayed below in the constructor - * 1.1 - * 1.0 2005-10-24 CDH - First dated version for use with CP 11 - */ -package org.hibernate.dialect; - -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; -/* -import org.hibernate.exception.ErrorCodeConverter; -import org.hibernate.exception.SQLExceptionConverter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -*/ - -import java.sql.Types; -import org.hibernate.Hibernate; -import org.hibernate.sql.CaseFragment; -import org.hibernate.sql.DecodeCaseFragment; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - -/** - * @author Ploski and Hanson - */ -public class RDMSOS2200Dialect extends Dialect { - - private static Log log = LogFactory.getLog(RDMSOS2200Dialect.class); - - public RDMSOS2200Dialect() { - super(); - // Display the dialect version. - log.info("RDMSOS2200Dialect version: 1.0"); - - /** - * This section registers RDMS Biult-in Functions (BIFs) with Hibernate. - * The first parameter is the 'register' function name with Hibernate. - * The second parameter is the defined RDMS SQL Function and it's - * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF - * name and the return type (if any) is specified. If - * SQLFunctionTemplate(...) is used, the return type and a template - * string is provided, plus an optional hasParenthesesIfNoArgs flag. - */ - - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); - - registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.INTEGER) ); - registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.INTEGER) ); - registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER) ); - - // The RDMS concat() function only supports 2 parameters - registerFunction( "concat", new SQLFunctionTemplate(Hibernate.STRING, "concat(?1, ?2)") ); - registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.STRING) ); - registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); - registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); - registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); - - registerFunction("lcase", new StandardSQLFunction("lcase") ); - registerFunction("lower", new StandardSQLFunction("lower") ); - registerFunction("ltrim", new StandardSQLFunction("ltrim") ); - registerFunction("reverse", new StandardSQLFunction("reverse") ); - registerFunction("rtrim", new StandardSQLFunction("rtrim") ); - // RDMS does not directly support the trim() function, we use rtrim() and ltrim() - registerFunction("trim", new SQLFunctionTemplate(Hibernate.INTEGER, "ltrim(rtrim(?1))" ) ); - registerFunction("soundex", new StandardSQLFunction("soundex") ); - registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) ); - registerFunction("ucase", new StandardSQLFunction("ucase") ); - registerFunction("upper", new StandardSQLFunction("upper") ); - - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction("cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); - registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) ); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction("sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); - registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction("tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); - - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "trunc", new StandardSQLFunction("trunc") ); - registerFunction( "ceil", new StandardSQLFunction("ceil") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); - - registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); - registerFunction( "initcap", new StandardSQLFunction("initcap") ); - - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); - - registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) ); - registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); - registerFunction("curdate", new NoArgSQLFunction("curdate",Hibernate.DATE) ); - registerFunction("curtime", new NoArgSQLFunction("curtime",Hibernate.TIME) ); - registerFunction("days", new StandardSQLFunction("days",Hibernate.INTEGER) ); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",Hibernate.INTEGER) ); - registerFunction("dayname", new StandardSQLFunction("dayname",Hibernate.STRING) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek",Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear",Hibernate.INTEGER) ); - registerFunction("hour", new StandardSQLFunction("hour",Hibernate.INTEGER) ); - - registerFunction("last_day", new StandardSQLFunction("last_day",Hibernate.DATE) ); - registerFunction("microsecond", new StandardSQLFunction("microsecond",Hibernate.INTEGER) ); - registerFunction("minute", new StandardSQLFunction("minute",Hibernate.INTEGER) ); - registerFunction("month", new StandardSQLFunction("month",Hibernate.INTEGER) ); - registerFunction("monthname", new StandardSQLFunction("monthname",Hibernate.STRING) ); - registerFunction("now", new NoArgSQLFunction("now",Hibernate.TIMESTAMP) ); - registerFunction("quarter", new StandardSQLFunction("quarter",Hibernate.INTEGER) ); - registerFunction("second", new StandardSQLFunction("second",Hibernate.INTEGER) ); - registerFunction("time", new StandardSQLFunction("time",Hibernate.TIME) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp",Hibernate.TIMESTAMP) ); - registerFunction("week", new StandardSQLFunction("week",Hibernate.INTEGER) ); - registerFunction("year", new StandardSQLFunction("year",Hibernate.INTEGER) ); - registerFunction("atan2", new StandardSQLFunction("atan2",Hibernate.DOUBLE) ); - registerFunction( "mod", new StandardSQLFunction("mod",Hibernate.INTEGER) ); - registerFunction( "nvl", new StandardSQLFunction("nvl") ); - registerFunction( "power", new StandardSQLFunction("power", Hibernate.DOUBLE) ); - - /** - * For a list of column types to register, see section A-1 - * in 7862 7395, the Unisys JDBC manual. - * - * Here are column sizes as documented in Table A-1 of - * 7831 0760, "Enterprise Relational Database Server - * for ClearPath OS2200 Administration Guide" - * Numeric - 21 - * Decimal - 22 (21 digits plus one for sign) - * Float - 60 bits - * Char - 28000 - * NChar - 14000 - * BLOB+ - 4294967296 (4 Gb) - * + RDMS JDBC driver does not support BLOBs - * - * DATE, TIME and TIMESTAMP literal formats are - * are all described in section 2.3.4 DATE Literal Format - * in 7830 8160. - * The DATE literal format is: YYYY-MM-DD - * The TIME literal format is: HH:MM:SS[.[FFFFFF]] - * The TIMESTAMP literal format is: YYYY-MM-DD HH:MM:SS[.[FFFFFF]] - * - * Note that $l (dollar-L) will use the length value if provided. - * Also new for Hibernate3 is the $p percision and $s (scale) parameters - */ - registerColumnType(Types.BIT, "SMALLINT"); - registerColumnType(Types.TINYINT, "SMALLINT"); - registerColumnType(Types.BIGINT, "NUMERIC(21,0)"); - registerColumnType(Types.SMALLINT, "SMALLINT"); - registerColumnType(Types.CHAR, "CHARACTER(1)"); - registerColumnType(Types.DOUBLE, "DOUBLE PRECISION"); - registerColumnType(Types.FLOAT, "FLOAT"); - registerColumnType(Types.REAL, "REAL"); - registerColumnType(Types.INTEGER, "INTEGER"); - registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)"); - registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)"); - registerColumnType(Types.DATE, "DATE"); - registerColumnType(Types.TIME, "TIME"); - registerColumnType(Types.TIMESTAMP, "TIMESTAMP"); - registerColumnType(Types.VARCHAR, "CHARACTER($l)"); - registerColumnType(Types.BLOB, "BLOB($l)" ); - /* - * The following types are not supported in RDMS/JDBC and therefore commented out. - * However, in some cases, mapping them to CHARACTER columns works - * for many applications, but does not work for all cases. - */ - // registerColumnType(Types.VARBINARY, "CHARACTER($l)"); - // registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0 - // registerColumnType(Types.CLOB, "CHARACTER($l)" ); - } - - // The following methods over-ride the default behaviour in the Dialect object. - - /** - * RDMS does not support qualifing index names with the schema name. - */ - public boolean qualifyIndexName() { - return false; - } - - /** - * The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC - * driver does not support this feature, so a false is return. - * The base dialect also returns a false, but we will leave this over-ride - * in to make sure it stays false. - */ - public boolean forUpdateOfColumns() { - return false; - } - - /** - * Since the RDMS-JDBC driver does not support for updates, this string is - * set to an empty string. Whenever, the driver does support this feature, - * the returned string should be " FOR UPDATE OF". Note that RDMS does not - * support the string 'FOR UPDATE' string. - */ - public String getForUpdateString() { - return ""; // Original Dialect.java returns " for update"; - } - - /** - * RDMS does not support adding Unique constraints via create and alter table. - */ - public boolean supportsUniqueConstraintInCreateAlterTable() { - return true; - } - - // Verify the state of this new method in Hibernate 3.0 Dialect.java - /** - * RDMS does not support Cascade Deletes. - * Need to review this in the future when support is provided. - */ - public boolean supportsCascadeDelete() { - return false; // Origial Dialect.java returns true; - } - - /** - * Currently, RDMS-JDBC does not support ForUpdate. - * Need to review this in the future when support is provided. - */ - public boolean supportsOuterJoinForUpdate() { - return false; - } - - /** - * Build an instance of the SQLExceptionConverter preferred by this dialect for - * converting SQLExceptions into Hibernate's JDBCException hierarchy. The default - * Dialect implementation simply returns a converter based on X/Open SQLState codes. - * <p/> - * It is strongly recommended that specific Dialect implementations override this - * method, since interpretation of a SQL error is much more accurate when based on - * the ErrorCode rather than the SQLState. Unfortunately, the ErrorCode is a vendor- - * specific approach. - * - * @return The Dialect's preferred SQLExceptionConverter. - */ -// public SQLExceptionConverter buildSQLExceptionConverter() { -// return new ExceptionConverter( getViolatedConstraintNameExtracter() ); -// } -// -// private static class ExceptionConverter extends ErrorCodeConverter { -// private int[] sqlGrammarCodes = new int[] { 1054, 1064, 1146 }; -// private int[] integrityViolationCodes = new int[] { 1062, 1216, 1217 }; -// private int[] connectionCodes = new int[] { 1049 }; -// private int[] lockAcquisitionErrorCodes = new int[] { 1099, 1100, 1150, 1165, 1192, 1205, 1206, 1207, 1213, 1223 }; -// -// public ExceptionConverter(ViolatedConstraintNameExtracter extracter) { -// super(extracter); -// } -// -// protected int[] getSQLGrammarErrorCodes() { -// return sqlGrammarCodes; -// } -// -// protected int[] getIntegrityViolationErrorCodes() { -// return integrityViolationCodes; -// } -// -// protected int[] getConnectionErrorCodes() { -// return connectionCodes; -// } -// -// protected int[] getLockAcquisitionErrorCodes() { -// return lockAcquisitionErrorCodes; -// } -// } - - - public String getAddColumnString() { - return "add"; - } - - public String getNullColumnString() { - // The keyword used to specify a nullable column. - return " null"; - } - - // *** Sequence methods - start. The RDMS dialect needs these - // methods to make it possible to use the Native Id generator - public boolean supportsSequences() { - return true; - } - - public String getSequenceNextValString(String sequenceName) { - // The where clause was added to eliminate this statement from Brute Force Searches. - return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 "; - } - - public String getCreateSequenceString(String sequenceName) { - // We must return a valid RDMS/RSA command from this method to - // prevent RDMS/RSA from issuing *ERROR 400 - return ""; - } - - public String getDropSequenceString(String sequenceName) { - // We must return a valid RDMS/RSA command from this method to - // prevent RDMS/RSA from issuing *ERROR 400 - return ""; - } - - // *** Sequence methods - end - - public String getCascadeConstraintsString() { - // Used with DROP TABLE to delete all records in the table. - return " including contents"; - } - - public CaseFragment createCaseFragment() { - return new DecodeCaseFragment(); - } - - public boolean supportsLimit() { - return true; - } - - public boolean supportsLimitOffset() { - return false; - } - - public String getLimitString(String sql, int offset, int limit) { - if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries"); - return new StringBuffer(sql.length() + 40) - .append(sql) - .append(" fetch first ") - .append(limit) - .append(" rows only ") - .toString(); - } - - public boolean supportsVariableLimit() { - return false; - } - - public boolean supportsUnionAll() { - // RDMS supports the UNION ALL clause. - return true; - } - -} // End of class RDMSOS2200Dialect +/* + * Created on Aug 24, 2005 + * This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS). + * This dialect was developed for use with Hibernate 3.0.5. Other versions may + * require modifications to the dialect. + * + * Version History: + * Also change the version displayed below in the constructor + * 1.1 + * 1.0 2005-10-24 CDH - First dated version for use with CP 11 + */ +package org.hibernate.dialect; + +import org.hibernate.dialect.function.NoArgSQLFunction; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; + +import java.sql.Types; +import org.hibernate.Hibernate; +import org.hibernate.LockMode; +import org.hibernate.persister.entity.Lockable; +import org.hibernate.sql.CaseFragment; +import org.hibernate.sql.DecodeCaseFragment; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author Ploski and Hanson + */ +public class RDMSOS2200Dialect extends Dialect { + private static Log log = LogFactory.getLog(RDMSOS2200Dialect.class); + + public RDMSOS2200Dialect() { + super(); + // Display the dialect version. + log.info("RDMSOS2200Dialect version: 1.0"); + + /** + * This section registers RDMS Biult-in Functions (BIFs) with Hibernate. + * The first parameter is the 'register' function name with Hibernate. + * The second parameter is the defined RDMS SQL Function and it's + * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF + * name and the return type (if any) is specified. If + * SQLFunctionTemplate(...) is used, the return type and a template + * string is provided, plus an optional hasParenthesesIfNoArgs flag. + */ + registerFunction( "abs", new StandardSQLFunction("abs") ); + registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + + registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); + registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.INTEGER) ); + registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.INTEGER) ); + registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER) ); + + // The RDMS concat() function only supports 2 parameters + registerFunction( "concat", new SQLFunctionTemplate(Hibernate.STRING, "concat(?1, ?2)") ); + registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.STRING) ); + registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); + registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); + registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); + registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); + + registerFunction("lcase", new StandardSQLFunction("lcase") ); + registerFunction("lower", new StandardSQLFunction("lower") ); + registerFunction("ltrim", new StandardSQLFunction("ltrim") ); + registerFunction("reverse", new StandardSQLFunction("reverse") ); + registerFunction("rtrim", new StandardSQLFunction("rtrim") ); + + // RDMS does not directly support the trim() function, we use rtrim() and ltrim() + registerFunction("trim", new SQLFunctionTemplate(Hibernate.INTEGER, "ltrim(rtrim(?1))" ) ); + registerFunction("soundex", new StandardSQLFunction("soundex") ); + registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) ); + registerFunction("ucase", new StandardSQLFunction("ucase") ); + registerFunction("upper", new StandardSQLFunction("upper") ); + + registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); + registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); + registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); + registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); + registerFunction("cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); + registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); + registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); + registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); + registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); + registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); + registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); + registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) ); + registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); + registerFunction("sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); + registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); + registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); + registerFunction("tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); + + registerFunction( "round", new StandardSQLFunction("round") ); + registerFunction( "trunc", new StandardSQLFunction("trunc") ); + registerFunction( "ceil", new StandardSQLFunction("ceil") ); + registerFunction( "floor", new StandardSQLFunction("floor") ); + + registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); + registerFunction( "initcap", new StandardSQLFunction("initcap") ); + + registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); + + registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); + registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) ); + registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); + registerFunction("curdate", new NoArgSQLFunction("curdate",Hibernate.DATE) ); + registerFunction("curtime", new NoArgSQLFunction("curtime",Hibernate.TIME) ); + registerFunction("days", new StandardSQLFunction("days",Hibernate.INTEGER) ); + registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",Hibernate.INTEGER) ); + registerFunction("dayname", new StandardSQLFunction("dayname",Hibernate.STRING) ); + registerFunction("dayofweek", new StandardSQLFunction("dayofweek",Hibernate.INTEGER) ); + registerFunction("dayofyear", new StandardSQLFunction("dayofyear",Hibernate.INTEGER) ); + registerFunction("hour", new StandardSQLFunction("hour",Hibernate.INTEGER) ); + registerFunction("last_day", new StandardSQLFunction("last_day",Hibernate.DATE) ); + registerFunction("microsecond", new StandardSQLFunction("microsecond",Hibernate.INTEGER) ); + registerFunction("minute", new StandardSQLFunction("minute",Hibernate.INTEGER) ); + registerFunction("month", new StandardSQLFunction("month",Hibernate.INTEGER) ); + registerFunction("monthname", new StandardSQLFunction("monthname",Hibernate.STRING) ); + registerFunction("now", new NoArgSQLFunction("now",Hibernate.TIMESTAMP) ); + registerFunction("quarter", new StandardSQLFunction("quarter",Hibernate.INTEGER) ); + registerFunction("second", new StandardSQLFunction("second",Hibernate.INTEGER) ); + registerFunction("time", new StandardSQLFunction("time",Hibernate.TIME) ); + registerFunction("timestamp", new StandardSQLFunction("timestamp",Hibernate.TIMESTAMP) ); + registerFunction("week", new StandardSQLFunction("week",Hibernate.INTEGER) ); + registerFunction("year", new StandardSQLFunction("year",Hibernate.INTEGER) ); + + registerFunction("atan2", new StandardSQLFunction("atan2",Hibernate.DOUBLE) ); + registerFunction( "mod", new StandardSQLFunction("mod",Hibernate.INTEGER) ); + registerFunction( "nvl", new StandardSQLFunction("nvl") ); + registerFunction( "power", new StandardSQLFunction("power", Hibernate.DOUBLE) ); + + /** + * For a list of column types to register, see section A-1 + * in 7862 7395, the Unisys JDBC manual. + * + * Here are column sizes as documented in Table A-1 of + * 7831 0760, "Enterprise Relational Database Server + * for ClearPath OS2200 Administration Guide" + * Numeric - 21 + * Decimal - 22 (21 digits plus one for sign) + * Float - 60 bits + * Char - 28000 + * NChar - 14000 + * BLOB+ - 4294967296 (4 Gb) + * + RDMS JDBC driver does not support BLOBs + * + * DATE, TIME and TIMESTAMP literal formats are + * are all described in section 2.3.4 DATE Literal Format + * in 7830 8160. + * The DATE literal format is: YYYY-MM-DD + * The TIME literal format is: HH:MM:SS[.[FFFFFF]] + * The TIMESTAMP literal format is: YYYY-MM-DD HH:MM:SS[.[FFFFFF]] + * + * Note that $l (dollar-L) will use the length value if provided. + * Also new for Hibernate3 is the $p percision and $s (scale) parameters + */ + registerColumnType(Types.BIT, "SMALLINT"); + registerColumnType(Types.TINYINT, "SMALLINT"); + registerColumnType(Types.BIGINT, "NUMERIC(21,0)"); + registerColumnType(Types.SMALLINT, "SMALLINT"); + registerColumnType(Types.CHAR, "CHARACTER(1)"); + registerColumnType(Types.DOUBLE, "DOUBLE PRECISION"); + registerColumnType(Types.FLOAT, "FLOAT"); + registerColumnType(Types.REAL, "REAL"); + registerColumnType(Types.INTEGER, "INTEGER"); + registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)"); + registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)"); + registerColumnType(Types.DATE, "DATE"); + registerColumnType(Types.TIME, "TIME"); + registerColumnType(Types.TIMESTAMP, "TIMESTAMP"); + registerColumnType(Types.VARCHAR, "CHARACTER($l)"); + registerColumnType(Types.BLOB, "BLOB($l)" ); + /* + * The following types are not supported in RDMS/JDBC and therefore commented out. + * However, in some cases, mapping them to CHARACTER columns works + * for many applications, but does not work for all cases. + */ + // registerColumnType(Types.VARBINARY, "CHARACTER($l)"); + // registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0 + // registerColumnType(Types.CLOB, "CHARACTER($l)" ); + } + + + // Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * RDMS does not support qualifing index names with the schema name. + */ + public boolean qualifyIndexName() { + return false; + } + + /** + * The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC + * driver does not support this feature, so a false is return. + * The base dialect also returns a false, but we will leave this over-ride + * in to make sure it stays false. + */ + public boolean forUpdateOfColumns() { + return false; + } + + /** + * Since the RDMS-JDBC driver does not support for updates, this string is + * set to an empty string. Whenever, the driver does support this feature, + * the returned string should be " FOR UPDATE OF". Note that RDMS does not + * support the string 'FOR UPDATE' string. + */ + public String getForUpdateString() { + return ""; // Original Dialect.java returns " for update"; + } + + /** + * RDMS does not support adding Unique constraints via create and alter table. + */ + public boolean supportsUniqueConstraintInCreateAlterTable() { + return true; + } + + // Verify the state of this new method in Hibernate 3.0 Dialect.java + /** + * RDMS does not support Cascade Deletes. + * Need to review this in the future when support is provided. + */ + public boolean supportsCascadeDelete() { + return false; // Origial Dialect.java returns true; + } + + /** + * Currently, RDMS-JDBC does not support ForUpdate. + * Need to review this in the future when support is provided. + */ + public boolean supportsOuterJoinForUpdate() { + return false; + } + + public String getAddColumnString() { + return "add"; + } + + public String getNullColumnString() { + // The keyword used to specify a nullable column. + return " null"; + } + + // *** Sequence methods - start. The RDMS dialect needs these + + // methods to make it possible to use the Native Id generator + + public boolean supportsSequences() { + return true; + } + + public String getSequenceNextValString(String sequenceName) { + // The where clause was added to eliminate this statement from Brute Force Searches. + return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 "; + } + + public String getCreateSequenceString(String sequenceName) { + // We must return a valid RDMS/RSA command from this method to + // prevent RDMS/RSA from issuing *ERROR 400 + return ""; + } + + public String getDropSequenceString(String sequenceName) { + // We must return a valid RDMS/RSA command from this method to + // prevent RDMS/RSA from issuing *ERROR 400 + return ""; + } + + // *** Sequence methods - end + + public String getCascadeConstraintsString() { + // Used with DROP TABLE to delete all records in the table. + return " including contents"; + } + + public CaseFragment createCaseFragment() { + return new DecodeCaseFragment(); + } + + public boolean supportsLimit() { + return true; + } + + public boolean supportsLimitOffset() { + return false; + } + + public String getLimitString(String sql, int offset, int limit) { + if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries"); + return new StringBuffer(sql.length() + 40) + .append(sql) + .append(" fetch first ") + .append(limit) + .append(" rows only ") + .toString(); + } + + public boolean supportsVariableLimit() { + return false; + } + + public boolean supportsUnionAll() { + // RDMS supports the UNION ALL clause. + return true; + } + + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax... + if ( lockMode.greaterThan( LockMode.READ ) ) { + return new UpdateLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } + } +} Index: SQLServerDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/SQLServerDialect.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- SQLServerDialect.java 16 Jan 2006 19:33:11 -0000 1.30 +++ SQLServerDialect.java 23 Feb 2006 17:30:39 -0000 1.31 @@ -91,6 +91,7 @@ public String appendLockHint(LockMode mode, String tableName) { if ( mode.greaterThan(LockMode.READ) ) { + // does this need holdlock also? : return tableName + " with (updlock, rowlock, holdlock)"; return tableName + " with (updlock, rowlock)"; } else { Index: TimesTenDialect.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/dialect/TimesTenDialect.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- TimesTenDialect.java 30 Nov 2005 03:37:19 -0000 1.9 +++ TimesTenDialect.java 23 Feb 2006 17:30:39 -0000 1.10 @@ -3,9 +3,14 @@ import java.sql.Types; import org.hibernate.Hibernate; +import org.hibernate.LockMode; +import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.SelectLockingStrategy; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.OracleJoinFragment; @@ -186,4 +191,13 @@ return "on commit delete rows"; } + public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { + // TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax... + if ( lockMode.greaterThan( LockMode.READ ) ) { + return new UpdateLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } + } } |