1 /*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.sql;
27
28 /**
29 * <P>The object used for executing a static SQL statement
30 * and returning the results it produces.
31 * <P>
32 * By default, only one <code>ResultSet</code> object per <code>Statement</code>
33 * object can be open at the same time. Therefore, if the reading of one
34 * <code>ResultSet</code> object is interleaved
35 * with the reading of another, each must have been generated by
36 * different <code>Statement</code> objects. All execution methods in the
37 * <code>Statement</code> interface implicitly close a current
38 * <code>ResultSet</code> object of the statement if an open one exists.
39 *
40 * @see Connection#createStatement
41 * @see ResultSet
42 */
43 public interface Statement extends Wrapper, AutoCloseable {
44
45 /**
46 * Executes the given SQL statement, which returns a single
47 * <code>ResultSet</code> object.
1350 * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
1351 * or <code>DELETE</code> statements, or 0 for SQL statements
1352 * that return nothing
1353 * @exception SQLException if a database access error occurs,
1354 * this method is called on a closed <code>Statement</code>, the SQL
1355 * statement returns a <code>ResultSet</code> object, the
1356 * second argument supplied to this method is not a <code>String</code> array
1357 * whose elements are valid column names, the method is called on a
1358 * <code>PreparedStatement</code> or <code>CallableStatement</code>
1359 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
1360 * @throws SQLTimeoutException when the driver has determined that the
1361 * timeout value that was specified by the {@code setQueryTimeout}
1362 * method has been exceeded and has at least attempted to cancel
1363 * the currently running {@code Statement}
1364 * @since 1.8
1365 */
1366 default long executeLargeUpdate(String sql, String columnNames[])
1367 throws SQLException {
1368 throw new SQLFeatureNotSupportedException("executeLargeUpdate not implemented");
1369 }
1370 }
|
1 /*
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.sql;
27
28 import java.util.regex.Pattern;
29 import static java.util.stream.Collectors.joining;
30
31 /**
32 * <P>The object used for executing a static SQL statement
33 * and returning the results it produces.
34 * <P>
35 * By default, only one <code>ResultSet</code> object per <code>Statement</code>
36 * object can be open at the same time. Therefore, if the reading of one
37 * <code>ResultSet</code> object is interleaved
38 * with the reading of another, each must have been generated by
39 * different <code>Statement</code> objects. All execution methods in the
40 * <code>Statement</code> interface implicitly close a current
41 * <code>ResultSet</code> object of the statement if an open one exists.
42 *
43 * @see Connection#createStatement
44 * @see ResultSet
45 */
46 public interface Statement extends Wrapper, AutoCloseable {
47
48 /**
49 * Executes the given SQL statement, which returns a single
50 * <code>ResultSet</code> object.
1353 * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
1354 * or <code>DELETE</code> statements, or 0 for SQL statements
1355 * that return nothing
1356 * @exception SQLException if a database access error occurs,
1357 * this method is called on a closed <code>Statement</code>, the SQL
1358 * statement returns a <code>ResultSet</code> object, the
1359 * second argument supplied to this method is not a <code>String</code> array
1360 * whose elements are valid column names, the method is called on a
1361 * <code>PreparedStatement</code> or <code>CallableStatement</code>
1362 * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
1363 * @throws SQLTimeoutException when the driver has determined that the
1364 * timeout value that was specified by the {@code setQueryTimeout}
1365 * method has been exceeded and has at least attempted to cancel
1366 * the currently running {@code Statement}
1367 * @since 1.8
1368 */
1369 default long executeLargeUpdate(String sql, String columnNames[])
1370 throws SQLException {
1371 throw new SQLFeatureNotSupportedException("executeLargeUpdate not implemented");
1372 }
1373
1374 // JDBC 4.3
1375
1376 /**
1377 * Returns a {@code String} enclosed in single quotes. Any occurrence of a
1378 * single quote within the string will be replaced by two single quotes.
1379 *<p>
1380 * <blockquote>
1381 * <table border = 1 cellspacing=0 cellpadding=5 >
1382 * <caption>Examples of the conversion:</caption>
1383 * <tr><th>Value</th><th>Result</th></tr>
1384 * <tr> <td align='center'>Hello</td> <td align='center'>'Hello'</td> </tr>
1385 * <tr> <td align='center'>G'Day</td> <td align='center'>'G''Day'</td> </tr>
1386 * <tr> <td align='center'>'G''Day'</td>
1387 * <td align='center'>'''G''''Day'''</td> </tr>
1388 * <tr> <td align='center'>I'''M</td> <td align='center'>'I''''''M'</td>
1389 * </tr>
1390 *
1391 * </table>
1392 * </blockquote>
1393 * @implNote
1394 * JDBC driver implementations may need to provide their own implementation
1395 * of this method in order to meet the requirements of the underlying
1396 * datasource.
1397 * @param val a character string
1398 * @return A string enclosed by single quotes with every single quote
1399 * converted to two single quotes
1400 * @throws NullPointerException if val is null
1401 */
1402 default String enquoteLiteral(String val) {
1403 return val.chars()
1404 .mapToObj(c -> c == '\'' ? "\'\'" : String.valueOf((char) c))
1405 .collect(joining("", "'", "'"));
1406 }
1407
1408
1409 /**
1410 * Returns a SQL identifier. If {@code identifier} is a simple SQL identifier:
1411 * <ul>
1412 * <li>Return the original value if {@code alwaysQuote} is
1413 * {@code false}</li>
1414 * <li>Return a delimited identifier if {@code alwaysQuote} is
1415 * {@code true}</li>
1416 * </ul>
1417 *
1418 * If {@code identifier} is not a simple SQL identifier, {@code identifier} will be
1419 * enclosed in double quotes if not already present. If the datasource does
1420 * not support double quotes for delimited identifiers, the
1421 * identifier should be enclosed by the string returned from
1422 * {@link DatabaseMetaData#getIdentifierQuoteString}. If the datasource
1423 * does not support delimited identifiers, a
1424 * {@code SQLFeatureNotSupportedException} should be thrown.
1425 * <p>
1426 * A {@code SQLException} will be thrown if {@code identifier} contains any
1427 * characters invalid in a delimited identifier or the identifier length is
1428 * invalid for the datasource.
1429 *
1430 * @implSpec
1431 * The default implementation uses the following criteria to
1432 * determine a valid simple SQL identifier:
1433 * <ul>
1434 * <li>The string is not enclosed in double quotes</li>
1435 * <li>The first character is an alphabetic character from a through z, or
1436 * from A through Z</li>
1437 * <li>The name only contains alphanumeric characters or the character "_"</li>
1438 * </ul>
1439 *
1440 * The default implementation will throw a {@code SQLException} if:
1441 * <ul>
1442 * <li>{@code identifier} contains a null character or double quote, and is not
1443 * a simple SQL identifier.</li>
1444 * <li>The length of {@code identifier} is less than 1 or greater than 128 characters
1445 * </ul>
1446 * <blockquote>
1447 * <table border = 1 cellspacing=0 cellpadding=5 >
1448 * <caption>Examples of the conversion:</caption>
1449 * <tr>
1450 * <th>identifier</th>
1451 * <th>alwaysQuote</th>
1452 * <th>Result</th></tr>
1453 * <tr>
1454 * <td align='center'>Hello</td>
1455 * <td align='center'>false</td>
1456 * <td align='center'>Hello</td>
1457 * </tr>
1458 * <tr>
1459 * <td align='center'>Hello</td>
1460 * <td align='center'>true</td>
1461 * <td align='center'>"Hello"</td>
1462 * </tr>
1463 * <tr>
1464 * <td align='center'>G'Day</td>
1465 * <td align='center'>false</td>
1466 * <td align='center'>"G'Day"</td>
1467 * </tr>
1468 * <tr>
1469 * <td align='center'>"Bruce Wayne"</td>
1470 * <td align='center'>false</td>
1471 * <td align='center'>"Bruce Wayne"</td>
1472 * </tr>
1473 * <tr>
1474 * <td align='center'>"Bruce Wayne"</td>
1475 * <td align='center'>true</td>
1476 * <td align='center'>"Bruce Wayne"</td>
1477 * </tr>
1478 * <tr>
1479 * <td align='center'>GoodDay$</td>
1480 * <td align='center'>false</td>
1481 * <td align='center'>"GoodDay$"</td>
1482 * </tr>
1483 * <tr>
1484 * <td align='center'>Hello"World</td>
1485 * <td align='center'>false</td>
1486 * <td align='center'>SQLException</td>
1487 * </tr>
1488 * <tr>
1489 * <td align='center'>"Hello"World"</td>
1490 * <td align='center'>false</td>
1491 * <td align='center'>SQLException</td>
1492 * </tr>
1493 * </table>
1494 * </blockquote>
1495 * @implNote
1496 * JDBC driver implementations may need to provide their own implementation
1497 * of this method in order to meet the requirements of the underlying
1498 * datasource.
1499 * @param identifier a SQL identifier
1500 * @param alwaysQuote indicates if a simple SQL identifier should be
1501 * returned as a quoted identifier
1502 * @return A simple SQL identifier or a delimited identifier
1503 * @throws SQLException if identifier is not a valid identifier
1504 * @throws SQLFeatureNotSupportedException if the datasource does not support
1505 * delimited identifiers
1506 * @throws NullPointerException if identifier is null
1507 */
1508 default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException {
1509 int len = identifier.length();
1510 if (len < 1 || len > 128) {
1511 throw new SQLException("Invalid name");
1512 }
1513 if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]+").matcher(identifier).matches()) {
1514 return alwaysQuote ? "\"" + identifier + "\"" : identifier;
1515 }
1516 if (identifier.matches("^\".+\"$")) {
1517 identifier = identifier.substring(1, len - 1);
1518 }
1519 if (Pattern.compile("[^\u0000\"]+").matcher(identifier).matches()) {
1520 return "\"" + identifier + "\"";
1521 } else {
1522 throw new SQLException("Invalid name");
1523 }
1524 }
1525 }
|