From 74fcb4406065daee253dc138a61b67cd9c06db23 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 7 May 2020 14:35:17 +0200 Subject: [PATCH] [jOOQ/jOOQ#6256] Add jOOQ-kotlin This commit includes a first draft of Extensions.kt to improve the Kotlin/jOOQ experience. More work to be added soon --- jOOQ-examples/jOOQ-kotlin-example/pom.xml | 25 +- jOOQ-kotlin/.gitignore | 6 + jOOQ-kotlin/LICENSE.txt | 19 + jOOQ-kotlin/NOTICE.txt | 10 + jOOQ-kotlin/pom.xml | 80 +++++ .../main/kotlin/org/jooq/kotlin/Extensions.kt | 336 ++++++++++++++++++ .../src/main/resources/META-INF/LICENSE.txt | 19 + .../src/main/resources/META-INF/README.txt | 2 + .../kotlin/org/jooq/kotlin/ExtensionsTest.kt | 71 ++++ jOOQ-kotlin/src/test/resources/db.sql | 40 +++ jOOQ-kotlin/src/test/resources/log4j2.xml | 14 + pom.xml | 67 +++- 12 files changed, 676 insertions(+), 13 deletions(-) create mode 100644 jOOQ-kotlin/.gitignore create mode 100644 jOOQ-kotlin/LICENSE.txt create mode 100644 jOOQ-kotlin/NOTICE.txt create mode 100644 jOOQ-kotlin/pom.xml create mode 100644 jOOQ-kotlin/src/main/kotlin/org/jooq/kotlin/Extensions.kt create mode 100644 jOOQ-kotlin/src/main/resources/META-INF/LICENSE.txt create mode 100644 jOOQ-kotlin/src/main/resources/META-INF/README.txt create mode 100644 jOOQ-kotlin/src/test/kotlin/org/jooq/kotlin/ExtensionsTest.kt create mode 100644 jOOQ-kotlin/src/test/resources/db.sql create mode 100644 jOOQ-kotlin/src/test/resources/log4j2.xml diff --git a/jOOQ-examples/jOOQ-kotlin-example/pom.xml b/jOOQ-examples/jOOQ-kotlin-example/pom.xml index cdd5a4d8dc..b8d421cabb 100644 --- a/jOOQ-examples/jOOQ-kotlin-example/pom.xml +++ b/jOOQ-examples/jOOQ-kotlin-example/pom.xml @@ -29,36 +29,40 @@ - org.jooq jooq - ${project.version} - com.h2database - h2 - ${org.h2.version} + org.jooq + jooq-kotlin org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} + kotlin-stdlib + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 org.jetbrains.kotlin kotlin-reflect - ${kotlin.version} + + + + + com.h2database + h2 junit junit - 4.13 jar test @@ -105,7 +109,6 @@ org.codehaus.mojo sql-maven-plugin - 1.5 ${maven.test.skip} @@ -145,7 +148,6 @@ org.jooq jooq-codegen-maven - ${project.version} @@ -182,7 +184,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 diff --git a/jOOQ-kotlin/.gitignore b/jOOQ-kotlin/.gitignore new file mode 100644 index 0000000000..41b88d42d8 --- /dev/null +++ b/jOOQ-kotlin/.gitignore @@ -0,0 +1,6 @@ +/target + +/.cache + +/.idea +/*.iml \ No newline at end of file diff --git a/jOOQ-kotlin/LICENSE.txt b/jOOQ-kotlin/LICENSE.txt new file mode 100644 index 0000000000..d090694f44 --- /dev/null +++ b/jOOQ-kotlin/LICENSE.txt @@ -0,0 +1,19 @@ +Licensed 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. + +Other licenses: +----------------------------------------------------------------------------- +Commercial licenses for this work are available. These replace the above +ASL 2.0 and offer limited warranties, support, maintenance, and commercial +database integrations. + +For more information, please visit: http://www.jooq.org/licenses \ No newline at end of file diff --git a/jOOQ-kotlin/NOTICE.txt b/jOOQ-kotlin/NOTICE.txt new file mode 100644 index 0000000000..698edf47ee --- /dev/null +++ b/jOOQ-kotlin/NOTICE.txt @@ -0,0 +1,10 @@ +Third party NOTICE.txt contents +=============================== + +Contents of https://github.com/apache/commons-lang/blob/master/NOTICE.txt +------------------------------------------------------------------------- +Apache Commons Lang +Copyright 2001-2019 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/jOOQ-kotlin/pom.xml b/jOOQ-kotlin/pom.xml new file mode 100644 index 0000000000..ee51167e93 --- /dev/null +++ b/jOOQ-kotlin/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + + org.jooq + jooq-parent + 3.14.0-SNAPSHOT + + + jooq-kotlin + jOOQ Kotlin + + + src/main/kotlin + src/test/kotlin + + + kotlin-maven-plugin + org.jetbrains.kotlin + + + + + org.apache.maven.plugins + maven-jar-plugin + + + empty-javadoc-jar + package + + jar + + + javadoc + ${basedir}/javadoc + + + org.jooq.kotlin + + + + + + + + + + + + org.jooq + jooq + + + + org.jetbrains.kotlin + kotlin-stdlib + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + + + + + org.jetbrains.kotlin + kotlin-reflect + + + + + + + + + + + \ No newline at end of file diff --git a/jOOQ-kotlin/src/main/kotlin/org/jooq/kotlin/Extensions.kt b/jOOQ-kotlin/src/main/kotlin/org/jooq/kotlin/Extensions.kt new file mode 100644 index 0000000000..34923fc3e3 --- /dev/null +++ b/jOOQ-kotlin/src/main/kotlin/org/jooq/kotlin/Extensions.kt @@ -0,0 +1,336 @@ +package org.jooq.kotlin + +import org.jooq.* +import org.jooq.conf.Settings +import org.jooq.impl.DSL +import org.jooq.impl.DSL.field +import java.util.* + +@Support +inline fun Result.into(): MutableList { + return this.into(T::class.java) +} + +// ---------------------------------------------------------------------------- +// Class reification extensions +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Field extensions +// ---------------------------------------------------------------------------- + +@Support +inline fun Select>.`as`(alias: String): Field { + return field(this).`as`(alias); +} + +@Support +inline fun Select>.`as`(alias: Name): Field { + return field(this).`as`(alias); +} + +@Support +inline fun Select>.`as`(alias: Field<*>): Field { + return field(this).`as`(alias); +} + +@Support +inline fun Select>.eq(value: T): Condition { + return field(this).eq(value); +} + +@Support +inline fun Select>.eq(value: Field): Condition { + return field(this).eq(value); +} + +@Support +inline fun Select>.eq(value: Select>): Condition { + return field(this).eq(value); +} + +@Support +inline fun Select>.eq(value: QuantifiedSelect>): Condition { + return field(this).eq(value); +} + +@Support +inline fun Select>.equal(value: T): Condition { + return field(this).equal(value); +} + +@Support +inline fun Select>.equal(value: Field): Condition { + return field(this).equal(value); +} + +@Support +inline fun Select>.equal(value: Select>): Condition { + return field(this).equal(value); +} + +@Support +inline fun Select>.equal(value: QuantifiedSelect>): Condition { + return field(this).equal(value); +} + +@Support +inline fun Select>.ne(value: T): Condition { + return field(this).ne(value); +} + +@Support +inline fun Select>.ne(value: Field): Condition { + return field(this).ne(value); +} + +@Support +inline fun Select>.ne(value: Select>): Condition { + return field(this).ne(value); +} + +@Support +inline fun Select>.ne(value: QuantifiedSelect>): Condition { + return field(this).ne(value); +} + +@Support +inline fun Select>.notEqual(value: T): Condition { + return field(this).notEqual(value); +} + +@Support +inline fun Select>.notEqual(value: Field): Condition { + return field(this).notEqual(value); +} + +@Support +inline fun Select>.notEqual(value: Select>): Condition { + return field(this).notEqual(value); +} + +@Support +inline fun Select>.notEqual(value: QuantifiedSelect>): Condition { + return field(this).notEqual(value); +} + +@Support +inline fun Select>.gt(value: T): Condition { + return field(this).gt(value); +} + +@Support +inline fun Select>.gt(value: Field): Condition { + return field(this).gt(value); +} + +@Support +inline fun Select>.gt(value: Select>): Condition { + return field(this).gt(value); +} + +@Support +inline fun Select>.gt(value: QuantifiedSelect>): Condition { + return field(this).gt(value); +} + +@Support +inline fun Select>.greaterThan(value: T): Condition { + return field(this).greaterThan(value); +} + +@Support +inline fun Select>.greaterThan(value: Field): Condition { + return field(this).greaterThan(value); +} + +@Support +inline fun Select>.greaterThan(value: Select>): Condition { + return field(this).greaterThan(value); +} + +@Support +inline fun Select>.greaterThan(value: QuantifiedSelect>): Condition { + return field(this).greaterThan(value); +} + +@Support +inline fun Select>.ge(value: T): Condition { + return field(this).ge(value); +} + +@Support +inline fun Select>.ge(value: Field): Condition { + return field(this).ge(value); +} + +@Support +inline fun Select>.ge(value: Select>): Condition { + return field(this).ge(value); +} + +@Support +inline fun Select>.ge(value: QuantifiedSelect>): Condition { + return field(this).ge(value); +} + +@Support +inline fun Select>.greaterOrEqual(value: T): Condition { + return field(this).greaterOrEqual(value); +} + +@Support +inline fun Select>.greaterOrEqual(value: Field): Condition { + return field(this).greaterOrEqual(value); +} + +@Support +inline fun Select>.greaterOrEqual(value: Select>): Condition { + return field(this).greaterOrEqual(value); +} + +@Support +inline fun Select>.greaterOrEqual(value: QuantifiedSelect>): Condition { + return field(this).greaterOrEqual(value); +} + +@Support +inline fun Select>.lt(value: T): Condition { + return field(this).lt(value); +} + +@Support +inline fun Select>.lt(value: Field): Condition { + return field(this).lt(value); +} + +@Support +inline fun Select>.lt(value: Select>): Condition { + return field(this).lt(value); +} + +@Support +inline fun Select>.lt(value: QuantifiedSelect>): Condition { + return field(this).lt(value); +} + +@Support +inline fun Select>.lessThan(value: T): Condition { + return field(this).lessThan(value); +} + +@Support +inline fun Select>.lessThan(value: Field): Condition { + return field(this).lessThan(value); +} + +@Support +inline fun Select>.lessThan(value: Select>): Condition { + return field(this).lessThan(value); +} + +@Support +inline fun Select>.lessThan(value: QuantifiedSelect>): Condition { + return field(this).lessThan(value); +} + +@Support +inline fun Select>.le(value: T): Condition { + return field(this).le(value); +} + +@Support +inline fun Select>.le(value: Field): Condition { + return field(this).le(value); +} + +@Support +inline fun Select>.le(value: Select>): Condition { + return field(this).le(value); +} + +@Support +inline fun Select>.le(value: QuantifiedSelect>): Condition { + return field(this).le(value); +} + +@Support +inline fun Select>.lessOrEqual(value: T): Condition { + return field(this).lessOrEqual(value); +} + +@Support +inline fun Select>.lessOrEqual(value: Field): Condition { + return field(this).lessOrEqual(value); +} + +@Support +inline fun Select>.lessOrEqual(value: Select>): Condition { + return field(this).lessOrEqual(value); +} + +@Support +inline fun Select>.lessOrEqual(value: QuantifiedSelect>): Condition { + return field(this).lessOrEqual(value); +} + +@Support +inline fun Select>.asc(): SortField { + return field(this).asc(); +} + +@Support +inline fun Select>.desc(): SortField { + return field(this).desc(); +} + +@Support +inline fun Select>.`in`(values: Collection<*>): Condition { + return field(this).`in`(values) +} + +@Support +inline fun Select>.`in`(values: Result>): Condition { + return field(this).`in`(values) +} + +@Support +inline fun Select>.`in`(vararg values: T): Condition { + return field(this).`in`(values.asList()) +} + +@Support +inline fun Select>.`in`(vararg values: Field<*>): Condition { + return field(this).`in`(values.asList()) +} + +@Support +inline fun Select>.`in`(query: Select>): Condition { + return field(this).`in`(query) +} + +@Support +inline fun Select>.notIn(values: Collection<*>): Condition { + return field(this).notIn(values) +} + +@Support +inline fun Select>.notIn(values: Result>): Condition { + return field(this).notIn(values) +} + +@Support +inline fun Select>.notIn(vararg values: T): Condition { + return field(this).notIn(values.asList()) +} + +@Support +inline fun Select>.notIn(vararg values: Field<*>): Condition { + return field(this).notIn(values.asList()) +} + +@Support +inline fun Select>.notIn(query: Select>): Condition { + return field(this).notIn(query) +} + diff --git a/jOOQ-kotlin/src/main/resources/META-INF/LICENSE.txt b/jOOQ-kotlin/src/main/resources/META-INF/LICENSE.txt new file mode 100644 index 0000000000..d090694f44 --- /dev/null +++ b/jOOQ-kotlin/src/main/resources/META-INF/LICENSE.txt @@ -0,0 +1,19 @@ +Licensed 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. + +Other licenses: +----------------------------------------------------------------------------- +Commercial licenses for this work are available. These replace the above +ASL 2.0 and offer limited warranties, support, maintenance, and commercial +database integrations. + +For more information, please visit: http://www.jooq.org/licenses \ No newline at end of file diff --git a/jOOQ-kotlin/src/main/resources/META-INF/README.txt b/jOOQ-kotlin/src/main/resources/META-INF/README.txt new file mode 100644 index 0000000000..3e6e227e05 --- /dev/null +++ b/jOOQ-kotlin/src/main/resources/META-INF/README.txt @@ -0,0 +1,2 @@ +Thanks for downloading jOOQ. +Please visit http://www.jooq.org for more information. \ No newline at end of file diff --git a/jOOQ-kotlin/src/test/kotlin/org/jooq/kotlin/ExtensionsTest.kt b/jOOQ-kotlin/src/test/kotlin/org/jooq/kotlin/ExtensionsTest.kt new file mode 100644 index 0000000000..34d5f9ffa4 --- /dev/null +++ b/jOOQ-kotlin/src/test/kotlin/org/jooq/kotlin/ExtensionsTest.kt @@ -0,0 +1,71 @@ +package org.jooq.kotlin + +import org.jooq.SQLDialect +import org.jooq.SQLDialect.H2 +import org.jooq.impl.DSL +import org.jooq.impl.DSL.* +import org.jooq.impl.SQLDataType +import org.jooq.impl.SQLDataType.INTEGER +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runners.MethodSorters + +import kotlin.io.* + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class ExtensionsTest { + + val i = field(unquotedName("i"), INTEGER) + val j = field(unquotedName("j"), INTEGER) + val dsl = DSL.using(H2) + + @Test + fun testScalarSubqueries() { + assertEquals(field(select(i)).`as`("i"), select(i).`as`("i")) + assertEquals(field(select(i)).`as`(name("i")), select(i).`as`(name("i"))) + assertEquals(field(select(i)).`as`(i), select(i).`as`(i)) + + assertEquals(field(select(i)).eq(1), select(i).eq(1)) + assertEquals(field(select(i)).eq(value(1)), select(i).eq(value(1))) + assertEquals(field(select(i)).eq(select(value(1))), select(i).eq(select(value(1)))) + assertEquals(field(select(i)).eq(any(select(value(1)))), select(i).eq(any(select(value(1))))) + + assertEquals(field(select(i)).ne(1), select(i).ne(1)) + assertEquals(field(select(i)).ne(value(1)), select(i).ne(value(1))) + assertEquals(field(select(i)).ne(select(value(1))), select(i).ne(select(value(1)))) + assertEquals(field(select(i)).ne(any(select(value(1)))), select(i).ne(any(select(value(1))))) + + assertEquals(field(select(i)).gt(1), select(i).gt(1)) + assertEquals(field(select(i)).gt(value(1)), select(i).gt(value(1))) + assertEquals(field(select(i)).gt(select(value(1))), select(i).gt(select(value(1)))) + assertEquals(field(select(i)).gt(any(select(value(1)))), select(i).gt(any(select(value(1))))) + + assertEquals(field(select(i)).ge(1), select(i).ge(1)) + assertEquals(field(select(i)).ge(value(1)), select(i).ge(value(1))) + assertEquals(field(select(i)).ge(select(value(1))), select(i).ge(select(value(1)))) + assertEquals(field(select(i)).ge(any(select(value(1)))), select(i).ge(any(select(value(1))))) + + assertEquals(field(select(i)).lt(1), select(i).lt(1)) + assertEquals(field(select(i)).lt(value(1)), select(i).lt(value(1))) + assertEquals(field(select(i)).lt(select(value(1))), select(i).lt(select(value(1)))) + assertEquals(field(select(i)).lt(any(select(value(1)))), select(i).lt(any(select(value(1))))) + + assertEquals(field(select(i)).le(1), select(i).le(1)) + assertEquals(field(select(i)).le(value(1)), select(i).le(value(1))) + assertEquals(field(select(i)).le(select(value(1))), select(i).le(select(value(1)))) + assertEquals(field(select(i)).le(any(select(value(1)))), select(i).le(any(select(value(1))))) + + assertEquals(field(select(i)).asc(), select(i).asc()) + assertEquals(field(select(i)).desc(), select(i).desc()) + + assertEquals(field(select(i)).`in`(1, 2), select(i).`in`(1, 2)) + assertEquals(field(select(i)).`in`(value(1), value(2)), select(i).`in`(value(1), value(2))) + assertEquals(field(select(i)).`in`(select(value(1))), select(i).`in`(select(value(1)))) + + assertEquals(field(select(i)).notIn(1, 2), select(i).notIn(1, 2)) + assertEquals(field(select(i)).notIn(value(1), value(2)), select(i).notIn(value(1), value(2))) + assertEquals(field(select(i)).notIn(select(value(1))), select(i).notIn(select(value(1)))) + } +} \ No newline at end of file diff --git a/jOOQ-kotlin/src/test/resources/db.sql b/jOOQ-kotlin/src/test/resources/db.sql new file mode 100644 index 0000000000..05adcd4db1 --- /dev/null +++ b/jOOQ-kotlin/src/test/resources/db.sql @@ -0,0 +1,40 @@ +DROP TABLE IF EXISTS t_book; +DROP TABLE IF EXISTS t_author; +DROP SEQUENCE IF EXISTS s_author_id; +CREATE SEQUENCE s_author_id START WITH 1; + +CREATE TABLE t_author ( + id INT NOT NULL, + first_name VARCHAR(50), + last_name VARCHAR(50) NOT NULL, + date_of_birth DATE, + year_of_birth INT, + address VARCHAR(50), + + CONSTRAINT pk_t_author PRIMARY KEY (ID) +); + +CREATE TABLE t_book ( + id INT NOT NULL, + author_id INT NOT NULL, + details_id INT, + title VARCHAR(400) NOT NULL, + published_in INT NOT NULL, + language_id INT NOT NULL, + content_text CLOB, + content_pdf BLOB, + + rec_version INT, + rec_timestamp TIMESTAMP, + + CONSTRAINT pk_t_book PRIMARY KEY (id), + CONSTRAINT fk_t_book_author_id FOREIGN KEY (author_id) REFERENCES t_author(id) +); + +INSERT INTO t_author VALUES (next value for s_author_id, 'George', 'Orwell', '1903-06-25', 1903, null); +INSERT INTO t_author VALUES (next value for s_author_id, 'Paulo', 'Coelho', '1947-08-24', 1947, null); + +INSERT INTO t_book VALUES (1, 1, null, '1984', 1948, 1, 'To know and not to know, to be conscious of complete truthfulness while telling carefully constructed lies, to hold simultaneously two opinions which cancelled out, knowing them to be contradictory and believing in both of them, to use logic against logic, to repudiate morality while laying claim to it, to believe that democracy was impossible and that the Party was the guardian of democracy, to forget, whatever it was necessary to forget, then to draw it back into memory again at the moment when it was needed, and then promptly to forget it again, and above all, to apply the same process to the process itself -- that was the ultimate subtlety; consciously to induce unconsciousness, and then, once again, to become unconscious of the act of hypnosis you had just performed. Even to understand the word ''doublethink'' involved the use of doublethink..', null, 1, '2010-01-01 00:00:00'); +INSERT INTO t_book VALUES (2, 1, null, 'Animal Farm', 1945, 1, null, null, null, '2010-01-01 00:00:00'); +INSERT INTO t_book VALUES (3, 2, null, 'O Alquimista', 1988, 4, null, null, 1, null); +INSERT INTO t_book VALUES (4, 2, null, 'Brida', 1990, 2, null, null, null, null); diff --git a/jOOQ-kotlin/src/test/resources/log4j2.xml b/jOOQ-kotlin/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..f61aa0c50c --- /dev/null +++ b/jOOQ-kotlin/src/test/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7e3e1ae752..2174e44057 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,9 @@ 2.3.1 1.2.0 + + 1.3.72 + 2.2 @@ -100,6 +103,30 @@ jooq-meta-extensions ${project.version} + + org.jooq + jooq-kotlin + ${project.version} + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + + org.jooq jooq-scala_2.13 @@ -463,6 +490,44 @@ 4.3.0 + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + + compile + process-sources + + compile + + + + src/main/java + src/main/kotlin + src/main/resources + + + + + + + + + + + + + + + + + + + + + org.eclipse.xtend xtend-maven-plugin @@ -533,13 +598,13 @@ jOOQ-meta-extensions jOOQ-codegen jOOQ-codegen-maven + jOOQ-kotlin jOOQ-scala_2.13 - jOOQ-xtend