Skip to content

Commit 10bbe97

Browse files
committed
[database] sql fix case of GenerationMode.Generated_keys
1 parent 3f269f0 commit 10bbe97

File tree

2 files changed

+42
-41
lines changed

2 files changed

+42
-41
lines changed

vertigo-database/src/main/java/io/vertigo/database/impl/sql/SqlManagerImpl.java

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package io.vertigo.database.impl.sql;
1919

2020
import java.sql.PreparedStatement;
21-
import java.sql.ResultSet;
2221
import java.sql.SQLException;
2322
import java.sql.Statement;
2423
import java.util.HashMap;
@@ -41,7 +40,6 @@
4140
import io.vertigo.database.sql.statement.SqlParameter;
4241
import io.vertigo.database.sql.statement.SqlStatement;
4342
import io.vertigo.database.sql.vendor.SqlDialect.GenerationMode;
44-
import io.vertigo.database.sql.vendor.SqlMapping;
4543

4644
/**
4745
* Implémentation standard du gestionnaire des données et des accès aux données.
@@ -82,8 +80,8 @@ public SqlManagerImpl(
8280
this.analyticsManager = analyticsManager;
8381
connectionProviderPluginMap = new HashMap<>();
8482
for (final SqlConnectionProviderPlugin sqlConnectionProviderPlugin : sqlConnectionProviderPlugins) {
85-
final String name = sqlConnectionProviderPlugin.getName();
86-
final SqlConnectionProvider previous = connectionProviderPluginMap.put(name, sqlConnectionProviderPlugin);
83+
final var name = sqlConnectionProviderPlugin.getName();
84+
final var previous = connectionProviderPluginMap.put(name, sqlConnectionProviderPlugin);
8785
Assertion.check().isNull(previous, "ConnectionProvider {0}, was already registered", name);
8886
}
8987
localeManager.add("io.vertigo.database.impl.sql.DataBase", io.vertigo.database.impl.sql.Resources.values());
@@ -94,7 +92,7 @@ public SqlManagerImpl(
9492
/** {@inheritDoc} */
9593
@Override
9694
public SqlConnectionProvider getConnectionProvider(final String name) {
97-
final SqlConnectionProvider sqlConnectionProvider = connectionProviderPluginMap.get(name);
95+
final var sqlConnectionProvider = connectionProviderPluginMap.get(name);
9896
Assertion.check().isNotNull(sqlConnectionProvider, "ConnectionProvider {0}, wasn't registered.", name);
9997
return sqlConnectionProvider;
10098
}
@@ -112,7 +110,7 @@ public <O> List<O> executeQuery(
112110
.isNotNull(dataType)
113111
.isNotNull(connection);
114112
//-----
115-
try (final PreparedStatement statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
113+
try (final var statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
116114
sqlStatementDriver.setParameters(statement, sqlStatement.getSqlParameters(), basicTypeAdapters, connection);
117115
//-----
118116
return traceWithReturn(sqlStatement.getSqlQuery(), tracer -> doExecuteQuery(statement, tracer, dataType, basicTypeAdapters, limit, connection));
@@ -130,8 +128,8 @@ private <O> List<O> doExecuteQuery(
130128
final Integer limit,
131129
final SqlConnection connection) {
132130
// ResultSet JDBC
133-
final SqlMapping mapping = connection.getDataBase().getSqlMapping();
134-
try (final ResultSet resultSet = statement.executeQuery()) {
131+
final var mapping = connection.getDataBase().getSqlMapping();
132+
try (final var resultSet = statement.executeQuery()) {
135133
//Le Handler a la responsabilité de créer les données.
136134
final List<O> result = sqlStatementDriver.buildResult(dataType, basicTypeAdapters, mapping, resultSet, limit);
137135
tracer.setMeasure("nbSelectedRow", result.size());
@@ -158,12 +156,12 @@ public <O> Tuple<Integer, O> executeUpdateWithGeneratedKey(
158156
.isNotNull(dataType)
159157
.isNotNull(connection);
160158
//---
161-
try (final PreparedStatement statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), generationMode, new String[] { columnName }, connection)) {
159+
try (final var statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), generationMode, new String[] { columnName }, connection)) {
162160
sqlStatementDriver.setParameters(statement, sqlStatement.getSqlParameters(), basicTypeAdapters, connection);
163161
//---
164162
//execution de la Requête
165163
final int result = traceWithReturn(sqlStatement.getSqlQuery(), tracer -> doExecute(statement, tracer));
166-
final List<O> generatedIds = sqlStatementDriver.getGeneratedKeys(statement, columnName, dataType, connection);
164+
final List<O> generatedIds = sqlStatementDriver.getGeneratedKeys(statement, generationMode, columnName, dataType, connection);
167165
if (generatedIds.isEmpty()) {
168166
throw new SQLException("GeneratedKeys empty", "02000", NO_GENERATED_KEY_ERROR_VENDOR_CODE);
169167
}
@@ -186,7 +184,7 @@ public int executeUpdate(
186184
.isNotNull(sqlStatement)
187185
.isNotNull(connection);
188186
//---
189-
try (final PreparedStatement statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
187+
try (final var statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
190188
sqlStatementDriver.setParameters(statement, sqlStatement.getSqlParameters(), basicTypeAdapters, connection);
191189
//---
192190
return traceWithReturn(sqlStatement.getSqlQuery(), tracer -> doExecute(statement, tracer));
@@ -197,7 +195,7 @@ public int executeUpdate(
197195

198196
private static int doExecute(final PreparedStatement statement, final Tracer tracer) {
199197
try {
200-
final int res = statement.executeUpdate();
198+
final var res = statement.executeUpdate();
201199
tracer.setMeasure("nbModifiedRow", res);
202200
return res;
203201
} catch (final SQLException e) {
@@ -231,7 +229,7 @@ public OptionalInt executeBatch(
231229
.isNotNull(sqlStatement)
232230
.isNotNull(connection);
233231
//---
234-
try (final PreparedStatement statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
232+
try (final var statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), connection)) {
235233
for (final List<SqlParameter> parameters : sqlStatement.getSqlParametersForBatch()) {
236234
sqlStatementDriver.setParameters(statement, parameters, basicTypeAdapters, connection);
237235
statement.addBatch();
@@ -244,9 +242,9 @@ public OptionalInt executeBatch(
244242

245243
private static OptionalInt doExecuteBatch(final PreparedStatement statement, final Tracer tracer) {
246244
try {
247-
final int[] res = statement.executeBatch();
245+
final var res = statement.executeBatch();
248246
//Calcul du nombre total de lignes affectées par le batch.
249-
int count = 0;
247+
var count = 0;
250248
for (final int rowCount : res) {
251249
count += rowCount;
252250
if (rowCount == Statement.SUCCESS_NO_INFO) {
@@ -277,13 +275,13 @@ public <O> Tuple<Integer, List<O>> executeBatchWithGeneratedKeys(
277275
.isNotNull(dataType)
278276
.isNotNull(connection);
279277
//---
280-
try (final PreparedStatement statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), generationMode, new String[] { columnName }, connection)) {
278+
try (final var statement = sqlStatementDriver.createStatement(sqlStatement.getSqlQuery(), generationMode, new String[] { columnName }, connection)) {
281279
for (final List<SqlParameter> parameters : sqlStatement.getSqlParametersForBatch()) {
282280
sqlStatementDriver.setParameters(statement, parameters, basicTypeAdapters, connection);
283281
statement.addBatch();
284282
}
285-
final OptionalInt result = traceWithReturn(sqlStatement.getSqlQuery(), tracer -> doExecuteBatch(statement, tracer));
286-
final List<O> generatedIds = sqlStatementDriver.getGeneratedKeys(statement, columnName, dataType, connection);
283+
final var result = traceWithReturn(sqlStatement.getSqlQuery(), tracer -> doExecuteBatch(statement, tracer));
284+
final List<O> generatedIds = sqlStatementDriver.getGeneratedKeys(statement, generationMode, columnName, dataType, connection);
287285
if (generatedIds.isEmpty()) {
288286
throw new SQLException("GeneratedKeys wasNull", "23502");
289287
}
@@ -302,7 +300,7 @@ private <O> O traceWithReturn(final String sql, final Function<Tracer, O> functi
302300
final String requestTracerHeader;
303301
if (sql.startsWith("/*")) { //default build query startWith /* task name */ : use it for tracer header
304302
final int indexStart;
305-
final int indexEnds = sql.indexOf("*/");
303+
final var indexEnds = sql.indexOf("*/");
306304
if (sql.startsWith("/* TaskEngine : ")) { //default build query startWith /* task name */ : use it for tracer header
307305
indexStart = "/* TaskEngine : ".length();
308306
} else {
@@ -317,7 +315,7 @@ private <O> O traceWithReturn(final String sql, final Function<Tracer, O> functi
317315
"sql",
318316
"/execute/" + requestTracerHeader,
319317
tracer -> {
320-
final O result = function.apply(tracer);
318+
final var result = function.apply(tracer);
321319
tracer.setTag("statementHeader", requestTracerHeader)
322320
.setMetadata("statement", sql.substring(0, Math.min(REQUEST_STATEMENT_FOR_TRACER, sql.length())));
323321
return result;

vertigo-database/src/main/java/io/vertigo/database/impl/sql/SqlStatementDriver.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package io.vertigo.database.impl.sql;
1919

20-
import java.lang.reflect.Method;
2120
import java.math.BigDecimal;
2221
import java.sql.PreparedStatement;
2322
import java.sql.ResultSet;
@@ -70,7 +69,7 @@ final class SqlStatementDriver {
7069

7170
PreparedStatement createStatement(final String sql, final SqlConnection connection) throws SQLException {
7271
//created PrepareStatement must be use into a try-with-resource in caller
73-
final PreparedStatement preparedStatement = connection.getJdbcConnection()
72+
final var preparedStatement = connection.getJdbcConnection()
7473
.prepareStatement(sql, Statement.NO_GENERATED_KEYS);
7574
//by experience 150 is a right value (Oracle is set by default at 10 : that's not sufficient)
7675
preparedStatement.setFetchSize(FETCH_SIZE);
@@ -83,7 +82,7 @@ PreparedStatement createStatement(
8382
final String[] generatedColumns,
8483
final SqlConnection connection) throws SQLException {
8584
//created PrepareStatement must be use into a try-with-resource in caller
86-
final PreparedStatement preparedStatement = switch (generationMode) {
85+
final var preparedStatement = switch (generationMode) {
8786
case GENERATED_KEYS -> connection.getJdbcConnection()
8887
.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
8988
case GENERATED_COLUMNS -> connection.getJdbcConnection()
@@ -102,15 +101,15 @@ void setParameters(
102101
final Map<Class, BasicTypeAdapter> basicTypeAdapters,
103102
final SqlConnection connection) throws SQLException {
104103
//-----
105-
for (int index = 0; index < parameters.size(); index++) {
106-
final SqlParameter parameter = parameters.get(index);
107-
final Class javaDataType = parameter.dataType();
104+
for (var index = 0; index < parameters.size(); index++) {
105+
final var parameter = parameters.get(index);
106+
final var javaDataType = parameter.dataType();
108107
if (isPrimitive(parameter.dataType())) {
109108
connection.getDataBase().getSqlMapping().setValueOnStatement(
110109
statement, index + 1, javaDataType, parameter.value());
111110
} else {
112111
// complex we find the adapter
113-
final BasicTypeAdapter adapter = basicTypeAdapters.get(parameter.dataType());
112+
final var adapter = basicTypeAdapters.get(parameter.dataType());
114113
connection.getDataBase().getSqlMapping().setValueOnStatement(
115114
statement, index + 1, adapter.getBasicType().getJavaClass(), adapter.toBasic(parameter.value()));
116115
}
@@ -149,9 +148,9 @@ private static <O> List<O> retrieveData(
149148
final SqlMapping sqlMapping,
150149
final ResultSet resultSet,
151150
final Integer limit) throws SQLException {
152-
final boolean isPrimitive = isPrimitive(dataType);
151+
final var isPrimitive = isPrimitive(dataType);
153152

154-
final MyField[] fields = isPrimitive ? null : findFields(dataType, resultSet.getMetaData());
153+
final var fields = isPrimitive ? null : findFields(dataType, resultSet.getMetaData());
155154
//Dans le cas d'une collection on retourne toujours qqChose
156155
//Si la requête ne retourne aucune ligne, on retourne une collection vide.
157156
final List<O> list = new ArrayList<>();
@@ -181,14 +180,14 @@ private static <O> O readRow(
181180
final ResultSet resultSet,
182181
final Class<O> dataType,
183182
final MyField[] fields) throws SQLException {
184-
final O bean = ClassUtil.newInstance(dataType);
183+
final var bean = ClassUtil.newInstance(dataType);
185184
Object value;
186-
for (int i = 0; i < fields.length; i++) {
185+
for (var i = 0; i < fields.length; i++) {
187186
final Class<?> javaFieldDataType = fields[i].type;
188187
if (isPrimitive(javaFieldDataType)) {
189188
fields[i].setValue(bean, mapping.getValueForResultSet(resultSet, i + 1, javaFieldDataType));
190189
} else {
191-
final BasicTypeAdapter adapter = basicTypeAdapters.get(javaFieldDataType);
190+
final var adapter = basicTypeAdapters.get(javaFieldDataType);
192191
value = adapter.toJava(mapping.getValueForResultSet(resultSet, i + 1, adapter.getBasicType().getJavaClass()), javaFieldDataType);
193192
fields[i].setValue(bean, value);
194193
}
@@ -204,15 +203,15 @@ private static <O> O readRow(
204203
private static MyField[] findFields(
205204
final Class dataType,
206205
final ResultSetMetaData resultSetMetaData) throws SQLException {
207-
final MyField[] fields = new MyField[resultSetMetaData.getColumnCount()];
206+
final var fields = new MyField[resultSetMetaData.getColumnCount()];
208207
String columnLabel;
209-
for (int i = 0; i < fields.length; i++) {
208+
for (var i = 0; i < fields.length; i++) {
210209
//getColumnLabel permet de récupérer le nom adapté lors du select (avec un select truc as machin from xxx)
211210
columnLabel = resultSetMetaData.getColumnLabel(i + 1);
212211
// toUpperCase nécessaire pour postgreSQL et SQLServer
213-
final String expectedFieldName = StringUtil.constToLowerCamelCase(columnLabel.toUpperCase(Locale.ENGLISH));
212+
final var expectedFieldName = StringUtil.constToLowerCamelCase(columnLabel.toUpperCase(Locale.ENGLISH));
214213
try {
215-
final Method getter = dataType.getDeclaredMethod("get" + StringUtil.first2UpperCase(expectedFieldName));
214+
final var getter = dataType.getDeclaredMethod("get" + StringUtil.first2UpperCase(expectedFieldName));
216215
fields[i] = new MyField(expectedFieldName, getter.getReturnType());
217216
} catch (final NoSuchMethodException e) {
218217
throw WrappedException.wrap(e);
@@ -257,23 +256,27 @@ private static boolean isPrimitive(final Class dataType) {
257256

258257
<O> List<O> getGeneratedKeys(
259258
final PreparedStatement statement,
259+
final GenerationMode generationMode,
260260
final String columnName,
261261
final Class<O> dataType,
262262
final SqlConnection connection) throws SQLException {
263263
Assertion.check()
264+
.isNotNull(generationMode)
264265
.isNotBlank(columnName)
265266
.isNotNull(dataType);
266267
//-----
267268
// L'utilisation des generatedKeys permet d'avoir un seul appel réseau entre le
268269
// serveur d'application et la base de données pour un insert et la récupération de la
269270
// valeur de la clé primaire en respectant les standards jdbc et sql ansi.
270-
final SqlMapping sqlMapping = connection.getDataBase().getSqlMapping();
271+
final var sqlMapping = connection.getDataBase().getSqlMapping();
271272
final List<O> generatedKeys = new ArrayList<>();
272-
try (final ResultSet rs = statement.getGeneratedKeys()) {
273+
try (final var rs = statement.getGeneratedKeys()) {
273274
while (rs.next()) {
274-
//ResultSet haven't correctly named columns so we fall back to get the first column, instead of looking for column index by name.
275-
int pkRsCol = rs.findColumn(columnName); //on cherche le bon index de la pk
276-
final O id = sqlMapping.getValueForResultSet(rs, pkRsCol, dataType);
275+
final var pkRsCol = switch (generationMode) {
276+
case GENERATED_KEYS -> 0; //ResultSet haven't correctly named columns so we fall back to get the first column, instead of looking for column index by name.
277+
case GENERATED_COLUMNS -> rs.findColumn(columnName); //on cherche le bon index de la pk;
278+
};
279+
final var id = sqlMapping.getValueForResultSet(rs, pkRsCol, dataType);
277280
if (rs.wasNull()) {
278281
throw new SQLException("GeneratedKeys wasNull", "23502", NULL_GENERATED_KEY_ERROR_VENDOR_CODE);
279282
}

0 commit comments

Comments
 (0)