1 30 31 32 package org.hsqldb.jdbc; 33 34 import java.sql.CallableStatement ; 35 import java.sql.Connection ; 36 import java.sql.DatabaseMetaData ; 37 import java.sql.PreparedStatement ; 38 import java.sql.SQLException ; 39 import java.sql.SQLWarning ; 40 import java.sql.Statement ; 41 42 import java.sql.Savepoint ; 44 45 import java.util.Map ; 48 49 import java.util.Locale ; 51 52 import org.hsqldb.DatabaseManager; 53 import org.hsqldb.DatabaseURL; 54 import org.hsqldb.HSQLClientConnection; 55 import org.hsqldb.HTTPClientConnection; 56 import org.hsqldb.HsqlException; 57 import org.hsqldb.persist.HsqlProperties; 58 import org.hsqldb.Result; 59 import org.hsqldb.ResultConstants; 60 import org.hsqldb.Session; 61 import org.hsqldb.SessionInterface; 62 import org.hsqldb.Trace; 63 import org.hsqldb.lib.StringUtil; 64 65 82 403 public class jdbcConnection implements Connection { 404 405 407 411 HsqlProperties connProperties; 412 413 417 SessionInterface sessionProxy; 418 419 422 boolean isInternal; 423 424 425 protected boolean isNetConn; 426 427 430 boolean isClosed; 431 432 433 private SQLWarning rootWarning; 434 435 436 private Object rootWarning_mutex = new Object (); 437 438 443 447 448 450 497 public synchronized Statement createStatement() throws SQLException { 498 499 checkClosed(); 500 501 Statement stmt = new jdbcStatement(this, 502 jdbcResultSet.TYPE_FORWARD_ONLY); 503 504 return stmt; 505 } 506 507 555 public synchronized PreparedStatement prepareStatement(String sql) 556 throws SQLException { 557 558 PreparedStatement stmt; 559 560 checkClosed(); 561 562 try { 563 stmt = new jdbcPreparedStatement(this, sql, 564 jdbcResultSet.TYPE_FORWARD_ONLY); 565 566 return stmt; 567 } catch (HsqlException e) { 568 throw Util.sqlException(e); 569 } 570 } 571 572 614 public synchronized CallableStatement prepareCall(String sql) 615 throws SQLException { 616 617 CallableStatement stmt; 618 619 checkClosed(); 620 621 try { 622 stmt = new jdbcCallableStatement(this, sql, 623 jdbcResultSet.TYPE_FORWARD_ONLY); 624 625 return stmt; 626 } catch (HsqlException e) { 627 throw Util.sqlException(e); 628 } 629 } 630 631 706 public synchronized String nativeSQL(final String sql) 707 throws SQLException { 708 709 checkClosed(); 716 717 if (sql == null || sql.length() == 0 || sql.indexOf('{') == -1) { 719 return sql; 720 } 721 722 int state = 0; 724 int len = sql.length(); 725 int nest = 0; 726 StringBuffer sb = new StringBuffer (sql.length()); String msg; 728 729 final int outside_all = 0; 731 final int outside_escape_inside_single_quotes = 1; 732 final int outside_escape_inside_double_quotes = 2; 733 734 final int inside_escape = 3; 736 final int inside_escape_inside_single_quotes = 4; 737 final int inside_escape_inside_double_quotes = 5; 738 739 sb.append(sql); 746 747 for (int i = 0; i < len; i++) { 748 char c = sb.charAt(i); 749 750 switch (state) { 751 752 case outside_all : if (c == '\'') { 754 state = outside_escape_inside_single_quotes; 755 } else if (c == '"') { 756 state = outside_escape_inside_double_quotes; 757 } else if (c == '{') { 758 i = onStartEscapeSequence(sql, sb, i); 759 760 nest++; 762 763 state = inside_escape; 764 } 765 break; 766 767 case outside_escape_inside_single_quotes : case inside_escape_inside_single_quotes : if (c == '\'') { 770 state -= 1; 771 } 772 break; 773 774 case outside_escape_inside_double_quotes : case inside_escape_inside_double_quotes : if (c == '"') { 777 state -= 2; 778 } 779 break; 780 781 case inside_escape : if (c == '\'') { 783 state = inside_escape_inside_single_quotes; 784 } else if (c == '"') { 785 state = inside_escape_inside_double_quotes; 786 } else if (c == '}') { 787 sb.setCharAt(i, ' '); 788 789 nest--; 791 792 state = (nest == 0) ? outside_all 793 : inside_escape; 794 } else if (c == '{') { 795 i = onStartEscapeSequence(sql, sb, i); 796 797 nest++; 799 800 state = inside_escape; 801 } 802 } 803 } 804 805 return sb.toString(); 806 } 807 808 857 public synchronized void setAutoCommit(boolean autoCommit) 858 throws SQLException { 859 860 checkClosed(); 861 862 try { 863 sessionProxy.setAutoCommit(autoCommit); 864 } catch (HsqlException e) { 865 throw Util.sqlException(e); 866 } 867 } 868 869 876 public synchronized boolean getAutoCommit() throws SQLException { 877 878 checkClosed(); 879 880 try { 881 return sessionProxy.isAutoCommit(); 882 } catch (HsqlException e) { 883 throw Util.sqlException(e); 884 } 885 } 886 887 916 public synchronized void commit() throws SQLException { 917 918 checkClosed(); 919 920 try { 921 sessionProxy.commit(); 922 } catch (HsqlException e) { 923 throw Util.sqlException(e); 924 } 925 } 926 927 956 public synchronized void rollback() throws SQLException { 957 958 checkClosed(); 959 960 try { 961 sessionProxy.rollback(); 962 } catch (HsqlException e) { 963 throw Util.sqlException(e); 964 } 965 } 966 967 992 public synchronized void close() throws SQLException { 993 994 if (isInternal || isClosed) { 999 return; 1000 } 1001 1002 isClosed = true; 1003 1004 if (sessionProxy != null) { 1005 sessionProxy.close(); 1006 } 1007 1008 sessionProxy = null; 1009 rootWarning = null; 1010 connProperties = null; 1011 } 1012 1013 1019 public synchronized boolean isClosed() { 1020 return isClosed; 1021 } 1022 1023 1061 public synchronized DatabaseMetaData getMetaData() throws SQLException { 1062 1063 checkClosed(); 1064 1065 return new jdbcDatabaseMetaData(this); 1066 } 1067 1068 1114 public synchronized void setReadOnly(boolean readonly) 1115 throws SQLException { 1116 1117 checkClosed(); 1118 1119 try { 1120 sessionProxy.setReadOnly(readonly); 1121 } catch (HsqlException e) { 1122 throw Util.sqlException(e); 1123 } 1124 } 1125 1126 1132 public synchronized boolean isReadOnly() throws SQLException { 1133 1134 try { 1135 return sessionProxy.isReadOnly(); 1136 } catch (HsqlException e) { 1137 throw Util.sqlException(e); 1138 } 1139 } 1140 1141 1161 public synchronized void setCatalog(String catalog) throws SQLException { 1162 checkClosed(); 1163 } 1164 1165 1184 public synchronized String getCatalog() throws SQLException { 1185 1186 checkClosed(); 1187 1188 return null; 1189 } 1190 1191 1220 public synchronized void setTransactionIsolation(int level) 1221 throws SQLException { 1222 1223 checkClosed(); 1224 1225 switch (level) { 1226 1227 case TRANSACTION_READ_UNCOMMITTED : 1228 case TRANSACTION_READ_COMMITTED : 1229 case TRANSACTION_REPEATABLE_READ : 1230 case TRANSACTION_SERIALIZABLE : 1231 break; 1232 1233 default : 1234 throw Util.invalidArgument(); 1235 } 1236 1237 try { 1238 sessionProxy.setIsolation(level); 1239 } catch (HsqlException e) { 1240 throw Util.sqlException(e); 1241 } 1242 } 1243 1244 1273 public synchronized int getTransactionIsolation() throws SQLException { 1274 1275 checkClosed(); 1276 1277 try { 1278 return sessionProxy.getIsolation(); 1279 } catch (HsqlException e) { 1280 throw Util.sqlException(e); 1281 } 1282 } 1283 1284 1316 public synchronized SQLWarning getWarnings() throws SQLException { 1317 1318 checkClosed(); 1319 1320 synchronized (rootWarning_mutex) { 1321 return rootWarning; 1322 } 1323 } 1324 1325 1346 public synchronized void clearWarnings() throws SQLException { 1347 1348 checkClosed(); 1349 1350 synchronized (rootWarning_mutex) { 1351 rootWarning = null; 1352 } 1353 } 1354 1355 1357 1415 public synchronized Statement createStatement(int type, 1416 int concurrency) throws SQLException { 1417 1418 checkClosed(); 1419 1420 type = xlateRSType(type); 1421 concurrency = xlateRSConcurrency(concurrency); 1422 1423 return new jdbcStatement(this, type); 1424 } 1425 1426 1473 public synchronized PreparedStatement prepareStatement(String sql, 1474 int type, int concurrency) throws SQLException { 1475 1476 checkClosed(); 1477 1478 type = xlateRSType(type); 1479 concurrency = xlateRSConcurrency(concurrency); 1480 1481 try { 1482 return new jdbcPreparedStatement(this, sql, type); 1483 } catch (HsqlException e) { 1484 throw Util.sqlException(e); 1485 } 1486 } 1487 1488 1532 public synchronized CallableStatement prepareCall(String sql, 1533 int resultSetType, int resultSetConcurrency) throws SQLException { 1534 1535 checkClosed(); 1536 1537 resultSetType = xlateRSType(resultSetType); 1538 resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency); 1539 1540 try { 1541 return new jdbcCallableStatement(this, sql, resultSetType); 1542 } catch (HsqlException e) { 1543 throw Util.sqlException(e); 1544 } 1545 } 1546 1547 1571 public synchronized Map getTypeMap() throws SQLException { 1572 1573 checkClosed(); 1574 1575 throw Util.notSupported(); 1576 } 1577 1578 1606 public synchronized void setTypeMap(Map map) throws SQLException { 1607 1608 checkClosed(); 1609 1610 throw Util.notSupported(); 1611 } 1612 1613 1618 1647 public synchronized void setHoldability(int holdability) 1649 throws SQLException { 1650 1651 checkClosed(); 1652 1653 switch (holdability) { 1654 1655 case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT : 1656 break; 1657 1658 case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT : 1659 String msg = "ResultSet holdability: " + holdability; 1661 throw Util.sqlException(Trace.FUNCTION_NOT_SUPPORTED, msg); 1662 default : 1663 throw Util.invalidArgument(); 1664 } 1665 } 1666 1667 1669 1694 public synchronized int getHoldability() throws SQLException { 1696 1697 checkClosed(); 1698 1699 return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT; 1700 } 1701 1702 1704 1732 public synchronized Savepoint setSavepoint() throws SQLException { 1734 1735 checkClosed(); 1736 1737 throw Util.notSupported(); 1738 } 1739 1740 1742 1760 public synchronized Savepoint setSavepoint(String name) 1762 throws SQLException { 1763 1764 Result req; 1765 1766 checkClosed(); 1767 1768 if (name == null) { 1769 String msg = "name is null"; 1770 1771 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1772 } 1773 1774 req = Result.newSetSavepointRequest(name); 1775 1776 try { 1777 sessionProxy.execute(req); 1778 } catch (HsqlException e) { 1779 Util.throwError(e); 1780 } 1781 1782 return new jdbcSavepoint(name, this); 1783 } 1784 1785 1787 1807 public synchronized void rollback(Savepoint savepoint) 1809 throws SQLException { 1810 1811 String msg; 1812 jdbcSavepoint sp; 1813 Result req; 1814 1815 checkClosed(); 1816 1817 if (savepoint == null) { 1818 msg = "savepoint is null"; 1819 1820 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1821 } 1822 1823 try { 1824 if (sessionProxy.isAutoCommit()) { 1825 msg = "connection is autocommit"; 1826 1827 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1828 } 1829 } catch (HsqlException e) { 1830 throw Util.sqlException(e); 1831 } 1832 1833 if (!(savepoint instanceof jdbcSavepoint)) { 1835 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT); 1836 } 1837 1838 sp = (jdbcSavepoint) savepoint; 1839 1840 if (this != sp.connection) { 1841 msg = savepoint + " was not issued on this connection"; 1842 1843 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1844 } 1845 1846 req = Result.newRollbackToSavepointRequest(sp.name); 1847 1848 try { 1849 Result result = sessionProxy.execute(req); 1850 1851 if (result.isError()) { 1852 Util.throwError(result); 1853 } 1854 } catch (HsqlException e) { 1855 Util.throwError(e); 1856 } 1857 } 1858 1859 1861 1879 public synchronized void releaseSavepoint(Savepoint savepoint) 1881 throws SQLException { 1882 1883 String msg; 1884 jdbcSavepoint sp; 1885 Result req; 1886 1887 checkClosed(); 1888 1889 if (savepoint == null) { 1890 msg = "savepoint is null"; 1891 1892 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1893 } 1894 1895 if (!(savepoint instanceof jdbcSavepoint)) { 1897 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT); 1898 } 1899 1900 sp = (jdbcSavepoint) savepoint; 1901 1902 if (this != sp.connection) { 1903 msg = savepoint.getSavepointName() 1904 + " was not issued on this connection"; 1905 1906 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 1907 } 1908 1909 req = Result.newReleaseSavepointRequest(sp.name); 1910 1911 try { 1912 Result result = sessionProxy.execute(req); 1913 1914 if (result.isError()) { 1915 Util.throwError(result); 1916 } 1917 } catch (HsqlException e) { 1918 Util.throwError(e); 1919 } 1920 } 1921 1922 1924 1969 public synchronized Statement createStatement(int resultSetType, 1971 int resultSetConcurrency, 1972 int resultSetHoldability) throws SQLException { 1973 1974 checkClosed(); 1975 1976 resultSetType = xlateRSType(resultSetType); 1977 resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency); 1978 resultSetHoldability = xlateRSHoldability(resultSetHoldability); 1979 1980 return new jdbcStatement(this, resultSetType); 1981 } 1982 1983 1985 2039 public synchronized PreparedStatement prepareStatement(String sql, 2041 int resultSetType, int resultSetConcurrency, 2042 int resultSetHoldability) throws SQLException { 2043 2044 checkClosed(); 2045 2046 resultSetType = xlateRSType(resultSetType); 2047 resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency); 2048 resultSetHoldability = xlateRSHoldability(resultSetHoldability); 2049 2050 try { 2051 return new jdbcPreparedStatement(this, sql, resultSetType); 2052 } catch (HsqlException e) { 2053 throw Util.sqlException(e); 2054 } 2055 } 2056 2057 2059 2112 public synchronized CallableStatement prepareCall(String sql, 2114 int resultSetType, int resultSetConcurrency, 2115 int resultSetHoldability) throws SQLException { 2116 2117 checkClosed(); 2118 2119 resultSetType = xlateRSType(resultSetType); 2120 resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency); 2121 resultSetHoldability = xlateRSHoldability(resultSetHoldability); 2122 2123 try { 2124 return new jdbcCallableStatement(this, sql, resultSetType); 2125 } catch (HsqlException e) { 2126 throw Util.sqlException(e); 2127 } 2128 } 2129 2130 2132 2184 public synchronized PreparedStatement prepareStatement(String sql, 2186 int autoGeneratedKeys) throws SQLException { 2187 2188 checkClosed(); 2189 2190 throw Util.notSupported(); 2191 } 2192 2193 2195 2249 public synchronized PreparedStatement prepareStatement(String sql, 2251 int[] columnIndexes) throws SQLException { 2252 2253 checkClosed(); 2254 2255 throw Util.notSupported(); 2256 } 2257 2258 2260 2314 public synchronized PreparedStatement prepareStatement(String sql, 2316 String [] columnNames) throws SQLException { 2317 2318 checkClosed(); 2319 2320 throw Util.notSupported(); 2321 } 2322 2323 2326 2350 public jdbcConnection(HsqlProperties props) throws SQLException { 2351 2352 String user = props.getProperty("user"); 2353 String password = props.getProperty("password"); 2354 String connType = props.getProperty("connection_type"); 2355 String host = props.getProperty("host"); 2356 int port = props.getIntegerProperty("port", 0); 2357 String path = props.getProperty("path"); 2358 String database = props.getProperty("database"); 2359 boolean isTLS = (connType == DatabaseURL.S_HSQLS 2360 || connType == DatabaseURL.S_HTTPS); 2361 2362 if (user == null) { 2363 user = "SA"; 2364 } 2365 2366 if (password == null) { 2367 password = ""; 2368 } 2369 2370 user = user.toUpperCase(Locale.ENGLISH); 2371 password = password.toUpperCase(Locale.ENGLISH); 2372 2373 try { 2374 if (DatabaseURL.isInProcessDatabaseType(connType)) { 2375 2376 2378 sessionProxy = DatabaseManager.newSession(connType, database, 2379 user, password, props); 2380 } else if (connType == DatabaseURL.S_HSQL 2381 || connType == DatabaseURL.S_HSQLS) { 2382 sessionProxy = new HSQLClientConnection(host, port, path, 2383 database, isTLS, user, password); 2384 isNetConn = true; 2385 } else if (connType == DatabaseURL.S_HTTP 2386 || connType == DatabaseURL.S_HTTPS) { 2387 sessionProxy = new HTTPClientConnection(host, port, path, 2388 database, isTLS, user, password); 2389 isNetConn = true; 2390 } else { throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT); 2392 } 2393 2394 connProperties = props; 2395 } catch (HsqlException e) { 2396 throw Util.sqlException(e); 2397 } 2398 } 2399 2400 2440 public jdbcConnection(Session c) throws HsqlException { 2441 2442 isInternal = true; 2444 sessionProxy = c; 2445 } 2446 2447 2451 protected void finalize() { 2452 2453 try { 2454 close(); 2455 } catch (SQLException e) {} 2456 } 2457 2458 2466 synchronized String getURL() throws SQLException { 2467 2468 checkClosed(); 2469 2470 if (isInternal) { 2471 return ((Session) sessionProxy).getInternalConnectionURL(); 2472 } 2473 2474 return connProperties.getProperty("url"); 2475 } 2476 2477 2482 synchronized void checkClosed() throws SQLException { 2483 2484 if (isClosed) { 2485 throw Util.sqlException(Trace.CONNECTION_IS_CLOSED); 2486 } 2487 } 2488 2489 2494 void addWarning(SQLWarning w) { 2495 2496 synchronized (rootWarning_mutex) { 2498 if (rootWarning == null) { 2499 rootWarning = w; 2500 } else { 2501 rootWarning.setNextWarning(w); 2502 } 2503 } 2504 } 2505 2506 2509 void clearWarningsNoCheck() { 2510 2511 synchronized (rootWarning_mutex) { 2512 rootWarning = null; 2513 } 2514 } 2515 2516 2532 int xlateRSType(int type) throws SQLException { 2533 2534 SQLWarning w; 2535 String msg; 2536 2537 switch (type) { 2538 2539 case jdbcResultSet.TYPE_FORWARD_ONLY : 2540 case jdbcResultSet.TYPE_SCROLL_INSENSITIVE : { 2541 return type; 2542 } 2543 case jdbcResultSet.TYPE_SCROLL_SENSITIVE : { 2544 msg = "TYPE_SCROLL_SENSITIVE => TYPE_SCROLL_SENSITIVE"; 2545 w = new SQLWarning (msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT); 2546 2547 addWarning(w); 2548 2549 return jdbcResultSet.TYPE_SCROLL_INSENSITIVE; 2550 } 2551 default : { 2552 msg = "ResultSet type: " + type; 2553 2554 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 2555 } 2556 } 2557 } 2558 2559 2572 int xlateRSConcurrency(int concurrency) throws SQLException { 2573 2574 SQLWarning w; 2575 String msg; 2576 2577 switch (concurrency) { 2578 2579 case jdbcResultSet.CONCUR_READ_ONLY : { 2580 return concurrency; 2581 } 2582 case jdbcResultSet.CONCUR_UPDATABLE : { 2583 msg = "CONCUR_UPDATABLE => CONCUR_READ_ONLY"; 2584 w = new SQLWarning (msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT); 2585 2586 addWarning(w); 2587 2588 return jdbcResultSet.CONCUR_READ_ONLY; 2589 } 2590 default : { 2591 msg = "ResultSet concurrency: " + concurrency; 2592 2593 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 2594 } 2595 } 2596 } 2597 2598 2614 int xlateRSHoldability(int holdability) throws SQLException { 2615 2616 SQLWarning w; 2617 String msg; 2618 2619 switch (holdability) { 2620 2621 case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT : { 2622 return holdability; 2623 } 2624 case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT : { 2625 msg = "CLOSE_CURSORS_AT_COMMIT => HOLD_CURSORS_OVER_COMMIT"; 2626 w = new SQLWarning (msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT); 2627 2628 addWarning(w); 2629 2630 return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT; 2631 } 2632 default : { 2633 msg = "ResultSet holdability: " + holdability; 2634 2635 throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg); 2636 } 2637 } 2638 } 2639 2640 2644 public void reset() throws SQLException { 2645 2646 try { 2647 this.sessionProxy.resetSession(); 2648 } catch (HsqlException e) { 2649 throw new SQLException ("Error resetting connection: " 2650 + e.getMessage()); 2651 } 2652 } 2653 2654 2657 private int onStartEscapeSequence(String sql, StringBuffer sb, 2658 int i) throws SQLException { 2659 2660 sb.setCharAt(i++, ' '); 2661 2662 i = StringUtil.skipSpaces(sql, i); 2663 2664 if (sql.regionMatches(true, i, "fn ", 0, 3) 2665 || sql.regionMatches(true, i, "oj ", 0, 3) 2666 || sql.regionMatches(true, i, "ts ", 0, 3)) { 2667 sb.setCharAt(i++, ' '); 2668 sb.setCharAt(i++, ' '); 2669 } else if (sql.regionMatches(true, i, "d ", 0, 2) 2670 || sql.regionMatches(true, i, "t ", 0, 2)) { 2671 sb.setCharAt(i++, ' '); 2672 } else if (sql.regionMatches(true, i, "call ", 0, 5)) { 2673 i += 4; 2674 } else if (sql.regionMatches(true, i, "?= call ", 0, 8)) { 2675 sb.setCharAt(i++, ' '); 2676 sb.setCharAt(i++, ' '); 2677 2678 i += 5; 2679 } else if (sql.regionMatches(true, i, "escape ", 0, 7)) { 2680 i += 6; 2681 } else { 2682 i--; 2683 2684 throw new SQLException ( 2685 Trace.getMessage( 2686 Trace.jdbcConnection_nativeSQL, true, new Object []{ 2687 sql.substring(i) }), "S0010", 2688 Trace.INVALID_JDBC_ARGUMENT); 2689 } 2690 2691 return i; 2692 } 2693} 2694 | Popular Tags |