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.
51 *<p>
52 * <strong>Note:</strong>This method cannot be called on a
53 * <code>PreparedStatement</code> or <code>CallableStatement</code>.
54 * @param sql an SQL statement to be sent to the database, typically a
55 * static SQL <code>SELECT</code> statement
56 * @return a <code>ResultSet</code> object that contains the data produced
57 * by the given query; never <code>null</code>
58 * @exception SQLException if a database access error occurs,
59 * this method is called on a closed <code>Statement</code>, the given
60 * SQL statement produces anything other than a single
61 * <code>ResultSet</code> object, the method is called on a
62 * <code>PreparedStatement</code> or <code>CallableStatement</code>
63 * @throws SQLTimeoutException when the driver has determined that the
64 * timeout value that was specified by the {@code setQueryTimeout}
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 {@code null}
1401 * @throws SQLException if a database access error occurs
1402 */
1403 default String enquoteLiteral(String val) throws SQLException {
1404 return "'" + val.replace("'", "''") + "'";
1405 }
1406
1407
1408 /**
1409 * Returns a SQL identifier. If {@code identifier} is a simple SQL identifier:
1410 * <ul>
1411 * <li>Return the original value if {@code alwaysQuote} is
1412 * {@code false}</li>
1413 * <li>Return a delimited identifier if {@code alwaysQuote} is
1414 * {@code true}</li>
1415 * </ul>
1416 *
1417 * If {@code identifier} is not a simple SQL identifier, {@code identifier} will be
1418 * enclosed in double quotes if not already present. If the datasource does
1419 * not support double quotes for delimited identifiers, the
1420 * identifier should be enclosed by the string returned from
1421 * {@link DatabaseMetaData#getIdentifierQuoteString}. If the datasource
1486 * </tr>
1487 * <tr>
1488 * <td align='center'>"Hello"World"</td>
1489 * <td align='center'>false</td>
1490 * <td align='center'>SQLException</td>
1491 * </tr>
1492 * </table>
1493 * </blockquote>
1494 * @implNote
1495 * JDBC driver implementations may need to provide their own implementation
1496 * of this method in order to meet the requirements of the underlying
1497 * datasource.
1498 * @param identifier a SQL identifier
1499 * @param alwaysQuote indicates if a simple SQL identifier should be
1500 * returned as a quoted identifier
1501 * @return A simple SQL identifier or a delimited identifier
1502 * @throws SQLException if identifier is not a valid identifier
1503 * @throws SQLFeatureNotSupportedException if the datasource does not support
1504 * delimited identifiers
1505 * @throws NullPointerException if identifier is {@code null}
1506 */
1507 default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException {
1508 int len = identifier.length();
1509 if (len < 1 || len > 128) {
1510 throw new SQLException("Invalid name");
1511 }
1512 if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches()) {
1513 return alwaysQuote ? "\"" + identifier + "\"" : identifier;
1514 }
1515 if (identifier.matches("^\".+\"$")) {
1516 identifier = identifier.substring(1, len - 1);
1517 }
1518 if (Pattern.compile("[^\u0000\"]+").matcher(identifier).matches()) {
1519 return "\"" + identifier + "\"";
1520 } else {
1521 throw new SQLException("Invalid name");
1522 }
1523 }
1524
1525 /**
1559 * <td align='center'>GoodDay$</td>
1560 * <td align='center'>false</td>
1561 * </tr>
1562 * <tr>
1563 * <td align='center'>Hello"World</td>
1564 * <td align='center'>false</td>
1565 * </tr>
1566 * <tr>
1567 * <td align='center'>"Hello"World"</td>
1568 * <td align='center'>false</td>
1569 * </tr>
1570 * </table>
1571 * </blockquote>
1572 * @implNote JDBC driver implementations may need to provide their own
1573 * implementation of this method in order to meet the requirements of the
1574 * underlying datasource.
1575 * @param identifier a SQL identifier
1576 * @return true if a simple SQL identifier, false otherwise
1577 * @throws NullPointerException if identifier is {@code null}
1578 * @throws SQLException if a database access error occurs
1579 */
1580 default boolean isSimpleIdentifier(String identifier) throws SQLException {
1581 int len = identifier.length();
1582 return len >= 1 && len <= 128
1583 && Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
1584 }
1585
1586 /**
1587 * Returns a {@code String} representing a National Character Set Literal
1588 * enclosed in single quotes and prefixed with a upper case letter N.
1589 * Any occurrence of a single quote within the string will be replaced
1590 * by two single quotes.
1591 *
1592 * <blockquote>
1593 * <table border = 1 cellspacing=0 cellpadding=5 >
1594 * <caption>Examples of the conversion:</caption>
1595 * <tr>
1596 * <th>Value</th>
1597 * <th>Result</th>
1598 * </tr>
1600 * <tr> <td align='center'>G'Day</td> <td align='center'>N'G''Day'</td> </tr>
1601 * <tr> <td align='center'>'G''Day'</td>
1602 * <td align='center'>N'''G''''Day'''</td> </tr>
1603 * <tr> <td align='center'>I'''M</td> <td align='center'>N'I''''''M'</td>
1604 * <tr> <td align='center'>N'Hello'</td> <td align='center'>N'N''Hello'''</td> </tr>
1605 *
1606 * </table>
1607 * </blockquote>
1608 * @implNote
1609 * JDBC driver implementations may need to provide their own implementation
1610 * of this method in order to meet the requirements of the underlying
1611 * datasource. An implementation of enquoteNCharLiteral may accept a different
1612 * set of characters than that accepted by the same drivers implementation of
1613 * enquoteLiteral.
1614 * @param val a character string
1615 * @return the result of replacing every single quote character in the
1616 * argument by two single quote characters where this entire result is
1617 * then prefixed with 'N'.
1618 * @throws NullPointerException if val is {@code null}
1619 * @throws SQLException if a database access error occurs
1620 */
1621 default String enquoteNCharLiteral(String val) throws SQLException {
1622 return "N'" + val.replace("'", "''") + "'";
1623 }
1624 }
|
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 * @since 1.1
46 */
47 public interface Statement extends Wrapper, AutoCloseable {
48
49 /**
50 * Executes the given SQL statement, which returns a single
51 * <code>ResultSet</code> object.
52 *<p>
53 * <strong>Note:</strong>This method cannot be called on a
54 * <code>PreparedStatement</code> or <code>CallableStatement</code>.
55 * @param sql an SQL statement to be sent to the database, typically a
56 * static SQL <code>SELECT</code> statement
57 * @return a <code>ResultSet</code> object that contains the data produced
58 * by the given query; never <code>null</code>
59 * @exception SQLException if a database access error occurs,
60 * this method is called on a closed <code>Statement</code>, the given
61 * SQL statement produces anything other than a single
62 * <code>ResultSet</code> object, the method is called on a
63 * <code>PreparedStatement</code> or <code>CallableStatement</code>
64 * @throws SQLTimeoutException when the driver has determined that the
65 * timeout value that was specified by the {@code setQueryTimeout}
1383 * <caption>Examples of the conversion:</caption>
1384 * <tr><th>Value</th><th>Result</th></tr>
1385 * <tr> <td align='center'>Hello</td> <td align='center'>'Hello'</td> </tr>
1386 * <tr> <td align='center'>G'Day</td> <td align='center'>'G''Day'</td> </tr>
1387 * <tr> <td align='center'>'G''Day'</td>
1388 * <td align='center'>'''G''''Day'''</td> </tr>
1389 * <tr> <td align='center'>I'''M</td> <td align='center'>'I''''''M'</td>
1390 * </tr>
1391 *
1392 * </table>
1393 * </blockquote>
1394 * @implNote
1395 * JDBC driver implementations may need to provide their own implementation
1396 * of this method in order to meet the requirements of the underlying
1397 * datasource.
1398 * @param val a character string
1399 * @return A string enclosed by single quotes with every single quote
1400 * converted to two single quotes
1401 * @throws NullPointerException if val is {@code null}
1402 * @throws SQLException if a database access error occurs
1403 *
1404 * @since 9
1405 */
1406 default String enquoteLiteral(String val) throws SQLException {
1407 return "'" + val.replace("'", "''") + "'";
1408 }
1409
1410
1411 /**
1412 * Returns a SQL identifier. If {@code identifier} is a simple SQL identifier:
1413 * <ul>
1414 * <li>Return the original value if {@code alwaysQuote} is
1415 * {@code false}</li>
1416 * <li>Return a delimited identifier if {@code alwaysQuote} is
1417 * {@code true}</li>
1418 * </ul>
1419 *
1420 * If {@code identifier} is not a simple SQL identifier, {@code identifier} will be
1421 * enclosed in double quotes if not already present. If the datasource does
1422 * not support double quotes for delimited identifiers, the
1423 * identifier should be enclosed by the string returned from
1424 * {@link DatabaseMetaData#getIdentifierQuoteString}. If the datasource
1489 * </tr>
1490 * <tr>
1491 * <td align='center'>"Hello"World"</td>
1492 * <td align='center'>false</td>
1493 * <td align='center'>SQLException</td>
1494 * </tr>
1495 * </table>
1496 * </blockquote>
1497 * @implNote
1498 * JDBC driver implementations may need to provide their own implementation
1499 * of this method in order to meet the requirements of the underlying
1500 * datasource.
1501 * @param identifier a SQL identifier
1502 * @param alwaysQuote indicates if a simple SQL identifier should be
1503 * returned as a quoted identifier
1504 * @return A simple SQL identifier or a delimited identifier
1505 * @throws SQLException if identifier is not a valid identifier
1506 * @throws SQLFeatureNotSupportedException if the datasource does not support
1507 * delimited identifiers
1508 * @throws NullPointerException if identifier is {@code null}
1509 *
1510 * @since 9
1511 */
1512 default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException {
1513 int len = identifier.length();
1514 if (len < 1 || len > 128) {
1515 throw new SQLException("Invalid name");
1516 }
1517 if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches()) {
1518 return alwaysQuote ? "\"" + identifier + "\"" : identifier;
1519 }
1520 if (identifier.matches("^\".+\"$")) {
1521 identifier = identifier.substring(1, len - 1);
1522 }
1523 if (Pattern.compile("[^\u0000\"]+").matcher(identifier).matches()) {
1524 return "\"" + identifier + "\"";
1525 } else {
1526 throw new SQLException("Invalid name");
1527 }
1528 }
1529
1530 /**
1564 * <td align='center'>GoodDay$</td>
1565 * <td align='center'>false</td>
1566 * </tr>
1567 * <tr>
1568 * <td align='center'>Hello"World</td>
1569 * <td align='center'>false</td>
1570 * </tr>
1571 * <tr>
1572 * <td align='center'>"Hello"World"</td>
1573 * <td align='center'>false</td>
1574 * </tr>
1575 * </table>
1576 * </blockquote>
1577 * @implNote JDBC driver implementations may need to provide their own
1578 * implementation of this method in order to meet the requirements of the
1579 * underlying datasource.
1580 * @param identifier a SQL identifier
1581 * @return true if a simple SQL identifier, false otherwise
1582 * @throws NullPointerException if identifier is {@code null}
1583 * @throws SQLException if a database access error occurs
1584 *
1585 * @since 9
1586 */
1587 default boolean isSimpleIdentifier(String identifier) throws SQLException {
1588 int len = identifier.length();
1589 return len >= 1 && len <= 128
1590 && Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
1591 }
1592
1593 /**
1594 * Returns a {@code String} representing a National Character Set Literal
1595 * enclosed in single quotes and prefixed with a upper case letter N.
1596 * Any occurrence of a single quote within the string will be replaced
1597 * by two single quotes.
1598 *
1599 * <blockquote>
1600 * <table border = 1 cellspacing=0 cellpadding=5 >
1601 * <caption>Examples of the conversion:</caption>
1602 * <tr>
1603 * <th>Value</th>
1604 * <th>Result</th>
1605 * </tr>
1607 * <tr> <td align='center'>G'Day</td> <td align='center'>N'G''Day'</td> </tr>
1608 * <tr> <td align='center'>'G''Day'</td>
1609 * <td align='center'>N'''G''''Day'''</td> </tr>
1610 * <tr> <td align='center'>I'''M</td> <td align='center'>N'I''''''M'</td>
1611 * <tr> <td align='center'>N'Hello'</td> <td align='center'>N'N''Hello'''</td> </tr>
1612 *
1613 * </table>
1614 * </blockquote>
1615 * @implNote
1616 * JDBC driver implementations may need to provide their own implementation
1617 * of this method in order to meet the requirements of the underlying
1618 * datasource. An implementation of enquoteNCharLiteral may accept a different
1619 * set of characters than that accepted by the same drivers implementation of
1620 * enquoteLiteral.
1621 * @param val a character string
1622 * @return the result of replacing every single quote character in the
1623 * argument by two single quote characters where this entire result is
1624 * then prefixed with 'N'.
1625 * @throws NullPointerException if val is {@code null}
1626 * @throws SQLException if a database access error occurs
1627 *
1628 * @since 9
1629 */
1630 default String enquoteNCharLiteral(String val) throws SQLException {
1631 return "N'" + val.replace("'", "''") + "'";
1632 }
1633 }
|