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

org.eclipse.persistence.platform.database.PervasivePlatform Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All Rights Reserved.
 * Copyright (c) 2012, 2018 Pervasive Software Inc. All Rights Reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//       Peter Lohman - initial implementation
//

 /*

    For minimal implementation, compare with:
         C:\PL\JPA\EclipseLink\SVN\org.eclipse.persistence\foundation\org.eclipse.persistence.core\src\org\eclipse\persistence\platform\database\CloudscapePlatform.java

    For PVSW data type mapping, see: getColumnClassName():C:\cmsynergy\psql11.20_pnl\psql\comp\sdk\jdbc\pvjdbc2\src\com\pervasive\jdbc\v2\ResultSetMetaData.java

*/
package org.eclipse.persistence.platform.database;

import java.io.IOException;
import java.io.Writer;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.tools.schemaframework.FieldDefinition;

/** 

Purpose: Provides Pervasive SQL DBMS specific behavior. * *

* Pervasive SQL Platform file
* Contributed by: Pervasive Software, Inc.
* Contributed under bug: 392109 *

* * Developed on Pervasive PSQL Server 11.30 *

*
    *
  • Eclipselink Core SRG Test passes with known limitations. *
  • Eclipselink JPA SRG Test passes with known limitations. *
  • Eclipselink stored procedure tests "CustomSQLTestModel", "StoredProcedureGeneratorModel" pass with known limitations. *
*
* *

Limitations *

    *
  • Updates are not supported on joined queries or queries with group by. *
  • The platform method getSelectForUpdateString() currently returns an empty string. This is * to avoid avoid joined queries with FOR UPDATE in them, which Pervasive does not support. *
  • Columns used in indexes must total no more than 255 bytes in length. *
  • Pervasive SQL does not support dynamic parameters in the SELECT list. *
  • IDENTITY columns are either 2- or 4-byte integers. Foreign keys referencing such columns must use the same datatypes. *
* **/ public class PervasivePlatform extends org.eclipse.persistence.platform.database.DatabasePlatform { public static final int DEFAULT_CHAR_SIZE = 80; // // Cloned from AccessPlatform.java // @Override protected Map buildClassTypes() { Map classTypeMapping = super.buildClassTypes(); // Causes BLOB to translate to LONGVARBINARY(via java.sql.Blob) instead of BINARY (via Byte[]) classTypeMapping.put("BLOB", java.sql.Blob.class); return classTypeMapping; } @Override protected Hashtable buildFieldTypes() { Hashtable fieldTypeMapping; fieldTypeMapping = new Hashtable(); fieldTypeMapping.put(String.class, new FieldTypeDefinition("VARCHAR", DEFAULT_CHAR_SIZE)); // fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("BIGINT", false)); fieldTypeMapping.put(java.math.BigInteger.class, new FieldTypeDefinition("BIGINT", false)); fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("INTEGER", false)); fieldTypeMapping.put(Long.class, new FieldTypeDefinition("INTEGER", false)); fieldTypeMapping.put(Short.class, new FieldTypeDefinition("SMALLINT", false)); fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("TINYINT", false)); fieldTypeMapping.put(Float.class, new FieldTypeDefinition("REAL", false)); fieldTypeMapping.put(Double.class, new FieldTypeDefinition("DOUBLE", false)); fieldTypeMapping.put(Character.class, new FieldTypeDefinition("CHAR", 1)); fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATE", false)); fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("TIME", false)); fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMP", false)); fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BINARY", DEFAULT_CHAR_SIZE )); fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("LONGVARBINARY", false)); fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("CHAR", DEFAULT_CHAR_SIZE)); fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("BIT", false)); fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition("LONGVARBINARY", false)); fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition("LONGVARCHAR", false)); fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("DECIMAL",38, 0)); // From MySQL fieldTypeMapping.put(Number.class, new FieldTypeDefinition("DECIMAL",38,0)); // From MySQL // fieldTypeMapping.put(java.lang.Number.class, new FieldTypeDefinition("BIGINT", false)); fieldTypeMapping.put(char[].class, new FieldTypeDefinition("LONGVARCHAR", false)); fieldTypeMapping.put(java.util.Calendar.class, new FieldTypeDefinition("TIMESTAMP")); fieldTypeMapping.put(java.util.Date.class, new FieldTypeDefinition("TIMESTAMP")); return fieldTypeMapping; } /** * * Pervasive uses the INOUT keyword, as opposed to "IN OUT". */ @Override public String getInOutputProcedureToken() { return "INOUT"; } /** * Pervasive uses IN prefix for INPUT parameters. * */ @Override public String getInputProcedureToken() { return "IN"; } /** * Pervasive uses ":" as prefix for procedure arguments. */ @Override public String getProcedureArgumentString() { return ":"; } /** * * Pervasive requires BEGIN in a procedure statement. */ @Override public String getProcedureBeginString() { return "BEGIN "; } /** * In CREATE PROCEDURE, Pervasive requires brackets after the procedure name, even if there are no arguments. */ @Override public boolean requiresProcedureBrackets() { return true; } /** * Pervasive uses CALL or EXECUTE not CALL PROCEDURE or EXECUTE PROCEDURE */ @Override public String getProcedureCallHeader() { return "CALL "; } /** * * Pervasive requires END in a procedure statement. */ @Override public String getProcedureEndString() { return "END"; } /** * Pervasive uses ":" as prefix for procedure parameters. */ @Override public String getStoredProcedureParameterPrefix() { return ":"; } /** * Pervasive requires the OUTPUT keyword for output parameters */ @Override public boolean requiresProcedureCallOuputToken() { return true; } @Override protected void initializePlatformOperators() { super.initializePlatformOperators(); addOperator(ExpressionOperator.simpleThreeArgumentFunction(ExpressionOperator.Substring, "SUBSTRING")); addOperator(singleArgumentSubstringOperator()); addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Nvl, "ISNULL")); addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.Ceil, "CEILING")); addOperator(toNumberOperator()); addOperator(toCharOperator()); addOperator(toDateOperator()); } /** * Cloned from MySQLPlatform.java * */ /** * INTERNAL: * Pervasive SQL stored procedure calls do not require the argument name be printed in the call string * e.g. call MyStoredProc(?) instead of call MyStoredProc(myvariable = ?) */ @Override public boolean shouldPrintStoredProcedureArgumentNameInCall(){ return false; } protected ExpressionOperator toNumberOperator() { ExpressionOperator exOperator = new ExpressionOperator(); exOperator.setType(ExpressionOperator.FunctionOperator); exOperator.setSelector(ExpressionOperator.ToNumber); Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); v.addElement("CONVERT("); v.addElement(", SQL_NUMERIC)"); exOperator.printsAs(v); exOperator.bePrefix(); exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } /** * Cloned from MySQLPlatform.java */ protected ExpressionOperator toDateOperator() { ExpressionOperator exOperator = new ExpressionOperator(); exOperator.setType(ExpressionOperator.FunctionOperator); exOperator.setSelector(ExpressionOperator.ToDate); Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); v.addElement("CONVERT("); v.addElement(", DATETIME)"); exOperator.printsAs(v); exOperator.bePrefix(); exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } /** * Cloned from MySQLPlatform.java */ protected ExpressionOperator toCharOperator() { ExpressionOperator exOperator = new ExpressionOperator(); exOperator.setType(ExpressionOperator.FunctionOperator); exOperator.setSelector(ExpressionOperator.ToChar); Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); v.addElement("CONVERT("); v.addElement(", SQL_CHAR)"); exOperator.printsAs(v); exOperator.bePrefix(); exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } /** * * Cloned from MySQLPlatform.java */ protected ExpressionOperator dateToStringOperator() { ExpressionOperator exOperator = new ExpressionOperator(); exOperator.setType(ExpressionOperator.FunctionOperator); exOperator.setSelector(ExpressionOperator.DateToString); Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2); v.addElement("CONVERT("); v.addElement(", SQL_CHAR)"); exOperator.printsAs(v); exOperator.bePrefix(); exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } /** * Answers whether platform is Pervasive */ @Override public boolean isPervasive() { return true; } /** * JDBC defines an outer join syntax which many drivers do not support. So we normally avoid it. */ @Override public boolean shouldUseJDBCOuterJoinSyntax() { return false; // not sure about this } /** Append the receiver's field 'identity' constraint clause to * a writer. * * Taken from * org.eclipse.persistence\foundation\org.eclipse.persistence.core\src\org\eclipse\persistence\platform\database\AccessPlatform.java */ @Override public void printFieldIdentityClause(Writer writer) throws ValidationException { try { writer.write(" IDENTITY"); } catch (IOException ioException) { throw ValidationException.fileError(ioException); } } /** * Override the default SubstringSingleArg operator. * Cloned from SybasePlatform.java */ public ExpressionOperator singleArgumentSubstringOperator() { ExpressionOperator result = new ExpressionOperator(); result.setSelector(ExpressionOperator.SubstringSingleArg); result.setType(ExpressionOperator.FunctionOperator); Vector v = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); v.addElement("SUBSTRING("); v.addElement(","); v.addElement(", CHAR_LENGTH("); v.addElement("))"); result.printsAs(v); int[] indices = new int[3]; indices[0] = 0; indices[1] = 1; indices[2] = 0; result.setArgumentIndices(indices); result.setNodeClass(ClassConstants.FunctionExpression_Class); result.bePrefix(); return result; } /** * * Indicates whether the platform supports identity. * */ @Override public boolean supportsIdentity() { return true; } // // Most Temp Table settings cloned from SQLServerPlatform.java // /** * INTERNAL: */ @Override public boolean supportsLocalTempTables() { return true; } @Override public boolean supportsGlobalTempTables() { return true; } /** * INTERNAL: */ @Override protected String getCreateTempTableSqlPrefix() { return "CREATE TABLE "; } /** * INTERNAL: */ @Override public DatabaseTable getTempTableForTable(DatabaseTable table) { return new DatabaseTable("#" + table.getName(), table.getTableQualifier(), table.shouldUseDelimiters(), getStartDelimiter(), getEndDelimiter()); } /** * * Taken from org.eclipse.persistence\foundation\org.eclipse.persistence.core\src\org\eclipse\persistence\platform\database\AccessPlatform.java */ @Override public void printFieldTypeSize(Writer writer, FieldDefinition field,FieldTypeDefinition fieldType, boolean shouldPrintFieldIdentityClause) throws IOException { if (!shouldPrintFieldIdentityClause) { // if type requires both precision and scale: NUMERIC, DECIMAL if ((fieldType.getName().equals("NUMERIC")) || (fieldType.getName().equals("DECIMAL"))) { writer.write(fieldType.getName()); writer.write("("); if (field.getSize() == 0) { writer.write(Integer.toString(fieldType.getDefaultSize())); } else { writer.write(Integer.toString(field.getSize())); } writer.write(","); if (field.getSubSize() != 0) { writer.write(Integer.toString(field.getSubSize())); } else { writer.write(Integer.toString(fieldType.getDefaultSubSize())); } writer.write(")"); } else { super.printFieldTypeSize(writer, field, fieldType, shouldPrintFieldIdentityClause); } } } /** * INTERNAL: * Build the identity query for native sequencing. * * Taken verbatim from org.eclipse.persistence\foundation\org.eclipse.persistence.core\src\org\eclipse\persistence\platform\database\SQLServerPlatform.java * */ @Override public ValueReadQuery buildSelectQueryForIdentity() { ValueReadQuery selectQuery = new ValueReadQuery(); selectQuery.setSQLString("SELECT @@IDENTITY"); return selectQuery; } /** * Temporary workaround to avoid joined queries with FOR UPDATE * in them * */ @Override public String getSelectForUpdateString() { return ""; } /** * INTERNAL: * Indicates whether SELECT DISTINCT ... FOR UPDATE is allowed by the platform (Oracle doesn't allow this). */ @Override public boolean isForUpdateCompatibleWithDistinct() { return false; } /** * Setting this to false (cf. Sybase) to work around problem * that unspecified default delete rule is RESTRICT, even when * not allowed due to self-referencing table. */ @Override public boolean supportsDeleteOnCascade() { return true; } /** Attempts to remove FOR UPDATE from queries */ @Override public boolean shouldPrintLockingClauseAfterWhereClause() { return false; } /** * INTERNAL: * Indicates whether locking clause could be applied to the query that has more than one table */ @Override public boolean supportsLockingQueriesWithMultipleTables() { return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy