FileDocCategorySizeDatePackage
OraclePlatform.javaAPI DocGlassfish v2 API22919Tue May 22 16:54:48 BST 2007oracle.toplink.essentials.platform.database.oracle

OraclePlatform

public class OraclePlatform extends DatabasePlatform

Purpose: Provides Oracle specific behaviour.

Responsibilities:

  • Native SQL for byte[], Date, Time, & Timestamp.
  • Native sequencing named sequences.
since
TOPLink/Java 1.0

Fields Summary
Constructors Summary
Methods Summary
public booleanallowsSizeInProcedureArguments()
INTERNAL: Used for sp defs.

        return false;
    
protected voidappendByteArray(byte[] bytes, java.io.Writer writer)
INTERNAL: If using native SQL then print a byte[] literally as a hex string otherwise use ODBC format as provided in DatabasePlatform.

        if (usesNativeSQL()) {
            writer.write('\'");
            Helper.writeHexString(bytes, writer);
            writer.write('\'");
        } else {
            super.appendByteArray(bytes, writer);
        }
    
protected voidappendCalendar(java.util.Calendar calendar, java.io.Writer writer)
INTERNAL: Appends an Oracle specific Timestamp, if usesNativeSQL is true otherwise use the ODBC format. Native Format: to_date ('1997-11-06 10:35:45.0' , 'yyyy-mm-dd hh:mm:ss.n')

        if (usesNativeSQL()) {
            writer.write("to_date('");
            writer.write(Helper.printCalendarWithoutNanos(calendar));
            writer.write("','yyyy-mm-dd hh24:mi:ss')");
        } else {
            super.appendCalendar(calendar, writer);
        }
    
protected voidappendDate(java.sql.Date date, java.io.Writer writer)
INTERNAL: Appends an Oracle specific date if usesNativeSQL is true otherwise use the ODBC format. Native FORMAT: to_date('1997-11-06','yyyy-mm-dd')

        if (usesNativeSQL()) {
            writer.write("to_date('");
            writer.write(Helper.printDate(date));
            writer.write("','yyyy-mm-dd')");
        } else {
            super.appendDate(date, writer);
        }
    
protected voidappendTime(java.sql.Time time, java.io.Writer writer)
INTERNAL: Appends an Oracle specific time if usesNativeSQL is true otherwise use the ODBC format. Native FORMAT: to_date(#####, 'sssss').

        if (usesNativeSQL()) {
            writer.write("to_date('");
            writer.write(Helper.printTime(time));
            writer.write("','hh24:mi:ss')");
        } else {
            super.appendTime(time, writer);
        }
    
protected voidappendTimestamp(java.sql.Timestamp timestamp, java.io.Writer writer)
INTERNAL: Appends an Oracle specific Timestamp, if usesNativeSQL is true otherwise use the ODBC format. Native Format: to_date ('1997-11-06 10:35:45.0' , 'yyyy-mm-dd hh:mm:ss.n')

        if (usesNativeSQL()) {
            writer.write("to_date('");
            writer.write(Helper.printTimestampWithoutNanos(timestamp));
            writer.write("','yyyy-mm-dd hh24:mi:ss')");
        } else {
            super.appendTimestamp(timestamp, writer);
        }
    
public oracle.toplink.essentials.expressions.ExpressionOperatoratan2Operator()
INTERNAL: Build operator.

        return ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Atan2, "ATAN2");
    
public oracle.toplink.essentials.internal.databaseaccess.DatabaseCallbuildCallWithReturning(oracle.toplink.essentials.queryframework.SQLCall sqlCall, java.util.Vector returnFields)
INTERNAL Returns null unless the platform supports call with returning

        SQLCall call = new SQLCall();
        call.setParameters(sqlCall.getParameters());
        call.setParameterTypes(sqlCall.getParameterTypes());

        Writer writer = new CharArrayWriter(200);
        try {
            writer.write("BEGIN ");
            writer.write(sqlCall.getSQLString());
            writer.write(" RETURNING ");

            for (int i = 0; i < returnFields.size(); i++) {
                DatabaseField field = (DatabaseField)returnFields.elementAt(i);
                writer.write(field.getName());
                if ((i + 1) < returnFields.size()) {
                    writer.write(", ");
                }
            }

            writer.write(" INTO ");

            for (int i = 0; i < returnFields.size(); i++) {
                DatabaseField field = (DatabaseField)returnFields.elementAt(i);
                call.appendOut(writer, field);
                if ((i + 1) < returnFields.size()) {
                    writer.write(", ");
                }
            }

            writer.write("; END;");

            call.setQueryString(writer.toString());

        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }

        return call;
    
protected java.util.HashtablebuildClassTypes()
Return the mapping of class types to database types for the schema framework.

        //use what is defined in DatabasePlatform and override the blob/clob entries
        Hashtable classTypeMapping = super.buildClassTypes();
        classTypeMapping.put("BLOB", java.sql.Blob.class);
        classTypeMapping.put("CLOB", java.sql.Clob.class);

        return classTypeMapping;
    
protected java.util.HashtablebuildFieldTypes()

        Hashtable fieldTypeMapping;

        fieldTypeMapping = new Hashtable();
        fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("NUMBER(1) default 0", false));

        fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("NUMBER", 10));
        fieldTypeMapping.put(Long.class, new FieldTypeDefinition("NUMBER", 19));
        fieldTypeMapping.put(Float.class, new FieldTypeDefinition("NUMBER", 19, 4));
        fieldTypeMapping.put(Double.class, new FieldTypeDefinition("NUMBER", 19, 4));
        fieldTypeMapping.put(Short.class, new FieldTypeDefinition("NUMBER", 5));
        fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("NUMBER", 3));
        fieldTypeMapping.put(java.math.BigInteger.class, new FieldTypeDefinition("NUMBER", 38));
        fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("NUMBER", 38).setLimits(38, -38, 38));
        fieldTypeMapping.put(Number.class, new FieldTypeDefinition("NUMBER", 38).setLimits(38, -38, 38));

        fieldTypeMapping.put(String.class, new FieldTypeDefinition("VARCHAR2", 255));
        fieldTypeMapping.put(Character.class, new FieldTypeDefinition("CHAR", 1));

        fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("LONG RAW", false));
        fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("LONG", false));
        fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("LONG RAW", false));
        fieldTypeMapping.put(char[].class, new FieldTypeDefinition("LONG", false)); 
        fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition("BLOB", false));
        fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition("CLOB", false));         

        fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATE", false));
        fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("TIMESTAMP", false));
        fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMP", false));

        return fieldTypeMapping;
    
