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

org.apache.openjpa.jdbc.sql.EmpressDictionary Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.jdbc.sql;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Locale;

import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Table;

/**
 * Dictionary for Empress using ODBC server combined with their
 * type 2 driver. This dictionary may issues with other
 * driver/topology configurations.
 *  Empress does not allow multiple connections to read rows
 * read in a transaction, effectively forcing pessimistic transactions
 * regardless of the Optimistic setting. To allow users to use
 * optimistic transactions in a multi-connection evironment, you
 * must set the AllowConcurrentRead setting to true in addition
 * to standard options.
 *  Empress has the following additional limitations:
 * 
    *
  • Foreign keys are quite limited in Empress and it is recommended * that these be created by hand.
  • *
  • Batching can be unreliable. Using BatchLimit=0 is strongly * recommended.
  • *
  • Using AllowConcurrentRead should be accompanied by * SimulateLocking=true
  • *
  • Connections should be rolled back on return to ensure locks * are released (see OpenJPA default DataSource documentation.
  • *
  • Certain outer joins requiring parameters in a subselect is not * supported by Empress and may under certain configurations cause * size () calls on query results and LRS fields to throw an exception.
  • *
  • Certain aggregate functions are not supported.
  • *
*/ public class EmpressDictionary extends DBDictionary { /** * This setting inserts "BYPASS" after every "SELECT". This * allows for multiple transactional reads of the same row * from different connections at the expense of loss of * pessimistic locking. Defaults to false. */ public boolean allowConcurrentRead = false; public EmpressDictionary() { platform = "Empress"; validationSQL = "SELECT DISTINCT today FROM sys_tables"; joinSyntax = SYNTAX_TRADITIONAL; toUpperCaseFunction = "TOUPPER({0})"; toLowerCaseFunction = "TOLOWER({0})"; supportsDeferredConstraints = false; requiresAliasForSubselect = true; maxTableNameLength = 28; maxColumnNameLength = 28; maxIndexNameLength = 28; maxConstraintNameLength = 28; schemaCase = SCHEMA_CASE_PRESERVE; useGetBytesForBlobs = true; useSetBytesForBlobs = true; useGetStringForClobs = true; useSetStringForClobs = true; clobTypeName = "TEXT"; blobTypeName = "BULK"; realTypeName = "FLOAT(8)"; bigintTypeName = "DECIMAL(38)"; timestampTypeName = "DATE"; varcharTypeName = "CHARACTER"; tinyintTypeName = "DOUBLE PRECISION"; doubleTypeName = "SMALLINT"; bitTypeName = "SMALLINT"; fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{ "TEXT", "BULK", "LONGFLOAT", "INTEGER64", "SHORTINTEGER", "LONGINTEGER", })); } @Override public boolean isSystemIndex(String name, Table table) { return name.toUpperCase(Locale.ENGLISH).startsWith("SYS_"); } @Override public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch, SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having, SQLBuffer order, boolean distinct, boolean forUpdate, long startIdx, long endIdx) { if (!allowConcurrentRead) return super.toSelect(selects, fetch, from, where, group, having, order, distinct, forUpdate, startIdx, endIdx); // override to allow a "BYPASS" to be inserted post-"select" // depending on allowConcurrentRead setting SQLBuffer buf = new SQLBuffer(this); buf.append("SELECT BYPASS "); if (distinct) buf.append("DISTINCT "); buf.append(selects).append(" FROM ").append(from); if (where != null && !where.isEmpty()) buf.append(" WHERE ").append(where); if (group != null && !group.isEmpty()) buf.append(" GROUP BY ").append(group); if (having != null && !having.isEmpty()) buf.append(" HAVING ").append(having); if (order != null && !order.isEmpty()) buf.append(" ORDER BY ").append(order); return buf; } @Override public String[] getDropColumnSQL(Column column) { // empress wants dropped columns in the form: ALTER TABLE foo // DELETE columnToDrop return new String[]{ "ALTER TABLE " + getFullName(column.getTable(), false) + " DELETE " + getColumnDBName(column) }; } @Override public void setFloat(PreparedStatement stmnt, int idx, float val, Column col) throws SQLException { // empress seems to allow INFINITY to be stored, but not retrieved, // which can prove to be difficult to handle if (val == Float.POSITIVE_INFINITY) { val = Float.MAX_VALUE; storageWarning(new Float(Float.POSITIVE_INFINITY), new Float(val)); } else if (val == Float.NEGATIVE_INFINITY) { val = Float.MIN_VALUE + 1; storageWarning(new Float(Float.NEGATIVE_INFINITY), new Float(val)); } super.setFloat(stmnt, idx, val, col); } @Override public void setDouble(PreparedStatement stmnt, int idx, double val, Column col) throws SQLException { // empress seems to allow INFINITY to be stored, but not retrieved, // which can prove to be difficult to handle if (val == Double.POSITIVE_INFINITY) { val = Double.MAX_VALUE; storageWarning(new Double(Double.POSITIVE_INFINITY), new Double(val)); } else if (val == Double.NEGATIVE_INFINITY) { val = Double.MIN_VALUE + 1; storageWarning(new Double(Double.NEGATIVE_INFINITY), new Double(val)); } super.setDouble(stmnt, idx, val, col); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy