org.hibernate.dialect.Oracle9iDialect.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.dialect.Oracle9iDialect.java

Source

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.dialect;

import java.sql.Types;
import java.util.Locale;

import org.hibernate.LockOptions;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.sql.ANSICaseFragment;
import org.hibernate.sql.CaseFragment;

/**
 * A dialect for Oracle 9i databases.
 * <p/>
 * Specifies to not use "ANSI join syntax" because 9i does not seem to properly handle it in all cases.
 *
 * @author Steve Ebersole
 */
public class Oracle9iDialect extends Oracle8iDialect {

    private static final AbstractLimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
        @Override
        public String processSql(String sql, RowSelection selection) {
            final boolean hasOffset = LimitHelper.hasFirstRow(selection);
            sql = sql.trim();
            String forUpdateClause = null;
            boolean isForUpdate = false;
            final int forUpdateIndex = sql.toLowerCase(Locale.ROOT).lastIndexOf("for update");
            if (forUpdateIndex > -1) {
                // save 'for update ...' and then remove it
                forUpdateClause = sql.substring(forUpdateIndex);
                sql = sql.substring(0, forUpdateIndex - 1);
                isForUpdate = true;
            }

            final StringBuilder pagingSelect = new StringBuilder(sql.length() + 100);
            if (hasOffset) {
                pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
            } else {
                pagingSelect.append("select * from ( ");
            }
            pagingSelect.append(sql);
            if (hasOffset) {
                pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
            } else {
                pagingSelect.append(" ) where rownum <= ?");
            }

            if (isForUpdate) {
                pagingSelect.append(" ");
                pagingSelect.append(forUpdateClause);
            }

            return pagingSelect.toString();
        }

        @Override
        public boolean supportsLimit() {
            return true;
        }

        @Override
        public boolean bindLimitParametersInReverseOrder() {
            return true;
        }

        @Override
        public boolean useMaxForLimit() {
            return true;
        }
    };

    @Override
    protected void registerCharacterTypeMappings() {
        registerColumnType(Types.CHAR, "char(1 char)");
        registerColumnType(Types.VARCHAR, 4000, "varchar2($l char)");
        registerColumnType(Types.VARCHAR, "long");
        registerColumnType(Types.NVARCHAR, "nvarchar2($l)");
        registerColumnType(Types.LONGNVARCHAR, "nvarchar2($l)");
    }

    @Override
    protected void registerDateTimeTypeMappings() {
        registerColumnType(Types.DATE, "date");
        registerColumnType(Types.TIME, "date");
        registerColumnType(Types.TIMESTAMP, "timestamp");
    }

    @Override
    public CaseFragment createCaseFragment() {
        // Oracle did add support for ANSI CASE statements in 9i
        return new ANSICaseFragment();
    }

    @Override
    public LimitHandler getLimitHandler() {
        return LIMIT_HANDLER;
    }

    @Override
    public String getLimitString(String sql, boolean hasOffset) {
        sql = sql.trim();
        String forUpdateClause = null;
        boolean isForUpdate = false;
        final int forUpdateIndex = sql.toLowerCase(Locale.ROOT).lastIndexOf("for update");
        if (forUpdateIndex > -1) {
            // save 'for update ...' and then remove it
            forUpdateClause = sql.substring(forUpdateIndex);
            sql = sql.substring(0, forUpdateIndex - 1);
            isForUpdate = true;
        }

        final StringBuilder pagingSelect = new StringBuilder(sql.length() + 100);
        if (hasOffset) {
            pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
        } else {
            pagingSelect.append("select * from ( ");
        }
        pagingSelect.append(sql);
        if (hasOffset) {
            pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
        } else {
            pagingSelect.append(" ) where rownum <= ?");
        }

        if (isForUpdate) {
            pagingSelect.append(" ");
            pagingSelect.append(forUpdateClause);
        }

        return pagingSelect.toString();
    }

    @Override
    public String getSelectClauseNullString(int sqlType) {
        return getBasicSelectClauseNullString(sqlType);
    }

    @Override
    public String getCurrentTimestampSelectString() {
        return "select systimestamp from dual";
    }

    @Override
    public String getCurrentTimestampSQLFunctionName() {
        // the standard SQL function name is current_timestamp...
        return "current_timestamp";
    }

    @Override
    public String getForUpdateString() {
        return " for update";
    }

    @Override
    public String getWriteLockString(int timeout) {
        if (timeout == LockOptions.NO_WAIT) {
            return " for update nowait";
        } else if (timeout > 0) {
            // convert from milliseconds to seconds
            final float seconds = timeout / 1000.0f;
            timeout = Math.round(seconds);
            return " for update wait " + timeout;
        } else {
            return " for update";
        }
    }

    @Override
    public String getReadLockString(int timeout) {
        return getWriteLockString(timeout);
    }

    /**
     * HHH-4907, I don't know if oracle 8 supports this syntax, so I'd think it is better add this 
     * method here. Reopen this issue if you found/know 8 supports it.
     * <p/>
     * {@inheritDoc}
     */
    @Override
    public boolean supportsRowValueConstructorSyntaxInInList() {
        return true;
    }

    @Override
    public boolean supportsTupleDistinctCounts() {
        return false;
    }
}