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

future-architect / uroborosql / #929

26 Oct 2025 08:30AM UTC coverage: 90.839% (+0.05%) from 90.787%
#929

Pull #374

Copilot
Remove unused import from test class

- Removed unused containsString import from SqlEntityQueryMultiColumnInTest

Co-authored-by: HidekiSugimoto189 <21981922+HidekiSugimoto189@users.noreply.github.com>
Pull Request #374: Add multi-column IN clause support for DAO query interface

77 of 79 new or added lines in 1 file covered. (97.47%)

5 existing lines in 1 file now uncovered.

9291 of 10228 relevant lines covered (90.84%)

0.91 hits per line

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

98.55
/src/main/java/jp/co/future/uroborosql/AbstractExtractionCondition.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.util.ArrayList;
10
import java.util.List;
11
import java.util.Map;
12
import java.util.Objects;
13

14
import jp.co.future.uroborosql.context.ExecutionContext;
15
import jp.co.future.uroborosql.fluent.ExtractionCondition;
16
import jp.co.future.uroborosql.mapping.TableMetadata;
17
import jp.co.future.uroborosql.utils.BeanAccessor;
18
import jp.co.future.uroborosql.utils.CaseFormat;
19
import jp.co.future.uroborosql.utils.ObjectUtils;
20

21
/**
22
 * 抽出条件の生成を担当するクラス
23
 *
24
 * @param <T> SqlFluent型を継承するSqlEntity実装型
25
 * @author H.Sugimoto
26
 */
27
abstract class AbstractExtractionCondition<T extends ExtractionCondition<T>> implements ExtractionCondition<T> {
28
        /** 抽出条件のパラメータ名に付与するプレフィックス */
29
        protected static final String PREFIX = "_";
30

31
        /** SqlAgent. */
32
        private final SqlAgent agent;
33

34
        /** ExecutionContext. */
35
        private final ExecutionContext context;
36

37
        /** テーブルメタデータ */
38
        private final TableMetadata tableMetadata;
39

40
        /** where句文字列 */
41
        private final List<CharSequence> rawStrings;
42

43
        /** オペレータを使用したかどうか */
44
        private boolean useOperator = false;
1✔
45

46
        /**
47
         * Constructor
48
         *
49
         * @param agent SqlAgent
50
         * @param tableMetadata TableMetadata
51
         * @param context ExecutionContext
52
         */
53
        AbstractExtractionCondition(final SqlAgent agent, final TableMetadata tableMetadata,
54
                        final ExecutionContext context) {
1✔
55
                this.agent = agent;
1✔
56
                this.context = context;
1✔
57
                this.tableMetadata = tableMetadata;
1✔
58
                context.setSchema(tableMetadata.getSchema());
1✔
59
                this.rawStrings = new ArrayList<>();
1✔
60
                this.useOperator = false;
1✔
61
        }
1✔
62

63
        /**
64
         * SqlAgentの取得.
65
         *
66
         * @return SqlAgent
67
         */
68
        protected SqlAgent agent() {
69
                return agent;
1✔
70
        }
71

72
        /**
73
         * ExecutionContextの取得.
74
         * @return ExecutionContext
75
         */
76
        protected ExecutionContext context() {
77
                return context;
1✔
78
        }
79

80
        /**
81
         * TableMetadataの取得.
82
         * @return TableMetadata
83
         */
84
        protected TableMetadata tableMetadata() {
85
                return tableMetadata;
1✔
86
        }
87

88
        /**
89
         * WHERE句を生成する
90
         *
91
         * @return WHERE句の文字列
92
         */
93
        protected String getWhereClause() {
94
                var where = new StringBuilder();
1✔
95
                
96
                // MultiColumnIn operator の特別処理
97
                if (this.useOperator) {
1✔
98
                        var multiColumnInParam = context().getParam(PREFIX + "multiColumnIn");
1✔
99
                        if (multiColumnInParam != null && multiColumnInParam.getValue() instanceof MultiColumnIn) {
1✔
100
                                var ope = (MultiColumnIn<?>) multiColumnInParam.getValue();
1✔
101
                                where.append("\t").append("AND ");
1✔
102
                                where.append(buildMultiColumnInClause(ope)).append(System.lineSeparator());
1✔
103
                        }
104
                }
105
                
106
                for (var col : this.tableMetadata.getColumns()) {
1✔
107
                        var camelColName = col.getCamelColumnName();
1✔
108

109
                        if (this.useOperator) {
1✔
110
                                var param = context().getParam(PREFIX + camelColName);
1✔
111
                                if (param != null && param.getValue() instanceof Operator) {
1✔
112
                                        var ope = (Operator) param.getValue();
1✔
113
                                        where.append("\t").append("AND ");
1✔
114
                                        if (ope.useColumnIdentifier()) {
1✔
115
                                                where.append(col.getColumnIdentifier());
1✔
116
                                        }
117
                                        where.append(ope.toConditionString()).append(System.lineSeparator());
1✔
118
                                }
119
                        } else {
1✔
120
                                var param = context().getParam(camelColName);
1✔
121
                                if (param != null) {
1✔
UNCOV
122
                                        where.append("\t").append("AND ").append(col.getColumnIdentifier())
×
UNCOV
123
                                                        .append(" = ").append("/*").append(camelColName).append("*/''")
×
UNCOV
124
                                                        .append(System.lineSeparator());
×
125
                                }
126
                        }
127
                }
1✔
128
                if (!this.rawStrings.isEmpty()) {
1✔
129
                        for (var raw : rawStrings) {
1✔
130
                                if (where.length() > 0) {
1✔
131
                                        where.append("\t").append("AND ( ").append(raw).append(" )").append(System.lineSeparator());
1✔
132
                                } else {
133
                                        where.append("\t").append("( ").append(raw).append(" )").append(System.lineSeparator());
1✔
134
                                }
135
                        }
1✔
136
                }
137

138
                if (where.length() > 0) {
1✔
139
                        return new StringBuilder().append("WHERE").append(System.lineSeparator()).append(where.toString())
1✔
140
                                        .toString();
1✔
141
                } else {
142
                        return "";
1✔
143
                }
144
        }
145

146
        /**
147
         * MultiColumnIn用のWHERE句を生成する
148
         *
149
         * @param ope MultiColumnIn Operator
150
         * @return WHERE句の文字列
151
         */
152
        private String buildMultiColumnInClause(final MultiColumnIn<?> ope) {
153
                var columnNames = ope.getColumnNames();
1✔
154
                var beans = ope.getBeans();
1✔
155
                var beansList = new ArrayList<>();
1✔
156
                beans.forEach(beansList::add);
1✔
157
                
158
                if (columnNames.isEmpty() || beansList.isEmpty()) {
1✔
159
                        return "1 = 0"; // 空の場合は常に偽の条件を返す
1✔
160
                }
161
                
162
                // カラム名リストの構築
163
                var columns = new StringBuilder("(");
1✔
164
                var firstCol = true;
1✔
165
                for (var columnName : columnNames) {
1✔
166
                        var column = this.tableMetadata.getColumn(columnName);
1✔
167
                        if (column != null) {
1✔
168
                                if (!firstCol) {
1✔
169
                                        columns.append(", ");
1✔
170
                                }
171
                                columns.append(column.getColumnIdentifier());
1✔
172
                                firstCol = false;
1✔
173
                        }
174
                }
1✔
175
                columns.append(")");
1✔
176
                
177
                // タプルリストの構築
178
                var tuples = new StringBuilder("(");
1✔
179
                var firstBean = true;
1✔
180
                var rowIndex = 0;
1✔
181
                
182
                for (var bean : beansList) {
1✔
183
                        if (!firstBean) {
1✔
184
                                tuples.append(", ");
1✔
185
                        }
186
                        
187
                        // 各Beanからフィールド値を取得してタプルを作成
188
                        var fields = BeanAccessor.fields(bean.getClass());
1✔
189
                        var tuple = new StringBuilder("(");
1✔
190
                        var firstField = true;
1✔
191
                        var colIndex = 0;
1✔
192
                        
193
                        for (var field : fields) {
1✔
194
                                var fieldName = CaseFormat.CAMEL_CASE.convert(field.getName());
1✔
195
                                var column = this.tableMetadata.getColumn(fieldName);
1✔
196
                                if (column != null) {
1✔
197
                                        if (!firstField) {
1✔
198
                                                tuple.append(", ");
1✔
199
                                        }
200
                                        
201
                                        // パラメータをコンテキストに追加
202
                                        var paramName = ope.getParamNamePrefix() + "_" + rowIndex + "_" + colIndex;
1✔
203
                                        var value = BeanAccessor.value(field, bean);
1✔
204
                                        context().param(paramName, value);
1✔
205
                                        
206
                                        // パラメータバインド用のマーカーを追加
207
                                        tuple.append("/*").append(paramName).append("*/''");
1✔
208
                                        
209
                                        firstField = false;
1✔
210
                                        colIndex++;
1✔
211
                                }
212
                        }
1✔
213
                        tuple.append(")");
1✔
214
                        tuples.append(tuple);
1✔
215
                        
216
                        firstBean = false;
1✔
217
                        rowIndex++;
1✔
218
                }
1✔
219
                tuples.append(")");
1✔
220
                
221
                // 完全な条件式を返す
222
                return columns + " " + ope.getOperator() + " " + tuples;
1✔
223
        }
224

225
        /**
226
         * {@inheritDoc}
227
         *
228
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#equal(java.lang.String, java.lang.Object)
229
         */
230
        @SuppressWarnings("unchecked")
231
        @Override
232
        public <V> T equal(final String col, final V value) {
233
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new Equal<>(col, value));
1✔
234
                this.useOperator = true;
1✔
235
                return (T) this;
1✔
236
        }