public oracle.toplink.essentials.queryframework.ValueReadQuerybuildSelectQueryForNativeSequence(java.lang.String seqName, java.lang.Integer size)
INTERNAL: Produce a DataReadQuery which updates(!) the sequence number in the db and returns it. Currently implemented on Oracle only.

param
sequenceName Name known by Oracle to be a defined sequence

        return new ValueReadQuery("SELECT " + getQualifiedSequenceName(seqName) + ".NEXTVAL FROM DUAL");
    
public booleancanBuildCallWithReturning()
INTERNAL Indicates whether the platform can build call with returning. In case this method returns true, buildCallWithReturning method may be called.

        return true;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatorcurrentDateOperator()

        return ExpressionOperator.simpleFunctionNoParentheses(ExpressionOperator.CurrentDate, "TO_DATE(CURRENT_DATE)");
    
protected oracle.toplink.essentials.expressions.ExpressionOperatorcurrentTimeOperator()

        return ExpressionOperator.simpleFunctionNoParentheses(ExpressionOperator.CurrentTime, "SYSDATE");
    
public java.lang.StringgetAssignmentString()
INTERNAL Used for stored function calls.

        return ":= ";
    
public java.lang.StringgetBatchBeginString()
INTERNAL: Used for batch writing and sp defs.

        return "BEGIN ";
    
public java.lang.StringgetBatchEndString()
INTERNAL: Used for batch writing and sp defs.

        return "END;";
    
public java.lang.StringgetJDBCOuterJoinString()
Returns the JDBC outer join operator for SELECT statements. Overwrites the default implementation, as some Oracle versions seem to require the syntax given here.

        return "{'oj ";
    
public intgetMaxFieldNameSize()
INTERNAL: returns the maximum number of characters that can be used in a field name on this platform.

        return 30;
    
