[#1786] Fix SEQUENCE support for Firebird

This commit is contained in:
Lukas Eder 2012-09-02 14:46:33 +02:00
parent 6562d3dae4
commit d9c8a91a83
5 changed files with 101 additions and 134 deletions

View File

@ -73,6 +73,7 @@ import org.jooq.test._.converters.Boolean_YES_NO_LC;
import org.jooq.test._.converters.Boolean_YES_NO_UC;
import org.jooq.test._.converters.Boolean_YN_LC;
import org.jooq.test._.converters.Boolean_YN_UC;
import org.jooq.test.firebird.generatedclasses.Sequences;
import org.jooq.test.firebird.generatedclasses.tables.records.TAuthorRecord;
import org.jooq.test.firebird.generatedclasses.tables.records.TBookRecord;
import org.jooq.test.firebird.generatedclasses.tables.records.TBookStoreRecord;
@ -692,7 +693,7 @@ public class jOOQFirebirdTest extends jOOQAbstractTest<
@Override
protected Class<?> cSequences() {
return null;
return Sequences.class;
}
@Override

View File

@ -39,6 +39,7 @@ import static org.jooq.SQLDialect.ASE;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
@ -872,7 +873,7 @@ public interface FactoryOperations extends Configuration {
*
* @throws DataAccessException if something went wrong executing the query
*/
@Support({ CUBRID, DB2, DERBY, H2, HSQLDB, INGRES, ORACLE, POSTGRES, SYBASE })
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, POSTGRES, SYBASE })
<T extends Number> T nextval(Sequence<T> sequence) throws DataAccessException;
/**
@ -881,7 +882,7 @@ public interface FactoryOperations extends Configuration {
*
* @throws DataAccessException if something went wrong executing the query
*/
@Support({ CUBRID, DB2, H2, INGRES, ORACLE, POSTGRES, SYBASE })
@Support({ CUBRID, DB2, FIREBIRD, H2, INGRES, ORACLE, POSTGRES, SYBASE })
<T extends Number> T currval(Sequence<T> sequence) throws DataAccessException;
/**

View File

@ -38,6 +38,7 @@ package org.jooq;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DB2;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.INGRES;
@ -72,12 +73,12 @@ public interface Sequence<T extends Number> extends Serializable {
/**
* Get the current value of this sequence
*/
@Support({ CUBRID, DB2, H2, INGRES, ORACLE, POSTGRES, SYBASE })
@Support({ CUBRID, DB2, FIREBIRD, H2, INGRES, ORACLE, POSTGRES, SYBASE })
Field<T> currval();
/**
* Increment the sequence and get the next value
*/
@Support({ CUBRID, DB2, DERBY, H2, HSQLDB, INGRES, ORACLE, POSTGRES, SYBASE })
@Support({ CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, ORACLE, POSTGRES, SYBASE })
Field<T> nextval();
}

View File

@ -1,128 +0,0 @@
/**
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.impl;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.impl.Factory.field;
import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.RenderContext;
import org.jooq.Schema;
import org.jooq.exception.SQLDialectNotSupportedException;
/**
* @author Lukas Eder
*/
class SequenceFunction<T extends Number> extends AbstractFunction<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = 2292275568395094887L;
private final SequenceImpl<T> sequence;
private final String method;
SequenceFunction(SequenceImpl<T> sequence, String method) {
super(method, sequence.type);
this.sequence = sequence;
this.method = method;
}
@Override
final Field<T> getFunction0(Configuration configuration) {
switch (configuration.getDialect()) {
case DB2:
case INGRES:
case ORACLE:
case SYBASE: {
String field = getQualifiedName(configuration) + "." + method;
return field(field, getDataType());
}
case H2:
case POSTGRES: {
String field = method + "('" + getQualifiedName(configuration) + "')";
return field(field, getDataType());
}
case DERBY:
case HSQLDB: {
if ("nextval".equals(method)) {
String field = "next value for " + getQualifiedName(configuration);
return field(field, getDataType());
}
else {
throw new SQLDialectNotSupportedException("The sequence's current value functionality is not supported for the " + configuration.getDialect() + " dialect.");
}
}
case CUBRID: {
String field = getQualifiedName(configuration) + ".";
if ("nextval".equals(method)) {
field += "next_value";
}
else {
field += "current_value";
}
return field(field, getDataType());
}
// Default is needed for hashCode() and toString()
default: {
String field = getQualifiedName(configuration) + "." + method;
return field(field, getDataType());
}
}
}
private final String getQualifiedName(Configuration configuration) {
RenderContext local = create(configuration).renderContext();
Schema mappedSchema = Util.getMappedSchema(configuration, sequence.schema);
if (mappedSchema != null && configuration.getDialect() != CUBRID) {
local.sql(mappedSchema);
local.sql(".");
}
local.literal(sequence.name);
return local.render();
}
}

View File

@ -35,10 +35,18 @@
*/
package org.jooq.impl;
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.impl.Factory.field;
import org.jooq.Configuration;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.RenderContext;
import org.jooq.SQLDialect;
import org.jooq.Schema;
import org.jooq.Sequence;
import org.jooq.exception.SQLDialectNotSupportedException;
/**
* A common base class for sequences
@ -90,6 +98,90 @@ public class SequenceImpl<T extends Number> implements Sequence<T> {
}
private final Field<T> getSequence(final String sequence) {
return new SequenceFunction<T>(this, sequence);
return new SequenceFunction(sequence);
}
private class SequenceFunction extends AbstractFunction<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = 2292275568395094887L;
private final String method;
SequenceFunction(String method) {
super(method, type);
this.method = method;
}
@Override
final Field<T> getFunction0(Configuration configuration) {
SQLDialect dialect = configuration.getDialect();
switch (dialect) {
case DB2:
case INGRES:
case ORACLE:
case SYBASE: {
String field = getQualifiedName(configuration) + "." + method;
return field(field, getDataType());
}
case H2:
case POSTGRES: {
String field = method + "('" + getQualifiedName(configuration) + "')";
return field(field, getDataType());
}
case FIREBIRD:
case DERBY:
case HSQLDB: {
if ("nextval".equals(method)) {
String field = "next value for " + getQualifiedName(configuration);
return field(field, getDataType());
}
else if (dialect == FIREBIRD) {
return field("gen_id(" + getQualifiedName(configuration) + ", 0)", getDataType());
}
else {
throw new SQLDialectNotSupportedException("The sequence's current value functionality is not supported for the " + dialect + " dialect.");
}
}
case CUBRID: {
String field = getQualifiedName(configuration) + ".";
if ("nextval".equals(method)) {
field += "next_value";
}
else {
field += "current_value";
}
return field(field, getDataType());
}
// Default is needed for hashCode() and toString()
default: {
String field = getQualifiedName(configuration) + "." + method;
return field(field, getDataType());
}
}
}
private final String getQualifiedName(Configuration configuration) {
RenderContext local = create(configuration).renderContext();
Schema mappedSchema = Util.getMappedSchema(configuration, schema);
if (mappedSchema != null && configuration.getDialect() != CUBRID) {
local.sql(mappedSchema);
local.sql(".");
}
local.literal(name);
return local.render();
}
}
}