237

238
        /**
239
         * {@inheritDoc}
240
         *
241
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#equalIfNotEmpty(java.lang.String, java.lang.Object)
242
         */
243
        @SuppressWarnings("unchecked")
244
        @Override
245
        public <V> T equalIfNotEmpty(final String col, final V value) {
246
                if (ObjectUtils.isNotEmpty(value)) {
1✔
247
                        this.equal(col, value);
1✔
248
                }
249
                return (T) this;
1✔
250
        }
251

252
        /**
253
         * {@inheritDoc}
254
         *
255
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notEqual(java.lang.String, java.lang.Object)
256
         */
257
        @SuppressWarnings("unchecked")
258
        @Override
259
        public <V> T notEqual(final String col, final V value) {
260
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new NotEqual<>(col, value));
1✔
261
                this.useOperator = true;
1✔
262
                return (T) this;
1✔
263
        }
264

265
        /**
266
         * {@inheritDoc}
267
         *
268
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notEqualIfNotEmpty(java.lang.String, java.lang.Object)
269
         */
270
        @SuppressWarnings("unchecked")
271
        @Override
272
        public <V> T notEqualIfNotEmpty(final String col, final V value) {
273
                if (ObjectUtils.isNotEmpty(value)) {
1✔
274
                        this.notEqual(col, value);
1✔
275
                }
276
                return (T) this;
1✔
277
        }
278

279
        /**
280
         * {@inheritDoc}
281
         *
282
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#greaterThan(java.lang.String, java.lang.Object)
283
         */
284
        @SuppressWarnings("unchecked")
285
        @Override
286
        public <V> T greaterThan(final String col, final V value) {
287
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new GreaterThan<>(col, value));
1✔
288
                this.useOperator = true;
1✔
289
                return (T) this;
1✔
290
        }
291

292
        /**
293
         * {@inheritDoc}
294
         *
295
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#lessThan(java.lang.String, java.lang.Object)
296
         */
297
        @SuppressWarnings("unchecked")
298
        @Override
299
        public <V> T lessThan(final String col, final V value) {
300
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new LessThan<>(col, value));
1✔
301
                this.useOperator = true;
1✔
302
                return (T) this;
1✔
303
        }
304

305
        /**
306
         * {@inheritDoc}
307
         *
308
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#greaterEqual(java.lang.String, java.lang.Object)
309
         */
310
        @SuppressWarnings("unchecked")
311
        @Override
312
        public <V> T greaterEqual(final String col, final V value) {
313
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new GreaterEqual<>(col, value));
1✔
314
                this.useOperator = true;
1✔
315
                return (T) this;