public java.util.VectorgetNativeTableInfo(java.lang.String table, java.lang.String creator, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Return the catalog information through using the native SQL catalog selects. This is required because many JDBC driver do not support meta-data. Willcards can be passed as arguments.

        String query = "SELECT * FROM ALL_TABLES WHERE OWNER NOT IN ('SYS', 'SYSTEM')";
        if (table != null) {
            if (table.indexOf('%") != -1) {
                query = query + " AND TABLE_NAME LIKE " + table;
            } else {
                query = query + " AND TABLE_NAME = " + table;
            }
        }
        if (creator != null) {
            if (creator.indexOf('%") != -1) {
                query = query + " AND OWNER LIKE " + creator;
            } else {
                query = query + " AND OWNER = " + creator;
            }
        }
        return session.executeSelectingCall(new oracle.toplink.essentials.queryframework.SQLCall(query));
    
public java.lang.ObjectgetObjectFromResultSet(java.sql.ResultSet resultSet, int columnNumber, int type)
INTERNAL: Get a timestamp value from a result set. Overrides the default behavior to specifically return a timestamp. Added to overcome an issue with the oracle 9.0.1.4 JDBC driver.

        //Bug#3381652 10G Drivers return sql.Date instead of timestamp on DATE field
        if ((type == Types.TIMESTAMP) || (type == Types.DATE)) {
            return resultSet.getTimestamp(columnNumber);
        } else {
            return resultSet.getObject(columnNumber);
        }
    
public java.lang.StringgetProcedureArgumentSetter()
INTERNAL: Used for sp calls.

        return "=>";
    
public java.lang.StringgetProcedureCallHeader()
INTERNAL: Used for sp calls.

        return "BEGIN ";
    
public java.lang.StringgetProcedureCallTail()
INTERNAL: Used for sp calls.

        return "; END;";
    
protected java.lang.StringgetQualifiedSequenceName(java.lang.String seqName)
INTERNAL: Prepend sequence name with table qualifier (if any)

        if (getTableQualifier().equals("")) {
            return seqName;
        } else {
            return getTableQualifier() + "." + seqName;
        }
    
public java.lang.StringgetSelectForUpdateString()
INTERNAL:

        return " FOR UPDATE";
    
public java.lang.StringgetStoredProcedureParameterPrefix()
INTERNAL:

        return "P_";
    
public java.lang.StringgetStoredProcedureTerminationToken()
INTERNAL:

        return "";
    
public oracle.toplink.essentials.queryframework.ValueReadQuerygetSystemChangeNumberQuery()
INTERNAL: The query to select the current system change number from Oracle. In order to execute this query a database administrator may need to grant execute permission on pl/sql package DBMS_FLASHBACK.

        ValueReadQuery sCNQuery = new ValueReadQuery();
        sCNQuery.setSQLString("SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL");
        return sCNQuery;
    
public oracle.toplink.essentials.queryframework.ValueReadQuerygetTimestampQuery()
INTERNAL: This method returns the query to select the timestamp from the server for Oracle.

        if (timestampQuery == null) {
            timestampQuery = new ValueReadQuery();
            timestampQuery.setSQLString("SELECT SYSDATE FROM DUAL");
        }
        return timestampQuery;
    
protected voidinitializePlatformOperators()
INTERNAL: Initialize any platform-specific operators

        super.initializePlatformOperators();
        addOperator(operatorOuterJoin());
        addOperator(logOperator());
        addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Concat, "CONCAT"));
        addOperator(todayOperator());
        addOperator(currentDateOperator());
        addOperator(currentTimeOperator());
        addOperator(ExpressionOperator.truncateDate());
        addOperator(ExpressionOperator.newTime());
        addOperator(ExpressionOperator.ifNull());
        addOperator(atan2Operator());
        addOperator(ExpressionOperator.oracleDateName());
        addOperator(operatorLocate());
        addOperator(operatorLocate2());
    
public booleanisOracle()

        return true;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatorlogOperator()
INTERNAL: Create the log operator for this platform

        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.Log);
        Vector v = new Vector(2);
        v.addElement("LOG(");
        v.addElement(", 10)");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(FunctionExpression.class);
        return result;

    
public java.util.HashtablemaximumNumericValues()
INTERNAL: Builds a table of maximum numeric values keyed on java class. This is used for type testing but might also be useful to end users attempting to sanitize values.

