Skip to content

Commit 5032a31

Browse files
tsegismontvietj
authored andcommitted
Support JsonObject params when using SqlTemplate#mapFrom
Fixes #1034 The previous implementation of SqlTemplate#mapFrom created a Map of params that is only made of maps and lists. This prevented from being able to persist data in Postgres JSONB columns. The new implementation creates a Map that can contain JsonObject or JsonArray instances. Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent a65d307 commit 5032a31

File tree

2 files changed

+129
-18
lines changed

2 files changed

+129
-18
lines changed

vertx-sql-client-templates/src/main/java/io/vertx/sqlclient/templates/SqlTemplate.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/*
2+
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
112
package io.vertx.sqlclient.templates;
213

314
import io.vertx.codegen.annotations.GenIgnore;
@@ -13,6 +24,7 @@
1324
import io.vertx.sqlclient.impl.SqlClientInternal;
1425
import io.vertx.sqlclient.templates.impl.SqlTemplateImpl;
1526

27+
import java.util.LinkedHashMap;
1628
import java.util.List;
1729
import java.util.Map;
1830
import java.util.function.Function;
@@ -81,7 +93,14 @@ static SqlTemplate<Map<String, Object>, SqlResult<Void>> forUpdate(SqlClient cli
8193
* @return a new template
8294
*/
8395
default <T> SqlTemplate<T, R> mapFrom(Class<T> type) {
84-
return mapFrom(TupleMapper.mapper(params -> JsonObject.mapFrom(params).getMap()));
96+
return mapFrom(TupleMapper.mapper(params -> {
97+
JsonObject jsonObject = JsonObject.mapFrom(params);
98+
Map<String, Object> map = new LinkedHashMap<>(jsonObject.size());
99+
for (String fieldName : jsonObject.fieldNames()) {
100+
map.put(fieldName, jsonObject.getValue(fieldName));
101+
}
102+
return map;
103+
}));
85104
}
86105

87106
/**

vertx-sql-client-templates/src/test/java/io/vertx/sqlclient/templates/PgClientTest.java

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
/*
2-
* Copyright (C) 2017 Julien Viet
2+
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
158
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
1610
*/
1711

1812
package io.vertx.sqlclient.templates;
@@ -28,14 +22,14 @@
2822
import io.vertx.sqlclient.SqlResult;
2923
import org.junit.Test;
3024

25+
import java.time.Instant;
3126
import java.time.LocalDateTime;
32-
import java.util.Arrays;
33-
import java.util.Collections;
34-
import java.util.HashMap;
35-
import java.util.List;
36-
import java.util.Map;
27+
import java.util.*;
3728
import java.util.function.Function;
3829

30+
import static org.junit.Assert.assertEquals;
31+
import static org.junit.Assert.assertTrue;
32+
3933
/**
4034
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
4135
*/
@@ -175,4 +169,102 @@ public void testAnemicJson(TestContext ctx) {
175169
ctx.assertEquals("hello world", row.getString(2));
176170
}));
177171
}
172+
173+
@Test
174+
public void testInsertJsonObject(TestContext ctx) {
175+
connection.query("DROP TABLE IF EXISTS distributors").execute(ctx.asyncAssertSuccess(dropped -> {
176+
connection.query("CREATE TABLE distributors(name VARCHAR(40), attrs JSONB)").execute(ctx.asyncAssertSuccess(created -> {
177+
178+
MyObject value = new MyObject();
179+
value.setName("foo");
180+
181+
Attributes attributes = new Attributes();
182+
Instant createdOn = Instant.now();
183+
attributes.setCreatedOn(createdOn);
184+
List<String> stringAttributes = Arrays.asList("foo", "bar", "baz");
185+
attributes.setStringAttributes(stringAttributes);
186+
value.setAttributes(attributes);
187+
188+
SqlTemplate
189+
.forQuery(connection, "INSERT INTO distributors (name,attrs) VALUES(#{name},#{attributes})")
190+
.mapFrom(MyObject.class)
191+
.execute(value, ctx.asyncAssertSuccess(inserted -> {
192+
connection.query("SELECT name, attrs FROM distributors").execute(ctx.asyncAssertSuccess(rows -> {
193+
ctx.verify(v -> {
194+
assertEquals(1, rows.size());
195+
Row row = rows.iterator().next();
196+
assertEquals("foo", row.getValue("name"));
197+
Object object = row.getValue("attrs");
198+
assertTrue(object instanceof JsonObject);
199+
JsonObject attrs = (JsonObject) object;
200+
assertEquals(createdOn, attrs.getInstant("createdOn"));
201+
assertEquals(stringAttributes, attrs.getJsonArray("stringAttributes").getList());
202+
});
203+
}));
204+
}));
205+
}));
206+
}));
207+
}
208+
209+
@SuppressWarnings("unused")
210+
private static class MyObject {
211+
212+
private String name;
213+
private Attributes attributes;
214+
215+
public String getName() {
216+
return name;
217+
}
218+
219+
public void setName(String name) {
220+
this.name = name;
221+
}
222+
223+
public Attributes getAttributes() {
224+
return attributes;
225+
}
226+
227+
public void setAttributes(Attributes attributes) {
228+
this.attributes = attributes;
229+
}
230+
231+
@Override
232+
public String toString() {
233+
return "MyObject{" +
234+
"name='" + name + '\'' +
235+
", attributes=" + attributes +
236+
'}';
237+
}
238+
}
239+
240+
@SuppressWarnings("unused")
241+
private static class Attributes {
242+
243+
private Instant createdOn;
244+
private List<String> stringAttributes;
245+
246+
public Instant getCreatedOn() {
247+
return createdOn;
248+
}
249+
250+
public void setCreatedOn(Instant createdOn) {
251+
this.createdOn = createdOn;
252+
}
253+
254+
public List<String> getStringAttributes() {
255+
return stringAttributes;
256+
}
257+
258+
public void setStringAttributes(List<String> stringAttributes) {
259+
this.stringAttributes = stringAttributes;
260+
}
261+
262+
@Override
263+
public String toString() {
264+
return "Attributes{" +
265+
"createdOn=" + createdOn +
266+
", stringAttributes=" + stringAttributes +
267+
'}';
268+
}
269+
}
178270
}

0 commit comments

Comments
 (0)