-
Notifications
You must be signed in to change notification settings - Fork 206
Expand file tree
/
Copy pathSqlTemplate.java
More file actions
200 lines (182 loc) · 7.29 KB
/
SqlTemplate.java
File metadata and controls
200 lines (182 loc) · 7.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.sqlclient.templates;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.Future;
import io.vertx.sqlclient.*;
import io.vertx.sqlclient.impl.SqlClientInternal;
import io.vertx.sqlclient.templates.impl.CursorSqlTemplateImpl;
import io.vertx.sqlclient.templates.impl.SqlTemplateImpl;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
/**
* An SQL template.
*
* <p>SQL templates are useful for interacting with a relational database.
*
* <p>SQL templates execute queries using named instead of positional parameters. Query execution is parameterized
* by a map of string to objects instead of a {@link io.vertx.sqlclient.Tuple}. The default source of parameters is a
* simple map, a user defined mapping can be used instead given it maps the source to such a map.
*
* <p>SQL template default results are {@link Row}, a user defined mapping can be used instead, mapping the
* result set {@link Row} to a {@link RowSet} of the mapped type.
*/
@VertxGen
public interface SqlTemplate<I, R> {
/**
* Create an SQL template for query purpose consuming map parameters and returning {@link Row}.
*
* @param client the wrapped SQL client
* @param template the template query string
* @return the template
*/
static SqlTemplate<Map<String, Object>, RowSet<Row>> forQuery(SqlClient client, String template) {
SqlClientInternal clientInternal = (SqlClientInternal) client;
io.vertx.sqlclient.templates.impl.SqlTemplate sqlTemplate = io.vertx.sqlclient.templates.impl.SqlTemplate.create(clientInternal, template);
return new SqlTemplateImpl<>(clientInternal, sqlTemplate, Function.identity(), sqlTemplate::mapTuple);
}
/**
* Create an SQL template for query purpose consuming map parameters and returning void.
*
* @param client the wrapped SQL client
* @param template the template update string
* @return the template
*/
static SqlTemplate<Map<String, Object>, SqlResult<Void>> forUpdate(SqlClient client, String template) {
SqlClientInternal clientInternal = (SqlClientInternal) client;
io.vertx.sqlclient.templates.impl.SqlTemplate sqlTemplate = io.vertx.sqlclient.templates.impl.SqlTemplate.create(clientInternal, template);
return new SqlTemplateImpl<>(clientInternal, sqlTemplate, query -> query.collecting(SqlTemplateImpl.NULL_COLLECTOR), sqlTemplate::mapTuple);
}
/**
* Create an SQL template for streaming query results consuming map parameters and returning {@link Row}.
*
* <p>Delegates to {@link SqlTemplateStream#forStream(SqlConnection, String, int)}.
*
* @param client the wrapped SQL connection
* @param template the template query string
* @param fetchSize the cursor fetch size
* @return the template
*/
static SqlTemplateStream<Map<String, Object>, Row> forStream(SqlConnection client, String template, int fetchSize) {
return SqlTemplateStream.forStream(client, template, fetchSize);
}
/**
* Create an SQL template for cursor-based query execution consuming map parameters and returning a {@link Cursor}.
*
* @param client the wrapped SQL connection
* @param template the template query string
* @return the template
*/
static SqlTemplate<Map<String, Object>, Cursor> forCursor(SqlConnection client, String template) {
SqlClientInternal clientInternal = (SqlClientInternal) client;
io.vertx.sqlclient.templates.impl.SqlTemplate sqlTemplate = io.vertx.sqlclient.templates.impl.SqlTemplate.create(clientInternal, template);
return new CursorSqlTemplateImpl<>(client, sqlTemplate, sqlTemplate::mapTuple);
}
/**
* @return the computed SQL for this template
*/
String sql();
/**
* Set a parameters user defined mapping function.
*
* <p> At query execution, the {@code mapper} is called to map the parameters object
* to a {@code Tuple} that configures the prepared query.
*
* @param mapper the mapping function
* @return a new template
*/
<T> SqlTemplate<T, R> mapFrom(TupleMapper<T> mapper);
/**
* Set a parameters user defined class mapping.
*
* <p> At query execution, the parameters object is is mapped to a {@code Map<String, Object>} that
* configures the prepared query.
*
* <p> This feature relies on {@link io.vertx.core.json.JsonObject#mapFrom} feature. This likely requires
* to use Jackson databind in the project.
*
* @param type the mapping type
* @return a new template
*/
default <T> SqlTemplate<T, R> mapFrom(Class<T> type) {
return mapFrom(TupleMapper.mapper(type));
}
/**
* Set a row user defined mapping function.
*
* <p> When the query execution completes, the {@code mapper} function is called to map the resulting
* rows to objects.
*
* @param mapper the mapping function
* @return a new template
*/
<U> SqlTemplate<I, RowSet<U>> mapTo(RowMapper<U> mapper);
/**
* Set a row user defined mapping function.
*
* <p> When the query execution completes, resulting rows are mapped to {@code type} instances.
*
* <p> This feature relies on {@link io.vertx.core.json.JsonObject#mapFrom} feature. This likely requires
* to use Jackson databind in the project.
*
* @param type the mapping type
* @return a new template
*/
<U> SqlTemplate<I, RowSet<U>> mapTo(Class<U> type);
/**
* Set a collector that will process the output and produce a custom result.
*
* @param collector the collector
* @return a new template
*/
@GenIgnore
<U> SqlTemplate<I, SqlResult<U>> collecting(Collector<Row, ?, U> collector);
/**
* Returns a new template, using the specified {@code client}.
* <p>
* This method does not compute the template query again, so it can be useful to execute a template on a specific {@link io.vertx.sqlclient.SqlConnection}.
* For example, after starting a transaction:
*
* <pre>
* // Typically stored as a verticle field
* // So that heavy computation of the template happens once
* SqlTemplate<Map<String, Object>, RowSet<World>> template = SqlTemplate
* .forQuery(pool, "SELECT id, randomnumber FROM tmp_world")
* .mapTo(World.class);
*
* // Executing the template inside a transaction
* Future<RowSet<World>> future = pool.withTransaction(conn -> template.withClient(conn).execute(Map.of()));
* </pre>
*
* @param client the client that will execute requests
* @return a new template
*/
SqlTemplate<I, R> withClient(SqlClient client);
/**
* Execute the query with the {@code parameters}
*
* @param params the query parameters
* @return a future notified with the result
*/
Future<R> execute(I params);
/**
* Execute a batch query with the {@code batch}.
*
* <p>Each item in the batch is mapped to a tuple.
*
* @param batch the batch
* @return a future notified with the result
*/
Future<R> executeBatch(List<I> batch);
}