NOTE: BigInteger & BigDecimal maximums are dependent upon their precision & Scale

        Hashtable values = new Hashtable();

        values.put(Integer.class, new Integer(Integer.MAX_VALUE));
        values.put(Long.class, new Long(Long.MAX_VALUE));
        values.put(Double.class, new Double((double)9.9999E125));
        values.put(Short.class, new Short(Short.MAX_VALUE));
        values.put(Byte.class, new Byte(Byte.MAX_VALUE));
        values.put(Float.class, new Float(Float.MAX_VALUE));
        values.put(java.math.BigInteger.class, new java.math.BigInteger("0"));
        values.put(java.math.BigDecimal.class, new java.math.BigDecimal(new java.math.BigInteger("0"), 38));
        return values;
    
public java.util.HashtableminimumNumericValues()
INTERNAL: Builds a table of minimum numeric values keyed on java class. This is used for type testing but might also be useful to end users attempting to sanitize values.

NOTE: BigInteger & BigDecimal minimums are dependent upon their precision & Scale

        Hashtable values = new Hashtable();

        values.put(Integer.class, new Integer(Integer.MIN_VALUE));
        values.put(Long.class, new Long(Long.MIN_VALUE));
        values.put(Double.class, new Double((double)-1E-129));
        values.put(Short.class, new Short(Short.MIN_VALUE));
        values.put(Byte.class, new Byte(Byte.MIN_VALUE));
        values.put(Float.class, new Float(Float.MIN_VALUE));
        values.put(java.math.BigInteger.class, new java.math.BigInteger("0"));
        values.put(java.math.BigDecimal.class, new java.math.BigDecimal(new java.math.BigInteger("0"), 38));
        return values;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatoroperatorLocate()
INTERNAL: Override the default locate operator

        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.Locate);
        Vector v = new Vector(3);
        v.addElement("INSTR(");
        v.addElement(", ");
        v.addElement(")");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(RelationExpression.class);
        return result;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatoroperatorLocate2()
INTERNAL: Override the default locate operator

        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.Locate2);
        Vector v = new Vector(4);
        v.addElement("INSTR(");
        v.addElement(", ");
        v.addElement(", ");
        v.addElement(")");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(RelationExpression.class);
        return result;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatoroperatorOuterJoin()
INTERNAL: Create the outer join operator for this platform

        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.EqualOuterJoin);
        Vector v = new Vector(2);
        v.addElement(" (+) = ");
        result.printsAs(v);
        result.bePostfix();
        result.setNodeClass(RelationExpression.class);
        return result;

    
public voidprintFieldNullClause(java.io.Writer writer)
INTERNAL: Append the receiver's field 'NULL' constraint clause to a writer.

        try {
            writer.write(" NULL");
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    
public java.lang.StringserverTimestampString()
INTERNAL: Return the current date and time from the server.

        return "SYSDATE";
    
public voidsetPrimitiveParameterValue(java.sql.PreparedStatement statement, int index, java.lang.Object parameter)
INTERNAL: Set a primitive parameter.

        if (parameter instanceof java.sql.Date)
        {
            //Essentials Bug#1878 - Fix the bug that the wrong date is entered into the oracle database 
            //when the timezone is Korea/Seoul. The bug is fixed by caculating the date with the default 
            //timezone, which is that of the virtual machine running the application. 
            statement.setDate(index,(java.sql.Date)parameter,null);
        } else {
            statement.setObject(index, parameter);
        }
    
public booleanshouldPrintOuterJoinInWhereClause()
INTERNAL: Some database require outer joins to be given in the where clause, others require it in the from clause.

        return true;
    
public booleanshouldUseJDBCOuterJoinSyntax()
INTERNAL: JDBC defines and outer join syntax, many drivers do not support this. So we normally avoid it.

        return false;
    
public booleansupportsNativeSequenceNumbers()
INTERNAL: Return true if the receiver uses host sequence numbers, generated on the database. Oracle does through global sequence objects.

        return true;
    
public booleansupportsSelectForUpdateNoWait()
INTERNAL: Returns true if the database supports SQL syntax not to wait on a SELECT..FOR UPADTE (i.e. In Oracle adding NOWAIT to the end will accomplish this)

        return true;
    
public booleansupportsStoredFunctions()
INTERNAL:

        return true;
    
protected oracle.toplink.essentials.expressions.ExpressionOperatortodayOperator()
INTERNAL: Create the sysdate operator for this platform

        return ExpressionOperator.simpleFunctionNoParentheses(ExpressionOperator.Today, "SYSDATE");