• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

future-architect / uroborosql / #743

28 Jun 2024 04:17PM UTC coverage: 90.988% (+0.5%) from 90.484%
#743

push

web-flow
add paramIfNotEmpty method (#318)

* v0.x to master merge

* fix nanoseconds diff (java8 to java11)

* eclipse cleanup and  optimize import

* eclipse format

* optimize Imports

* remove unused annotation

* library version up

* migrate v0.x to master
- update java version 8 to 11
- update junit4 to junit5
- library version update

* fix test failed

* remove unused annotation

* fixed bug

* use var

* fix java8 coding style

* Refactoring TransactionContextManager

* Refactoring SqlAgent

* 途中コミット

* fix testcase

* fix review

* fix javadoc comments

* merge v0.x PR

* cleanup code

* cleanup test code

* change build status badge

* - agent.query, update, proc, batch にそれぞれSupplierを引数にとるメソッドを追加
- SqlQuery.paramとSqlEntityUpdate.setにFunctionを受け取るメソッドを追加

* testcaseの整形

* - SqlFluent と ExtractionCondition の分離
- Arrays.asList -> List.of への変更
- テストの整形

* - v0.x系の不具合対応の追いつき
- ログ出力の整理

* - SqlKindの整理(ENTITY_XXXの追加)
- REPL_LOGの追加
- Deprecatedメソッドの削除(SqlAgent)
- SqlAgent, ExecutionContextでsetterをfluent APIに変更

* DB接続URLの修正

* add and fix testcases.

* add event testcases.

* fix typo

* add paramIfNotEmpty method and StringUtils rename ObjectUtils

* fix review comments.

* remove unused import

1695 of 1958 new or added lines in 97 files covered. (86.57%)

26 existing lines in 10 files now uncovered.

8249 of 9066 relevant lines covered (90.99%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.35
/src/main/java/jp/co/future/uroborosql/SqlEntityQueryImpl.java
1
/**
2
 * Copyright (c) 2017-present, Future Corporation
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
package jp.co.future.uroborosql;
8

9
import java.sql.SQLException;
10
import java.util.ArrayList;
11
import java.util.HashMap;
12
import java.util.List;
13
import java.util.Optional;
14
import java.util.stream.Collectors;
15
import java.util.stream.Stream;
16

17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19

20
import jp.co.future.uroborosql.context.ExecutionContext;
21
import jp.co.future.uroborosql.dialect.Dialect;
22
import jp.co.future.uroborosql.enums.ForUpdateType;
23
import jp.co.future.uroborosql.exception.DataNonUniqueException;
24
import jp.co.future.uroborosql.exception.EntitySqlRuntimeException;
25
import jp.co.future.uroborosql.exception.UroborosqlRuntimeException;
26
import jp.co.future.uroborosql.fluent.SqlEntityQuery;
27
import jp.co.future.uroborosql.mapping.EntityHandler;
28
import jp.co.future.uroborosql.mapping.MappingUtils;
29
import jp.co.future.uroborosql.mapping.TableMetadata;
30
import jp.co.future.uroborosql.utils.BeanAccessor;
31
import jp.co.future.uroborosql.utils.CaseFormat;
32

33
/**
34
 * SqlEntityQuery実装
35
 *
36
 * @param <E> Entity型
37
 * @author ota
38
 */
39
final class SqlEntityQueryImpl<E> extends AbstractExtractionCondition<SqlEntityQuery<E>> implements SqlEntityQuery<E> {
40
        /** ロガー */
41
        private static final Logger LOG = LoggerFactory.getLogger("jp.co.future.uroborosql.log");
1✔
42

43
        private final EntityHandler<?> entityHandler;
44
        private final Class<? extends E> entityType;
45
        private final List<SortOrder> sortOrders;
46
        private final List<String> optimizerHints;
47
        private final Dialect dialect;
48
        private long limit;
49
        private long offset;
50
        private ForUpdateType forUpdateType;
51
        private int waitSeconds;
52

53
        private final List<String> includeColumns;
54
        private final List<String> excludeColumns;
55

56
        /**
57
         * Constructor
58
         *
59
         * @param agent SqlAgent
60
         * @param entityHandler EntityHandler
61
         * @param tableMetadata TableMetadata
62
         * @param context ExecutionContext
63
         * @param entityType エンティティタイプ
64
         */
65
        SqlEntityQueryImpl(final SqlAgent agent, final EntityHandler<?> entityHandler, final TableMetadata tableMetadata,
66
                        final ExecutionContext context, final Class<? extends E> entityType) {
67
                super(agent, tableMetadata, context);
1✔
68
                this.entityHandler = entityHandler;
1✔
69
                this.entityType = entityType;
1✔
70
                this.sortOrders = new ArrayList<>();
1✔
71
                this.optimizerHints = new ArrayList<>();
1✔
72
                this.dialect = agent.getSqlConfig().getDialect();
1✔
73
                this.limit = -1;
1✔
74
                this.offset = -1;
1✔
75
                this.forUpdateType = null;
1✔
76
                this.waitSeconds = -1;
1✔
77
                this.includeColumns = new ArrayList<>();
1✔
78
                this.excludeColumns = new ArrayList<>();
1✔
79
        }
1✔
80

81
        /**
82
         * {@inheritDoc}
83
         *
84
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#collect()
85
         */
86
        @Override
87
        public List<E> collect() {
88
                try (var stream = stream()) {
1✔
89
                        return stream.collect(Collectors.toList());
1✔
90
                }
91
        }
92

93
        /**
94
         * {@inheritDoc}
95
         *
96
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#first()
97
         */
98
        @Override
99
        public Optional<E> first() {
100
                try (var stream = stream()) {
1✔
101
                        return stream.findFirst();
1✔
102
                }
103
        }
104

105
        /**
106
         * {@inheritDoc}
107
         *
108
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#one()
109
         */
110
        @Override
111
        public Optional<E> one() {
112
                try (var stream = stream()) {
1✔
113
                        var entities = stream.limit(2).collect(Collectors.toList());
1✔
114
                        if (entities.size() > 1) {
1✔
115
                                throw new DataNonUniqueException("two or more query results.");
1✔
116
                        }
117
                        return entities.stream().findFirst();
1✔
118
                }
119
        }
120

121
        /**
122
         * {@inheritDoc}
123
         *
124
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#stream()
125
         */
126
        @Override
127
        public Stream<E> stream() {
128
                try {
129
                        var selectClause = context().getSql();
1✔
130
                        if (!includeColumns.isEmpty() || !excludeColumns.isEmpty()) {
1✔
131
                                // 除外対象カラムを取得する
132
                                List<? extends TableMetadata.Column> excludeCols = List.of();
1✔
133
                                if (!includeColumns.isEmpty()) {
1✔
134
                                        excludeCols = tableMetadata().getColumns().stream()
1✔
135
                                                        .filter(col -> !includeColumns.contains(col.getCamelColumnName()))
1✔
136
                                                        .collect(Collectors.toList());
1✔
137
                                        if (excludeCols.size() == tableMetadata().getColumns().size()) {
1✔
138
                                                // includeColumnsに含まれるカラムが1つもselect句に含まれない場合は実行時例外とする
139
                                                throw new UroborosqlRuntimeException("None of the includeColumns matches the column name.");
1✔
140
                                        }
141
                                } else if (!excludeColumns.isEmpty()) {
1✔
142
                                        excludeCols = tableMetadata().getColumns().stream()
1✔
143
                                                        .filter(col -> excludeColumns.contains(col.getCamelColumnName()))
1✔
144
                                                        .collect(Collectors.toList());
1✔
145
                                }
146
                                if (!excludeCols.isEmpty()) {
1✔
147
                                        // 除外対象カラムをselect句から除外する置換処理を行う
148
                                        selectClause = selectClause.replaceAll(excludeCols.stream()
1✔
149
                                                        .map(TableMetadata.Column::getColumnIdentifier)
1✔
150
                                                        .collect(Collectors.joining("|", "\\s*,*\\s+(", ").+")), "");
1✔
151
                                        // SELECT句の直後にカンマがくる場合はそのカンマを除外する
152
                                        selectClause = selectClause.replaceFirst("(SELECT.+\\s*)(,)", "$1 ");
1✔
153
                                }
154
                        }
155
                        var sql = new StringBuilder(selectClause).append(getWhereClause())
1✔
156
                                        .append(getOrderByClause());
1✔
157
                        if (dialect.supportsLimitClause()) {
1✔
158
                                sql.append(dialect.getLimitClause(this.limit, this.offset));
1✔
159
                        }
160
                        if (this.forUpdateType != null) {
1✔
161
                                sql = dialect.addForUpdateClause(sql, this.forUpdateType, this.waitSeconds);
1✔
162
                        }
163
                        if (!this.optimizerHints.isEmpty()) {
1✔
164
                                sql = dialect.addOptimizerHints(sql, this.optimizerHints);
1✔
165
                        }
166
                        context().setSql(sql.toString());
1✔
167
                        return this.entityHandler.doSelect(agent(), context(), this.entityType);
1✔
NEW
168
                } catch (final SQLException ex) {
×
NEW
169
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
170
                }
171
        }
172

173
        /**
174
         * {@inheritDoc}
175
         *
176
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#select(java.lang.String, java.lang.Class)
177
         */
178
        @Override
179
        public <C> Stream<C> select(final String col, final Class<C> type) {
180
                var fieldName = CaseFormat.CAMEL_CASE.convert(col);
1✔
181
                var field = BeanAccessor.fields(entityType).stream()
1✔
182
                                .filter(f -> f.getName().equalsIgnoreCase(fieldName))
1✔
183
                                .findFirst()
1✔
184
                                .orElseThrow(() -> new UroborosqlRuntimeException(
1✔
185
                                                "field:" + fieldName + " not found in " + entityType.getSimpleName() + "."));
1✔
186
                includeColumns(fieldName);
1✔
187

188
                return stream().map(e -> type.cast(BeanAccessor.value(field, e)));
1✔
189
        }
190

191
        /**
192
         * 集計関数で集計する元となるSQL文字列を生成する.<br>
193
         * 集計する場合はソートする必要がないので order by が除かれている
194
         *
195
         * @return 集計関数で集計する元となるSQL文字列
196
         */
197
        private StringBuilder aggregationSourceSql() {
198
                var sql = new StringBuilder(context().getSql()).append(getWhereClause());
1✔
199
                if (dialect.supportsLimitClause()) {
1✔
200
                        sql.append(dialect.getLimitClause(this.limit, this.offset));
1✔
201
                }
202
                if (this.forUpdateType != null) {
1✔
203
                        sql = dialect.addForUpdateClause(sql, this.forUpdateType, this.waitSeconds);
1✔
204
                }
205
                return sql;
1✔
206
        }
207

208
        /**
209
         * {@inheritDoc}
210
         *
211
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#count()
212
         */
213
        @Override
214
        public long count() {
215
                return count(null);
1✔
216
        }
217

218
        /**
219
         * {@inheritDoc}
220
         *
221
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#count(java.lang.String)
222
         */
223
        @Override
224
        public long count(final String col) {
225
                var expr = col != null
1✔
226
                                ? tableMetadata().getColumn(CaseFormat.CAMEL_CASE.convert(col)).getColumnIdentifier()
1✔
227
                                : "*";
1✔
228
                var sql = new StringBuilder("select count(").append(expr).append(") from (")
1✔
229
                                .append(System.lineSeparator())
1✔
230
                                .append(aggregationSourceSql())
1✔
231
                                .append(System.lineSeparator())
1✔
232
                                .append(") t_");
1✔
233
                context().setSql(sql.toString());
1✔
234
                try (var rs = agent().query(context())) {
1✔
235
                        rs.next();
1✔
236
                        return rs.getLong(1);
1✔
NEW
237
                } catch (final SQLException ex) {
×
NEW
238
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
239
                }
240
        }
241

242
        /**
243
         * {@inheritDoc}
244
         *
245
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#sum(java.lang.String)
246
         */
247
        @SuppressWarnings("unchecked")
248
        @Override
249
        public <T> T sum(final String col) {
250
                var camelColumnName = CaseFormat.CAMEL_CASE.convert(col);
1✔
251
                var mappingColumn = MappingUtils.getMappingColumn(context().getSchema(), entityType, camelColumnName);
1✔
252
                if (!mappingColumn.isNumber()) {
1✔
253
                        throw new UroborosqlRuntimeException("Column is not of type Number. col=" + camelColumnName);
1✔
254
                }
255
                var column = tableMetadata().getColumn(camelColumnName);
1✔
256
                var sql = new StringBuilder("select sum(t_.").append(column.getColumnIdentifier()).append(") as ")
1✔
257
                                .append(column.getColumnIdentifier()).append(" from (")
1✔
258
                                .append(System.lineSeparator())
1✔
259
                                .append(aggregationSourceSql())
1✔
260
                                .append(System.lineSeparator())
1✔
261
                                .append(") t_");
1✔
262
                context().setSql(sql.toString());
1✔
263
                try {
264
                        return (T) mappingColumn
1✔
265
                                        .getValue(this.entityHandler.doSelect(agent(), context(), this.entityType).findFirst().get());
1✔
NEW
266
                } catch (final SQLException ex) {
×
NEW
267
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
268
                }
269
        }
270

271
        /**
272
         * {@inheritDoc}
273
         *
274
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#min(java.lang.String)
275
         */
276
        @SuppressWarnings("unchecked")
277
        @Override
278
        public <T> T min(final String col) {
279
                var camelColumnName = CaseFormat.CAMEL_CASE.convert(col);
1✔
280
                var mappingColumn = MappingUtils.getMappingColumn(context().getSchema(), entityType, camelColumnName);
1✔
281
                var column = tableMetadata().getColumn(camelColumnName);
1✔
282
                var sql = new StringBuilder("select min(t_.").append(column.getColumnIdentifier()).append(") as ")
1✔
283
                                .append(column.getColumnIdentifier()).append(" from (")
1✔
284
                                .append(System.lineSeparator())
1✔
285
                                .append(aggregationSourceSql())
1✔
286
                                .append(System.lineSeparator())
1✔
287
                                .append(") t_");
1✔
288
                context().setSql(sql.toString());
1✔
289
                try {
290
                        return (T) mappingColumn
1✔
291
                                        .getValue(this.entityHandler.doSelect(agent(), context(), this.entityType).findFirst().get());
1✔
NEW
292
                } catch (SQLException ex) {
×
NEW
293
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
294
                }
295
        }
296

297
        /**
298
         * {@inheritDoc}
299
         *
300
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#max(java.lang.String)
301
         */
302
        @SuppressWarnings("unchecked")
303
        @Override
304
        public <T> T max(final String col) {
305
                var camelColumnName = CaseFormat.CAMEL_CASE.convert(col);
1✔
306
                var mappingColumn = MappingUtils.getMappingColumn(context().getSchema(), entityType, camelColumnName);
1✔
307
                var column = tableMetadata().getColumn(camelColumnName);
1✔
308
                var sql = new StringBuilder("select max(t_.").append(column.getColumnIdentifier()).append(") as ")
1✔
309
                                .append(column.getColumnIdentifier()).append(" from (")
1✔
310
                                .append(System.lineSeparator())
1✔
311
                                .append(aggregationSourceSql())
1✔
312
                                .append(System.lineSeparator())
1✔
313
                                .append(") t_");
1✔
314
                context().setSql(sql.toString());
1✔
315
                try {
316
                        return (T) mappingColumn
1✔
317
                                        .getValue(this.entityHandler.doSelect(agent(), context(), this.entityType).findFirst().get());
1✔
NEW
318
                } catch (SQLException ex) {
×
NEW
319
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
320
                }
321
        }
322

323
        /**
324
         * {@inheritDoc}
325
         *
326
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#exists(java.lang.Runnable)
327
         */
328
        @Override
329
        public void exists(final Runnable runnable) {
330
                var sql = new StringBuilder("select 1 from (")
1✔
331
                                .append(System.lineSeparator())
1✔
332
                                .append(aggregationSourceSql())
1✔
333
                                .append(System.lineSeparator())
1✔
334
                                .append(") t_");
1✔
335
                context().setSql(sql.toString());
1✔
336
                try (var rs = agent().query(context())) {
1✔
337
                        if (rs.next()) {
1✔
338
                                runnable.run();
×
339
                        }
NEW
340
                } catch (final SQLException ex) {
×
NEW
341
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
342
                }
1✔
343
        }
1✔
344

345
        /**
346
         * {@inheritDoc}
347
         *
348
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#notExists(java.lang.Runnable)
349
         */
350
        @Override
351
        public void notExists(final Runnable runnable) {
352
                var sql = new StringBuilder("select 1 from (")
1✔
353
                                .append(System.lineSeparator())
1✔
354
                                .append(aggregationSourceSql())
1✔
355
                                .append(System.lineSeparator())
1✔
356
                                .append(") t_");
1✔
357
                context().setSql(sql.toString());
1✔
358
                try (var rs = agent().query(context())) {
1✔
359
                        if (!rs.next()) {
1✔
360
                                runnable.run();
×
361
                        }
NEW
362
                } catch (final SQLException ex) {
×
NEW
363
                        throw new EntitySqlRuntimeException(context().getSqlKind(), ex);
×
364
                }
1✔
365
        }
1✔
366

367
        /**
368
         * ORDER BY句を生成する
369
         *
370
         * @return ORDER BY句の文字列
371
         */
372
        @SuppressWarnings("unchecked")
373
        private String getOrderByClause() {
374
                var firstFlag = true;
1✔
375
                List<TableMetadata.Column> keys;
376
                var existsSortOrders = new HashMap<TableMetadata.Column, SortOrder>();
1✔
377

378
                if (this.sortOrders.isEmpty()) {
1✔
379
                        // ソート条件の指定がない場合は主キーでソートする
380
                        keys = (List<TableMetadata.Column>) tableMetadata().getKeyColumns();
1✔
381
                        for (var key : keys) {
1✔
382
                                existsSortOrders.put(key, new SortOrder(key.getCamelColumnName(), Order.ASCENDING));
1✔
383
                        }
1✔
384
                } else {
385
                        // ソート条件の指定がある場合は指定されたカラムでソートする
386
                        keys = new ArrayList<>();
1✔
387
                        for (var sortOrder : sortOrders) {
1✔
388
                                for (var metaCol : tableMetadata().getColumns()) {
1✔
389
                                        if (sortOrder.getCol().equals(metaCol.getCamelColumnName())) {
1✔
390
                                                keys.add(metaCol);
1✔
391
                                                existsSortOrders.put(metaCol, sortOrder);
1✔
392
                                                break;
1✔
393
                                        }
394
                                }
1✔
395
                        }
1✔
396
                }
397

398
                if (!keys.isEmpty()) {
1✔
399
                        var sql = new StringBuilder();
1✔
400
                        sql.append("ORDER BY").append(System.lineSeparator());
1✔
401
                        firstFlag = true;
1✔
402
                        for (final TableMetadata.Column key : keys) {
1✔
403
                                var sortOrder = existsSortOrders.get(key);
1✔
404
                                sql.append("\t");
1✔
405
                                if (firstFlag) {
1✔
406
                                        sql.append("  ");
1✔
407
                                        firstFlag = false;
1✔
408
                                } else {
409
                                        sql.append(", ");
1✔
410
                                }
411
                                sql.append(key.getColumnIdentifier()).append(" ").append(sortOrder.getOrder().toString());
1✔
412
                                if (dialect.supportsNullValuesOrdering()) {
1✔
413
                                        sql.append(" ").append(sortOrder.getNulls().toString());
1✔
414
                                }
415
                                sql.append(System.lineSeparator());
1✔
416
                        }
1✔
417
                        return sql.toString();
1✔
418
                } else {
419
                        return "";
1✔
420
                }
421
        }
422

423
        /**
424
         * {@inheritDoc}
425
         *
426
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#asc(java.lang.String[])
427
         */
428
        @Override
429
        public SqlEntityQuery<E> asc(final String... cols) {
430
                for (var col : cols) {
1✔
431
                        this.sortOrders.add(new SortOrder(col, Order.ASCENDING));
1✔
432
                }
433
                return this;
1✔
434
        }
435

436
        /**
437
         * {@inheritDoc}
438
         *
439
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#asc(java.lang.String, jp.co.future.uroborosql.fluent.SqlEntityQuery.Nulls)
440
         */
441
        @Override
442
        public SqlEntityQuery<E> asc(final String col, final Nulls nulls) {
443
                this.sortOrders.add(new SortOrder(col, Order.ASCENDING, nulls));
1✔
444
                return this;
1✔
445
        }
446

447
        /**
448
         * {@inheritDoc}
449
         *
450
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#desc(java.lang.String[])
451
         */
452
        @Override
453
        public SqlEntityQuery<E> desc(final String... cols) {
454
                for (var col : cols) {
1✔
455
                        this.sortOrders.add(new SortOrder(col, Order.DESCENDING));
1✔
456
                }
457
                return this;
1✔
458
        }
459

460
        /**
461
         * {@inheritDoc}
462
         *
463
        s         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#desc(java.lang.String, jp.co.future.uroborosql.fluent.SqlEntityQuery.Nulls)
464
         */
465
        @Override
466
        public SqlEntityQuery<E> desc(final String col, final Nulls nulls) {
467
                this.sortOrders.add(new SortOrder(col, Order.DESCENDING, nulls));
1✔
468
                return this;
1✔
469
        }
470

471
        /**
472
         * {@inheritDoc}
473
         *
474
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#limit(long)
475
         */
476
        @Override
477
        public SqlEntityQuery<E> limit(final long limit) {
478
                if (!dialect.supportsLimitClause()) {
1✔
479
                        throw new UroborosqlRuntimeException("Unsupported limit clause.");
×
480
                }
481
                this.limit = limit;
1✔
482
                return this;
1✔
483
        }
484

485
        /**
486
         * {@inheritDoc}
487
         *
488
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#offset(long)
489
         */
490
        @Override
491
        public SqlEntityQuery<E> offset(final long offset) {
492
                if (!dialect.supportsLimitClause()) {
1✔
493
                        throw new UroborosqlRuntimeException("Unsupported offset clause.");
×
494
                }
495
                this.offset = offset;
1✔
496
                return this;
1✔
497
        }
498

499
        /**
500
         * {@inheritDoc}
501
         *
502
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#forUpdate()
503
         */
504
        @Override
505
        public SqlEntityQuery<E> forUpdate() {
506
                if (dialect.supportsForUpdate()) {
1✔
507
                        this.forUpdateType = ForUpdateType.NORMAL;
1✔
508
                        return this;
1✔
509
                } else {
510
                        throw new UroborosqlRuntimeException("Unsupported for update clause.");
×
511
                }
512
        }
513

514
        /**
515
         * {@inheritDoc}
516
         *
517
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#forUpdateNoWait()
518
         */
519
        @Override
520
        public SqlEntityQuery<E> forUpdateNoWait() {
521
                if (dialect.supportsForUpdateNoWait()) {
1✔
522
                        this.forUpdateType = ForUpdateType.NOWAIT;
×
523
                        return this;
×
524
                } else if (!agent().getSqlConfig().getSqlAgentProvider().isStrictForUpdateType()
1✔
525
                                && dialect.supportsForUpdate()) {
1✔
526
                        if (LOG.isWarnEnabled()) {
1✔
527
                                LOG.warn("'FOR UPDATE NOWAIT' is not supported. Set 'FOR UPDATE' instead.");
1✔
528
                        }
529
                        this.forUpdateType = ForUpdateType.NORMAL;
1✔
530
                        return this;
1✔
531
                } else {
532
                        throw new UroborosqlRuntimeException("Unsupported for update nowait clause.");
1✔
533
                }
534
        }
535

536
        /**
537
         * {@inheritDoc}
538
         *
539
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#forUpdateWait()
540
         */
541
        @Override
542
        public SqlEntityQuery<E> forUpdateWait() {
543
                if (dialect.supportsForUpdateWait()) {
1✔
544
                        return forUpdateWait(agent().getSqlConfig().getSqlAgentProvider().getDefaultForUpdateWaitSeconds());
×
545
                } else if (!agent().getSqlConfig().getSqlAgentProvider().isStrictForUpdateType()
1✔
546
                                && dialect.supportsForUpdate()) {
1✔
547
                        if (LOG.isWarnEnabled()) {
1✔
548
                                LOG.warn("'FOR UPDATE WAIT' is not supported. Set 'FOR UPDATE' instead.");
1✔
549
                        }
550
                        this.forUpdateType = ForUpdateType.NORMAL;
1✔
551
                        return this;
1✔
552
                } else {
553
                        throw new UroborosqlRuntimeException("Unsupported for update wait clause.");
1✔
554
                }
555
        }
556

557
        /**
558
         * {@inheritDoc}
559
         *
560
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#forUpdateWait(int)
561
         */
562
        @Override
563
        public SqlEntityQuery<E> forUpdateWait(final int waitSeconds) {
564
                if (dialect.supportsForUpdateWait()) {
1✔
565
                        this.forUpdateType = ForUpdateType.WAIT;
×
566
                        this.waitSeconds = waitSeconds;
×
567
                        return this;
×
568
                } else if (!agent().getSqlConfig().getSqlAgentProvider().isStrictForUpdateType()
1✔
569
                                && dialect.supportsForUpdate()) {
1✔
570
                        if (LOG.isWarnEnabled()) {
1✔
571
                                LOG.warn("'FOR UPDATE WAIT' is not supported. Set 'FOR UPDATE' instead.");
1✔
572
                        }
573
                        this.forUpdateType = ForUpdateType.NORMAL;
1✔
574
                        return this;
1✔
575
                } else {
576
                        throw new UroborosqlRuntimeException("Unsupported for update wait clause.");
1✔
577
                }
578
        }
579

580
        /**
581
         * {@inheritDoc}
582
         *
583
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#hint(java.lang.String)
584
         */
585
        @Override
586
        public SqlEntityQuery<E> hint(final String hint) {
587
                if (dialect.supportsOptimizerHints()) {
1✔
588
                        this.optimizerHints.add(hint);
1✔
589
                } else {
NEW
590
                        if (LOG.isWarnEnabled()) {
×
NEW
591
                                LOG.warn("Optimizer Hints is not supported.");
×
592
                        }
593
                }
594
                return this;
1✔
595
        }
596

597
        /**
598
         * {@inheritDoc}
599
         *
600
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#includeColumns(java.lang.String[])
601
         */
602
        @Override
603
        public SqlEntityQuery<E> includeColumns(final String... cols) {
604
                if (cols != null && cols.length != 0) {
1✔
605
                        for (var col : cols) {
1✔
606
                                includeColumns.add(CaseFormat.CAMEL_CASE.convert(col));
1✔
607
                        }
608
                }
609
                return this;
1✔
610
        }
611

612
        /**
613
         * {@inheritDoc}
614
         *
615
         * @see jp.co.future.uroborosql.fluent.SqlEntityQuery#excludeColumns(java.lang.String[])
616
         */
617
        @Override
618
        public SqlEntityQuery<E> excludeColumns(final String... cols) {
619
                if (cols != null && cols.length != 0) {
1✔
620
                        for (var col : cols) {
1✔
621
                                excludeColumns.add(CaseFormat.CAMEL_CASE.convert(col));
1✔
622
                        }
623
                }
624
                return this;
1✔
625
        }
626

627
        /**
628
         * Sort Order
629
         */
630
        private static class SortOrder {
631
                private final String col;
632
                private final Order order;
633
                private final Nulls nulls;
634

635
                /**
636
                 * Constructor
637
                 *
638
                 * @param col sort column name (camelCase)
639
                 * @param order {@link Order}
640
                 */
641
                SortOrder(final String col, final Order order) {
642
                        this(col, order, Nulls.LAST);
1✔
643
                }
1✔
644

645
                /**
646
                 * Constructor
647
                 *
648
                 * @param col sort column name (camelCase)
649
                 * @param order {@link Order}
650
                 * @param nulls {@link Nulls}
651
                 */
652
                SortOrder(final String col, final Order order, final Nulls nulls) {
1✔
653
                        if (col == null) {
1✔
654
                                throw new UroborosqlRuntimeException("argument col is required.");
×
655
                        }
656
                        this.col = CaseFormat.CAMEL_CASE.convert(col);
1✔
657
                        this.order = order != null ? order : Order.ASCENDING;
1✔
658
                        this.nulls = nulls != null ? nulls : Nulls.LAST;
1✔
659
                }
1✔
660

661
                final String getCol() {
662
                        return col;
1✔
663
                }
664

665
                final Order getOrder() {
666
                        return order;
1✔
667
                }
668

669
                final Nulls getNulls() {
670
                        return nulls;
1✔
671
                }
672
        }
673
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc