From 1c7cbc1089110be14e11ba980cbcd7c7d0540393 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 31 May 2013 13:31:30 +0200 Subject: [PATCH] [#2496] Add support for SQL Server 2012 sequences --- .../util/sqlserver/SQLServerDatabase.java | 43 ++++++++++++++++++- .../src/org/jooq/test/SQLServerTest.java | 3 +- .../test/sqlserver/generatedclasses/Dbo.java | 14 +++++- .../sqlserver/generatedclasses/Sequences.java | 18 ++++++++ .../src/org/jooq/test/sqlserver/reset.sql | 7 ++- .../main/java/org/jooq/impl/SequenceImpl.java | 15 ++++++- 6 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Sequences.java diff --git a/jOOQ-meta/src/main/java/org/jooq/util/sqlserver/SQLServerDatabase.java b/jOOQ-meta/src/main/java/org/jooq/util/sqlserver/SQLServerDatabase.java index 28239a4561..444a5c3027 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/sqlserver/SQLServerDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/sqlserver/SQLServerDatabase.java @@ -40,12 +40,12 @@ import static org.jooq.util.sqlserver.information_schema.Tables.KEY_COLUMN_USAGE import static org.jooq.util.sqlserver.information_schema.Tables.REFERENTIAL_CONSTRAINTS; import static org.jooq.util.sqlserver.information_schema.Tables.ROUTINES; import static org.jooq.util.sqlserver.information_schema.Tables.SCHEMATA; +import static org.jooq.util.sqlserver.information_schema.Tables.SEQUENCES; import static org.jooq.util.sqlserver.information_schema.Tables.TABLES; import static org.jooq.util.sqlserver.information_schema.Tables.TABLE_CONSTRAINTS; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.jooq.DSLContext; @@ -57,7 +57,10 @@ import org.jooq.impl.DSL; import org.jooq.util.AbstractDatabase; import org.jooq.util.ArrayDefinition; import org.jooq.util.ColumnDefinition; +import org.jooq.util.DataTypeDefinition; +import org.jooq.util.DefaultDataTypeDefinition; import org.jooq.util.DefaultRelations; +import org.jooq.util.DefaultSequenceDefinition; import org.jooq.util.EnumDefinition; import org.jooq.util.PackageDefinition; import org.jooq.util.RoutineDefinition; @@ -76,6 +79,18 @@ import org.jooq.util.UDTDefinition; */ public class SQLServerDatabase extends AbstractDatabase { + private static Boolean is2012; + + private boolean is2012() { + if (is2012 == null) { + is2012 = create().selectCount() + .from(SEQUENCES) + .fetchOne(0, boolean.class); + } + + return is2012; + } + @Override protected DSLContext create0() { return DSL.using(getConnection(), SQLDialect.SQLSERVER); @@ -189,7 +204,31 @@ public class SQLServerDatabase extends AbstractDatabase { @Override protected List getSequences0() throws SQLException { - return Collections.emptyList(); + List result = new ArrayList(); + + if (is2012()) { + for (Record record : create() + .select( + SEQUENCES.SEQUENCE_SCHEMA, + SEQUENCES.SEQUENCE_NAME, + SEQUENCES.DATA_TYPE) + .from(SEQUENCES) + .where(SEQUENCES.SEQUENCE_SCHEMA.in(getInputSchemata())) + .fetch()) { + + SchemaDefinition schema = getSchema(record.getValue(SEQUENCES.SEQUENCE_SCHEMA)); + + DataTypeDefinition type = new DefaultDataTypeDefinition( + this, + schema, + record.getValue(SEQUENCES.DATA_TYPE), 0, 0, 0); + + result.add(new DefaultSequenceDefinition( + schema, record.getValue(SEQUENCES.SEQUENCE_NAME), type)); + } + } + + return result; } @Override diff --git a/jOOQ-test/src/org/jooq/test/SQLServerTest.java b/jOOQ-test/src/org/jooq/test/SQLServerTest.java index 8097658024..ec2eb2b7f5 100644 --- a/jOOQ-test/src/org/jooq/test/SQLServerTest.java +++ b/jOOQ-test/src/org/jooq/test/SQLServerTest.java @@ -81,6 +81,7 @@ import org.jooq.test._.converters.Boolean_YN_LC; import org.jooq.test._.converters.Boolean_YN_UC; import org.jooq.test.sqlserver.generatedclasses.Keys; import org.jooq.test.sqlserver.generatedclasses.Routines; +import org.jooq.test.sqlserver.generatedclasses.Sequences; import org.jooq.test.sqlserver.generatedclasses.tables.records.TAuthorRecord; import org.jooq.test.sqlserver.generatedclasses.tables.records.TBookRecord; import org.jooq.test.sqlserver.generatedclasses.tables.records.TBookStoreRecord; @@ -722,7 +723,7 @@ public class SQLServerTest extends jOOQAbstractTest< @Override protected Class cSequences() { - return null; + return Sequences.class; } @Override diff --git a/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Dbo.java b/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Dbo.java index 29d9bfc62c..f8f66fad7e 100644 --- a/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Dbo.java +++ b/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Dbo.java @@ -9,7 +9,7 @@ package org.jooq.test.sqlserver.generatedclasses; @java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" }) public class Dbo extends org.jooq.impl.SchemaImpl { - private static final long serialVersionUID = 1363181024; + private static final long serialVersionUID = 754782530; /** * The singleton instance of dbo @@ -23,6 +23,18 @@ public class Dbo extends org.jooq.impl.SchemaImpl { super("dbo"); } + @Override + public final java.util.List> getSequences() { + java.util.List result = new java.util.ArrayList(); + result.addAll(getSequences0()); + return result; + } + + private final java.util.List> getSequences0() { + return java.util.Arrays.>asList( + org.jooq.test.sqlserver.generatedclasses.Sequences.S_AUTHOR_ID); + } + @Override public final java.util.List> getTables() { java.util.List result = new java.util.ArrayList(); diff --git a/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Sequences.java b/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Sequences.java new file mode 100644 index 0000000000..cc75139ed6 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/sqlserver/generatedclasses/Sequences.java @@ -0,0 +1,18 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.sqlserver.generatedclasses; + +/** + * This class is generated by jOOQ. + * + * Convenience access to all sequences in dbo + */ +@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Sequences { + + /** + * The sequence dbo.s_author_id + */ + public static final org.jooq.Sequence S_AUTHOR_ID = new org.jooq.impl.SequenceImpl("s_author_id", org.jooq.test.sqlserver.generatedclasses.Dbo.DBO, org.jooq.impl.SQLDataType.BIGINT); +} diff --git a/jOOQ-test/src/org/jooq/test/sqlserver/reset.sql b/jOOQ-test/src/org/jooq/test/sqlserver/reset.sql index 40ccf20490..76537c9d5a 100644 --- a/jOOQ-test/src/org/jooq/test/sqlserver/reset.sql +++ b/jOOQ-test/src/org/jooq/test/sqlserver/reset.sql @@ -11,6 +11,9 @@ DELETE FROM t_identity/ DELETE FROM t_identity_pk/ DELETE FROM t_triggers/ +DROP SEQUENCE s_author_id;/ +CREATE SEQUENCE s_author_id START WITH 1;/ + INSERT INTO t_language (id, cd, description, description_english) VALUES (1, 'en', 'English', 'English')/ INSERT INTO t_language (id, cd, description, description_english) VALUES (2, 'de', 'Deutsch', 'German')/ INSERT INTO t_language (id, cd, description, description_english) VALUES (3, 'fr', 'Français', 'French')/ @@ -18,8 +21,8 @@ INSERT INTO t_language (id, cd, description, description_english) VALUES (4, 'pt / INSERT INTO t_author (id, first_name, last_name, date_of_birth, year_of_birth, address) -VALUES (1, 'George', 'Orwell', '1903-06-25', 1903, null), - (2, 'Paulo', 'Coelho', '1947-08-24', 1947, null) +VALUES (next value for s_author_id, 'George', 'Orwell', '1903-06-25', 1903, null), + (next value for s_author_id, 'Paulo', 'Coelho', '1947-08-24', 1947, null) / INSERT INTO t_book (id, author_id, co_author_id, details_id, title, published_in, language_id, content_text, content_pdf) diff --git a/jOOQ/src/main/java/org/jooq/impl/SequenceImpl.java b/jOOQ/src/main/java/org/jooq/impl/SequenceImpl.java index f824a107cc..1b0e8f34b5 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SequenceImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/SequenceImpl.java @@ -37,7 +37,9 @@ package org.jooq.impl; import static org.jooq.SQLDialect.CUBRID; import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.select; import org.jooq.Configuration; import org.jooq.DataType; @@ -137,7 +139,8 @@ public class SequenceImpl implements Sequence { case FIREBIRD: case DERBY: - case HSQLDB: { + case HSQLDB: + case SQLSERVER: { if ("nextval".equals(method)) { String field = "next value for " + getQualifiedName(configuration); return field(field, getDataType()); @@ -145,6 +148,16 @@ public class SequenceImpl implements Sequence { else if (dialect == FIREBIRD) { return field("gen_id(" + getQualifiedName(configuration) + ", 0)", getDataType()); } + else if (dialect == SQLSERVER) { + return select(field("current_value")) + .from("sys.sequences sq") + .join("sys.schemas sc") + .on("sq.schema_id = sc.schema_id") + .where("sq.name = ?", name) + .and("sc.name = ?", schema.getName()) + .asField() + .cast(type); + } else { throw new SQLDialectNotSupportedException("The sequence's current value functionality is not supported for the " + dialect + " dialect."); }