diff --git a/jOOQ-codegen-gradle/LICENSE.txt b/jOOQ-codegen-gradle/LICENSE.txt new file mode 100644 index 0000000000..60d18fae51 --- /dev/null +++ b/jOOQ-codegen-gradle/LICENSE.txt @@ -0,0 +1,33 @@ + Copyright (c) 2009-2013, 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. \ No newline at end of file diff --git a/jOOQ-codegen-gradle/README.md b/jOOQ-codegen-gradle/README.md new file mode 100644 index 0000000000..aa0a7abca6 --- /dev/null +++ b/jOOQ-codegen-gradle/README.md @@ -0,0 +1,48 @@ +# Gradle jOOQ Plugin + +[jOOQ](http://www.jooq.org) generates a simple Java representation of your database schema. +Every table, view, stored procedure, enum, UDT is a class. This plugin performs code generation +as part of the Gradle build. + +## Usage + +This plugin is hosted on the Maven Central Repository. All actions are logged at the `info` level. + +The configuration is defined as an XML DSL based on jOOQ's +[codegen schema](http://www.jooq.org/xsd/jooq-codegen-3.0.0.xsd). The default target directory is +updated to reflect Gradle's build directory (`build/generated-sources/jooq`). + +```groovy +apply plugin: 'jooq' + +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jooq:jooq-codegen-gradle:${versions.jOOQ}" + } +} + +jooq { + jdbc { + url 'jdbc:mysql://localhost:3306' + driver 'com.mysql.jdbc.Driver' + user 'root' + } + generator { + database { + name 'org.jooq.util.mysql.MySQLDatabase' + inputSchema 'example' + includes '.*' + } + } +} +``` + +## Tasks + +### `generateJooq` + +Executes the jOOQ [code generator](http://www.jooq.org/doc/3.0/manual/code-generation/). diff --git a/jOOQ-codegen-gradle/example/README.md b/jOOQ-codegen-gradle/example/README.md new file mode 100644 index 0000000000..6026cf06da --- /dev/null +++ b/jOOQ-codegen-gradle/example/README.md @@ -0,0 +1,7 @@ +This example shows how to combine jOOQ, [Flyway](http://flywaydb.org) database migrations, and the +[H2](http://www.h2database.com) embedded database to code generate during the build. This approach +allows developers to avoid checking generated code into source control and supports Gradle's +incremental building. The process optionally supports schema per project for service isolation. At +application runtime a traditional database can be used, such as Postgres, using the generated jOOQ +models. An alternative mapping library, [ModelMapper](http://modelmapper.org), is used to +demonstrate automatically projecting the record into a complex model. diff --git a/jOOQ-codegen-gradle/example/build.gradle b/jOOQ-codegen-gradle/example/build.gradle new file mode 100644 index 0000000000..2e3381dd46 --- /dev/null +++ b/jOOQ-codegen-gradle/example/build.gradle @@ -0,0 +1,78 @@ +apply plugin: 'java' +apply plugin: 'jooq' +apply plugin: 'flyway' + +buildscript { + repositories { + mavenLocal() + mavenCentral() + } + + dependencies { + classpath 'com.h2database:h2:1.3.170' + classpath 'com.github.ben-manes:gradle-flyway-plugin:0.6' + classpath 'org.jooq:jooq-codegen-gradle:latest.integration' + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.jooq:jooq:3.1.0' + compile 'com.google.guava:guava:14.0' + compile 'com.google.inject:guice:3.0' + + testCompile 'com.h2database:h2:1.3.170' + testCompile 'org.hamcrest:hamcrest-all:1.3' + testCompile 'org.modelmapper:modelmapper:0.5.5' + testCompile 'com.googlecode.flyway:flyway-core:2.1' + testCompile dependencies.create('org.testng:testng:6.8') { + exclude group: 'junit' + } +} + +test { + useTestNG() +} + +generateJooq.dependsOn(flywayMigrate) +compileJava.dependsOn(generateJooq) + +flyway { + databases { + main { + url = "jdbc:h2:${buildDir}/db/flyway" + schemas = [ 'example' ] + user = 'su' + } + } +} + +generateJooq { + outputs.upToDateWhen { + !flywayMigrate.didWork + } +} + +jooq { + jdbc { + url "jdbc:h2:${buildDir}/db/flyway" + driver 'org.h2.Driver' + user 'su' + } + generator { + database { + name 'org.jooq.util.h2.H2Database' + inputSchema 'example' + includes '.*' + } + generate { + deprecated false + } + target { + packageName 'example.generated' + } + } +} diff --git a/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.jar b/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..a7634b071c Binary files /dev/null and b/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.jar differ diff --git a/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.properties b/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..a0f8de8b06 --- /dev/null +++ b/jOOQ-codegen-gradle/example/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Jul 02 12:36:46 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip diff --git a/jOOQ-codegen-gradle/example/gradlew b/jOOQ-codegen-gradle/example/gradlew new file mode 100755 index 0000000000..91a7e269e1 --- /dev/null +++ b/jOOQ-codegen-gradle/example/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/jOOQ-codegen-gradle/example/gradlew.bat b/jOOQ-codegen-gradle/example/gradlew.bat new file mode 100644 index 0000000000..aec99730b4 --- /dev/null +++ b/jOOQ-codegen-gradle/example/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/jOOQ-codegen-gradle/example/settings.gradle b/jOOQ-codegen-gradle/example/settings.gradle new file mode 100644 index 0000000000..dec58e646b --- /dev/null +++ b/jOOQ-codegen-gradle/example/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'gradle-jooq-example' diff --git a/jOOQ-codegen-gradle/example/src/main/java/example/JooqModule.java b/jOOQ-codegen-gradle/example/src/main/java/example/JooqModule.java new file mode 100644 index 0000000000..38b9e6f71e --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/main/java/example/JooqModule.java @@ -0,0 +1,55 @@ +/* + * Copyright 2013 Ben Manes. All Rights Reserved. + * + * 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. + */ +package example; + +import javax.sql.DataSource; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.google.inject.Singleton; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.conf.Settings; +import org.jooq.impl.DSL; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A module that configures JOOQ. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +public final class JooqModule extends AbstractModule { + private final SQLDialect dialect; + private final Settings setting; + + public JooqModule() { + this(SQLDialect.H2, new Settings().withRenderSchema(false)); + } + + public JooqModule(SQLDialect dialect, Settings setting) { + this.dialect = checkNotNull(dialect); + this.setting = checkNotNull(setting); + } + + @Override + protected void configure() {} + + @Provides @Singleton + DSLContext providesDSLContext(DataSource dataSource) { + return DSL.using(dataSource, dialect, setting); + } +} diff --git a/jOOQ-codegen-gradle/example/src/main/resources/db/migration/V1__Add_table.sql b/jOOQ-codegen-gradle/example/src/main/resources/db/migration/V1__Add_table.sql new file mode 100644 index 0000000000..379faae7f0 --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/main/resources/db/migration/V1__Add_table.sql @@ -0,0 +1,7 @@ +CREATE TABLE user ( + id INT PRIMARY KEY AUTO_INCREMENT, + first_name VARCHAR(255) NOT NULL, + last_name VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX name_idx ON user (first_name, last_name); diff --git a/jOOQ-codegen-gradle/example/src/test/java/example/H2Module.java b/jOOQ-codegen-gradle/example/src/test/java/example/H2Module.java new file mode 100644 index 0000000000..3e9f616b20 --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/test/java/example/H2Module.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Ben Manes. All Rights Reserved. + * + * 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. + */ +package example; + +import java.util.concurrent.atomic.AtomicInteger; + +import javax.sql.DataSource; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.googlecode.flyway.core.Flyway; +import org.h2.jdbcx.JdbcDataSource; + +/** + * A module that configures the H2 data source. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +public class H2Module extends AbstractModule { + private static final String URL = "jdbc:h2:mem:test_%d;DB_CLOSE_DELAY=-1"; + private static final AtomicInteger counter = new AtomicInteger(); + + @Override + protected void configure() {} + + @Provides + DataSource providesDataSource() { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setURL(String.format(URL, counter.incrementAndGet())); + + Flyway flyway = new Flyway(); + flyway.setDataSource(dataSource); + flyway.migrate(); + + return dataSource; + } +} diff --git a/jOOQ-codegen-gradle/example/src/test/java/example/JooqTest.java b/jOOQ-codegen-gradle/example/src/test/java/example/JooqTest.java new file mode 100644 index 0000000000..2eae01cde9 --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/test/java/example/JooqTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2013 Ben Manes. All Rights Reserved. + * + * 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. + */ +package example; + +import java.util.List; + +import com.google.inject.Inject; +import example.generated.tables.records.UserRecord; +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.RecordMapper; +import org.modelmapper.ModelMapper; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static example.generated.tables.User.USER; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; + +/** + * @author Ben Manes (ben.manes@gmail.com) + */ +@Guice(modules = {JooqModule.class, H2Module.class}) +public final class JooqTest { + @Inject DSLContext db; + @Inject ModelMapper mapper; + RecordMapper recordMapper; + + @BeforeClass + public void beforeClass() { + recordMapper = new RecordMapper() { + @Override public User map(Record record) { + return mapper.map(record, User.class); + } + }; + } + + @AfterMethod + public void afterMethod() { + db.truncate(USER).execute(); + } + + @Test + public void select() { + User john = insertUser("John", "Doe"); + User user = db.selectFrom(USER) + .where(USER.FIRST_NAME.equal("John")) + .fetchOne().map(recordMapper); + assertThat(user, is(john)); + } + + @Test + public void selectAll() { + User john = insertUser("John", "Doe"); + User jane = insertUser("Jane", "Doe"); + List users = db.selectFrom(USER).fetch().map(recordMapper); + assertThat(users, contains(john, jane)); + } + + @Test + public void insert() { + User john = insertUser("John", "Doe"); + assertThat(john.getId(), is(1)); + } + + @Test + public void update() { + User jane = insertUser("Jane", "Doe"); + jane.getName().setLastName("Smith"); + + UserRecord record = mapper.map(jane, UserRecord.class); + db.executeUpdate(record); + + User user = db.selectFrom(USER) + .where(USER.LAST_NAME.equal("Smith")) + .fetchOne().map(recordMapper); + assertThat(user, is(jane)); + } + + private User insertUser(String firstName, String lastName) { + UserRecord record = new UserRecord(); + record.setFirstName(firstName); + record.setLastName(lastName); + return db.insertInto(USER).set(record).returning().fetchOne().map(recordMapper); + } +} diff --git a/jOOQ-codegen-gradle/example/src/test/java/example/Name.java b/jOOQ-codegen-gradle/example/src/test/java/example/Name.java new file mode 100644 index 0000000000..54601bbb10 --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/test/java/example/Name.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013 Ben Manes. All Rights Reserved. + * + * 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. + */ +package example; + +import com.google.common.base.Objects; + +/** + * The application model of a user's name. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +public final class Name { + private String firstName; + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof Name)) { + return false; + } + Name name = (Name) o; + return Objects.equal(firstName, name.firstName) + && Objects.equal(lastName, name.lastName); + } + + @Override + public int hashCode() { + return Objects.hashCode(firstName, lastName); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("firstName", firstName) + .add("lastName", lastName) + .toString(); + } +} diff --git a/jOOQ-codegen-gradle/example/src/test/java/example/User.java b/jOOQ-codegen-gradle/example/src/test/java/example/User.java new file mode 100644 index 0000000000..0ed2817bd0 --- /dev/null +++ b/jOOQ-codegen-gradle/example/src/test/java/example/User.java @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Ben Manes. All Rights Reserved. + * + * 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. + */ +package example; + +import com.google.common.base.Objects; + +/** + * The application model of a user. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +final class User { + private Name name; + private int id; + + public User() { + this.name = new Name(); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Name getName() { + return name; + } + + public void setName(Name name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof User)) { + return false; + } + User user = (User) o; + return Objects.equal(id, user.id) + && Objects.equal(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("id", id) + .add("name", name) + .toString(); + } +} diff --git a/jOOQ-codegen-gradle/pom.xml b/jOOQ-codegen-gradle/pom.xml new file mode 100644 index 0000000000..2305125340 --- /dev/null +++ b/jOOQ-codegen-gradle/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + org.jooq + jooq-parent + 3.2.0-SNAPSHOT + + + jooq-codegen-gradle + ${project.artifactId} + jar + + + + org.jooq + jooq-codegen + + + org.jooq + jooq-meta + + + org.codehaus.groovy + groovy-all + 1.8.6 + provided + + + org.gradle + gradle-core + ${version.gradle} + provided + + + org.gradle + gradle-base-services + ${version.gradle} + provided + + + org.gradle + gradle-base-services-groovy + ${version.gradle} + provided + + + + + src/main/groovy + + + maven-compiler-plugin + 3.1 + + groovy-eclipse-compiler + + + + org.codehaus.groovy + groovy-eclipse-compiler + 2.8.0-01 + + + org.codehaus.groovy + groovy-eclipse-batch + 1.8.6-01 + + + + + + + diff --git a/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/GenerateJooqTask.groovy b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/GenerateJooqTask.groovy new file mode 100644 index 0000000000..6684460e28 --- /dev/null +++ b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/GenerateJooqTask.groovy @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2009-2013, 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.util.gradle + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction +import org.jooq.util.GenerationTool +import org.jooq.util.jaxb.Generator +import org.jooq.util.jaxb.Target + +/** + * A task that performs jOOQ code generation. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +class GenerateJooqTask extends DefaultTask { + def configuration + + GenerateJooqTask() { + description = 'Generates jOOQ Java classes.' + group = 'Build' + + project.afterEvaluate { + parseConfiguration() + outputs.dir configuration.generator.target.directory + project.sourceSets.main.java.srcDirs += [ configuration.generator.target.directory ] + } + } + + @TaskAction + def generateJooq() { + logger.info 'Using this configuration:\n{}', project.jooq.xml + GenerationTool.main(configuration); + } + + def parseConfiguration() { + configuration = GenerationTool.load(new ByteArrayInputStream(project.jooq.xml.getBytes('utf8'))) + if (useDefaultTargetDirectory()) { + gradleTargertDir() + } + } + + def useDefaultTargetDirectory() { + def parsed = new XmlParser().parseText(project.jooq.xml) + parsed.generator.target.directory.text().isEmpty() + } + + def gradleTargertDir() { + configuration.generator = configuration.generator ?: new Generator() + configuration.generator.target = configuration.generator.target ?: new Target() + configuration.generator.target.directory = "${project.buildDir}/generated-sources/jooq" + } +} diff --git a/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqExtension.groovy b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqExtension.groovy new file mode 100644 index 0000000000..75a4cc61d7 --- /dev/null +++ b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqExtension.groovy @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2009-2013, 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.util.gradle + +import groovy.xml.MarkupBuilder + +/** + * The configuration as an XML DSL matching jOOQ's schema. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +public class JooqExtension { + private def builder + private def printer + private def writer + private def done + + public JooqExtension() { + writer = new StringWriter() + printer = new IndentPrinter(writer) + builder = new MarkupBuilder(printer) + start() + } + + private def start() { + printer.incrementIndent() + printer.println('') + printer.printIndent() + } + + private def end() { + if (!done) { + done = true + printer.println('\n') + } + } + + def methodMissing(String name, args) { + builder.invokeMethod(name, args) + } + + def getXml() { + end() + writer.toString() + } +} diff --git a/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqPlugin.groovy b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqPlugin.groovy new file mode 100644 index 0000000000..4b8d70ffcd --- /dev/null +++ b/jOOQ-codegen-gradle/src/main/groovy/org/jooq/util/gradle/JooqPlugin.groovy @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2009-2013, 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.util.gradle; + +import org.gradle.api.Plugin +import org.gradle.api.Project + +/** + * Registers the plugin's tasks. + * + * @author Ben Manes (ben.manes@gmail.com) + */ +public class JooqPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.extensions.create('jooq', JooqExtension) + project.tasks.create('generateJooq', GenerateJooqTask) + } +} diff --git a/jOOQ-codegen-gradle/src/main/resources/META-INF/gradle-plugins/jooq.properties b/jOOQ-codegen-gradle/src/main/resources/META-INF/gradle-plugins/jooq.properties new file mode 100644 index 0000000000..7dca65417e --- /dev/null +++ b/jOOQ-codegen-gradle/src/main/resources/META-INF/gradle-plugins/jooq.properties @@ -0,0 +1 @@ +implementation-class=org.jooq.util.gradle.JooqPlugin diff --git a/pom.xml b/pom.xml index 34613753e8..25f27e68ba 100644 --- a/pom.xml +++ b/pom.xml @@ -130,6 +130,7 @@ jOOQ jOOQ-codegen + jOOQ-codegen-gradle jOOQ-codegen-maven @@ -137,6 +138,10 @@ jOOQ-scala + + 1.6 + + @@ -177,6 +182,27 @@ + + + maven-central + http://repo1.maven.org/maven2 + + + gradle + http://repo.gradle.org/gradle/libs-releases-local + + false + + + + gradle-workaround + http://flywaydb.org/repo + + false + + + + deploy ${project.artifactId}-${project.version}