Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for latest jOOQ version #91

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ subprojects {
ext.jdbiVer = '2.72'

ext.retrofitVer = '1.9.0'
ext.jooqVer = '3.6.4' // 3jooq.7.x support only Java 8+
ext.jooqJdk6Ver = '3.6.4' // jOOQ versions >= 3.7 only support Java 8+
ext.jooqJdk8Ver = '3.9.0'
ext.slf4jApiVer = '1.7.21'
ext.log4jVer = '1.2.17'
ext.guavaVer = '19.0'
Expand Down Expand Up @@ -403,7 +404,7 @@ project (':comsat-jersey-server') {

project (':comsat-jooq') {
dependencies {
compile "org.jooq:jooq:$jooqVer"
compile "org.jooq:jooq:$jooqJdk6Ver"
compile project (':comsat-jdbc')
testCompile project(':comsat-test-utils')
}
Expand Down Expand Up @@ -531,6 +532,7 @@ ext.javadocLinks = [
"http://square.github.io/retrofit/1.x/retrofit/",
"http://jdbi.org/apidocs/",
"http://www.jooq.org/javadoc/3.6.x/",
"http://www.jooq.org/javadoc/latest/",
"http://docs.oracle.com/javase/7/docs/api/",
"http://puniverse.github.io/quasar/javadoc/",
"http://google.github.io/guava/releases/19.0/api/docs/",
Expand Down
64 changes: 64 additions & 0 deletions comsat-jooq-java8/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
sourceSets {
jdk8 {
java {
srcDir 'src/main/java'
}

compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath
}
}

compileJdk8Java {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}

if (ext.java8) {
compileTestJava {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
else {
sourceSets {
test {
java {
exclude 'co/paralleluniverse/fibers/jooq/**'
}
}
}
}

dependencies {
compile "org.jooq:jooq:$jooqJdk8Ver"
compile project(':comsat-jdbc')
testCompile project(':comsat-test-utils')
}

// remove default artifact
configurations.runtime.artifacts.with { archives ->
archives.each {
archives.remove(it)
}
}

def ssets = []
if (ext.java8) {
ssets += sourceSets.jdk8
}

ssets.each { set ->
def jarTask = task("${set.name}Jar", type: Jar) {
from set.output
from { project.configurations["${set.name}Runtime"].collect { it.isDirectory() ? it : zipTree(it) } }
}

assemble.dependsOn jarTask

artifacts {
archives jarTask
archives sourcesJar
archives javadocJar
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* COMSAT
* Copyright (C) 2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.fibers.jooq;

import co.paralleluniverse.fibers.instrument.LogLevel;
import co.paralleluniverse.fibers.instrument.MethodDatabase;
import co.paralleluniverse.fibers.instrument.SimpleSuspendableClassifier;
import co.paralleluniverse.fibers.instrument.SuspendableClassifier;

/**
* Given classes and methodRegexps, Instrumenting all the extending methods in
* the scope of given package prefix.
*/
public class JooqClassifier implements SuspendableClassifier {
private static final String PKG_PREFIX = "org/jooq";
private String[][] methodsArray = {

{"java/sql/Connection", ".*"},
{"java/sql/Statement", ".*"},

{"java/util/Iterator", "hasNext"},
{"java/util/concurrent/ForkJoinPool", "managedBlock"},
{"java/util/concurrent/ForkJoinPool$ManagedBlocker", "block"},
{"java/util/function/Supplier", "get"},
{"java/util/function/Supplier", "get"},

{"org/jooq/BindContext", "bind", "bindValue", "bindValues"},
{"org/jooq/Binding", "get.*"},
{"org/jooq/Binding", "register", "get", "set"},
{"org/jooq/ConnectionProvider", "acquire", "release"},
{"org/jooq/Context", "visit", "bindValue"},
{"org/jooq/Cursor", "fetch.*", "hasNext"},
{"org/jooq/DSLContext", "fetch.*", "execute.*", "transaction.*"},
{"org/jooq/DeleteResultStep", "fetch.*"},
{"org/jooq/ExecuteContext", "connection"},
{"org/jooq/InsertResultStep", "fetch.*"},
{"org/jooq/Query", "execute"},
{"org/jooq/QueryPartInternal", "accept", "bind"},
{"org/jooq/ResultQuery", "getResult", "fetch.*"},
{"org/jooq/TransactionProvider", "begin", "rollback", "commit"},
{"org/jooq/TransactionalCallable", "run"},
{"org/jooq/TransactionalRunnable", "run"},
{"org/jooq/UpdateResultStep", "fetch.*"},

{"org/jooq/impl/AbstractBindContext", "bindValue0", "bindInternal"},
{"org/jooq/impl/AbstractContext", "visit0"},
{"org/jooq/impl/AbstractDMLQuery", "accept0", "selectReturning"},
{"org/jooq/impl/AbstractField", "accept"},
{"org/jooq/impl/AbstractQuery", "execute"},
{"org/jooq/impl/AbstractQuery", "prepare"},
{"org/jooq/impl/AbstractResultQuery", "getFields"},
{"org/jooq/impl/AbstractStoreQuery", "accept0"},
{"org/jooq/impl/CursorImpl", "close"},
{"org/jooq/impl/CursorImpl$CursorIterator", "fetch.*"},
{"org/jooq/impl/CursorImpl$CursorIterator", "hasNext"},
{"org/jooq/impl/CursorImpl$CursorIterator$CursorRecordInitialiser", "setValue"},
{"org/jooq/impl/CursorImpl$CursorResultSet", ".*"},
{"org/jooq/impl/DSL", "using"},
{"org/jooq/impl/DefaultConnectionProvider", "rollback", "commit", "getAutoCommit", "setAutoCommit", "setSavepoint", "releaseSavepoint"},
{"org/jooq/impl/DefaultTransactionProvider", "connection", "brace", "autoCommit", "setSavepoint"},
{"org/jooq/impl/InsertQueryImpl", "toSQLInsert"},
{"org/jooq/impl/MetaDataFieldProvider", "init"},
{"org/jooq/impl/RecordDelegate", "operate"},
{"org/jooq/impl/RecordOperation", "operate"},
{"org/jooq/impl/SelectQueryImpl", "toSQLReference0", "toSQLReferenceLimitDefault"},
{"org/jooq/impl/Tools", "consumeWarnings", "safeClose", "fetch.*", },
{"org/jooq/impl/Utils", "safeClose", "consumeWarnings", "fetch.*"},

{"org/jooq/tools/jdbc/JDBCUtils", "dialect", "safeClose", "wasNull"}
};

@Override
public MethodDatabase.SuspendableType isSuspendable (
MethodDatabase db,
String sourceName, String sourceDebugInfo,
boolean isInterface, String className, String superClassName, String[] interfaces,
String methodName, String methodDesc, String methodSignature, String[] methodExceptions
) {
// skipping ctors to avoid unnecessary instrumentation errors
if (methodName.charAt(0) == '<')
return null;

// declares given methods as supers
for (String[] susExtendables : methodsArray) {
if (className.equals(susExtendables[0]))
for (int i = 1; i < susExtendables.length; i++) {
if (methodName.matches(susExtendables[i])) {
if (db.isVerbose())
db.getLog().log(LogLevel.INFO, JooqClassifier.class.getName() + ": " + className + "." + methodName + " supersOrEqual " + susExtendables[0] + "." + susExtendables[i]);
return MethodDatabase.SuspendableType.SUSPENDABLE;
}
}
}

// declares extending classes in jooq packages as suspendables
if (!className.startsWith(PKG_PREFIX))
return null;
for (String[] susExtendables : methodsArray) {
if (SimpleSuspendableClassifier.extendsOrImplements(susExtendables[0], db, className, superClassName, interfaces))
for (int i = 1; i < susExtendables.length; i++) {
if (methodName.matches(susExtendables[i])) {
if (db.isVerbose())
db.getLog().log(LogLevel.INFO, JooqClassifier.class.getName() + ": " + className + "." + methodName + " extends " + susExtendables[0] + "." + susExtendables[i]);
return MethodDatabase.SuspendableType.SUSPENDABLE;
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
co.paralleluniverse.fibers.jooq.JooqClassifier
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package co.paralleluniverse.fibers.jooq;

/*
* COMSAT
* Copyright (C) 2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
import co.paralleluniverse.embedded.db.H2JdbcDatasource;
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.fibers.jdbc.FiberDataSource;
import co.paralleluniverse.strands.SuspendableRunnable;
import java.io.IOException;
import java.sql.Connection;
import java.util.Arrays;
import java.util.Collection;
import javax.sql.DataSource;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.RecordMapper;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.using;

import org.jooq.impl.DSL;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class JooqContextTest {

@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{H2JdbcDatasource.class},});
}
private final Class<? extends DataSource> dsCls;
private Connection conn;
private DSLContext ctx;

public JooqContextTest(Class<? extends DataSource> cls) {
this.dsCls = cls;
}

@Before
public void setUp() throws Exception {
DataSource dataSource = dsCls.newInstance();
// snippet creation
this.conn = FiberDataSource.wrap(dataSource).getConnection();
this.ctx = using(conn);
// end of snippet
conn.createStatement().execute("create table something (id int primary key, name varchar(100))");
}

@After
public void tearDown() throws Exception {
conn.createStatement().execute("drop table something");
conn.close();
}

@Test
public void testInsertSelect() throws IOException, InterruptedException, Exception {
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
// snippet usage
for (int i = 0; i < 100; i++)
ctx.insertInto(table("something"), field("id"), field("name")).values(i, "name" + i).execute();
for (int i = 0; i < 50; i++) {
Something something = ctx.select(field("id"), field("name")).from(table("something")).where(field("id", Integer.class).eq(i)).fetchOne().map(Something.mapper);
assertEquals("name" + i, something.name);
}
// end of snippet
}
}).start().join();
}

@Test
public void testTransaction() throws IOException, InterruptedException, Exception {
new Fiber<Void>((SuspendableRunnable) () -> {
// snippet usage
ctx.transaction((config) -> {
DSLContext innerCtx = DSL.using(config);
for (int i = 0; i < 100; i++)
innerCtx.insertInto(table("something"), field("id"), field("name")).values(i, "name" + i).execute();
});
// end of snippet
}).start().join();
}

// snippet mapper
public static class Something {
public final int id;
public final String name;
public static RecordMapper<Record, Something> mapper = new RecordMapper<Record, Something>() {
@Override
public Something map(Record r) {
return new Something(r.getValue(field("id", Integer.class)), r.getValue(field("name", String.class)));
}
};

public Something(int id, String name) {
this.id = id;
this.name = name;
}
}
// end of snippet
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
public class JooqClassifier implements SuspendableClassifier {
private static final String PKG_PREFIX = "org/jooq";
String[][] methodsArray = {
private String[][] methodsArray = {
{"java/util/Iterator", "hasNext"},
{"java/sql/Statement", ".*"},
{"java/sql/Connection", ".*"},
Expand Down Expand Up @@ -72,6 +72,10 @@ public MethodDatabase.SuspendableType isSuspendable (
boolean isInterface, String className, String superClassName, String[] interfaces,
String methodName, String methodDesc, String methodSignature, String[] methodExceptions
) {
// skipping ctors to avoid unnecessary instrumentation errors
if (methodName.charAt(0) == '<')
return null;

// declares given methods as supers
for (String[] susExtendables : methodsArray) {
if (className.equals(susExtendables[0]))
Expand Down
5 changes: 4 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ Then add the following Maven/Gradle dependencies:
| [Retrofit](http://square.github.io/retrofit/) integration with fibers. | `co.paralleluniverse:comsat-retrofit:0.7.0`
| [JDBI](http://jdbi.org/) integration with fibers. | `co.paralleluniverse:comsat-jdbi:0.7.0`
| JDBC integration with fibers. | `co.paralleluniverse:comsat-jdbc:0.7.0`
| [jOOQ](http://www.jooq.org/) integration with fibers. | `co.paralleluniverse:comsat-jooq:0.7.0`
| [jOOQ](http://www.jooq.org) integration with fibers for using jOOQ with Java 7 and below. | `co.paralleluniverse:comsat-jooq:0.7.0`
| [jOOQ](http://www.jooq.org) integration with fibers for using jOOQ with Java 8. | `co.paralleluniverse:comsat-jooq-java8:0.7.0`
| MongoDB fiber-blocking integration for the [Allanbank API](http://www.allanbank.com/mongodb-async-driver/index.html). | `co.paralleluniverse:comsat-mongodb-allanbank:0.7.0`
| [OkHttp](https://github.com/square/okhttp) HTTP+SPDY client integration. | `co.paralleluniverse:comsat-okhttp:0.7.0`
| The Web Actors API. | `co.paralleluniverse:comsat-actors-api:0.7.0`
Expand Down Expand Up @@ -495,6 +496,8 @@ The interface now can be registered and used as usual from fibers:
{% include_snippet usage ./comsat-jooq/src/test/java/co/paralleluniverse/fibers/jooq/JooqContextTest.java %}
~~~

Starting with versions 3.7 jOOQ requires Java 8 and Comsat provides two separate jOOQ integrations: `comsat-jooq` supports Java 6+ and jOOQ 3.6.x while `comsat-jooq-java8` supports jOOQ 3.8.x with Java 8.

#### MongoDB

Comsat integrates with MongoDB and offers a fiber-blocking [allanbank API](http://www.allanbank.com/mongodb-async-driver/index.html).
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ include 'comsat-jetty-loader'
include 'comsat-jdbc'
include 'comsat-jdbi'
include 'comsat-jooq'
include 'comsat-jooq-java8'
include 'comsat-dropwizard'
include 'comsat-retrofit'
include 'comsat-httpclient'
Expand Down