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

mybatis / mybatis-3 / #3393

25 Dec 2023 01:42AM UTC coverage: 86.665% (+0.05%) from 86.619%
#3393

Pull #2971

github

web-flow
Merge 9b99f44b6 into 01225f508
Pull Request #2971: docs: add dynamic sql example to @Select

3498 of 4275 branches covered (0.0%)

9294 of 10724 relevant lines covered (86.67%)

0.87 hits per line

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

92.64
/src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java
1
/*
2
 *    Copyright 2009-2023 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.apache.ibatis.jdbc;
17

18
import java.io.IOException;
19
import java.util.ArrayList;
20
import java.util.Arrays;
21
import java.util.Collections;
22
import java.util.List;
23
import java.util.function.BooleanSupplier;
24
import java.util.function.Consumer;
25

26
/**
27
 * @author Clinton Begin
28
 * @author Jeff Butler
29
 * @author Adam Gent
30
 * @author Kazuki Shimizu
31
 */
32
public abstract class AbstractSQL<T> {
1✔
33

34
  private static final String AND = ") \nAND (";
35
  private static final String OR = ") \nOR (";
36

37
  private final SQLStatement sql = new SQLStatement();
1✔
38

39
  public abstract T getSelf();
40

41
  public T UPDATE(String table) {
42
    sql().statementType = SQLStatement.StatementType.UPDATE;
1✔
43
    sql().tables.add(table);
1✔
44
    return getSelf();
1✔
45
  }
46

47
  public T SET(String sets) {
48
    sql().sets.add(sets);
1✔
49
    return getSelf();
1✔
50
  }
51

52
  /**
53
   * Sets the.
54
   *
55
   * @param sets
56
   *          the sets
57
   *
58
   * @return the t
59
   *
60
   * @since 3.4.2
61
   */
62
  public T SET(String... sets) {
63
    sql().sets.addAll(Arrays.asList(sets));
1✔
64
    return getSelf();
1✔
65
  }
66

67
  public T INSERT_INTO(String tableName) {
68
    sql().statementType = SQLStatement.StatementType.INSERT;
1✔
69
    sql().tables.add(tableName);
1✔
70
    return getSelf();
1✔
71
  }
72

73
  public T VALUES(String columns, String values) {
74
    INTO_COLUMNS(columns);
1✔
75
    INTO_VALUES(values);
1✔
76
    return getSelf();
1✔
77
  }
78

79
  /**
80
   * Into columns.
81
   *
82
   * @param columns
83
   *          the columns
84
   *
85
   * @return the t
86
   *
87
   * @since 3.4.2
88
   */
89
  public T INTO_COLUMNS(String... columns) {
90
    sql().columns.addAll(Arrays.asList(columns));
1✔
91
    return getSelf();
1✔
92
  }
93

94
  /**
95
   * Into values.
96
   *
97
   * @param values
98
   *          the values
99
   *
100
   * @return the t
101
   *
102
   * @since 3.4.2
103
   */
104
  public T INTO_VALUES(String... values) {
105
    List<String> list = sql().valuesList.get(sql().valuesList.size() - 1);
1✔
106
    Collections.addAll(list, values);
1✔
107
    return getSelf();
1✔
108
  }
109

110
  public T SELECT(String columns) {
111
    sql().statementType = SQLStatement.StatementType.SELECT;
1✔
112
    sql().select.add(columns);
1✔
113
    return getSelf();
1✔
114
  }
115

116
  /**
117
   * Select.
118
   *
119
   * @param columns
120
   *          the columns
121
   *
122
   * @return the t
123
   *
124
   * @since 3.4.2
125
   */
126
  public T SELECT(String... columns) {
127
    sql().statementType = SQLStatement.StatementType.SELECT;
1✔
128
    sql().select.addAll(Arrays.asList(columns));
1✔
129
    return getSelf();
1✔
130
  }
131

132
  public T SELECT_DISTINCT(String columns) {
133
    sql().distinct = true;
×
134
    SELECT(columns);
×
135
    return getSelf();
×
136
  }
137

138
  /**
139
   * Select distinct.
140
   *
141
   * @param columns
142
   *          the columns
143
   *
144
   * @return the t
145
   *
146
   * @since 3.4.2
147
   */
148
  public T SELECT_DISTINCT(String... columns) {
149
    sql().distinct = true;
1✔
150
    SELECT(columns);
1✔
151
    return getSelf();
1✔
152
  }
153

154
  public T DELETE_FROM(String table) {
155
    sql().statementType = SQLStatement.StatementType.DELETE;
1✔
156
    sql().tables.add(table);
1✔
157
    return getSelf();
1✔
158
  }
159

160
  public T FROM(String table) {
161
    sql().tables.add(table);
1✔
162
    return getSelf();
1✔
163
  }
164

165
  /**
166
   * From.
167
   *
168
   * @param tables
169
   *          the tables
170
   *
171
   * @return the t
172
   *
173
   * @since 3.4.2
174
   */
175
  public T FROM(String... tables) {
176
    sql().tables.addAll(Arrays.asList(tables));
1✔
177
    return getSelf();
1✔
178
  }
179

180
  public T JOIN(String join) {
181
    sql().join.add(join);
×
182
    return getSelf();
×
183
  }
184

185
  /**
186
   * Join.
187
   *
188
   * @param joins
189
   *          the joins
190
   *
191
   * @return the t
192
   *
193
   * @since 3.4.2
194
   */
195
  public T JOIN(String... joins) {
196
    sql().join.addAll(Arrays.asList(joins));
1✔
197
    return getSelf();
1✔
198
  }
199

200
  public T INNER_JOIN(String join) {
201
    sql().innerJoin.add(join);
1✔
202
    return getSelf();
1✔
203
  }
204

205
  /**
206
   * Inner join.
207
   *
208
   * @param joins
209
   *          the joins
210
   *
211
   * @return the t
212
   *
213
   * @since 3.4.2
214
   */
215
  public T INNER_JOIN(String... joins) {
216
    sql().innerJoin.addAll(Arrays.asList(joins));
1✔
217
    return getSelf();
1✔
218
  }
219

220
  public T LEFT_OUTER_JOIN(String join) {
221
    sql().leftOuterJoin.add(join);
×
222
    return getSelf();
×
223
  }
224

225
  /**
226
   * Left outer join.
227
   *
228
   * @param joins
229
   *          the joins
230
   *
231
   * @return the t
232
   *
233
   * @since 3.4.2
234
   */
235
  public T LEFT_OUTER_JOIN(String... joins) {
236
    sql().leftOuterJoin.addAll(Arrays.asList(joins));
1✔
237
    return getSelf();
1✔
238
  }
239

240
  public T RIGHT_OUTER_JOIN(String join) {
241
    sql().rightOuterJoin.add(join);
×
242
    return getSelf();
×
243
  }
244

245
  /**
246
   * Right outer join.
247
   *
248
   * @param joins
249
   *          the joins
250
   *
251
   * @return the t
252
   *
253
   * @since 3.4.2
254
   */
255
  public T RIGHT_OUTER_JOIN(String... joins) {
256
    sql().rightOuterJoin.addAll(Arrays.asList(joins));
1✔
257
    return getSelf();
1✔
258
  }
259

260
  public T OUTER_JOIN(String join) {
261
    sql().outerJoin.add(join);
×
262
    return getSelf();
×
263
  }
264

265
  /**
266
   * Outer join.
267
   *
268
   * @param joins
269
   *          the joins
270
   *
271
   * @return the t
272
   *
273
   * @since 3.4.2
274
   */
275
  public T OUTER_JOIN(String... joins) {
276
    sql().outerJoin.addAll(Arrays.asList(joins));
1✔
277
    return getSelf();
1✔
278
  }
279

280
  public T WHERE(String conditions) {
281
    sql().where.add(conditions);
1✔
282
    sql().lastList = sql().where;
1✔
283
    return getSelf();
1✔
284
  }
285

286
  /**
287
   * Where.
288
   *
289
   * @param conditions
290
   *          the conditions
291
   *
292
   * @return the t
293
   *
294
   * @since 3.4.2
295
   */
296
  public T WHERE(String... conditions) {
297
    sql().where.addAll(Arrays.asList(conditions));
1✔
298
    sql().lastList = sql().where;
1✔
299
    return getSelf();
1✔
300
  }
301

302
  public T OR() {
303
    sql().lastList.add(OR);
1✔
304
    return getSelf();
1✔
305
  }
306

307
  public T AND() {
308
    sql().lastList.add(AND);
×
309
    return getSelf();
×
310
  }
311

312
  public T GROUP_BY(String columns) {
313
    sql().groupBy.add(columns);
1✔
314
    return getSelf();
1✔
315
  }
316

317
  /**
318
   * Group by.
319
   *
320
   * @param columns
321
   *          the columns
322
   *
323
   * @return the t
324
   *
325
   * @since 3.4.2
326
   */
327
  public T GROUP_BY(String... columns) {
328
    sql().groupBy.addAll(Arrays.asList(columns));
1✔
329
    return getSelf();
1✔
330
  }
331

332
  public T HAVING(String conditions) {
333
    sql().having.add(conditions);
1✔
334
    sql().lastList = sql().having;
1✔
335
    return getSelf();
1✔
336
  }
337

338
  /**
339
   * Having.
340
   *
341
   * @param conditions
342
   *          the conditions
343
   *
344
   * @return the t
345
   *
346
   * @since 3.4.2
347
   */
348
  public T HAVING(String... conditions) {
349
    sql().having.addAll(Arrays.asList(conditions));
1✔
350
    sql().lastList = sql().having;
1✔
351
    return getSelf();
1✔
352
  }
353

354
  public T ORDER_BY(String columns) {
355
    sql().orderBy.add(columns);
1✔
356
    return getSelf();
1✔
357
  }
358

359
  /**
360
   * Order by.
361
   *
362
   * @param columns
363
   *          the columns
364
   *
365
   * @return the t
366
   *
367
   * @since 3.4.2
368
   */
369
  public T ORDER_BY(String... columns) {
370
    sql().orderBy.addAll(Arrays.asList(columns));
1✔
371
    return getSelf();
1✔
372
  }
373

374
  /**
375
   * Set the limit variable string(e.g. {@code "#{limit}"}).
376
   *
377
   * @param variable
378
   *          a limit variable string
379
   *
380
   * @return a self instance
381
   *
382
   * @see #OFFSET(String)
383
   *
384
   * @since 3.5.2
385
   */
386
  public T LIMIT(String variable) {
387
    sql().limit = variable;
1✔
388
    sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.OFFSET_LIMIT;
1✔
389
    return getSelf();
1✔
390
  }
391

392
  /**
393
   * Set the limit value.
394
   *
395
   * @param value
396
   *          an offset value
397
   *
398
   * @return a self instance
399
   *
400
   * @see #OFFSET(long)
401
   *
402
   * @since 3.5.2
403
   */
404
  public T LIMIT(int value) {
405
    return LIMIT(String.valueOf(value));
1✔
406
  }
407

408
  /**
409
   * Set the offset variable string(e.g. {@code "#{offset}"}).
410
   *
411
   * @param variable
412
   *          a offset variable string
413
   *
414
   * @return a self instance
415
   *
416
   * @see #LIMIT(String)
417
   *
418
   * @since 3.5.2
419
   */
420
  public T OFFSET(String variable) {
421
    sql().offset = variable;
1✔
422
    sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.OFFSET_LIMIT;
1✔
423
    return getSelf();
1✔
424
  }
425

426
  /**
427
   * Set the offset value.
428
   *
429
   * @param value
430
   *          an offset value
431
   *
432
   * @return a self instance
433
   *
434
   * @see #LIMIT(int)
435
   *
436
   * @since 3.5.2
437
   */
438
  public T OFFSET(long value) {
439
    return OFFSET(String.valueOf(value));
1✔
440
  }
441

442
  /**
443
   * Set the fetch first rows variable string(e.g. {@code "#{fetchFirstRows}"}).
444
   *
445
   * @param variable
446
   *          a fetch first rows variable string
447
   *
448
   * @return a self instance
449
   *
450
   * @see #OFFSET_ROWS(String)
451
   *
452
   * @since 3.5.2
453
   */
454
  public T FETCH_FIRST_ROWS_ONLY(String variable) {
455
    sql().limit = variable;
1✔
456
    sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.ISO;
1✔
457
    return getSelf();
1✔
458
  }
459

460
  /**
461
   * Set the fetch first rows value.
462
   *
463
   * @param value
464
   *          a fetch first rows value
465
   *
466
   * @return a self instance
467
   *
468
   * @see #OFFSET_ROWS(long)
469
   *
470
   * @since 3.5.2
471
   */
472
  public T FETCH_FIRST_ROWS_ONLY(int value) {
473
    return FETCH_FIRST_ROWS_ONLY(String.valueOf(value));
1✔
474
  }
475

476
  /**
477
   * Set the offset rows variable string(e.g. {@code "#{offset}"}).
478
   *
479
   * @param variable
480
   *          a offset rows variable string
481
   *
482
   * @return a self instance
483
   *
484
   * @see #FETCH_FIRST_ROWS_ONLY(String)
485
   *
486
   * @since 3.5.2
487
   */
488
  public T OFFSET_ROWS(String variable) {
489
    sql().offset = variable;
1✔
490
    sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.ISO;
1✔
491
    return getSelf();
1✔
492
  }
493

494
  /**
495
   * Set the offset rows value.
496
   *
497
   * @param value
498
   *          an offset rows value
499
   *
500
   * @return a self instance
501
   *
502
   * @see #FETCH_FIRST_ROWS_ONLY(int)
503
   *
504
   * @since 3.5.2
505
   */
506
  public T OFFSET_ROWS(long value) {
507
    return OFFSET_ROWS(String.valueOf(value));
1✔
508
  }
509

510
  /**
511
   * used to add a new inserted row while do multi-row insert.
512
   *
513
   * @return the t
514
   *
515
   * @since 3.5.2
516
   */
517
  public T ADD_ROW() {
518
    sql().valuesList.add(new ArrayList<>());
1✔
519
    return getSelf();
1✔
520
  }
521

522
  private SQLStatement sql() {
523
    return sql;
1✔
524
  }
525

526
  public <A extends Appendable> A usingAppender(A a) {
527
    sql().sql(a);
1✔
528
    return a;
1✔
529
  }
530

531
  /**
532
   * Apply sql phrases that provide by SQL consumer if condition is matches.
533
   *
534
   * @param applyCondition
535
   *          if {@code true} apply sql phrases
536
   * @param sqlConsumer
537
   *          a consumer that append sql phrase to SQL instance
538
   *
539
   * @return a self instance
540
   *
541
   * @see #applyIf(BooleanSupplier, Consumer)
542
   *
543
   * @since 3.5.15
544
   */
545
  public T applyIf(boolean applyCondition, Consumer<T> sqlConsumer) {
546
    T self = getSelf();
1✔
547
    if (applyCondition) {
1✔
548
      sqlConsumer.accept(self);
1✔
549
    }
550
    return self;
1✔
551
  }
552

553
  /**
554
   * Apply sql phrases that provide by SQL consumer if condition is matches.
555
   *
556
   * @param applyConditionSupplier
557
   *          if supplier return {@code true} apply sql phrases
558
   * @param sqlConsumer
559
   *          a consumer that append sql phrase to SQL instance
560
   *
561
   * @return a self instance
562
   *
563
   * @see #applyIf(boolean, Consumer)
564
   *
565
   * @since 3.5.15
566
   */
567
  public T applyIf(BooleanSupplier applyConditionSupplier, Consumer<T> sqlConsumer) {
568
    return applyIf(applyConditionSupplier.getAsBoolean(), sqlConsumer);
1✔
569
  }
570

571
  /**
572
   * Apply sql phrases that provide by SQL consumer for iterable.
573
   *
574
   * @param iterable
575
   *          an iterable
576
   * @param forEachSqlConsumer
577
   *          a consumer that append sql phrase to SQL instance
578
   *
579
   * @return a self instance
580
   *
581
   * @param <E>
582
   *          element type of iterable
583
   *
584
   * @since 3.5.15
585
   */
586
  public <E> T applyForEach(Iterable<E> iterable, ForEachConsumer<T, E> forEachSqlConsumer) {
587
    T self = getSelf();
1✔
588
    int elementIndex = 0;
1✔
589
    for (E element : iterable) {
1✔
590
      forEachSqlConsumer.accept(self, element, elementIndex);
1✔
591
      elementIndex++;
1✔
592
    }
1✔
593
    return self;
1✔
594
  }
595

596
  @Override
597
  public String toString() {
598
    StringBuilder sb = new StringBuilder();
1✔
599
    sql().sql(sb);
1✔
600
    return sb.toString();
1✔
601
  }
602

603
  private static class SafeAppendable {
604
    private final Appendable appendable;
605
    private boolean empty = true;
1✔
606

607
    public SafeAppendable(Appendable a) {
1✔
608
      this.appendable = a;
1✔
609
    }
1✔
610

611
    public SafeAppendable append(CharSequence s) {
612
      try {
613
        if (empty && s.length() > 0) {
1!
614
          empty = false;
1✔
615
        }
616
        appendable.append(s);
1✔
617
      } catch (IOException e) {
×
618
        throw new RuntimeException(e);
×
619
      }
1✔
620
      return this;
1✔
621
    }
622

623
    public boolean isEmpty() {
624
      return empty;
1✔
625
    }
626

627
  }
628

629
  private static class SQLStatement {
630

631
    public enum StatementType {
1✔
632

633
      DELETE,
1✔
634

635
      INSERT,
1✔
636

637
      SELECT,
1✔
638

639
      UPDATE
1✔
640

641
    }
642

643
    private enum LimitingRowsStrategy {
1✔
644
      NOP {
1✔
645
        @Override
646
        protected void appendClause(SafeAppendable builder, String offset, String limit) {
647
          // NOP
648
        }
1✔
649
      },
650
      ISO {
1✔
651
        @Override
652
        protected void appendClause(SafeAppendable builder, String offset, String limit) {
653
          if (offset != null) {
1✔
654
            builder.append(" OFFSET ").append(offset).append(" ROWS");
1✔
655
          }
656
          if (limit != null) {
1✔
657
            builder.append(" FETCH FIRST ").append(limit).append(" ROWS ONLY");
1✔
658
          }
659
        }
1✔
660
      },
661
      OFFSET_LIMIT {
1✔
662
        @Override
663
        protected void appendClause(SafeAppendable builder, String offset, String limit) {
664
          if (limit != null) {
1✔
665
            builder.append(" LIMIT ").append(limit);
1✔
666
          }
667
          if (offset != null) {
1✔
668
            builder.append(" OFFSET ").append(offset);
1✔
669
          }
670
        }
1✔
671
      };
672

673
      protected abstract void appendClause(SafeAppendable builder, String offset, String limit);
674

675
    }
676

677
    StatementType statementType;
678
    List<String> sets = new ArrayList<>();
1✔
679
    List<String> select = new ArrayList<>();
1✔
680
    List<String> tables = new ArrayList<>();
1✔
681
    List<String> join = new ArrayList<>();
1✔
682
    List<String> innerJoin = new ArrayList<>();
1✔
683
    List<String> outerJoin = new ArrayList<>();
1✔
684
    List<String> leftOuterJoin = new ArrayList<>();
1✔
685
    List<String> rightOuterJoin = new ArrayList<>();
1✔
686
    List<String> where = new ArrayList<>();
1✔
687
    List<String> having = new ArrayList<>();
1✔
688
    List<String> groupBy = new ArrayList<>();
1✔
689
    List<String> orderBy = new ArrayList<>();
1✔
690
    List<String> lastList = new ArrayList<>();
1✔
691
    List<String> columns = new ArrayList<>();
1✔
692
    List<List<String>> valuesList = new ArrayList<>();
1✔
693
    boolean distinct;
694
    String offset;
695
    String limit;
696
    LimitingRowsStrategy limitingRowsStrategy = LimitingRowsStrategy.NOP;
1✔
697

698
    public SQLStatement() {
1✔
699
      // Prevent Synthetic Access
700
      valuesList.add(new ArrayList<>());
1✔
701
    }
1✔
702

703
    private void sqlClause(SafeAppendable builder, String keyword, List<String> parts, String open, String close,
704
        String conjunction) {
705
      if (!parts.isEmpty()) {
1✔
706
        if (!builder.isEmpty()) {
1✔
707
          builder.append("\n");
1✔
708
        }
709
        builder.append(keyword);
1✔
710
        builder.append(" ");
1✔
711
        builder.append(open);
1✔
712
        String last = "________";
1✔
713
        for (int i = 0, n = parts.size(); i < n; i++) {
1✔
714
          String part = parts.get(i);
1✔
715
          if (i > 0 && !part.equals(AND) && !part.equals(OR) && !last.equals(AND) && !last.equals(OR)) {
1!
716
            builder.append(conjunction);
1✔
717
          }
718
          builder.append(part);
1✔
719
          last = part;
1✔
720
        }
721
        builder.append(close);
1✔
722
      }
723
    }
1✔
724

725
    private String selectSQL(SafeAppendable builder) {
726
      if (distinct) {
1✔
727
        sqlClause(builder, "SELECT DISTINCT", select, "", "", ", ");
1✔
728
      } else {
729
        sqlClause(builder, "SELECT", select, "", "", ", ");
1✔
730
      }
731

732
      sqlClause(builder, "FROM", tables, "", "", ", ");
1✔
733
      joins(builder);
1✔
734
      sqlClause(builder, "WHERE", where, "(", ")", " AND ");
1✔
735
      sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
1✔
736
      sqlClause(builder, "HAVING", having, "(", ")", " AND ");
1✔
737
      sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");
1✔
738
      limitingRowsStrategy.appendClause(builder, offset, limit);
1✔
739
      return builder.toString();
1✔
740
    }
741

742
    private void joins(SafeAppendable builder) {
743
      sqlClause(builder, "JOIN", join, "", "", "\nJOIN ");
1✔
744
      sqlClause(builder, "INNER JOIN", innerJoin, "", "", "\nINNER JOIN ");
1✔
745
      sqlClause(builder, "OUTER JOIN", outerJoin, "", "", "\nOUTER JOIN ");
1✔
746
      sqlClause(builder, "LEFT OUTER JOIN", leftOuterJoin, "", "", "\nLEFT OUTER JOIN ");
1✔
747
      sqlClause(builder, "RIGHT OUTER JOIN", rightOuterJoin, "", "", "\nRIGHT OUTER JOIN ");
1✔
748
    }
1✔
749

750
    private String insertSQL(SafeAppendable builder) {
751
      sqlClause(builder, "INSERT INTO", tables, "", "", "");
1✔
752
      sqlClause(builder, "", columns, "(", ")", ", ");
1✔
753
      for (int i = 0; i < valuesList.size(); i++) {
1✔
754
        sqlClause(builder, i > 0 ? "," : "VALUES", valuesList.get(i), "(", ")", ", ");
1✔
755
      }
756
      return builder.toString();
1✔
757
    }
758

759
    private String deleteSQL(SafeAppendable builder) {
760
      sqlClause(builder, "DELETE FROM", tables, "", "", "");
1✔
761
      sqlClause(builder, "WHERE", where, "(", ")", " AND ");
1✔
762
      limitingRowsStrategy.appendClause(builder, null, limit);
1✔
763
      return builder.toString();
1✔
764
    }
765

766
    private String updateSQL(SafeAppendable builder) {
767
      sqlClause(builder, "UPDATE", tables, "", "", "");
1✔
768
      joins(builder);
1✔
769
      sqlClause(builder, "SET", sets, "", "", ", ");
1✔
770
      sqlClause(builder, "WHERE", where, "(", ")", " AND ");
1✔
771
      limitingRowsStrategy.appendClause(builder, null, limit);
1✔
772
      return builder.toString();
1✔
773
    }
774

775
    public String sql(Appendable a) {
776
      SafeAppendable builder = new SafeAppendable(a);
1✔
777
      if (statementType == null) {
1!
778
        return null;
×
779
      }
780

781
      String answer;
782

783
      switch (statementType) {
1!
784
        case DELETE:
785
          answer = deleteSQL(builder);
1✔
786
          break;
1✔
787

788
        case INSERT:
789
          answer = insertSQL(builder);
1✔
790
          break;
1✔
791

792
        case SELECT:
793
          answer = selectSQL(builder);
1✔
794
          break;
1✔
795

796
        case UPDATE:
797
          answer = updateSQL(builder);
1✔
798
          break;
1✔
799

800
        default:
801
          answer = null;
×
802
      }
803

804
      return answer;
1✔
805
    }
806
  }
807

808
  /**
809
   * Consumer for 'forEach' operation.
810
   *
811
   * @param <T>
812
   *          SQL type
813
   * @param <E>
814
   *          Element type of iterable
815
   *
816
   * @since 3.5.15
817
   */
818
  public interface ForEachConsumer<T, E> {
819

820
    /**
821
     * Accept an iterable element with index.
822
     *
823
     * @param sql
824
     *          SQL instance
825
     * @param element
826
     *          an iterable element
827
     * @param elementIndex
828
     *          an element index
829
     */
830
    void accept(T sql, E element, int elementIndex);
831

832
  }
833

834
}
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