Skip to content

Commit 7221e16

Browse files
committed
Add optional argument factory, fix #46
1 parent 15d2fce commit 7221e16

6 files changed

Lines changed: 184 additions & 4 deletions

File tree

jooby-jdbc/src/main/java/org/jooby/jdbc/Jdbc.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
* <h2>hikari configuration</h2>
115115
* <p>
116116
* If you need to configure or tweak the <a
117-
* href="https://github.com/brettwooldridge/HikariCP">hikari poll</a> just add <code>hikari.*</code>
117+
* href="https://github.com/brettwooldridge/HikariCP">hikari pool</a> just add <code>hikari.*</code>
118118
* entries to your <code>application.conf</code> file:
119119
* </p>
120120
*

jooby-jdbi/src/main/java/org/jooby/jdbi/Jdbi.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* module.
4646
* </p>
4747
*
48-
* <h1>Getting Started</h1>
48+
* <h1>usage</h1>
4949
*
5050
* <p>
5151
* It is pretty straightforward:
@@ -67,8 +67,12 @@
6767
* });
6868
* }
6969
* </pre>
70+
* <p>
71+
* A call to <code>req.require(Handle.class)</code> is the same as:
72+
* <code>req.require(DBI.class).open(Handle.class)</code>.
73+
* </p>
7074
*
71-
* <h1>Working with SQL Objects</h1>
75+
* <h1>sql objects</h1>
7276
*
7377
* <p>
7478
* It is pretty straightforward (too):
@@ -105,7 +109,7 @@
105109
* }
106110
* </pre>
107111
*
108-
* <h1>Configuration</h1>
112+
* <h1>configuration</h1>
109113
* <p>
110114
* If you need to configure and/or customize a {@link DBI} instance, just do:
111115
* </p>
@@ -152,6 +156,8 @@ public void configure(final Env env, final Config config, final Binder binder) {
152156

153157
DBI dbi = new DBI(() -> dataSource().get().getConnection());
154158
dbi.setSQLLog(new SLF4JLog());
159+
dbi.registerArgumentFactory(new OptionalArgumentFactory());
160+
dbi.registerContainerFactory(new OptionalContainerFactory());
155161

156162
keys(DBI.class, key -> binder.bind(key).toInstance(dbi));
157163

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.jooby.jdbi;
2+
3+
import java.sql.Types;
4+
import java.util.Optional;
5+
6+
import org.skife.jdbi.v2.StatementContext;
7+
import org.skife.jdbi.v2.tweak.Argument;
8+
import org.skife.jdbi.v2.tweak.ArgumentFactory;
9+
10+
class OptionalArgumentFactory implements ArgumentFactory<Optional<?>> {
11+
12+
@Override
13+
public boolean accepts(final Class<?> expectedType, final Object value, final StatementContext ctx) {
14+
return value instanceof Optional;
15+
}
16+
17+
@Override
18+
public Argument build(final Class<?> expectedType, final Optional<?> value,
19+
final StatementContext sctx) {
20+
return (pos, stmt, ctx) -> {
21+
if (value.isPresent()) {
22+
stmt.setObject(pos, value.get());
23+
} else {
24+
stmt.setNull(pos, Types.OTHER);
25+
}
26+
};
27+
}
28+
29+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.jooby.jdbi;
20+
21+
import java.util.Optional;
22+
23+
import org.skife.jdbi.v2.ContainerBuilder;
24+
import org.skife.jdbi.v2.tweak.ContainerFactory;
25+
26+
class OptionalContainerFactory implements ContainerFactory<Optional<?>> {
27+
28+
@Override
29+
public boolean accepts(final Class<?> type) {
30+
return Optional.class.isAssignableFrom(type);
31+
}
32+
33+
@Override
34+
public ContainerBuilder<Optional<?>> newContainerBuilderFor(final Class<?> type) {
35+
return optional();
36+
}
37+
38+
private static ContainerBuilder<Optional<?>> optional() {
39+
return new ContainerBuilder<Optional<?>>() {
40+
41+
private Optional<?> value = Optional.empty();
42+
43+
@Override
44+
public Optional<?> build() {
45+
return value;
46+
}
47+
48+
@Override
49+
public ContainerBuilder<Optional<?>> add(final Object it) {
50+
value = Optional.ofNullable(it);
51+
return this;
52+
}
53+
};
54+
}
55+
56+
57+
58+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.jooby.jdbi;
2+
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertNotNull;
5+
import static org.junit.Assert.assertTrue;
6+
7+
import java.sql.PreparedStatement;
8+
import java.sql.Types;
9+
import java.util.Optional;
10+
11+
import org.jooby.MockUnit;
12+
import org.junit.Test;
13+
import org.skife.jdbi.v2.StatementContext;
14+
import org.skife.jdbi.v2.tweak.Argument;
15+
16+
public class OptionaArgumentFactoryTest {
17+
18+
@Test
19+
public void accepts() {
20+
assertTrue(new OptionalArgumentFactory().accepts(Optional.class, Optional.empty(), null));
21+
assertFalse(new OptionalArgumentFactory().accepts(Optional.class, new Object(), null));
22+
}
23+
24+
@Test
25+
public void empty() throws Exception {
26+
new MockUnit(StatementContext.class, PreparedStatement.class)
27+
.expect(unit -> {
28+
PreparedStatement stmt = unit.get(PreparedStatement.class);
29+
stmt.setNull(1, Types.OTHER);
30+
})
31+
.run(unit -> {
32+
Argument arg = new OptionalArgumentFactory()
33+
.build(Optional.class, Optional.empty(), unit.get(StatementContext.class));
34+
assertNotNull(arg);
35+
arg.apply(1, unit.get(PreparedStatement.class), unit.get(StatementContext.class));
36+
});
37+
}
38+
39+
@Test
40+
public void value() throws Exception {
41+
new MockUnit(StatementContext.class, PreparedStatement.class)
42+
.expect(unit -> {
43+
PreparedStatement stmt = unit.get(PreparedStatement.class);
44+
stmt.setObject(1, "x");
45+
})
46+
.run(unit -> {
47+
Argument arg = new OptionalArgumentFactory()
48+
.build(Optional.class, Optional.of("x"), unit.get(StatementContext.class));
49+
assertNotNull(arg);
50+
arg.apply(1, unit.get(PreparedStatement.class), unit.get(StatementContext.class));
51+
});
52+
}
53+
54+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.jooby.jdbi;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNotNull;
6+
import static org.junit.Assert.assertTrue;
7+
8+
import java.util.Optional;
9+
10+
import org.junit.Test;
11+
import org.skife.jdbi.v2.ContainerBuilder;
12+
13+
public class OptionalContainerFactoryTest {
14+
15+
@Test
16+
public void accepts() {
17+
assertTrue(new OptionalContainerFactory().accepts(Optional.class));
18+
assertFalse(new OptionalContainerFactory().accepts(Object.class));
19+
}
20+
21+
@Test
22+
public void newContainerBuilderFor() {
23+
ContainerBuilder<Optional<?>> cb = new OptionalContainerFactory()
24+
.newContainerBuilderFor(Optional.class);
25+
assertNotNull(cb);
26+
assertEquals(Optional.empty(), cb.build());
27+
28+
cb.add("x");
29+
30+
assertEquals(Optional.of("x"), cb.build());
31+
}
32+
33+
}

0 commit comments

Comments
 (0)