1✔
316
        }
317

318
        /**
319
         * {@inheritDoc}
320
         *
321
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#lessEqual(java.lang.String, java.lang.Object)
322
         */
323
        @SuppressWarnings("unchecked")
324
        @Override
325
        public <V> T lessEqual(final String col, final V value) {
326
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new LessEqual<>(col, value));
1✔
327
                this.useOperator = true;
1✔
328
                return (T) this;
1✔
329
        }
330

331
        /**
332
         * {@inheritDoc}
333
         *
334
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#in(java.lang.String, java.lang.Object[])
335
         */
336
        @SuppressWarnings("unchecked")
337
        @Override
338
        public <V> T in(final String col, final V... values) {
339
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new In<>(col, values));
1✔
340
                this.useOperator = true;
1✔
341
                return (T) this;
1✔
342
        }
343

344
        /**
345
         * {@inheritDoc}
346
         *
347
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#in(java.lang.String, java.lang.Iterable)
348
         */
349
        @SuppressWarnings("unchecked")
350
        @Override
351
        public <V> T in(final String col, final Iterable<V> valueList) {
352
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new In<>(col, valueList));
1✔
353
                this.useOperator = true;
1✔
354
                return (T) this;
1✔
355
        }
356

357
        /**
358
         * {@inheritDoc}
359
         *
360
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notIn(java.lang.String, java.lang.Object[])
361
         */
362
        @SuppressWarnings("unchecked")
363
        @Override
364
        public <V> T notIn(final String col, final V... values) {
365
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new NotIn<>(col, values));
1✔
366
                this.useOperator = true;
1✔
367
                return (T) this;
1✔
368
        }
369

370
        /**
371
         * {@inheritDoc}
372
         *
373
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notIn(java.lang.String, java.lang.Iterable)
374
         */
375
        @SuppressWarnings("unchecked")
376
        @Override
377
        public <V> T notIn(final String col, final Iterable<V> valueList) {
378
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new NotIn<>(col, valueList));
1✔
379
                this.useOperator = true;
1✔
380
                return (T) this;
1✔
381
        }
382

383
        /**
384
         * {@inheritDoc}
385
         *
386
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#in(java.lang.Iterable)
387
         */
388
        @SuppressWarnings("unchecked")
389
        @Override
390
        public <V> T in(final Iterable<V> beans) {
391
                context().param(PREFIX + "multiColumnIn", new MultiColumnIn<>(beans, this.tableMetadata));
1✔
392
                this.useOperator = true;
1✔
393
                return (T) this;
1✔
394
        }
395

396
        /**
397
         * {@inheritDoc}
398
         *
399
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#like(java.lang.String, java.lang.CharSequence)
400
         */
401
        @SuppressWarnings("unchecked")
402
        @Override
403
        public T like(final String col, final CharSequence searchValue) {
404
                var dialect = agent().getSqlConfig().getDialect();
1✔
405
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
406
                                new Like(col, searchValue, dialect.getEscapeChar()));
1✔
407
                this.useOperator = true;
1✔
408
                return (T) this;
1✔
409
        }
410

411
        /**
412
         * {@inheritDoc}
413
         *
414
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#startsWith(java.lang.String, java.lang.CharSequence)
415
         */
416
        @SuppressWarnings("unchecked")
417
        @Override
418
        public T startsWith(final String col, final CharSequence searchValue) {
419
                var dialect = agent().getSqlConfig().getDialect();
1✔
420
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
421
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
422
                                new Like(col, escaped, true, dialect.getEscapeChar()));
1✔
423
                this.useOperator = true;
1✔
424
                return (T) this;
1✔
425
        }
426

427
        /**
428
         * {@inheritDoc}
429
         *
430
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#endsWith(java.lang.String, java.lang.CharSequence)
431
         */
432
        @SuppressWarnings("unchecked")
433
        @Override
434
        public T endsWith(final String col, final CharSequence searchValue) {
435
                var dialect = agent().getSqlConfig().getDialect();
1✔
436
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
437
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
438
                                new Like(col, true, escaped, dialect.getEscapeChar()));
1✔
439
                this.useOperator = true;
1✔
440
                return (T) this;
1✔
441
        }
442

443
        /**
444
         * {@inheritDoc}
445
         *
446
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#contains(java.lang.String, java.lang.CharSequence)
447
         */
448
        @SuppressWarnings("unchecked")
449
        @Override
450
        public T contains(final String col, final CharSequence searchValue) {
451
                var dialect = agent().getSqlConfig().getDialect();
1✔
452
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
453
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
454
                                new Like(col, true, escaped, true, dialect.getEscapeChar()));
1✔
455
                this.useOperator = true;
1✔
456
                return (T) this;
1✔
457
        }
458

459
        /**
460
         * {@inheritDoc}
461
         *
462
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notLike(java.lang.String, java.lang.CharSequence)
463
         */
464
        @SuppressWarnings("unchecked")
465
        @Override
466
        public T notLike(final String col, final CharSequence searchValue) {
467
                var dialect = agent().getSqlConfig().getDialect();
1✔
468
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
469
                                new NotLike(col, searchValue, dialect.getEscapeChar()));
1✔
470
                this.useOperator = true;
1✔
471
                return (T) this;
1✔
472
        }
473

474
        /**
475
         * {@inheritDoc}
476
         *
477
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notStartsWith(java.lang.String, java.lang.CharSequence)
478
         */
479
        @SuppressWarnings("unchecked")
480
        @Override
481
        public T notStartsWith(final String col, final CharSequence searchValue) {
482
                var dialect = agent().getSqlConfig().getDialect();
1✔
483
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
484
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
485
                                new NotLike(col, escaped, true, dialect.getEscapeChar()));
1✔
486
                this.useOperator = true;
1✔
487
                return (T) this;
1✔
488
        }
489

490
        /**
491
         * {@inheritDoc}
492
         *
493
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notEndsWith(java.lang.String, java.lang.CharSequence)
494
         */
495
        @SuppressWarnings("unchecked")
496
        @Override
497
        public T notEndsWith(final String col, final CharSequence searchValue) {
498
                var dialect = agent().getSqlConfig().getDialect();
1✔
499
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
500
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
501
                                new NotLike(col, true, escaped, dialect.getEscapeChar()));
