001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.dbcp2; 018 019import java.sql.Connection; 020import java.sql.SQLException; 021import java.sql.Statement; 022import java.util.Arrays; 023import java.util.Objects; 024import java.util.function.Function; 025 026import org.apache.commons.dbcp2.PoolingConnection.StatementType; 027 028/** 029 * A key uniquely identifying {@link java.sql.PreparedStatement PreparedStatement}s. 030 * 031 * @since 2.0 032 */ 033public class PStmtKey { 034 035 /** 036 * Interface for Prepared or Callable Statement. 037 */ 038 @FunctionalInterface 039 private interface StatementBuilder { 040 Statement createStatement(Connection connection, PStmtKey key) throws SQLException; 041 } 042 043 private static final StatementBuilder CallConcurrency = (c, k) -> c.prepareCall(k.sql, k.resultSetType, k.resultSetConcurrency); 044 private static final StatementBuilder CallHoldability = (c, k) -> c.prepareCall(k.sql, k.resultSetType, k.resultSetConcurrency, k.resultSetHoldability); 045 private static final StatementBuilder CallSQL = (c, k) -> c.prepareCall(k.sql); 046 private static final StatementBuilder StatementAutoGeneratedKeys = (c, k) -> c.prepareStatement(k.sql, k.autoGeneratedKeys); 047 private static final StatementBuilder StatementColumnIndexes = (c, k) -> c.prepareStatement(k.sql, k.columnIndexes); 048 private static final StatementBuilder StatementColumnNames = (c, k) -> c.prepareStatement(k.sql, k.columnNames); 049 private static final StatementBuilder StatementConcurrency = (c, k) -> c.prepareStatement(k.sql, k.resultSetType, k.resultSetConcurrency); 050 private static final StatementBuilder StatementHoldability = (c, k) -> c.prepareStatement(k.sql, k.resultSetType, k.resultSetConcurrency, 051 k.resultSetHoldability); 052 private static final StatementBuilder StatementSQL = (c, k) -> c.prepareStatement(k.sql); 053 054 private static StatementBuilder match(final StatementType statementType, final StatementBuilder prep, final StatementBuilder call) { 055 switch (Objects.requireNonNull(statementType, "statementType")) { 056 case PREPARED_STATEMENT: 057 return prep; 058 case CALLABLE_STATEMENT: 059 return call; 060 default: 061 throw new IllegalArgumentException(statementType.toString()); 062 } 063 } 064 065 /** 066 * SQL defining Prepared or Callable Statement 067 */ 068 private final String sql; 069 070 /** 071 * Result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or 072 * {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 073 */ 074 private final Integer resultSetType; 075 076 /** 077 * Result set concurrency. A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 078 * {@code ResultSet.CONCUR_UPDATABLE}. 079 */ 080 private final Integer resultSetConcurrency; 081 082 /** 083 * Result set holdability. One of the following {@code ResultSet} constants: {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} 084 * or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 085 */ 086 private final Integer resultSetHoldability; 087 088 /** 089 * Database catalog. 090 */ 091 private final String catalog; 092 093 /** 094 * Database schema. 095 */ 096 private final String schema; 097 098 /** 099 * A flag indicating whether auto-generated keys should be returned; one of {@code Statement.RETURN_GENERATED_KEYS} or 100 * {@code Statement.NO_GENERATED_KEYS}. 101 */ 102 private final Integer autoGeneratedKeys; 103 104 /** 105 * An array of column indexes indicating the columns that should be returned from the inserted row or rows. 106 */ 107 private final int[] columnIndexes; 108 109 /** 110 * An array of column names indicating the columns that should be returned from the inserted row or rows. 111 */ 112 private final String[] columnNames; 113 114 /** 115 * Statement builder. 116 */ 117 private final transient StatementBuilder statementBuilder; 118 119 /** 120 * Statement type, prepared or callable. 121 */ 122 private final StatementType statementType; 123 124 /** 125 * Constructs a key to uniquely identify a prepared statement. 126 * 127 * @param sql The SQL statement. 128 * @deprecated Use {@link #PStmtKey(String, String, String)}. 129 */ 130 @Deprecated 131 public PStmtKey(final String sql) { 132 this(sql, null, StatementType.PREPARED_STATEMENT); 133 } 134 135 /** 136 * Constructs a key to uniquely identify a prepared statement. 137 * 138 * @param sql The SQL statement. 139 * @param resultSetType A result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 140 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 141 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 142 * {@code ResultSet.CONCUR_UPDATABLE}. 143 * @deprecated Use {@link #PStmtKey(String, String, String, int, int)}. 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 * Constructs a key to uniquely identify a prepared statement. 152 * 153 * @param sql The SQL statement. 154 * @param catalog The catalog. 155 * @deprecated Use {@link #PStmtKey(String, String, String)}. 156 */ 157 @Deprecated 158 public PStmtKey(final String sql, final String catalog) { 159 this(sql, catalog, StatementType.PREPARED_STATEMENT); 160 } 161 162 /** 163 * Constructs a key to uniquely identify a prepared statement. 164 * 165 * @param sql The SQL statement. 166 * @param catalog The catalog. 167 * @param autoGeneratedKeys A flag indicating whether auto-generated keys should be returned; one of 168 * {@code Statement.RETURN_GENERATED_KEYS} or {@code Statement.NO_GENERATED_KEYS}. 169 * @deprecated Use {@link #PStmtKey(String, String, String, int)}. 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 * Constructs a key to uniquely identify a prepared statement. 178 * 179 * @param sql The SQL statement. 180 * @param catalog The catalog. 181 * @param resultSetType A result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 182 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 183 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 184 * {@code ResultSet.CONCUR_UPDATABLE}. 185 * @deprecated Use {@link #PStmtKey(String, String, String, int, int)}. 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 * Constructs a key to uniquely identify a prepared statement. 194 * 195 * @param sql The SQL statement. 196 * @param catalog The catalog. 197 * @param resultSetType a result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 198 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 199 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 200 * {@code ResultSet.CONCUR_UPDATABLE} 201 * @param resultSetHoldability One of the following {@code ResultSet} constants: 202 * {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 203 * @deprecated Use {@link #PStmtKey(String, String, String, int, int, int)}. 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 * Constructs a key to uniquely identify a prepared statement. 212 * 213 * @param sql The SQL statement. 214 * @param catalog The catalog. 215 * @param resultSetType a result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 216 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE} 217 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 218 * {@code ResultSet.CONCUR_UPDATABLE}. 219 * @param resultSetHoldability One of the following {@code ResultSet} constants: 220 * {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 221 * @param statementType The SQL statement type, prepared or callable. 222 * @deprecated Use {@link #PStmtKey(String, String, String, int, int, int, PoolingConnection.StatementType)} 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 * Constructs a key to uniquely identify a prepared statement. 233 * 234 * @param sql The SQL statement. 235 * @param catalog The catalog. 236 * @param resultSetType A result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 237 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 238 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 239 * {@code ResultSet.CONCUR_UPDATABLE}. 240 * @param statementType The SQL statement type, prepared or callable. 241 * @deprecated Use {@link #PStmtKey(String, String, String, int, int, PoolingConnection.StatementType)}. 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 * Constructs a key to uniquely identify a prepared statement. 251 * 252 * @param sql The SQL statement. 253 * @param catalog The catalog. 254 * @param columnIndexes An array of column indexes indicating the columns that should be returned from the inserted row 255 * or rows. 256 * @deprecated Use {@link #PStmtKey(String, String, String, int[])}. 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 * Constructs a key to uniquely identify a prepared statement. 265 * 266 * @param sql The SQL statement. 267 * @param catalog The catalog. 268 * @param statementType The SQL statement type, prepared or callable. 269 * @deprecated Use {@link #PStmtKey(String, String, String, PoolingConnection.StatementType)}. 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 * Constructs a key to uniquely identify a prepared statement. 278 * 279 * @param sql The SQL statement. 280 * @param catalog The catalog. 281 * @param statementType The SQL statement type, prepared or callable. 282 * @param autoGeneratedKeys A flag indicating whether auto-generated keys should be returned; one of 283 * {@code Statement.RETURN_GENERATED_KEYS} or {@code Statement.NO_GENERATED_KEYS}. 284 * @deprecated Use {@link #PStmtKey(String, String, String, PoolingConnection.StatementType, Integer)} 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 * Constructs a key to uniquely identify a prepared statement. 294 * 295 * @param sql The SQL statement. 296 * @param catalog The catalog. 297 * @param schema The schema 298 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 306 * 307 * @param sql The SQL statement. 308 * @param catalog The catalog. 309 * @param schema The schema 310 * @param autoGeneratedKeys A flag indicating whether auto-generated keys should be returned; one of 311 * {@code Statement.RETURN_GENERATED_KEYS} or {@code Statement.NO_GENERATED_KEYS}. 312 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 320 * 321 * @param sql The SQL statement. 322 * @param catalog The catalog. 323 * @param schema The schema 324 * @param resultSetType A result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 325 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 326 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 327 * {@code ResultSet.CONCUR_UPDATABLE}. 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 * Constructs a key to uniquely identify a prepared statement. 335 * 336 * @param sql The SQL statement. 337 * @param catalog The catalog. 338 * @param schema The schema 339 * @param resultSetType a result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 340 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 341 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 342 * {@code ResultSet.CONCUR_UPDATABLE} 343 * @param resultSetHoldability One of the following {@code ResultSet} constants: 344 * {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 345 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 354 * 355 * @param sql The SQL statement. 356 * @param catalog The catalog. 357 * @param schema The schema. 358 * @param resultSetType a result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 359 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE} 360 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 361 * {@code ResultSet.CONCUR_UPDATABLE}. 362 * @param resultSetHoldability One of the following {@code ResultSet} constants: 363 * {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 364 * @param statementType The SQL statement type, prepared or callable. 365 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 375 * 376 * @param sql The SQL statement. 377 * @param catalog The catalog. 378 * @param schema The schema. 379 * @param resultSetType A result set type; one of {@code ResultSet.TYPE_FORWARD_ONLY}, 380 * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 381 * @param resultSetConcurrency A concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 382 * {@code ResultSet.CONCUR_UPDATABLE}. 383 * @param statementType The SQL statement type, prepared or callable. 384 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 394 * 395 * @param sql The SQL statement. 396 * @param catalog The catalog. 397 * @param schema The schema. 398 * @param columnIndexes An array of column indexes indicating the columns that should be returned from the inserted row 399 * or rows. 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 // Root constructor. 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 * Constructs a key to uniquely identify a prepared statement. 440 * 441 * @param sql The SQL statement. 442 * @param catalog The catalog. 443 * @param schema The schema. 444 * @param statementType The SQL statement type, prepared or callable. 445 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 453 * 454 * @param sql The SQL statement. 455 * @param catalog The catalog. 456 * @param schema The schema. 457 * @param statementType The SQL statement type, prepared or callable. 458 * @param autoGeneratedKeys A flag indicating whether auto-generated keys should be returned; one of 459 * {@code Statement.RETURN_GENERATED_KEYS} or {@code Statement.NO_GENERATED_KEYS}. 460 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 469 * 470 * @param sql The SQL statement. 471 * @param catalog The catalog. 472 * @param schema The schema. 473 * @param columnNames An array of column names indicating the columns that should be returned from the inserted row or 474 * rows. 475 * @since 2.5.0 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 * Constructs a key to uniquely identify a prepared statement. 483 * 484 * @param sql The SQL statement. 485 * @param catalog The catalog. 486 * @param columnNames An array of column names indicating the columns that should be returned from the inserted row or 487 * rows. 488 * @deprecated Use {@link #PStmtKey(String, String, String, String[])}. 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 * Creates a new Statement from the given Connection. 505 * 506 * @param connection The Connection to use to create the statement. 507 * @return The statement. 508 * @throws SQLException Thrown when there is a problem creating the statement. 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 * Gets a flag indicating whether auto-generated keys should be returned; one of {@code Statement.RETURN_GENERATED_KEYS} 558 * or {@code Statement.NO_GENERATED_KEYS}. 559 * 560 * @return a flag indicating whether auto-generated keys should be returned. 561 */ 562 public Integer getAutoGeneratedKeys() { 563 return autoGeneratedKeys; 564 } 565 566 /** 567 * Gets the catalog. 568 * 569 * @return The catalog. 570 */ 571 public String getCatalog() { 572 return catalog; 573 } 574 575 /** 576 * Gets an array of column indexes indicating the columns that should be returned from the inserted row or rows. 577 * 578 * @return An array of column indexes. 579 */ 580 public int[] getColumnIndexes() { 581 return clone(columnIndexes); 582 } 583 584 /** 585 * Gets an array of column names indicating the columns that should be returned from the inserted row or rows. 586 * 587 * @return An array of column names. 588 */ 589 public String[] getColumnNames() { 590 return clone(columnNames); 591 } 592 593 /** 594 * Gets the result set concurrency type; one of {@code ResultSet.CONCUR_READ_ONLY} or 595 * {@code ResultSet.CONCUR_UPDATABLE}. 596 * 597 * @return The result set concurrency type. 598 */ 599 public Integer getResultSetConcurrency() { 600 return resultSetConcurrency; 601 } 602 603 /** 604 * Gets the result set holdability, one of the following {@code ResultSet} constants: 605 * {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code ResultSet.CLOSE_CURSORS_AT_COMMIT}. 606 * 607 * @return The result set holdability. 608 */ 609 public Integer getResultSetHoldability() { 610 return resultSetHoldability; 611 } 612 613 /** 614 * Gets the result set type, one of {@code ResultSet.TYPE_FORWARD_ONLY}, {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or 615 * {@code ResultSet.TYPE_SCROLL_SENSITIVE}. 616 * 617 * @return the result set type. 618 */ 619 public Integer getResultSetType() { 620 return resultSetType; 621 } 622 623 /** 624 * Gets the schema. 625 * 626 * @return The catalog. 627 */ 628 public String getSchema() { 629 return schema; 630 } 631 632 /** 633 * Gets the SQL statement. 634 * 635 * @return the SQL statement. 636 */ 637 public String getSql() { 638 return sql; 639 } 640 641 /** 642 * Gets the SQL statement type. 643 * 644 * @return The SQL statement type. 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}