1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbcp2;
18
19 import java.sql.Connection;
20 import java.sql.SQLException;
21 import java.sql.Statement;
22 import java.util.Arrays;
23 import java.util.Objects;
24 import java.util.function.Function;
25
26 import org.apache.commons.dbcp2.PoolingConnection.StatementType;
27
28
29
30
31
32
33 public class PStmtKey {
34
35
36
37
38 @FunctionalInterface
39 private interface StatementBuilder {
40 Statement createStatement(Connection connection, PStmtKey key) throws SQLException;
41 }
42
43 private static final StatementBuilder CallConcurrency = (c, k) -> c.prepareCall(k.sql, k.resultSetType, k.resultSetConcurrency);
44 private static final StatementBuilder CallHoldability = (c, k) -> c.prepareCall(k.sql, k.resultSetType, k.resultSetConcurrency, k.resultSetHoldability);
45 private static final StatementBuilder CallSQL = (c, k) -> c.prepareCall(k.sql);
46 private static final StatementBuilder StatementAutoGeneratedKeys = (c, k) -> c.prepareStatement(k.sql, k.autoGeneratedKeys);
47 private static final StatementBuilder StatementColumnIndexes = (c, k) -> c.prepareStatement(k.sql, k.columnIndexes);
48 private static final StatementBuilder StatementColumnNames = (c, k) -> c.prepareStatement(k.sql, k.columnNames);
49 private static final StatementBuilder StatementConcurrency = (c, k) -> c.prepareStatement(k.sql, k.resultSetType, k.resultSetConcurrency);
50 private static final StatementBuilder StatementHoldability = (c, k) -> c.prepareStatement(k.sql, k.resultSetType, k.resultSetConcurrency,
51 k.resultSetHoldability);
52 private static final StatementBuilder StatementSQL = (c, k) -> c.prepareStatement(k.sql);
53
54 private static StatementBuilder match(final StatementType statementType, final StatementBuilder prep, final StatementBuilder call) {
55 switch (Objects.requireNonNull(statementType, "statementType")) {
56 case PREPARED_STATEMENT:
57 return prep;
58 case CALLABLE_STATEMENT:
59 return call;
60 default:
61 throw new IllegalArgumentException(statementType.toString());
62 }
63 }
64
65
66
67
68 private final String sql;
69
70
71
72
73
74 private final Integer resultSetType;
75
76
77
78
79
80 private final Integer resultSetConcurrency;
81
82
83
84
85
86 private final Integer resultSetHoldability;
87
88
89
90
91 private final String catalog;
92
93
94
95
96 private final String schema;
97
98
99
100
101
102 private final Integer autoGeneratedKeys;
103
104
105
106
107 private final int[] columnIndexes;
108
109
110
111
112 private final String[] columnNames;
113
114
115
116
117 private final transient StatementBuilder statementBuilder;
118
119
120
121
122 private final StatementType statementType;
123
124
125
126
127
128
129
130 @Deprecated
131 public PStmtKey(final String sql) {
132 this(sql, null, StatementType.PREPARED_STATEMENT);
133 }
134
135
136
137
138
139
140
141
142
143
144
145 @Deprecated
146 public PStmtKey(final String sql, final int resultSetType, final int resultSetConcurrency) {
147 this(sql, null, resultSetType, resultSetConcurrency, StatementType.PREPARED_STATEMENT);
148 }
149
150
151
152
153
154
155
156
157 @Deprecated
158 public PStmtKey(final String sql, final String catalog) {
159 this(sql, catalog, StatementType.PREPARED_STATEMENT);
160 }
161
162
163
164
165
166
167
168
169
170
171 @Deprecated
172 public PStmtKey(final String sql, final String catalog, final int autoGeneratedKeys) {
173 this(sql, catalog, StatementType.PREPARED_STATEMENT, autoGeneratedKeys);
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187 @Deprecated
188 public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency) {
189 this(sql, catalog, resultSetType, resultSetConcurrency, StatementType.PREPARED_STATEMENT);
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 @Deprecated
206 public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) {
207 this(sql, catalog, resultSetType, resultSetConcurrency, resultSetHoldability, StatementType.PREPARED_STATEMENT);
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 @Deprecated
225 public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability,
226 final StatementType statementType) {
227 this(sql, catalog, null, resultSetType, resultSetConcurrency, resultSetHoldability, null, null, null, statementType,
228 k -> match(statementType, StatementHoldability, CallHoldability));
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243 @Deprecated
244 public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency, final StatementType statementType) {
245 this(sql, catalog, null, resultSetType, resultSetConcurrency, null, null, null, null, statementType,
246 k -> match(statementType, StatementConcurrency, CallConcurrency));
247 }
248
249
250
251
252
253
254
255
256
257
258 @Deprecated
259 public PStmtKey(final String sql, final String catalog, final int[] columnIndexes) {
260 this(sql, catalog, null, null, null, null, null, columnIndexes, null, StatementType.PREPARED_STATEMENT, StatementColumnIndexes);
261 }
262
263
264
265
266
267
268
269
270
271 @Deprecated
272 public PStmtKey(final String sql, final String catalog, final StatementType statementType) {
273 this(sql, catalog, null, null, null, null, null, null, null, statementType, k -> match(statementType, StatementSQL, CallSQL));
274 }
275
276
277
278
279
280
281
282
283
284
285
286 @Deprecated
287 public PStmtKey(final String sql, final String catalog, final StatementType statementType, final Integer autoGeneratedKeys) {
288 this(sql, catalog, null, null, null, null, autoGeneratedKeys, null, null, statementType,
289 k -> match(statementType, StatementAutoGeneratedKeys, CallSQL));
290 }
291
292
293
294
295
296
297
298
299
300 public PStmtKey(final String sql, final String catalog, final String schema) {
301 this(sql, catalog, schema, StatementType.PREPARED_STATEMENT);
302 }
303
304
305
306
307
308
309
310
311
312
313
314 public PStmtKey(final String sql, final String catalog, final String schema, final int autoGeneratedKeys) {
315 this(sql, catalog, schema, StatementType.PREPARED_STATEMENT, autoGeneratedKeys);
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 public PStmtKey(final String sql, final String catalog, final String schema, final int resultSetType, final int resultSetConcurrency) {
330 this(sql, catalog, schema, resultSetType, resultSetConcurrency, StatementType.PREPARED_STATEMENT);
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 public PStmtKey(final String sql, final String catalog, final String schema, final int resultSetType, final int resultSetConcurrency,
348 final int resultSetHoldability) {
349 this(sql, catalog, schema, resultSetType, resultSetConcurrency, resultSetHoldability, StatementType.PREPARED_STATEMENT);
350 }
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367 public PStmtKey(final String sql, final String catalog, final String schema, final int resultSetType, final int resultSetConcurrency,
368 final int resultSetHoldability, final StatementType statementType) {
369 this(sql, catalog, schema, resultSetType, resultSetConcurrency, resultSetHoldability, null, null, null, statementType,
370 k -> match(statementType, StatementHoldability, CallHoldability));
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 public PStmtKey(final String sql, final String catalog, final String schema, final int resultSetType, final int resultSetConcurrency,
387 final StatementType statementType) {
388 this(sql, catalog, schema, resultSetType, resultSetConcurrency, null, null, null, null, statementType,
389 k -> match(statementType, StatementConcurrency, CallConcurrency));
390 }
391
392
393
394
395
396
397
398
399
400
401 public PStmtKey(final String sql, final String catalog, final String schema, final int[] columnIndexes) {
402 this(sql, catalog, schema, null, null, null, null, columnIndexes, null, StatementType.PREPARED_STATEMENT, StatementColumnIndexes);
403 }
404
405 private PStmtKey(final String sql, final String catalog, final String schema, final Integer resultSetType, final Integer resultSetConcurrency,
406 final Integer resultSetHoldability, final Integer autoGeneratedKeys, final int[] columnIndexes, final String[] columnNames,
407 final StatementType statementType, final Function<PStmtKey, StatementBuilder> statementBuilder) {
408 this.sql = Objects.requireNonNull(sql, "sql").trim();
409 this.catalog = catalog;
410 this.schema = schema;
411 this.resultSetType = resultSetType;
412 this.resultSetConcurrency = resultSetConcurrency;
413 this.resultSetHoldability = resultSetHoldability;
414 this.autoGeneratedKeys = autoGeneratedKeys;
415 this.columnIndexes = clone(columnIndexes);
416 this.columnNames = clone(columnNames);
417 this.statementBuilder = Objects.requireNonNull(Objects.requireNonNull(statementBuilder, "statementBuilder").apply(this), "statementBuilder");
418 this.statementType = statementType;
419 }
420
421
422 private PStmtKey(final String sql, final String catalog, final String schema, final Integer resultSetType, final Integer resultSetConcurrency,
423 final Integer resultSetHoldability, final Integer autoGeneratedKeys, final int[] columnIndexes, final String[] columnNames,
424 final StatementType statementType, final StatementBuilder statementBuilder) {
425 this.sql = sql;
426 this.catalog = catalog;
427 this.schema = schema;
428 this.resultSetType = resultSetType;
429 this.resultSetConcurrency = resultSetConcurrency;
430 this.resultSetHoldability = resultSetHoldability;
431 this.autoGeneratedKeys = autoGeneratedKeys;
432 this.columnIndexes = clone(columnIndexes);
433 this.columnNames = clone(columnNames);
434 this.statementBuilder = Objects.requireNonNull(statementBuilder, "statementBuilder");
435 this.statementType = statementType;
436 }
437
438
439
440
441
442
443
444
445
446
447 public PStmtKey(final String sql, final String catalog, final String schema, final StatementType statementType) {
448 this(sql, catalog, schema, null, null, null, null, null, null, statementType, k -> match(statementType, StatementSQL, CallSQL));
449 }
450
451
452
453
454
455
456
457
458
459
460
461
462 public PStmtKey(final String sql, final String catalog, final String schema, final StatementType statementType, final Integer autoGeneratedKeys) {
463 this(sql, catalog, schema, null, null, null, autoGeneratedKeys, null, null, statementType,
464 k -> match(statementType, StatementAutoGeneratedKeys, CallSQL));
465 }
466
467
468
469
470
471
472
473
474
475
476
477 public PStmtKey(final String sql, final String catalog, final String schema, final String[] columnNames) {
478 this(sql, catalog, schema, null, null, null, null, null, columnNames, StatementType.PREPARED_STATEMENT, StatementColumnNames);
479 }
480
481
482
483
484
485
486
487
488
489
490 @Deprecated
491 public PStmtKey(final String sql, final String catalog, final String[] columnNames) {
492 this(sql, catalog, null, null, null, null, null, null, columnNames, StatementType.PREPARED_STATEMENT, StatementColumnNames);
493 }
494
495 private int[] clone(final int[] array) {
496 return array == null ? null : array.clone();
497 }
498
499 private String[] clone(final String[] array) {
500 return array == null ? null : array.clone();
501 }
502
503
504
505
506
507
508
509
510 public Statement createStatement(final Connection connection) throws SQLException {
511 return statementBuilder.createStatement(connection, this);
512 }
513
514 @Override
515 public boolean equals(final Object obj) {
516 if (this == obj) {
517 return true;
518 }
519 if (obj == null) {
520 return false;
521 }
522 if (getClass() != obj.getClass()) {
523 return false;
524 }
525 final PStmtKey other = (PStmtKey) obj;
526 if (!Objects.equals(autoGeneratedKeys, other.autoGeneratedKeys)) {
527 return false;
528 }
529 if (!Objects.equals(catalog, other.catalog)) {
530 return false;
531 }
532 if (!Arrays.equals(columnIndexes, other.columnIndexes)) {
533 return false;
534 }
535 if (!Arrays.equals(columnNames, other.columnNames)) {
536 return false;
537 }
538 if (!Objects.equals(resultSetConcurrency, other.resultSetConcurrency)) {
539 return false;
540 }
541 if (!Objects.equals(resultSetHoldability, other.resultSetHoldability)) {
542 return false;
543 }
544 if (!Objects.equals(resultSetType, other.resultSetType)) {
545 return false;
546 }
547 if (!Objects.equals(schema, other.schema)) {
548 return false;
549 }
550 if (!Objects.equals(sql, other.sql)) {
551 return false;
552 }
553 return statementType == other.statementType;
554 }
555
556
557
558
559
560
561
562 public Integer getAutoGeneratedKeys() {
563 return autoGeneratedKeys;
564 }
565
566
567
568
569
570
571 public String getCatalog() {
572 return catalog;
573 }
574
575
576
577
578
579
580 public int[] getColumnIndexes() {
581 return clone(columnIndexes);
582 }
583
584
585
586
587
588
589 public String[] getColumnNames() {
590 return clone(columnNames);
591 }
592
593
594
595
596
597
598
599 public Integer getResultSetConcurrency() {
600 return resultSetConcurrency;
601 }
602
603
604
605
606
607
608
609 public Integer getResultSetHoldability() {
610 return resultSetHoldability;
611 }
612
613
614
615
616
617
618
619 public Integer getResultSetType() {
620 return resultSetType;
621 }
622
623
624
625
626
627
628 public String getSchema() {
629 return schema;
630 }
631
632
633
634
635
636
637 public String getSql() {
638 return sql;
639 }
640
641
642
643
644
645
646 public StatementType getStmtType() {
647 return statementType;
648 }
649
650 @Override
651 public int hashCode() {
652 return Objects.hash(autoGeneratedKeys, catalog, Arrays.hashCode(columnIndexes), Arrays.hashCode(columnNames), resultSetConcurrency,
653 resultSetHoldability, resultSetType, schema, sql, statementType);
654 }
655
656 @Override
657 public String toString() {
658 final StringBuilder buf = new StringBuilder();
659 buf.append("PStmtKey: sql=");
660 buf.append(sql);
661 buf.append(", catalog=");
662 buf.append(catalog);
663 buf.append(", schema=");
664 buf.append(schema);
665 buf.append(", resultSetType=");
666 buf.append(resultSetType);
667 buf.append(", resultSetConcurrency=");
668 buf.append(resultSetConcurrency);
669 buf.append(", resultSetHoldability=");
670 buf.append(resultSetHoldability);
671 buf.append(", autoGeneratedKeys=");
672 buf.append(autoGeneratedKeys);
673 buf.append(", columnIndexes=");
674 buf.append(Arrays.toString(columnIndexes));
675 buf.append(", columnNames=");
676 buf.append(Arrays.toString(columnNames));
677 buf.append(", statementType=");
678 buf.append(statementType);
679 return buf.toString();
680 }
681 }