Skip to content

Commit 0a74715

Browse files
committed
jdbi in clause doesn't work if there is any post named param fix #401
1 parent 7958314 commit 0a74715

File tree

5 files changed

+107
-50
lines changed

5 files changed

+107
-50
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.jooby.issues;
2+
3+
import org.jooby.jdbi.Jdbi;
4+
import org.jooby.test.ServerFeature;
5+
import org.junit.Test;
6+
import org.skife.jdbi.v2.Handle;
7+
import org.skife.jdbi.v2.util.StringColumnMapper;
8+
9+
import com.typesafe.config.ConfigFactory;
10+
import com.typesafe.config.ConfigValueFactory;
11+
12+
public class Issue401 extends ServerFeature {
13+
14+
{
15+
use(ConfigFactory.empty().withValue("db", ConfigValueFactory.fromAnyRef("mem")));
16+
17+
use(new Jdbi());
18+
19+
onStart(registry -> {
20+
try (Handle h = registry.require(Handle.class)) {
21+
h.execute("create table members (id int primary key, name varchar(100))");
22+
23+
h.execute("insert into members (id, name) values (?, ?)", 1, "a");
24+
h.execute("insert into members (id, name) values (?, ?)", 2, "b");
25+
h.execute("insert into members (id, name) values (?, ?)", 3, "c");
26+
h.execute("insert into members (id, name) values (?, ?)", 4, "d");
27+
h.execute("insert into members (id, name) values (?, ?)", 5, "e");
28+
h.execute("insert into members (id, name) values (?, ?)", 6, "f");
29+
h.execute("insert into members (id, name) values (?, ?)", 7, "g");
30+
h.execute("insert into members (id, name) values (?, ?)", 8, "h");
31+
h.execute("insert into members (id, name) values (?, ?)", 9, "i");
32+
}
33+
});
34+
35+
get("/401/pos", req -> {
36+
try (Handle h = req.require(Handle.class)) {
37+
return h
38+
.createQuery("select name from members where id in (?) order by name limit ? offset ?")
39+
.bind(0, req.param("id").toList(Integer.class))
40+
.bind(1, 5)
41+
.bind(2, 0)
42+
.map(StringColumnMapper.INSTANCE)
43+
.list();
44+
}
45+
});
46+
47+
get("/401/named", req -> {
48+
try (Handle h = req.require(Handle.class)) {
49+
return h.createQuery(
50+
"select name from members where id in (:id) order by name limit :limit offset :offset")
51+
.bind("id", req.param("id").toList(Integer.class))
52+
.bind("offset", 0)
53+
.bind("limit", 5)
54+
.map(StringColumnMapper.INSTANCE)
55+
.list();
56+
}
57+
});
58+
59+
}
60+
61+
@Test
62+
public void posParamShouldWork() throws Exception {
63+
request()
64+
.get("/401/pos?id=1&id=2&id=3&id=4&id=5&id=6&id=7")
65+
.expect("[a, b, c, d, e]");
66+
}
67+
68+
@Test
69+
public void namedParamShouldWork() throws Exception {
70+
request()
71+
.get("/401/named?id=1&id=2&id=3&id=4&id=5&id=6&id=7")
72+
.expect("[a, b, c, d, e]");
73+
}
74+
75+
}

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import static java.util.Objects.requireNonNull;
2222

23+
import java.util.ArrayList;
2324
import java.util.List;
2425
import java.util.function.BiConsumer;
2526

@@ -28,13 +29,14 @@
2829
import org.jooby.Env;
2930
import org.jooby.jdbc.Jdbc;
3031
import org.skife.jdbi.v2.DBI;
31-
import org.skife.jdbi.v2.DBI2;
3232
import org.skife.jdbi.v2.ExpandedStmtRewriter;
3333
import org.skife.jdbi.v2.Handle;
3434
import org.skife.jdbi.v2.IterableArgumentFactory;
3535
import org.skife.jdbi.v2.OptionalArgumentFactory;
3636
import org.skife.jdbi.v2.OptionalContainerFactory;
3737
import org.skife.jdbi.v2.logging.SLF4JLog;
38+
import org.skife.jdbi.v2.tweak.ArgumentFactory;
39+
import org.skife.jdbi.v2.tweak.ConnectionFactory;
3840