1✔
502
                this.useOperator = true;
1✔
503
                return (T) this;
1✔
504
        }
505

506
        /**
507
         * {@inheritDoc}
508
         *
509
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notContains(java.lang.String, java.lang.CharSequence)
510
         */
511
        @SuppressWarnings("unchecked")
512
        @Override
513
        public T notContains(final String col, final CharSequence searchValue) {
514
                var dialect = agent().getSqlConfig().getDialect();
1✔
515
                var escaped = dialect.escapeLikePattern(searchValue);
1✔
516
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col),
1✔
517
                                new NotLike(col, true, escaped, true, dialect.getEscapeChar()));
1✔
518
                this.useOperator = true;
1✔
519
                return (T) this;
1✔
520
        }
521

522
        /**
523
         * {@inheritDoc}
524
         *
525
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#between(java.lang.String, java.lang.Object, java.lang.Object)
526
         */
527
        @SuppressWarnings("unchecked")
528
        @Override
529
        public <V> T between(final String col, final V fromValue, final V toValue) {
530
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new Between<>(col, fromValue, toValue));
1✔
531
                this.useOperator = true;
1✔
532
                return (T) this;
1✔
533
        }
534

535
        /**
536
         *
537
         * {@inheritDoc}
538
         *
539
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notBetween(java.lang.String, java.lang.Object, java.lang.Object)
540
         */
541
        @SuppressWarnings("unchecked")
542
        @Override
543
        public <V> T notBetween(final String col, final V fromValue, final V toValue) {
544
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new NotBetween<>(col, fromValue, toValue));
1✔
545
                this.useOperator = true;
1✔
546
                return (T) this;
1✔
547
        }
548

549
        /**
550
         *
551
         * {@inheritDoc}
552
         *
553
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#betweenColumns(java.lang.Object, java.lang.String, java.lang.String)
554
         */
555
        @SuppressWarnings("unchecked")
556
        @Override
557
        public <V> T betweenColumns(final V value, final String fromCol, final String toCol) {
558
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(fromCol),
1✔
559
                                new BetweenColumns<>(value, fromCol, toCol, tableMetadata));
560
                this.useOperator = true;
1✔
561
                return (T) this;
1✔
562
        }
563

564
        /**
565
         *
566
         * {@inheritDoc}
567
         *
568
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#notBetweenColumns(java.lang.Object, java.lang.String, java.lang.String)
569
         */
570
        @SuppressWarnings("unchecked")
571
        @Override
572
        public <V> T notBetweenColumns(final V value, final String fromCol, final String toCol) {
573
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(fromCol),
1✔
574
                                new NotBetweenColumns<>(value, fromCol, toCol, tableMetadata));
575
                this.useOperator = true;
1✔
576
                return (T) this;
1✔
577
        }
578

579
        /**
580
         * {@inheritDoc}
581
         *
582
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#isNull(java.lang.String)
583
         */
584
        @SuppressWarnings("unchecked")
585
        @Override
586
        public T isNull(final String col) {
587
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new IsNull(col));
1✔
588
                this.useOperator = true;
1✔
589
                return (T) this;
1✔
590
        }
591

592
        /**
593
         * {@inheritDoc}
594
         *
595
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#isNotNull(java.lang.String)
596
         */
597
        @SuppressWarnings("unchecked")
598
        @Override
599
        public T isNotNull(final String col) {
600
                context().param(PREFIX + CaseFormat.CAMEL_CASE.convert(col), new IsNotNull(col));
1✔
601
                this.useOperator = true;
1✔
602
                return (T) this;
1✔
603
        }
604

605
        /**
606
         * {@inheritDoc}
607
         *
608
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#where(java.lang.CharSequence)
609
         */
610
        @SuppressWarnings("unchecked")
611
        @Override
612
        public T where(final CharSequence rawString) {
613
                if (ObjectUtils.isNotEmpty(rawString)) {
1✔
614
                        this.rawStrings.add(rawString);
1✔
615
                        this.useOperator = true;
1✔
616
                }
617
                return (T) this;
1✔
618
        }
619

620
        /**
621
         * {@inheritDoc}
622
         *
623
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#where(java.lang.CharSequence, java.lang.String, java.lang.Object)
624
         */
625
        @SuppressWarnings("unchecked")
626
        @Override
627
        public <V> T where(final CharSequence rawString, final String paramName, final V value) {
628
                if (ObjectUtils.isNotEmpty(rawString)) {
1✔
629
                        context().param(paramName, value);
1✔
630
                        this.where(rawString);
1✔
631
                }
632
                return (T) this;
1✔
633
        }
634

635
        /**
636
         * {@inheritDoc}
637
         *
638
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#whereIfNotEmpty(java.lang.CharSequence, java.lang.String, java.lang.Object)
639
         */
640
        @SuppressWarnings("unchecked")
641
        @Override
642
        public <V> T whereIfNotEmpty(final CharSequence rawString, final String paramName, final V value) {
643
                if (ObjectUtils.isNotEmpty(rawString) && ObjectUtils.isNotEmpty(value)) {
1✔
644
                        this.where(rawString, paramName, value);
1✔
645
                }
646
                return (T) this;
1✔
647
        }
648

649
        /**
650
         * {@inheritDoc}
651
         *
652
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#where(java.lang.CharSequence, java.util.Map)
653
         */
654
        @SuppressWarnings("unchecked")
655
        @Override
656
        public T where(final CharSequence rawString, final Map<String, Object> paramMap) {
657
                context().paramMap(paramMap);
1✔
658
                this.where(rawString);
1✔
659
                return (T) this;
1✔
660
        }
661

662
        /**
663
         * {@inheritDoc}
664
         *
665
         * @see jp.co.future.uroborosql.fluent.ExtractionCondition#contextAttrs()
666
         */
667
        @Override
668
        public Map<String, Object> contextAttrs() {
669
                return context().contextAttrs();
1✔
670
        }
671

672
        /**
673
         * 条件指定用のラップクラス
674
         */
