Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » dialect » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.dialect;
   26   
   27   import java.sql.Types;
   28   import java.sql.SQLException;
   29   import java.sql.ResultSet;
   30   import java.sql.CallableStatement;
   31   
   32   import org.hibernate.sql.CaseFragment;
   33   import org.hibernate.sql.DecodeCaseFragment;
   34   import org.hibernate.sql.JoinFragment;
   35   import org.hibernate.sql.OracleJoinFragment;
   36   import org.hibernate.cfg.Environment;
   37   import org.hibernate.dialect.function.StandardSQLFunction;
   38   import org.hibernate.dialect.function.NoArgSQLFunction;
   39   import org.hibernate.dialect.function.VarArgsSQLFunction;
   40   import org.hibernate.dialect.function.SQLFunctionTemplate;
   41   import org.hibernate.dialect.function.NvlFunction;
   42   import org.hibernate.Hibernate;
   43   import org.hibernate.HibernateException;
   44   import org.hibernate.util.ReflectHelper;
   45   import org.hibernate.exception.ViolatedConstraintNameExtracter;
   46   import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
   47   import org.hibernate.exception.JDBCExceptionHelper;
   48   
   49   /**
   50    * A dialect for Oracle 8i.
   51    *
   52    * @author Steve Ebersole
   53    */
   54   public class Oracle8iDialect extends Dialect {
   55   
   56   	public Oracle8iDialect() {
   57   		super();
   58   		registerCharacterTypeMappings();
   59   		registerNumericTypeMappings();
   60   		registerDateTimeTypeMappings();
   61   		registerLargeObjectTypeMappings();
   62   
   63   		registerReverseHibernateTypeMappings();
   64   
   65   		registerFunctions();
   66   
   67   		registerDefaultProperties();
   68   	}
   69   
   70   	protected void registerCharacterTypeMappings() {
   71   		registerColumnType( Types.CHAR, "char(1)" );
   72   		registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
   73   		registerColumnType( Types.VARCHAR, "long" );
   74   	}
   75   
   76   	protected void registerNumericTypeMappings() {
   77   		registerColumnType( Types.BIT, "number(1,0)" );
   78   		registerColumnType( Types.BIGINT, "number(19,0)" );
   79   		registerColumnType( Types.SMALLINT, "number(5,0)" );
   80   		registerColumnType( Types.TINYINT, "number(3,0)" );
   81   		registerColumnType( Types.INTEGER, "number(10,0)" );
   82   
   83   		registerColumnType( Types.FLOAT, "float" );
   84   		registerColumnType( Types.DOUBLE, "double precision" );
   85   		registerColumnType( Types.NUMERIC, "number($p,$s)" );
   86   		registerColumnType( Types.DECIMAL, "number($p,$s)" );
   87   	}
   88   
   89   	protected void registerDateTimeTypeMappings() {
   90   		registerColumnType( Types.DATE, "date" );
   91   		registerColumnType( Types.TIME, "date" );
   92   		registerColumnType( Types.TIMESTAMP, "date" );
   93   	}
   94   
   95   	protected void registerLargeObjectTypeMappings() {
   96   		registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
   97   		registerColumnType( Types.VARBINARY, "long raw" );
   98   
   99   		registerColumnType( Types.BLOB, "blob" );
  100   		registerColumnType( Types.CLOB, "clob" );
  101   	}
  102   
  103   	protected void registerReverseHibernateTypeMappings() {
  104   	}
  105   
  106   	protected void registerFunctions() {
  107   		registerFunction( "abs", new StandardSQLFunction("abs") );
  108   		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
  109   
  110   		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
  111   		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
  112   		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
  113   		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
  114   		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
  115   		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
  116   		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
  117   		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
  118   		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
  119   		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
  120   		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
  121   		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
  122   		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
  123   		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
  124   
  125   		registerFunction( "round", new StandardSQLFunction("round") );
  126   		registerFunction( "trunc", new StandardSQLFunction("trunc") );
  127   		registerFunction( "ceil", new StandardSQLFunction("ceil") );
  128   		registerFunction( "floor", new StandardSQLFunction("floor") );
  129   
  130   		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
  131   		registerFunction( "initcap", new StandardSQLFunction("initcap") );
  132   		registerFunction( "lower", new StandardSQLFunction("lower") );
  133   		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
  134   		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
  135   		registerFunction( "soundex", new StandardSQLFunction("soundex") );
  136   		registerFunction( "upper", new StandardSQLFunction("upper") );
  137   		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
  138   		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
  139   
  140   		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
  141   		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );
  142   
  143   		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
  144   		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
  145   		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
  146   
  147   		registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
  148   		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
  149   		registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
  150   		registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
  151   		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
  152   
  153   		registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
  154   		registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) );
  155   
  156   		// Multi-param string dialect functions...
  157   		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
  158   		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) );
  159   		registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) );
  160   		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
  161   		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
  162   		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
  163   		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
  164   		registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) );
  165   		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
  166   
  167   		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
  168   		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) );
  169   		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) );
  170   		registerFunction( "coalesce", new NvlFunction() );
  171   
  172   		// Multi-param numeric dialect functions...
  173   		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) );
  174   		registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) );
  175   		registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) );
  176   		registerFunction( "nvl", new StandardSQLFunction("nvl") );
  177   		registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
  178   		registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) );
  179   
  180   		// Multi-param date dialect functions...
  181   		registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) );
  182   		registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) );
  183   		registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) );
  184   
  185   		registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) );
  186   	}
  187   
  188   	protected void registerDefaultProperties() {
  189   		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
  190   		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
  191   		// Oracle driver reports to support getGeneratedKeys(), but they only
  192   		// support the version taking an array of the names of the columns to
  193   		// be returned (via its RETURNING clause).  No other driver seems to
  194   		// support this overloaded version.
  195   		getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
  196   	}
  197   
  198   
  199   	// features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~
  200   
  201   	/**
  202   	 * Support for the oracle proprietary join syntax...
  203   	 *
  204   	 * @return The orqacle join fragment
  205   	 */
  206   	public JoinFragment createOuterJoinFragment() {
  207   		return new OracleJoinFragment();
  208   	}
  209   
  210   	/**
  211   	 * Map case support to the Oracle DECODE function.  Oracle did not
  212   	 * add support for CASE until 9i.
  213   	 *
  214   	 * @return The oracle CASE -> DECODE fragment
  215   	 */
  216   	public CaseFragment createCaseFragment() {
  217   		return new DecodeCaseFragment();
  218   	}
  219   
  220   	public String getLimitString(String sql, boolean hasOffset) {
  221   		sql = sql.trim();
  222   		boolean isForUpdate = false;
  223   		if ( sql.toLowerCase().endsWith(" for update") ) {
  224   			sql = sql.substring( 0, sql.length()-11 );
  225   			isForUpdate = true;
  226   		}
  227   
  228   		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
  229   		if (hasOffset) {
  230   			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
  231   		}
  232   		else {
  233   			pagingSelect.append("select * from ( ");
  234   		}
  235   		pagingSelect.append(sql);
  236   		if (hasOffset) {
  237   			pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
  238   		}
  239   		else {
  240   			pagingSelect.append(" ) where rownum <= ?");
  241   		}
  242   
  243   		if ( isForUpdate ) {
  244   			pagingSelect.append( " for update" );
  245   		}
  246   
  247   		return pagingSelect.toString();
  248   	}
  249   
  250   	/**
  251   	 * Allows access to the basic {@link Dialect#getSelectClauseNullString}
  252   	 * implementation...
  253   	 *
  254   	 * @param sqlType The {@link java.sql.Types} mapping type code
  255   	 * @return The appropriate select cluse fragment
  256   	 */
  257   	public String getBasicSelectClauseNullString(int sqlType) {
  258   		return super.getSelectClauseNullString( sqlType );
  259   	}
  260   
  261   	public String getSelectClauseNullString(int sqlType) {
  262   		switch(sqlType) {
  263   			case Types.VARCHAR:
  264   			case Types.CHAR:
  265   				return "to_char(null)";
  266   			case Types.DATE:
  267   			case Types.TIMESTAMP:
  268   			case Types.TIME:
  269   				return "to_date(null)";
  270   			default:
  271   				return "to_number(null)";
  272   		}
  273   	}
  274   
  275   	public String getCurrentTimestampSelectString() {
  276   		return "select sysdate from dual";
  277   	}
  278   
  279   	public String getCurrentTimestampSQLFunctionName() {
  280   		return "sysdate";
  281   	}
  282   
  283   
  284   	// features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~
  285   
  286   	public String getAddColumnString() {
  287   		return "add";
  288   	}
  289   
  290   	public String getSequenceNextValString(String sequenceName) {
  291   		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
  292   	}
  293   
  294   	public String getSelectSequenceNextValString(String sequenceName) {
  295   		return sequenceName + ".nextval";
  296   	}
  297   
  298   	public String getCreateSequenceString(String sequenceName) {
  299   		return "create sequence " + sequenceName; //starts with 1, implicitly
  300   	}
  301   
  302   	public String getDropSequenceString(String sequenceName) {
  303   		return "drop sequence " + sequenceName;
  304   	}
  305   
  306   	public String getCascadeConstraintsString() {
  307   		return " cascade constraints";
  308   	}
  309   
  310   	public boolean dropConstraints() {
  311   		return false;
  312   	}
  313   
  314   	public String getForUpdateNowaitString() {
  315   		return " for update nowait";
  316   	}
  317   
  318   	public boolean supportsSequences() {
  319   		return true;
  320   	}
  321   
  322   	public boolean supportsPooledSequences() {
  323   		return true;
  324   	}
  325   
  326   	public boolean supportsLimit() {
  327   		return true;
  328   	}
  329   
  330   	public String getForUpdateString(String aliases) {
  331   		return getForUpdateString() + " of " + aliases;
  332   	}
  333   
  334   	public String getForUpdateNowaitString(String aliases) {
  335   		return getForUpdateString() + " of " + aliases + " nowait";
  336   	}
  337   
  338   	public boolean bindLimitParametersInReverseOrder() {
  339   		return true;
  340   	}
  341   
  342   	public boolean useMaxForLimit() {
  343   		return true;
  344   	}
  345   
  346   	public boolean forUpdateOfColumns() {
  347   		return true;
  348   	}
  349   
  350   	public String getQuerySequencesString() {
  351   		return    " select sequence_name from all_sequences"
  352   				+ "  union"
  353   				+ " select synonym_name"
  354   				+ "   from all_synonyms us, all_sequences asq"
  355   				+ "  where asq.sequence_name = us.table_name"
  356   				+ "    and asq.sequence_owner = us.table_owner";
  357   	}
  358   
  359   	public String getSelectGUIDString() {
  360   		return "select rawtohex(sys_guid()) from dual";
  361   	}
  362   
  363   	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
  364           return EXTRACTER;
  365   	}
  366   
  367   	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
  368   
  369   		/**
  370   		 * Extract the name of the violated constraint from the given SQLException.
  371   		 *
  372   		 * @param sqle The exception that was the result of the constraint violation.
  373   		 * @return The extracted constraint name.
  374   		 */
  375   		public String extractConstraintName(SQLException sqle) {
  376   			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
  377   			if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
  378   				return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
  379   			}
  380   			else if ( errorCode == 1400 ) {
  381   				// simple nullability constraint
  382   				return null;
  383   			}
  384   			else {
  385   				return null;
  386   			}
  387   		}
  388   
  389   	};
  390   
  391   	// not final-static to avoid possible classcast exceptions if using different oracle drivers.
  392   	int oracletypes_cursor_value = 0;
  393   	public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
  394   		if(oracletypes_cursor_value==0) {
  395   			try {
  396   				Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
  397   				oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
  398   			} catch (Exception se) {
  399   				throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
  400   			}
  401   		}
  402   		//	register the type of the out param - an Oracle specific type
  403   		statement.registerOutParameter(col, oracletypes_cursor_value);
  404   		col++;
  405   		return col;
  406   	}
  407   
  408   	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
  409   		ps.execute();
  410   		return ( ResultSet ) ps.getObject( 1 );
  411   	}
  412   
  413   	public boolean supportsUnionAll() {
  414   		return true;
  415   	}
  416   
  417   	public boolean supportsCommentOn() {
  418   		return true;
  419   	}
  420   
  421   	public boolean supportsTemporaryTables() {
  422   		return true;
  423   	}
  424   
  425   	public String generateTemporaryTableName(String baseTableName) {
  426   		String name = super.generateTemporaryTableName(baseTableName);
  427   		return name.length() > 30 ? name.substring( 1, 30 ) : name;
  428   	}
  429   
  430   	public String getCreateTemporaryTableString() {
  431   		return "create global temporary table";
  432   	}
  433   
  434   	public String getCreateTemporaryTablePostfix() {
  435   		return "on commit delete rows";
  436   	}
  437   
  438   	public boolean dropTemporaryTableAfterUse() {
  439   		return false;
  440   	}
  441   
  442   	public boolean supportsCurrentTimestampSelection() {
  443   		return true;
  444   	}
  445   
  446   	public boolean isCurrentTimestampSelectStringCallable() {
  447   		return false;
  448   	}
  449   
  450   
  451   	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  452   
  453   	public boolean supportsEmptyInList() {
  454   		return false;
  455   	}
  456   
  457   	public boolean supportsExistsInSelect() {
  458   		return false;
  459   	}
  460   
  461   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » dialect » [javadoc | source]