3941
import com.google.common.collect.Lists;
4042
import com.google.inject.Binder;
@@ -136,6 +138,25 @@
136138
*/
137139
public class Jdbi extends Jdbc {
138140

141+
public static final String ARG_FACTORIES = "__argumentFactories_";
142+
143+
static class DBI2 extends DBI {
144+
145+
private List<ArgumentFactory<?>> factories = new ArrayList<ArgumentFactory<?>>();
146+
147+
public DBI2(final ConnectionFactory connectionFactory) {
148+
super(connectionFactory);
149+
define(ARG_FACTORIES, factories);
150+
}
151+
152+
@Override
153+
public void registerArgumentFactory(final ArgumentFactory<?> argumentFactory) {
154+
factories.add(argumentFactory);
155+
super.registerArgumentFactory(argumentFactory);
156+
}
157+
158+
}
159+
139160
private BiConsumer<DBI, Config> configurer;
140161

141162
private List<Class<?>> sqlObjects;

jooby-jdbi/src/main/java/org/skife/jdbi/v2/DBI2.java

Lines changed: 0 additions & 44 deletions
This file was deleted.

jooby-jdbi/src/main/java/org/skife/jdbi/v2/ExpandedStmtRewriter.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,16 @@ public void bind(final Binding params, final PreparedStatement statement) throws
156156
if (stmt.positionalOnly) {
157157
// no named params, is easy
158158
boolean finished = false;
159-
int i = 0;
159+
int i = 0, p = 0;
160160
while (!finished) {
161-
final Argument a = params.forPosition(i);
161+
final Argument a = params.forPosition(p);
162162
if (a != null) {
163163
try {
164+
this.context.setAttribute("position", null);
164165
a.apply(i + 1, statement, this.context);
165166
Integer pos = (Integer) this.context.getAttribute("position");
166167
i += Optional.ofNullable(pos).orElse(1);
168+
p += 1;
167169
this.context.setAttribute("position", null);
168170
} catch (SQLException e) {
169171
throw new UnableToExecuteStatementException(
@@ -198,13 +200,15 @@ public void bind(final Binding params, final PreparedStatement statement) throws
198200
}
199201

200202
try {
203+
this.context.setAttribute("position", null);
201204
a.apply(i + 1, statement, this.context);
205+
Integer pos = (Integer) this.context.getAttribute("position");
206+
i += Optional.ofNullable(pos).orElse(1);
202207
} catch (SQLException e) {
203208
throw new UnableToCreateStatementException(String.format(
204209
"Exception while binding '%s'",
205210
named_param), e, context);
206211
}
207-
i++;
208212
}
209213
}
210214
}

jooby-jdbi/src/main/java/org/skife/jdbi/v2/IterableArgument.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.sql.SQLException;
2424
import java.util.List;
2525

26+
import org.jooby.jdbi.Jdbi;
2627
import org.skife.jdbi.v2.tweak.Argument;
2728
import org.skife.jdbi.v2.tweak.ArgumentFactory;
2829

@@ -47,7 +48,7 @@ public IterableArgument(final Object value, final StatementContext ctx) {
4748
this.values = (Iterable<?>) value;
4849
}
4950
this.foreman = new Foreman();
50-
List<ArgumentFactory> factories = (List<ArgumentFactory>) ctx.getAttribute(DBI2.ARG_FACTORIES);
51+
List<ArgumentFactory> factories = (List<ArgumentFactory>) ctx.getAttribute(Jdbi.ARG_FACTORIES);
5152
factories.forEach(foreman::register);
5253
}
5354

@@ -60,7 +61,7 @@ public void apply(final int position, final PreparedStatement stmt,
6061
i+=1;
6162
}
6263

63-
ctx.setAttribute("position", i);
64+
ctx.setAttribute("position", i - 1);
6465

6566
}
6667

0 commit comments

Comments
 (0)