From ee0a230c7f69710e7a86aa644bb397082067ee7b Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sun, 28 Oct 2012 10:51:22 +0100 Subject: [PATCH] [#1902] Duplicate SELECT API between Executor and Factory --- .../examples/org/jooq/examples/Library.java | 7 +- .../jooq/test/_/testcases/ExoticTests.java | 5 +- .../jooq/test/_/testcases/GroupByTests.java | 3 +- .../test/_/testcases/InsertUpdateTests.java | 30 +-- .../org/jooq/test/_/testcases/JoinTests.java | 29 ++- .../_/testcases/RowValueExpressionTests.java | 7 +- .../jooq/test/_/testcases/SelectTests.java | 14 +- .../main/java/org/jooq/FactoryOperations.java | 150 ++++++++---- .../src/main/java/org/jooq/impl/Executor.java | 89 ++++--- jOOQ/src/main/java/org/jooq/impl/Factory.java | 226 ++++++++++++++++++ 10 files changed, 432 insertions(+), 128 deletions(-) diff --git a/jOOQ-test/examples/org/jooq/examples/Library.java b/jOOQ-test/examples/org/jooq/examples/Library.java index eed89c127a..185455300d 100644 --- a/jOOQ-test/examples/org/jooq/examples/Library.java +++ b/jOOQ-test/examples/org/jooq/examples/Library.java @@ -35,6 +35,7 @@ */ package org.jooq.examples; +import static org.jooq.impl.Factory.selectDistinct; import static org.jooq.test.mysql.generatedclasses.Tables.T_LANGUAGE; import static org.jooq.test.mysql.generatedclasses.tables.TAuthor.T_AUTHOR; import static org.jooq.test.mysql.generatedclasses.tables.TBook.T_BOOK; @@ -171,15 +172,15 @@ public class Library { // WHERE T_BOOK.STATUS = 'SOLD OUT'); for (TAuthorRecord record : create().selectFrom(T_AUTHOR) - .where(TAuthor.ID.in(create().selectDistinct(TBook.AUTHOR_ID) + .where(TAuthor.ID.in(selectDistinct(TBook.AUTHOR_ID) .from(T_BOOK).where(TBook.STATUS.equal(TBookStatus.SOLD_OUT)))).fetch()) { System.out.println("Author : " + record.getFirstName() + " " + record.getLastName() + " has sold out books"); } for (TAuthorRecord record : create().selectFrom(T_AUTHOR) - .where(TAuthor.ID.in(create() - .selectDistinct(TBook.AUTHOR_ID) + .where(TAuthor.ID.in( + selectDistinct(TBook.AUTHOR_ID) .from(T_BOOK) .where(TBook.LANGUAGE_ID.in( create().select(TLanguage.ID) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java index 86f1f028df..a67de717df 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java @@ -49,6 +49,7 @@ import static org.jooq.impl.Factory.lower; import static org.jooq.impl.Factory.max; import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.prior; +import static org.jooq.impl.Factory.select; import static org.jooq.impl.Factory.substring; import static org.jooq.impl.Factory.sum; import static org.jooq.impl.Factory.sysConnectByPath; @@ -213,8 +214,8 @@ extends BaseTest lang = TBook_LANGUAGE_ID().cast(Integer.class).as("lang"); Result result3 = create().select() - .from(table(create().select(TBook_AUTHOR_ID(), lang) - .from(TBook())) + .from(table(select(TBook_AUTHOR_ID(), lang) + .from(TBook())) .pivot(count()) .on(lang) .in(1, 2, 3, 4)) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java index 7fe2156620..6922afde70 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/GroupByTests.java @@ -47,6 +47,7 @@ import static org.jooq.impl.Factory.groupingId; import static org.jooq.impl.Factory.groupingSets; import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.rollup; +import static org.jooq.impl.Factory.selectOne; import java.util.Arrays; @@ -140,7 +141,7 @@ extends BaseTest i = create().insertInto(TAuthor()) - .select(create().select(vals( - 1000, - val("Lukas"))) - .select(vals( - "Eder", - val(new Date(363589200000L)), - castNull(Integer.class), - nullField))); + .select(select(vals( + 1000, + val("Lukas"))) + .select(vals( + "Eder", + val(new Date(363589200000L)), + castNull(Integer.class), + nullField))); assertEquals(1, i.execute()); @@ -383,7 +385,7 @@ extends BaseTest q = create().mergeInto(TAuthor()) - .using(create().select(f, l)) + .using(select(f, l)) .on(TAuthor_LAST_NAME().equal(l)) .whenMatchedThenUpdate() .set(TAuthor_FIRST_NAME(), "James") @@ -841,8 +843,8 @@ extends BaseTest authors4 = create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(); diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/JoinTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/JoinTests.java index c637ef79f6..a9ce9190c3 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/JoinTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/JoinTests.java @@ -49,6 +49,8 @@ import static org.jooq.impl.Factory.falseCondition; import static org.jooq.impl.Factory.field; import static org.jooq.impl.Factory.lower; import static org.jooq.impl.Factory.one; +import static org.jooq.impl.Factory.select; +import static org.jooq.impl.Factory.selectOne; import static org.jooq.impl.Factory.val; import static org.jooq.impl.Factory.zero; @@ -109,7 +111,7 @@ extends BaseTest + * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#select(Field...)} instead. + *

* Example:

      * Factory create = new Factory();
      *
@@ -333,13 +339,93 @@ public interface FactoryOperations extends Configuration {
      *       .orderBy(field2)
      *       .execute();
      * 
+ * + * @see Factory#select(Field...) */ @Support SelectSelectStep select(Field... fields); + /** + * Create a new DSL select statement. + *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#select(Collection)} instead. + *

+ * Example:

+     * Factory create = new Factory();
+     *
+     * create.select(fields)
+     *       .from(table1)
+     *       .join(table2).on(field1.equal(field2))
+     *       .where(field1.greaterThan(100))
+     *       .orderBy(field2);
+     * 
+ * + * @see Factory#select(Collection) + */ + @Support + SelectSelectStep select(Collection> fields); + + /** + * Create a new DSL select statement. + *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#selectDistinct(Field...)} instead. + *

+ * Example:

+     * Factory create = new Factory();
+     *
+     * create.selectDistinct(field1, field2)
+     *       .from(table1)
+     *       .join(table2).on(field1.equal(field2))
+     *       .where(field1.greaterThan(100))
+     *       .orderBy(field2);
+     * 
+ * + * @see Factory#selectDistinct(Field...) + */ + @Support + SelectSelectStep selectDistinct(Field... fields); + + /** + * Create a new DSL select statement. + *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#selectDistinct(Collection)} instead. + *

+ * Example:

+     * Factory create = new Factory();
+     *
+     * create.selectDistinct(fields)
+     *       .from(table1)
+     *       .join(table2).on(field1.equal(field2))
+     *       .where(field1.greaterThan(100))
+     *       .orderBy(field2);
+     * 
+ * + * @see Factory#selectDistinct(Collection) + */ + @Support + SelectSelectStep selectDistinct(Collection> fields); + /** * Create a new DSL select statement for constant 0 literal *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#selectZero()} instead. + *

* Example:

      * Factory create = new Factory();
      *
@@ -352,6 +438,7 @@ public interface FactoryOperations extends Configuration {
      * 
* * @see Factory#zero() + * @see Factory#selectZero() */ @Support SelectSelectStep selectZero(); @@ -359,6 +446,12 @@ public interface FactoryOperations extends Configuration { /** * Create a new DSL select statement for constant 1 literal *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#selectOne()} instead. + *

* Example:

      * Factory create = new Factory();
      *
@@ -371,6 +464,7 @@ public interface FactoryOperations extends Configuration {
      * 
* * @see Factory#one() + * @see Factory#selectOne() */ @Support SelectSelectStep selectOne(); @@ -378,6 +472,12 @@ public interface FactoryOperations extends Configuration { /** * Create a new DSL select statement for COUNT(*) *

+ * This creates an attached, renderable and executable SELECT + * statement from this {@link Executor}. If you don't need to render or + * execute this SELECT statement (e.g. because you want to + * create a subselect), consider using the static + * {@link Factory#selectCount()} instead. + *

* Example:

      * Factory create = new Factory();
      *
@@ -388,58 +488,12 @@ public interface FactoryOperations extends Configuration {
      *       .orderBy(field2)
      *       .execute();
      * 
+ * + * @see Factory#selectCount() */ @Support SelectSelectStep selectCount(); - /** - * Create a new DSL select statement. - *

- * Example:

-     * Factory create = new Factory();
-     *
-     * create.selectDistinct(field1, field2)
-     *       .from(table1)
-     *       .join(table2).on(field1.equal(field2))
-     *       .where(field1.greaterThan(100))
-     *       .orderBy(field2);
-     * 
- */ - @Support - SelectSelectStep selectDistinct(Field... fields); - - /** - * Create a new DSL select statement. - *

- * Example:

-     * Factory create = new Factory();
-     *
-     * create.select(fields)
-     *       .from(table1)
-     *       .join(table2).on(field1.equal(field2))
-     *       .where(field1.greaterThan(100))
-     *       .orderBy(field2);
-     * 
- */ - @Support - SelectSelectStep select(Collection> fields); - - /** - * Create a new DSL select statement. - *

- * Example:

-     * Factory create = new Factory();
-     *
-     * create.selectDistinct(fields)
-     *       .from(table1)
-     *       .join(table2).on(field1.equal(field2))
-     *       .where(field1.greaterThan(100))
-     *       .orderBy(field2);
-     * 
- */ - @Support - SelectSelectStep selectDistinct(Collection> fields); - /** * Create a new {@link SelectQuery} */ diff --git a/jOOQ/src/main/java/org/jooq/impl/Executor.java b/jOOQ/src/main/java/org/jooq/impl/Executor.java index 8449cdeb0d..01ca0118d3 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Executor.java +++ b/jOOQ/src/main/java/org/jooq/impl/Executor.java @@ -37,12 +37,9 @@ package org.jooq.impl; import static org.jooq.conf.SettingsTools.getRenderMapping; -import static org.jooq.impl.Factory.count; import static org.jooq.impl.Factory.field; import static org.jooq.impl.Factory.fieldByName; -import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.trueCondition; -import static org.jooq.impl.Factory.zero; import java.io.IOException; import java.io.StringReader; @@ -114,6 +111,8 @@ import org.jooq.tools.JooqLogger; import org.jooq.tools.csv.CSVReader; /** + * TODO: Review this Javadoc + *

* A factory providing implementations to the org.jooq interfaces *

* This factory is the main entry point for client code, to access jOOQ classes @@ -1066,39 +1065,9 @@ public class Executor implements FactoryOperations { */ @Override public final SelectSelectStep select(Field... fields) { - return new SelectImpl(this).select(fields); - } - - /** - * {@inheritDoc} - */ - @Override - public final SelectSelectStep selectZero() { - return new SelectImpl(this).select(zero()); - } - - /** - * {@inheritDoc} - */ - @Override - public final SelectSelectStep selectOne() { - return new SelectImpl(this).select(one()); - } - - /** - * {@inheritDoc} - */ - @Override - public final SelectSelectStep selectCount() { - return new SelectImpl(this).select(count()); - } - - /** - * {@inheritDoc} - */ - @Override - public final SelectSelectStep selectDistinct(Field... fields) { - return new SelectImpl(this, true).select(fields); + SelectSelectStep result = Factory.select(fields); + result.attach(this); + return result; } /** @@ -1106,7 +1075,19 @@ public class Executor implements FactoryOperations { */ @Override public final SelectSelectStep select(Collection> fields) { - return new SelectImpl(this).select(fields); + SelectSelectStep result = Factory.select(fields); + result.attach(this); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public final SelectSelectStep selectDistinct(Field... fields) { + SelectSelectStep result = Factory.selectDistinct(fields); + result.attach(this); + return result; } /** @@ -1114,7 +1095,39 @@ public class Executor implements FactoryOperations { */ @Override public final SelectSelectStep selectDistinct(Collection> fields) { - return new SelectImpl(this, true).select(fields); + SelectSelectStep result = Factory.selectDistinct(fields); + result.attach(this); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public final SelectSelectStep selectZero() { + SelectSelectStep result = Factory.selectZero(); + result.attach(this); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public final SelectSelectStep selectOne() { + SelectSelectStep result = Factory.selectOne(); + result.attach(this); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public final SelectSelectStep selectCount() { + SelectSelectStep result = Factory.selectCount(); + result.attach(this); + return result; } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/Factory.java b/jOOQ/src/main/java/org/jooq/impl/Factory.java index 431a2e5159..22ba5f5470 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Factory.java +++ b/jOOQ/src/main/java/org/jooq/impl/Factory.java @@ -49,6 +49,7 @@ import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.SQLDialect.SYBASE; +import static org.jooq.impl.DefaultConfiguration.DEFAULT_CONFIGURATION; import static org.jooq.impl.Term.ROW_NUMBER; import static org.jooq.impl.Utils.combine; @@ -91,6 +92,7 @@ import org.jooq.RowN; import org.jooq.SQLDialect; import org.jooq.Schema; import org.jooq.Select; +import org.jooq.SelectSelectStep; import org.jooq.Support; import org.jooq.Table; import org.jooq.UDTRecord; @@ -106,6 +108,230 @@ import org.jooq.types.DayToSecond; */ public class Factory { + // ------------------------------------------------------------------------- + // XXX Static subselect factory methods + // ------------------------------------------------------------------------- + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * select(field1, field2)
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see FactoryOperations#select(Field...) + */ + @Support + public static SelectSelectStep select(Field... fields) { + return new SelectImpl(DEFAULT_CONFIGURATION).select(fields); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * select(fields)
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see FactoryOperations#select(Collection) + */ + @Support + public static SelectSelectStep select(Collection> fields) { + return new SelectImpl(DEFAULT_CONFIGURATION).select(fields); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * selectDistinct(field1, field2)
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see FactoryOperations#selectDistinct(Field...) + */ + @Support + public static SelectSelectStep selectDistinct(Field... fields) { + return new SelectImpl(DEFAULT_CONFIGURATION, true).select(fields); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * selectDistinct(fields)
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see FactoryOperations#selectDistinct(Collection) + */ + @Support + public static SelectSelectStep selectDistinct(Collection> fields) { + return new SelectImpl(DEFAULT_CONFIGURATION, true).select(fields); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * selectZero()
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see Factory#zero() + * @see FactoryOperations#selectZero() + */ + @Support + public static SelectSelectStep selectZero() { + return new SelectImpl(DEFAULT_CONFIGURATION).select(zero()); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * selectOne()
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see Factory#one() + * @see FactoryOperations#selectOne() + */ + @Support + public static SelectSelectStep selectOne() { + return new SelectImpl(DEFAULT_CONFIGURATION).select(one()); + } + + /** + * Create a new DSL subselect statement. + *

+ * Unlike {@link Select} factory methods in the {@link Executor} API, this + * creates an unattached, and thus not directly renderable or executable + * SELECT statement. You can use this statement in two ways: + *

    + *
  • As a subselect within another select
  • + *
  • As a statement, after attaching it using + * {@link Select#attach(org.jooq.Configuration)}
  • + *
+ *

+ * Example:

+     * import static org.jooq.impl.Factory.*;
+     *
+     * // [...]
+     *
+     * selectCount()
+     *  .from(table1)
+     *  .join(table2).on(field1.equal(field2))
+     *  .where(field1.greaterThan(100))
+     *  .orderBy(field2);
+     * 
+ * + * @see Factory#count() + * @see FactoryOperations#selectCount() + */ + @Support + public static SelectSelectStep selectCount() { + return new SelectImpl(DEFAULT_CONFIGURATION).select(count()); + } + // ------------------------------------------------------------------------- // XXX Quantified comparison predicate expressions // -------------------------------------------------------------------------