675
        public static abstract class Operator {
676
                protected final String col;
677

678
                /**
679
                 * Constructor
680
                 *
681
                 * @param col バインドしたカラム名
682
                 */
683
                public Operator(final String col) {
1✔
684
                        this.col = CaseFormat.CAMEL_CASE.convert(col);
1✔
685
                }
1✔
686

687
                /**
688
                 * バインドしたカラム名の取得
689
                 *
690
                 * @return カラム名
691
                 */
692
                public String getCol() {
693
                        return col;
1✔
694
                }
695

696
                /**
697
                 * 条件生成時にカラム識別子を使用するかどうか
698
                 *
699
                 * @return カラム識別子を使用する場合<code>true</code>
700
                 */
701
                public boolean useColumnIdentifier() {
702
                        return true;
1✔
703
                }
704

705
                /**
706
                 * オペレータを取得する
707
                 *
708
                 * @return オペレータ
709
                 */
710
                public abstract String getOperator();
711

712
                /**
713
                 * 評価式に変換する
714
                 *
715
                 * @return 評価式
716
                 */
717
                public String toConditionString() {
718
                        return " " + getOperator();
1✔
719
                }
720

721
                /**
722
                 * バインド変数文字列を生成する
723
                 *
724
                 * @param keyNames バインド変数名。複数指定した場合、"."区切りで結合する
725
                 * @return バインド変数文字列
726
                 */
727
                protected String wrap(final String... keyNames) {
728
                        return "/*" + PREFIX + String.join(".", keyNames) + "*/";
1✔
729
                }
730
        }
731

732
        /**
733
         * 値を1つもつオペレータ
734
         */
735
        public static abstract class SingleOperator<V> extends Operator {
736
                protected final V value;
737

738
                /**
739
                 * Constructor
740
                 * @param col bind column name
741
                 * @param value 値
742
                 */
743
                public SingleOperator(final String col, final V value) {
744
                        super(col);
1✔
745
                        this.value = value;
1✔
746
                }
1✔
747

748
                /**
749
                 * 値の取得
750
                 * @return 値
751
                 */
752
                public V getValue() {
753
                        return value;
1✔
754
                }
755

756
                /**
757
                 * {@inheritDoc}
758
                 *
759
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#toConditionString()
760
                 */
761
                @Override
762
                public String toConditionString() {
763
                        return " " + getOperator() + " " + wrap(getCol(), "value");
1✔
764
                }
765
        }
766

767
        /**
768
         * Listを持つオペレータ
769
         */
770
        public static abstract class ListOperator<V> extends Operator {
771
                protected final Iterable<V> valueList;
772

773
                /**
774
                 * Constructor
775
                 *
776
                 * @param col bind column name
777
                 * @param valueList 値のリスト
778
                 */
779
                public ListOperator(final String col, final Iterable<V> valueList) {
780
                        super(col);
1✔
781
                        this.valueList = valueList;
1✔
782
                }
1✔
783

784
                /**
785
                 * Constructor
786
                 *
787
                 * @param col bind column name
788
                 * @param values 値の配列
789
                 */
790
                @SafeVarargs
791
                public ListOperator(final String col, final V... values) {
792
                        super(col);
1✔
793
                        valueList = List.of(values);
1✔
794
                }
1✔
795

796
                /**
797
                 * 値のリストを取得する
798
                 *
799
                 * @return 値のリスト
800
                 */
801
                public Iterable<?> getValueList() {
802
                        return valueList;
1✔
803
                }
804

805
                /**
806
                 * {@inheritDoc}
807
                 *
808
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#toConditionString()
809
                 */
810
                @Override
811
                public String toConditionString() {
812
                        return " " + getOperator() + " " + wrap(getCol(), "valueList") + "()";
1✔
813
                }
814
        }
815

816
        /**
817
         * Equal Operator
818
         */
819
        public static class Equal<V> extends SingleOperator<V> {
820
                /**
821
                 * Constructor
822
                 *
823
                 * @param col bind column name
824
                 * @param value 値
825
                 */
826
                public Equal(final String col, final V value) {
827
                        super(col, value);
1✔
828
                }
1✔
829

830
                /**
831
                 * {@inheritDoc}
832
                 *
833
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
834
                 */
835
                @Override
836
                public String getOperator() {
837
                        return "=";
1✔
838
                }
839
        }
840

841
        /**
842
         * NotEqual Operator
843
         */
844
        public static class NotEqual<V> extends SingleOperator<V> {
845
                /**
846
                 * Constructor
847
                 *
848
                 * @param col bind column name
849
                 * @param value 値
850
                 */
851
                public NotEqual(final String col, final V value) {
852
                        super(col, value);
1✔
853
                }
1✔
854

855
                /**
856
                 * {@inheritDoc}
857
                 *
858
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
859
                 */
860
                @Override
861
                public String getOperator() {
862
                        return "!=";
1✔
863
                }
864
        }
865

866
        /**
867
         * Greater Than Operator
868
         */
869
        public static class GreaterThan<V> extends SingleOperator<V> {
870
                /**
871
                 * Constructor
872
                 *
873
                 * @param col bind column name
874
                 * @param value 値
875
                 */
876
                public GreaterThan(final String col, final V value) {
877
                        super(col, value);
1✔
878
                }
1✔
879

880
                /**
881
                 * {@inheritDoc}
882
                 *
883
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
884
                 */
885
                @Override
886
                public String getOperator() {
887
                        return ">";
1✔
888
                }
889
        }
890

891
        /**
892
         * Less Than Operator
893
         */
894
        public static class LessThan<V> extends SingleOperator<V> {
895
                /**
896
                 * Constructor
897
                 *
898
                 * @param col bind column name
899
                 * @param value 値
900
                 */
901
                public LessThan(final String col, final V value) {
902
                        super(col, value);
1✔
903
                }
1✔
904

905
                /**
906
                 * {@inheritDoc}
907
                 *
908
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
909
                 */
910
                @Override
911
                public String getOperator() {
912
                        return "<";
1✔
913
                }
914
        }
915

916
        /**
917
         * Greater Equal Operator
918
         */
919
        public static class GreaterEqual<V> extends SingleOperator<V> {
920
                /**
921
                 * Constructor
922
                 *
923
                 * @param col bind column name
924
                 * @param value 値
925
                 */
926
                public GreaterEqual(final String col, final V value) {
927
                        super(col, value);
1✔
928
                }
1✔
929

930
                /**
931
                 * {@inheritDoc}
932
                 *
933
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
934
                 */
935
                @Override
936
                public String getOperator() {
937
                        return ">=";
1✔
938
                }
939
        }
940

941
        /**
942
         * Less Than Operator
943
         */
944
        public static class LessEqual<V> extends SingleOperator<V> {
945
                /**
946
                 * Constructor
947
                 *
948
                 * @param col bind column name
949
                 * @param value 値
950
                 */
951
                public LessEqual(final String col, final V value) {
952
                        super(col, value);
1✔
953
                }
1✔
954

955
                /**
956
                 * {@inheritDoc}
957
                 *
958
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
959
                 */
960
                @Override
961
                public String getOperator() {
962
                        return "<=";
1✔
963
                }
964
        }
965

966
        /**
967
         * In Operator
968
         */
969
        public static class In<V> extends ListOperator<V> {
970
                /**
971
                 * Constructor
972
                 *
973
                 * @param col bind column name
974
                 * @param valueList 値リスト
975
                 */
976
                public In(final String col, final Iterable<V> valueList) {
977
                        super(col, valueList);
1✔
978
                }
1✔
979

980
                /**
981
                 * Constructor
982
                 *
983
                 * @param col bind column name
984
                 * @param values 値の配列
985
                 */
986
                @SafeVarargs
987
                public In(final String col, final V... values) {
988
                        super(col, values);
1✔
989
                }
1✔
990

991
                /**
992
                 * {@inheritDoc}
993
                 *
994
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
995
                 */
996
                @Override
997
                public String getOperator() {
998
                        return "IN";
1✔
999
                }
1000
        }
1001

1002
        /**
1003
         * Not In Operator
1004
         */
1005
        public static class NotIn<V> extends In<V> {
1006
                /**
1007
                 * Constructor
1008
                 *
1009
                 * @param col bind column name
1010
                 * @param valueList 値リスト
1011
                 */
1012
                public NotIn(final String col, final Iterable<V> valueList) {
1013
                        super(col, valueList);
1✔
1014
                }
1✔
1015

1016
                /**
1017
                 * Constructor
1018
                 *
1019
                 * @param col bind column name
1020
                 * @param values 値の配列
1021
                 */
1022
                @SafeVarargs
1023
                public NotIn(final String col, final V... values) {
1024
                        super(col, values);
1✔
1025
                }
1✔
1026

1027
                /**
1028
                 * {@inheritDoc}
1029
                 *
1030
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.In#getOperator()
1031
                 */
1032
                @Override
1033
                public String getOperator() {
1034
                        return "NOT IN";
1✔
1035
                }
1036
        }
1037

1038
        /**
1039
         * Multi-Column In Operator
1040
         */
1041
        public static class MultiColumnIn<V> extends Operator {
1042
                protected final Iterable<V> beans;
1043
                protected final TableMetadata metadata;
1044
                protected final List<String> columnNames;
1045
                protected final String paramNamePrefix;
1046

1047
                /**
1048
                 * Constructor
1049
                 *
1050
                 * @param beans Beanの集合
1051
                 * @param metadata テーブルメタデータ
1052
                 */
1053
                public MultiColumnIn(final Iterable<V> beans, final TableMetadata metadata) {
1054
                        super("");
1✔
1055
                        this.beans = beans;
1✔
1056
                        this.metadata = metadata;
1✔
1057
                        this.columnNames = new ArrayList<>();
1✔
1058
                        this.paramNamePrefix = "multiColumnIn";
1✔
1059
                        
1060
                        // Beanからカラム名を抽出
1061
                        var beansList = new ArrayList<V>();
1✔
1062
                        beans.forEach(beansList::add);
1✔
1063
                        
1064
                        if (!beansList.isEmpty()) {
1✔
1065
                                var firstBean = beansList.get(0);
1✔
1066
                                var fields = BeanAccessor.fields(firstBean.getClass());
1✔
1067
                                
1068
                                // カラム名を収集
1069
                                for (var field : fields) {
1✔
1070
                                        var fieldName = CaseFormat.CAMEL_CASE.convert(field.getName());
1✔
1071
                                        var column = metadata.getColumn(fieldName);
1✔
1072
                                        if (column != null) {
1✔
1073
                                                columnNames.add(fieldName);
1✔
1074
                                        }
1075
                                }
1✔
1076
                        }
1077
                }
1✔
1078

1079
                /**
1080
                 * Beanの集合を取得する
1081
                 *
1082
                 * @return Beanの集合
1083
                 */
1084
                public Iterable<V> getBeans() {
1085
                        return beans;
1✔
1086
                }
1087

1088
                /**
1089
                 * カラム名のリストを取得する
1090
                 *
1091
                 * @return カラム名のリスト
1092
                 */
1093
                public List<String> getColumnNames() {
1094
                        return columnNames;
1✔
1095
                }
1096

1097
                /**
1098
                 * パラメータ名プレフィックスを取得する
1099
                 *
1100
                 * @return パラメータ名プレフィックス
1101
                 */
1102
                public String getParamNamePrefix() {
1103
                        return paramNamePrefix;
1✔
1104
                }
1105

1106
                /**
1107
                 * {@inheritDoc}
1108
                 *
1109
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#useColumnIdentifier()
1110
                 */
1111
                @Override
1112
                public boolean useColumnIdentifier() {
NEW
UNCOV
1113
                        return false;
×
1114
                }
1115

1116
                /**
1117
                 * {@inheritDoc}
1118
                 *
1119
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1120
                 */
1121
                @Override
1122
                public String getOperator() {
1123
                        return "IN";
1✔
1124
                }
1125

1126
                /**
1127
                 * {@inheritDoc}
1128
                 *
1129
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#toConditionString()
1130
                 */
1131
                @Override
1132
                public String toConditionString() {
1133
                        // toConditionStringは使用しないため空文字を返す
NEW
UNCOV
1134
                        return "";
×
1135
                }
1136
        }
1137

1138
        /**
1139
         * Like Operator
1140
         */
1141
        public static class Like extends SingleOperator<CharSequence> {
1142
                protected boolean prefix;
1143
                protected boolean suffix;
1144
                protected char escapeChar;
1145

1146
                /**
1147
                 * Constructor
1148
                 *
1149
                 * @param col bind column name
1150
                 * @param value 値
1151
                 * @param escapeChar エスケープ文字
1152
                 */
1153
                public Like(final String col, final CharSequence value, final char escapeChar) {
1154
                        this(col, true, value, true, escapeChar);
1✔
1155
                }
1✔
1156

1157
                /**
1158
                 * Constructor
1159
                 *
1160
                 * @param col bind column name
1161
                 * @param prefix 前にワイルドカードを挿入するかどうか。trueの場合%を追加
1162
                 * @param value 値
1163
                 * @param escapeChar エスケープ文字
1164
                 */
1165
                public Like(final String col, final boolean prefix, final CharSequence value, final char escapeChar) {
1166
                        this(col, prefix, value, false, escapeChar);
1✔
1167
                }
1✔
1168

1169
                /**
1170
                 * Constructor
1171
                 *
1172
                 * @param col bind column name
1173
                 * @param value 値
1174
                 * @param suffix 後ろにワイルドカードを挿入するかどうか。trueの場合%を追加
1175
                 * @param escapeChar エスケープ文字
1176
                 */
1177
                public Like(final String col, final CharSequence value, final boolean suffix, final char escapeChar) {
1178
                        this(col, false, value, suffix, escapeChar);
1✔
1179
                }
1✔
1180

1181
                /**
1182
                 * Constructor
1183
                 *
1184
                 * @param col bind column name
1185
                 * @param prefix 前にワイルドカードを挿入するかどうか。trueの場合%を追加
1186
                 * @param value 値
1187
                 * @param suffix 後ろにワイルドカードを挿入するかどうか。trueの場合%を追加
1188
                 * @param escapeChar エスケープ文字
1189
                 */
1190
                public Like(final String col, final boolean prefix, final CharSequence value, final boolean suffix,
1191
                                final char escapeChar) {
1192
                        super(col, value);
1✔
1193
                        this.prefix = prefix;
1✔
1194
                        this.suffix = suffix;
1✔
1195
                        this.escapeChar = escapeChar;
1✔
1196
                }
1✔
1197

1198
                /**
1199
                 * {@inheritDoc}
1200
                 *
1201
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.SingleOperator#getValue()
1202
                 */
1203
                @Override
1204
                public CharSequence getValue() {
1205
                        var searchValue = Objects.toString(super.getValue(), "");
1✔
1206
                        if (prefix) {
1✔
1207
                                searchValue = "%" + searchValue;
1✔
1208
                        }
1209
                        if (suffix) {
1✔
1210
                                searchValue = searchValue + "%";
1✔
1211
                        }
1212
                        return searchValue;
1✔
1213
                }
1214

1215
                @Override
1216
                public String toConditionString() {
1217
                        return super.toConditionString() + " ESCAPE '" + escapeChar + "'";
1✔
1218
                }
1219

1220
                /**
1221
                 * {@inheritDoc}
1222
                 *
1223
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1224
                 */
1225
                @Override
1226
                public String getOperator() {
1227
                        return "LIKE";
1✔
1228
                }
1229
        }
1230

1231
        /**
1232
         * Not Like Operator
1233
         */
1234
        public static class NotLike extends Like {
1235
                /**
1236
                 * Constructor
1237
                 *
1238
                 * @param col bind column name
1239
                 * @param value 値
1240
                 * @param escapeChar エスケープ文字
1241
                 */
1242
                public NotLike(final String col, final CharSequence value, final char escapeChar) {
1243
                        super(col, value, escapeChar);
1✔
1244
                }
1✔
1245

1246
                /**
1247
                 * Constructor
1248
                 *
1249
                 * @param col bind column name
1250
                 * @param prefix 前にワイルドカードを挿入するかどうか。trueの場合%を追加
1251
                 * @param value 値
1252
                 * @param escapeChar エスケープ文字
1253
                 */
1254
                public NotLike(final String col, final boolean prefix, final CharSequence value, final char escapeChar) {
1255
                        super(col, prefix, value, escapeChar);
1✔
1256
                }
1✔
1257

1258
                /**
1259
                 * Constructor
1260
                 *
1261
                 * @param col bind column name
1262
                 * @param value 値
1263
                 * @param suffix 後ろにワイルドカードを挿入するかどうか。trueの場合%を追加
1264
                 * @param escapeChar エスケープ文字
1265
                 */
1266
                public NotLike(final String col, final CharSequence value, final boolean suffix, final char escapeChar) {
1267
                        super(col, value, suffix, escapeChar);
1✔
1268
                }
1✔
1269

1270
                /**
1271
                 * Constructor
1272
                 *
1273
                 * @param col bind column name
1274
                 * @param prefix 前にワイルドカードを挿入するかどうか。trueの場合%を追加
1275
                 * @param value 値
1276
                 * @param suffix 後ろにワイルドカードを挿入するかどうか。trueの場合%を追加
1277
                 * @param escapeChar エスケープ文字
1278
                 */
1279
                public NotLike(final String col, final boolean prefix, final CharSequence value, final boolean suffix,
1280
                                final char escapeChar) {
1281
                        super(col, prefix, value, suffix, escapeChar);
1✔
1282
                }
1✔
1283

1284
                /**
1285
                 * {@inheritDoc}
1286
                 *
1287
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Like#getOperator()
1288
                 */
1289
                @Override
1290
                public String getOperator() {
1291
                        return "NOT LIKE";
1✔
1292
                }
1293
        }
1294

1295
        /**
1296
         * Between Operator
1297
         */
1298
        public static class Between<V> extends Operator {
1299
                protected final V from;
1300
                protected final V to;
1301

1302
                /**
1303
                 * Constructor
1304
                 *
1305
                 * @param col bind column name
1306
                 * @param from from value
1307
                 * @param to to value
1308
                 */
1309
                public Between(final String col, final V from, final V to) {
1310
                        super(col);
1✔
1311
                        this.from = from;
1✔
1312
                        this.to = to;
1✔
1313
                }
1✔
1314

1315
                /**
1316
                 * From値の取得
1317
                 *
1318
                 * @return From値
1319
                 */
1320
                public V getFrom() {
1321
                        return from;
1✔
1322
                }
1323

1324
                /**
1325
                 * To値の取得
1326
                 *
1327
                 * @return To値
1328
                 */
1329
                public V getTo() {
1330
                        return to;
1✔
1331
                }
1332

1333
                /**
1334
                 * {@inheritDoc}
1335
                 *
1336
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#toConditionString()
1337
                 */
1338
                @Override
1339
                public String toConditionString() {
1340
                        return " " + getOperator() + " " + wrap(getCol(), "from") + " AND " + wrap(getCol(), "to");
1✔
1341
                }
1342

1343
                /**
1344
                 * {@inheritDoc}
1345
                 *
1346
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1347
                 */
1348
                @Override
1349
                public String getOperator() {
1350
                        return "BETWEEN";
1✔
1351
                }
1352
        }
1353

1354
        /**
1355
         * NotBetween Operator
1356
         */
1357
        public static class NotBetween<V> extends Between<V> {
1358
                /**
1359
                 * Constructor
1360
                 *
1361
                 * @param col bind column name
1362
                 * @param from from value
1363
                 * @param to to value
1364
                 */
1365
                public NotBetween(final String col, final V from, final V to) {
1366
                        super(col, from, to);
1✔
1367
                }
1✔
1368

1369
                /**
1370
                 *
1371
                 * {@inheritDoc}
1372
                 *
1373
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Between#getOperator()
1374
                 */
1375
                @Override
1376
                public String getOperator() {
1377
                        return "NOT BETWEEN";
1✔
1378
                }
1379
        }
1380

1381
        /**
1382
         * BetweenColumns Operator
1383
         */
1384
        public static class BetweenColumns<V> extends Operator {
1385
                protected final String toCol;
1386
                protected final V value;
1387
                protected final TableMetadata metadata;
1388

1389
                /**
1390
                 * Constructor
1391
                 *
1392
                 * @param col bind column name
1393
                 * @param from from value
1394
                 * @param to to value
1395
                 */
1396
                public BetweenColumns(final V value, final String fromCol, final String toCol, final TableMetadata metadata) {
1397
                        super(fromCol);
1✔
1398
                        this.toCol = CaseFormat.CAMEL_CASE.convert(toCol);
1✔
1399
                        this.value = value;
1✔
1400
                        this.metadata = metadata;
1✔
1401
                }
1✔
1402

1403
                /**
1404
                 * 値の取得
1405
                 *
1406
                 * @return To値
1407
                 */
1408
                public V getValue() {
1409
                        return value;
1✔
1410
                }
1411

1412
                /**
1413
                 * FromColの取得
1414
                 *
1415
                 * @return FromCol
1416
                 */
1417
                public String getFromCol() {
1418
                        return super.getCol();
1✔
1419
                }
1420

1421
                /**
1422
                 * toColの取得
1423
                 *
1424
                 * @return toCol
1425
                 */
1426
                public String getToCol() {
1427
                        return this.toCol;
1✔
1428
                }
1429

1430
                /**
1431
                 *
1432
                 * {@inheritDoc}
1433
                 *
1434
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#useColumnIdentifier()
1435
                 */
1436
                @Override
1437
                public boolean useColumnIdentifier() {
1438
                        return false;
1✔
1439
                }
1440

1441
                /**
1442
                 * {@inheritDoc}
1443
                 *
1444
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#toConditionString()
1445
                 */
1446
                @Override
1447
                public String toConditionString() {
1448
                        var fromColumn = this.metadata.getColumn(getFromCol());
1✔
1449
                        var toColumn = this.metadata.getColumn(getToCol());
1✔
1450

1451
                        return wrap(getCol(), "value") + " " + getOperator() + " "
1✔
1452
                                        + fromColumn.getColumnIdentifier() + " AND "
1✔
1453
                                        + toColumn.getColumnIdentifier();
1✔
1454
                }
1455

1456
                /**
1457
                 * {@inheritDoc}
1458
                 *
1459
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1460
                 */
1461
                @Override
1462
                public String getOperator() {
1463
                        return "BETWEEN";
1✔
1464
                }
1465
        }
1466

1467
        /**
1468
         * NotBetweenColumns Operator
1469
         */
1470
        public static class NotBetweenColumns<V> extends BetweenColumns<V> {
1471

1472
                /**
1473
                 * Constructor
1474
                 *
1475
                 * @param col bind column name
1476
                 * @param from from value
1477
                 * @param to to value
1478
                 */
1479
                public NotBetweenColumns(final V value, final String fromCol, final String toCol,
1480
                                final TableMetadata metadata) {
1481
                        super(value, fromCol, toCol, metadata);
1✔
1482
                }
1✔
1483

1484
                /**
1485
                 *
1486
                 * {@inheritDoc}
1487
                 *
1488
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.BetweenColumns#getOperator()
1489
                 */
1490
                @Override
1491
                public String getOperator() {
1492
                        return "NOT BETWEEN";
1✔
1493
                }
1494
        }
1495

1496
        /**
1497
         * IS NULL Operator
1498
         */
1499
        public static class IsNull extends Operator {
1500
                /**
1501
                 * Constructor
1502
                 *
1503
                 * @param col bind column name
1504
                 */
1505
                public IsNull(final String col) {
1506
                        super(col);
1✔
1507
                }
1✔
1508

1509
                /**
1510
                 * {@inheritDoc}
1511
                 *
1512
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1513
                 */
1514
                @Override
1515
                public String getOperator() {
1516
                        return "IS NULL";
1✔
1517
                }
1518
        }
1519

1520
        /**
1521
         * IS NOT NULL Operator
1522
         */
1523
        public static class IsNotNull extends Operator {
1524
                /**
1525
                 * Constructor
1526
                 *
1527
                 * @param col bind column name
1528
                 */
1529
                public IsNotNull(final String col) {
1530
                        super(col);
1✔
1531
                }
1✔
1532

1533
                /**
1534
                 * {@inheritDoc}
1535
                 *
1536
                 * @see jp.co.future.uroborosql.AbstractExtractionCondition.Operator#getOperator()
1537
                 */
1538
                @Override
1539
                public String getOperator() {
1540
                        return "IS NOT NULL";
1✔
1541
                }
1542
        }
1543
}
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