1 5 package org.h2.jdbc; 6 7 import java.io.InputStream ; 8 import java.io.Reader ; 9 import java.sql.Blob ; 10 import java.sql.CallableStatement ; 11 import java.sql.Clob ; 12 import java.sql.Connection ; 13 import java.sql.DatabaseMetaData ; 14 import java.sql.PreparedStatement ; 15 import java.sql.ResultSet ; 16 import java.sql.SQLException ; 17 import java.sql.SQLWarning ; 18 import java.sql.Savepoint ; 20 import java.sql.Statement ; 22 import java.util.Iterator ; 23 import java.util.Map ; 24 import java.util.Properties ; 25 26 import org.h2.command.CommandInterface; 27 import org.h2.engine.ConnectionInfo; 28 import org.h2.engine.Constants; 29 import org.h2.engine.SessionInterface; 30 import org.h2.engine.SessionRemote; 31 import org.h2.expression.ParameterInterface; 32 import org.h2.jdbcx.JdbcConnectionListener; 33 import org.h2.message.Message; 34 import org.h2.message.Trace; 35 import org.h2.message.TraceObject; 36 import org.h2.result.ResultInterface; 37 import org.h2.util.TempFileDeleter; 38 import org.h2.value.Value; 39 import org.h2.value.ValueInt; 40 import org.h2.value.ValueLob; 41 import org.h2.value.ValueNull; 42 43 51 53 56 public class JdbcConnection extends TraceObject implements Connection { 57 60 private String url; 61 private String user; 62 63 private int holdability 64 = ResultSet.HOLD_CURSORS_OVER_COMMIT 66 ; 68 69 private SessionInterface session; 70 private CommandInterface commit, rollback; 71 private CommandInterface setAutoCommitTrue, setAutoCommitFalse, getAutoCommit; 72 private CommandInterface getReadOnly, getGeneratedKeys; 73 private CommandInterface setLockMode, getLockMode; 74 private Exception openStackTrace; 75 private int savepointId; 77 private Trace trace; 79 private JdbcConnectionListener listener; 80 private boolean isInternal; 81 private String catalog; 82 private Statement executingStatement; 83 84 91 public Statement createStatement() throws SQLException { 92 try { 93 int id = getNextId(TraceObject.STATEMENT); 94 if(debug()) { 95 debugCodeAssign("Statement", TraceObject.STATEMENT, id); 96 debugCodeCall("createStatement"); 97 } 98 checkClosed(); 99 return new JdbcStatement(session, this, ResultSet.TYPE_FORWARD_ONLY, id, false); 100 } catch(Throwable e) { 101 throw logAndConvert(e); 102 } 103 } 104 105 113 public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { 114 try { 115 int id = getNextId(TraceObject.STATEMENT); 116 if(debug()) { 117 debugCodeAssign("Statement", TraceObject.STATEMENT, id); 118 debugCode("createStatement("+resultSetType+", "+resultSetConcurrency+");"); 119 } 120 checkClosed(); 121 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 122 return new JdbcStatement(session, this, resultSetType, id, false); 123 } catch(Throwable e) { 124 throw logAndConvert(e); 125 } 126 } 127 128 136 public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { 137 try { 138 int id = getNextId(TraceObject.STATEMENT); 139 if(debug()) { 140 debugCodeAssign("Statement", TraceObject.STATEMENT, id); 141 debugCode("createStatement("+resultSetType+", "+resultSetConcurrency+", "+resultSetHoldability+");"); 142 } 143 checkClosed(); 144 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 145 checkHoldability(resultSetHoldability); 146 return new JdbcStatement(session, this, resultSetType, id, false); 147 } catch(Throwable e) { 148 throw logAndConvert(e); 149 } 150 } 151 152 159 public PreparedStatement prepareStatement(String sql) throws SQLException { 160 try { 161 int id = getNextId(TraceObject.PREPARED_STATEMENT); 162 if(debug()) { 163 debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id); 164 debugCodeCall("prepareStatement", sql); 165 } 166 checkClosed(); 167 sql = translateSQL(sql); 168 return new JdbcPreparedStatement(session, this, sql, ResultSet.TYPE_FORWARD_ONLY, id, false); 169 } catch(Throwable e) { 170 throw logAndConvert(e); 171 } 172 } 173 174 PreparedStatement prepareAutoCloseStatement(String sql) throws SQLException { 175 try { 176 int id = getNextId(TraceObject.PREPARED_STATEMENT); 177 if(debug()) { 178 debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id); 179 debugCodeCall("prepareStatement", sql); 180 } 181 checkClosed(); 182 sql = translateSQL(sql); 183 return new JdbcPreparedStatement(session, this, sql, ResultSet.TYPE_FORWARD_ONLY, id, true); 184 } catch(Throwable e) { 185 throw logAndConvert(e); 186 } 187 } 188 189 196 public DatabaseMetaData getMetaData() throws SQLException { 197 try { 198 int id = getNextId(TraceObject.DATABASE_META_DATA); 199 if(debug()) { 200 debugCodeAssign("DatabaseMetaData", TraceObject.DATABASE_META_DATA, id); 201 debugCodeCall("getMetaData"); 202 } 203 checkClosed(); 204 return new JdbcDatabaseMetaData(this, trace, id); 205 } catch(Throwable e) { 206 throw logAndConvert(e); 207 } 208 } 209 210 213 public void setJdbcConnectionListener(JdbcConnectionListener listener) { 214 this.listener = listener; 215 } 216 217 223 public void close() throws SQLException { 224 TempFileDeleter.deleteUnused(); 225 synchronized(this) { 226 if(listener == null) { 227 closeConnection(); 228 } else { 229 listener.closed(this); 230 } 231 } 232 } 233 234 237 public void closeConnection() throws SQLException { 238 try { 239 debugCodeCall("close"); 240 if(executingStatement != null) { 241 executingStatement.cancel(); 242 } 243 if (session != null && !session.isClosed()) { 244 try { 245 rollbackInternal(); 246 commit = closeAndSetNull(commit); 247 rollback = closeAndSetNull(rollback); 248 setAutoCommitTrue = closeAndSetNull(setAutoCommitTrue); 249 setAutoCommitFalse = closeAndSetNull(setAutoCommitFalse); 250 getAutoCommit = closeAndSetNull(getAutoCommit); 251 getReadOnly = closeAndSetNull(getReadOnly); 252 getGeneratedKeys = closeAndSetNull(getGeneratedKeys); 253 getLockMode = closeAndSetNull(getLockMode); 254 setLockMode = closeAndSetNull(setLockMode); 255 } finally { 256 try { 257 session.close(); 258 } finally { 259 session = null; 260 } 261 } 262 } 263 } catch(Throwable e) { 264 throw logAndConvert(e); 265 } 266 } 267 268 private CommandInterface closeAndSetNull(CommandInterface command) { 269 if(command != null) { 270 command.close(); 271 } 272 return null; 273 } 274 275 284 public synchronized void setAutoCommit(boolean autoCommit) throws SQLException { 285 try { 286 if(debug()) { 287 debugCode("setAutoCommit("+autoCommit+");"); 288 } 289 checkClosed(); 290 if (autoCommit) { 291 setAutoCommitTrue = prepareCommand("SET AUTOCOMMIT TRUE", setAutoCommitTrue); 292 setAutoCommitTrue.executeUpdate(); 293 } else { 294 setAutoCommitFalse = prepareCommand("SET AUTOCOMMIT FALSE", setAutoCommitFalse); 295 setAutoCommitFalse.executeUpdate(); 296 } 297 } catch(Throwable e) { 298 throw logAndConvert(e); 299 } 300 } 301 302 309 public synchronized boolean getAutoCommit() throws SQLException { 310 debugCodeCall("getAutoCommit"); 311 return getInternalAutoCommit(); 312 } 313 314 private boolean getInternalAutoCommit() throws SQLException { 315 try { 316 checkClosed(); 317 getAutoCommit = prepareCommand("CALL AUTOCOMMIT()", getAutoCommit); 318 ResultInterface result = getAutoCommit.executeQuery(0, false); 319 result.next(); 320 boolean autocommit = result.currentRow()[0].getBoolean().booleanValue(); 321 result.close(); 322 return autocommit; 323 } catch(Throwable e) { 324 throw logAndConvert(e); 325 } 326 } 327 328 335 public synchronized void commit() throws SQLException { 336 try { 337 debugCodeCall("commit"); 338 checkClosed(); 339 commit = prepareCommand("COMMIT", commit); 340 commit.executeUpdate(); 341 } catch(Throwable e) { 342 throw logAndConvert(e); 343 } 344 } 345 346 353 public synchronized void rollback() throws SQLException { 354 try { 355 debugCodeCall("rollback"); 356 checkClosed(); 357 rollbackInternal(); 358 } catch(Throwable e) { 359 throw logAndConvert(e); 360 } 361 } 362 363 368 public boolean isClosed() throws SQLException { 369 try { 370 debugCodeCall("isClosed"); 371 return session == null || session.isClosed(); 372 } catch(Throwable e) { 373 throw logAndConvert(e); 374 } 375 } 376 377 378 385 public String nativeSQL(String sql) throws SQLException { 386 try { 387 debugCodeCall("nativeSQL", sql); 388 checkClosed(); 389 return translateSQL(sql); 390 } catch(Throwable e) { 391 throw logAndConvert(e); 392 } 393 } 394 395 403 public void setReadOnly(boolean readOnly) throws SQLException { 404 try { 405 if(debug()) { 406 debugCode("setReadOnly("+readOnly+");"); 407 } 408 checkClosed(); 409 } catch(Throwable e) { 410 throw logAndConvert(e); 411 } 412 } 413 414 421 public boolean isReadOnly() throws SQLException { 422 try { 423 debugCodeCall("isReadOnly"); 424 checkClosed(); 425 getReadOnly = prepareCommand("CALL READONLY()", getReadOnly); 426 ResultInterface result = getReadOnly.executeQuery(0, false); 427 result.next(); 428 boolean readOnly = result.currentRow()[0].getBoolean().booleanValue(); 429 return readOnly; 430 } catch(Throwable e) { 431 throw logAndConvert(e); 432 } 433 } 434 435 441 public void setCatalog(String catalog) throws SQLException { 442 try { 443 debugCodeCall("setCatalog", catalog); 444 checkClosed(); 445 } catch(Throwable e) { 446 throw logAndConvert(e); 447 } 448 } 449 450 456 public String getCatalog() throws SQLException { 457 try { 458 debugCodeCall("getCatalog"); 459 checkClosed(); 460 if(catalog == null) { 461 CommandInterface cat = prepareCommand("CALL DATABASE()"); 462 ResultInterface result = cat.executeQuery(0, false); 463 result.next(); 464 catalog = result.currentRow()[0].getString(); 465 cat.close(); 466 } 467 return catalog; 468 } catch(Throwable e) { 469 throw logAndConvert(e); 470 } 471 } 472 473 478 public SQLWarning getWarnings() throws SQLException { 479 try { 480 debugCodeCall("getWarnings"); 481 checkClosed(); 482 return null; 483 } catch(Throwable e) { 484 throw logAndConvert(e); 485 } 486 } 487 488 491 public void clearWarnings() throws SQLException { 492 try { 493 debugCodeCall("clearWarnings"); 494 checkClosed(); 495 } catch(Throwable e) { 496 throw logAndConvert(e); 497 } 498 } 499 500 509 public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { 510 try { 511 int id = getNextId(TraceObject.PREPARED_STATEMENT); 512 if(debug()) { 513 debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id); 514 debugCode("prepareStatement("+quote(sql)+", "+resultSetType+", "+resultSetConcurrency+");"); 515 } 516 checkClosed(); 517 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 518 sql = translateSQL(sql); 519 return new JdbcPreparedStatement(session, this, sql, resultSetType, id, false); 520 } catch(Throwable e) { 521 throw logAndConvert(e); 522 } 523 } 524 525 536 public void setTransactionIsolation(int level) throws SQLException { 537 try { 538 debugCodeCall("setTransactionIsolation", level); 539 checkClosed(); 540 int lockMode; 541 switch(level) { 542 case Connection.TRANSACTION_READ_UNCOMMITTED: 543 lockMode = Constants.LOCK_MODE_OFF; 544 break; 545 case Connection.TRANSACTION_READ_COMMITTED: 546 lockMode = Constants.LOCK_MODE_READ_COMMITTED; 547 break; 548 case Connection.TRANSACTION_REPEATABLE_READ: 549 case Connection.TRANSACTION_SERIALIZABLE: 550 lockMode = Constants.LOCK_MODE_TABLE; 551 break; 552 default: 553 throw Message.getInvalidValueException("" + level, "level"); 554 } 555 commit(); 556 setLockMode = prepareCommand("SET LOCK_MODE ?", setLockMode); 557 ((ParameterInterface)setLockMode.getParameters().get(0)).setValue(ValueInt.get(lockMode)); 558 setLockMode.executeUpdate(); 559 } catch(Throwable e) { 560 throw logAndConvert(e); 561 } 562 } 563 564 570 public int getTransactionIsolation() throws SQLException { 571 try { 572 debugCodeCall("getTransactionIsolation"); 573 checkClosed(); 574 getLockMode = prepareCommand("CALL LOCK_MODE()", getLockMode); 575 ResultInterface result = getLockMode.executeQuery(0, false); 576 result.next(); 577 int lockMode = result.currentRow()[0].getInt(); 578 result.close(); 579 int transactionIsolationLevel; 580 switch(lockMode) { 581 case Constants.LOCK_MODE_OFF: 582 transactionIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED; 583 break; 584 case Constants.LOCK_MODE_READ_COMMITTED: 585 transactionIsolationLevel = Connection.TRANSACTION_READ_COMMITTED; 586 break; 587 case Constants.LOCK_MODE_TABLE: 588 case Constants.LOCK_MODE_TABLE_GC: 589 transactionIsolationLevel = Connection.TRANSACTION_SERIALIZABLE; 590 break; 591 default: 592 throw Message.getInternalError("lockMode:" + lockMode); 593 } 594 return transactionIsolationLevel; 595 } catch(Throwable e) { 596 throw logAndConvert(e); 597 } 598 } 599 600 610 public void setHoldability(int holdability) throws SQLException { 611 try { 612 debugCodeCall("setHoldability", holdability); 613 checkClosed(); 614 checkHoldability(holdability); 615 this.holdability = holdability; 616 } catch(Throwable e) { 617 throw logAndConvert(e); 618 } 619 } 620 621 627 public int getHoldability() throws SQLException { 628 try { 629 debugCodeCall("getHoldability"); 630 checkClosed(); 631 return holdability; 632 } catch(Throwable e) { 633 throw logAndConvert(e); 634 } 635 } 636 637 644 public Map getTypeMap() throws SQLException { 645 try { 646 debugCodeCall("getTypeMap"); 647 checkClosed(); 648 return null; 649 } catch(Throwable e) { 650 throw logAndConvert(e); 651 } 652 } 653 654 659 public void setTypeMap(Map map) throws SQLException { 660 try { 661 debugCode("setTypeMap("+quoteMap(map)+");"); 662 if(map != null && map.size()>0) { 663 throw Message.getUnsupportedException(); 664 } 665 } catch(Throwable e) { 666 throw logAndConvert(e); 667 } 668 } 669 670 private String quoteMap(Map map) { 671 if(map == null) { 672 return "null"; 673 } 674 if(map.size() == 0) { 675 return "new Map()"; 676 } 677 StringBuffer buff = new StringBuffer ("new Map() /* "); 678 try { 679 for(Iterator it = map.entrySet().iterator(); it.hasNext(); ) { 681 Map.Entry entry = (Map.Entry ) it.next(); 682 String key = (String ) entry.getKey(); 683 buff.append(key); 684 buff.append(':'); 685 Class clazz = (Class ) entry.getValue(); 686 buff.append(clazz.getName()); 687 } 688 } catch(Exception e) { 689 buff.append(e.toString()+": "+map.toString()); 690 } 691 buff.append("*/"); 692 return buff.toString(); 693 } 694 695 702 public CallableStatement prepareCall(String sql) throws SQLException { 703 try { 704 int id = getNextId(TraceObject.CALLABLE_STATEMENT); 705 if(debug()) { 706 debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id); 707 debugCodeCall("prepareCall", sql); 708 } 709 checkClosed(); 710 sql = translateSQL(sql); 711 return new JdbcCallableStatement(session, this, sql, ResultSet.TYPE_FORWARD_ONLY, id); 712 } catch(Throwable e) { 713 throw logAndConvert(e); 714 } 715 } 716 717 726 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { 727 try { 728 int id = getNextId(TraceObject.CALLABLE_STATEMENT); 729 if(debug()) { 730 debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id); 731 debugCode("prepareCall("+quote(sql)+", "+resultSetType+", "+resultSetConcurrency+");"); 732 } 733 checkClosed(); 734 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 735 sql = translateSQL(sql); 736 return new JdbcCallableStatement(session, this, sql, resultSetType, id); 737 } catch(Throwable e) { 738 throw logAndConvert(e); 739 } 740 } 741 742 751 public CallableStatement prepareCall(String sql, int resultSetType, 752 int resultSetConcurrency, int resultSetHoldability) throws SQLException { 753 try { 754 int id = getNextId(TraceObject.CALLABLE_STATEMENT); 755 if(debug()) { 756 debugCodeAssign("CallableStatement", TraceObject.CALLABLE_STATEMENT, id); 757 debugCode("prepareCall("+quote(sql)+", "+resultSetType+", "+resultSetConcurrency+", "+resultSetHoldability+");"); 758 } 759 checkClosed(); 760 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 761 checkHoldability(resultSetHoldability); 762 sql = translateSQL(sql); 763 return new JdbcCallableStatement(session, this, sql, resultSetType, id); 764 } catch(Throwable e) { 765 throw logAndConvert(e); 766 } 767 } 768 769 774 public Savepoint setSavepoint() throws SQLException { 776 try { 777 int id = getNextId(TraceObject.SAVEPOINT); 778 if(debug()) { 779 debugCodeAssign("Savepoint", TraceObject.SAVEPOINT, id); 780 debugCodeCall("setSavepoint"); 781 } 782 checkClosed(); 783 CommandInterface set = prepareCommand("SAVEPOINT " + JdbcSavepoint.getName(null, savepointId)); 784 set.executeUpdate(); 785 JdbcSavepoint savepoint = new JdbcSavepoint(this, savepointId, null, trace, id); 786 savepointId++; 787 return savepoint; 788 } catch(Throwable e) { 789 throw logAndConvert(e); 790 } 791 } 792 794 799 public Savepoint setSavepoint(String name) throws SQLException { 801 try { 802 int id = getNextId(TraceObject.SAVEPOINT); 803 if(debug()) { 804 debugCodeAssign("Savepoint", TraceObject.SAVEPOINT, id); 805 debugCodeCall("setSavepoint", name); 806 } 807 checkClosed(); 808 CommandInterface set = prepareCommand("SAVEPOINT " + JdbcSavepoint.getName(name, 0)); 809 set.executeUpdate(); 810 JdbcSavepoint savepoint = new JdbcSavepoint(this, 0, name, trace, id); 811 return savepoint; 812 } catch(Throwable e) { 813 throw logAndConvert(e); 814 } 815 } 816 818 821 public void rollback(Savepoint savepoint) throws SQLException { 823 try { 824 JdbcSavepoint sp = convertSavepoint(savepoint); 825 debugCode("rollback("+sp.toString()+");"); 826 checkClosed(); 827 sp.rollback(); 828 } catch(Throwable e) { 829 throw logAndConvert(e); 830 } 831 } 832 834 837 public void releaseSavepoint(Savepoint savepoint) throws SQLException { 839 try { 840 debugCode("releaseSavepoint(savepoint);"); 841 checkClosed(); 842 convertSavepoint(savepoint).release(); 843 } catch(Throwable e) { 844 throw logAndConvert(e); 845 } 846 } 847 848 private JdbcSavepoint convertSavepoint(Savepoint savepoint) throws SQLException { 849 if (!(savepoint instanceof JdbcSavepoint)) { 850 throw Message.getSQLException(Message.SAVEPOINT_IS_INVALID_1, "" + savepoint); 851 } 852 return (JdbcSavepoint) savepoint; 853 } 854 856 863 public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { 864 try { 865 int id = getNextId(TraceObject.PREPARED_STATEMENT); 866 if(debug()) { 867 debugCodeAssign("PreparedStatement", TraceObject.PREPARED_STATEMENT, id); 868 debugCode("prepareStatement("+quote(sql)+", "+resultSetType+", "+resultSetConcurrency+", " + resultSetHoldability +");"); 869 } 870 checkClosed(); 871 checkTypeAndConcurrency(resultSetType, resultSetConcurrency); 872 checkHoldability(resultSetHoldability); 873 sql = translateSQL(sql); 874 return new JdbcPreparedStatement(session, this, sql, resultSetType, id, false); 875 } catch(Throwable e) { 876 throw logAndConvert(e); 877 } 878 } 879 880 888 public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { 889 try { 890 if(debug()) { 891 debugCode("prepareStatement("+quote(sql)+", "+autoGeneratedKeys+");"); 892 } 893 return prepareStatement(sql); 894 } catch(Throwable e) { 895 throw logAndConvert(e); 896 } 897 } 898 899 907 public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { 908 try { 909 if(debug()) { 910 debugCode("prepareStatement(" 911 +quote(sql)+", " 912 +quoteIntArray(columnIndexes)+");"); 913 } 914 return prepareStatement(sql); 915 } catch(Throwable e) { 916 throw logAndConvert(e); 917 } 918 } 919 920 928 public PreparedStatement prepareStatement(String sql, String [] columnNames) throws SQLException { 929 try { 930 if(debug()) { 931 debugCode("prepareStatement(" 932 +quote(sql)+", " 933 +quoteArray(columnNames)+");"); 934 } 935 return prepareStatement(sql); 936 } catch(Throwable e) { 937 throw logAndConvert(e); 938 } 939 } 940 941 943 946 public JdbcConnection(String url, Properties info) throws SQLException { 947 try { 948 checkJavaVersion(); 949 ConnectionInfo ci = new ConnectionInfo(url, info); 950 if (ci.isRemote()) { 951 session = new SessionRemote().createSession(ci); 952 } else { 953 SessionInterface si = (SessionInterface) Class.forName("org.h2.engine.Session").newInstance(); 954 session = si.createSession(ci); 955 } 956 trace = session.getTrace(); 957 int id = getNextId(TraceObject.CONNECTION); 958 setTrace(trace, TraceObject.CONNECTION, id); 959 if(info()) { 960 infoCodeAssign("Connection", TraceObject.CONNECTION, id); 961 trace.infoCode("DriverManager.getConnection("+quote(url)+", \"<user>\", \"<password>\");"); 962 } 963 this.url = ci.getURL(); 964 this.user = ci.getUserName(); 965 openStackTrace = new Exception ("Stack Trace"); 966 } catch(Throwable e) { 967 throw logAndConvert(e); 968 } 969 } 970 971 974 public JdbcConnection(SessionInterface session, String user, String url) throws SQLException { 975 isInternal = true; 976 this.session = session; 977 trace = session.getTrace(); 978 int id = getNextId(TraceObject.CONNECTION); 979 setTrace(trace, TraceObject.CONNECTION, id); 980 this.user = user; 981 this.url = url; 982 } 983 984 private void checkJavaVersion() throws SQLException { 985 try { 986 Class clazz = java.sql.Savepoint .class; 989 clazz.getClass(); 990 } catch(Throwable e) { 992 throw Message.getSQLException(Message.UNSUPPORTED_JAVA_VERSION); 993 } 994 } 995 996 CommandInterface prepareCommand(String sql) throws SQLException { 997 return session.prepareCommand(sql); 998 } 999 1000 CommandInterface prepareCommand(String sql, CommandInterface old) throws SQLException { 1001 return old == null ? session.prepareCommand(sql) : old; 1002 } 1003 1004 private int translateGetEnd(String sql, int i, char c) throws SQLException { 1005 int len = sql.length(); 1006 switch(c) { 1007 case '\'': { 1008 int j = sql.indexOf('\'', i + 1); 1009 if (j < 0) { 1010 throw Message.getSyntaxError(sql, i); 1011 } 1012 return j; 1013 } 1014 case '"': { 1015 int j = sql.indexOf('"', i + 1); 1016 if (j < 0) { 1017 throw Message.getSyntaxError(sql, i); 1018 } 1019 return j; 1020 } 1021 case '/': { 1022 checkRunOver(i+1, len, sql); 1023 if (sql.charAt(i + 1) == '*') { 1024 int j = sql.indexOf("*/", i + 2); 1026 if (j < 0) { 1027 throw Message.getSyntaxError(sql, i); 1028 } 1029 i = j + 1; 1030 } else if (sql.charAt(i + 1) == '/') { 1031 i += 2; 1033 while (i < len && (c = sql.charAt(i)) != '\r' && c != '\n') { 1034 i++; 1035 } 1036 } 1037 return i; 1038 } 1039 case '-': { 1040 checkRunOver(i+1, len, sql); 1041 if (sql.charAt(i + 1) == '-') { 1042 i += 2; 1044 while (i < len && (c = sql.charAt(i)) != '\r' && c != '\n') { 1045 i++; 1046 } 1047 } 1048 return i; 1049 } 1050 default: 1051 throw Message.getInternalError("c=" + c); 1052 } 1053 } 1054 1055 String translateSQL(String sql) throws SQLException { 1056 if (sql == null || sql.indexOf('{') < 0) { 1057 return sql; 1058 } 1059 int len = sql.length(); 1060 char[] chars = null; 1061 int level = 0; 1062 for (int i = 0; i < len; i++) { 1063 char c = sql.charAt(i); 1064 switch (c) { 1065 case '\'': 1066 case '"': 1067 case '/': 1068 case '-': 1069 i = translateGetEnd(sql, i, c); 1070 break; 1071 case '{': 1072 level++; 1073 if (chars == null) { 1074 chars = sql.toCharArray(); 1075 } 1076 chars[i] = ' '; 1077 while (Character.isSpaceChar(chars[i])) { 1078 i++; 1079 checkRunOver(i, len, sql); 1080 } 1081 int start = i; 1082 if(chars[i] >= '0' && chars[i] <= '9') { 1083 chars[i-1]='{'; 1084 while(true) { 1085 checkRunOver(i, len, sql); 1086 c = chars[i]; 1087 if(c=='}') { 1088 break; 1089 } 1090 switch(c) { 1091 case '\'': 1092 case '"': 1093 case '/': 1094 case '-': 1095 i = translateGetEnd(sql, i, c); 1096 break; 1097 } 1098 i++; 1099 } 1100 level--; 1101 break; 1102 } else if (chars[i] == '?') { 1103 chars[i++] = ' '; 1105 checkRunOver(i, len, sql); 1106 while (Character.isSpaceChar(chars[i])) { 1107 i++; 1108 checkRunOver(i, len, sql); 1109 } 1110 if (sql.charAt(i) != '=') { 1111 throw Message.getSyntaxError(sql, i, "="); 1112 } 1113 chars[i++] = ' '; 1114 checkRunOver(i, len, sql); 1115 while (Character.isSpaceChar(chars[i])) { 1116 i++; 1117 checkRunOver(i, len, sql); 1118 } 1119 } 1120 while (!Character.isSpaceChar(chars[i])) { 1121 i++; 1122 checkRunOver(i, len, sql); 1123 } 1124 int repl = 0; 1125 if (found(sql, start, "fn")) { 1126 repl = 2; 1127 } else if (found(sql, start, "escape")) { 1128 break; 1129 } else if (found(sql, start, "call")) { 1130 break; 1131 } else if (found(sql, start, "oj")) { 1132 repl = 2; 1133 } else if (found(sql, start, "ts")) { 1134 repl = 2; 1135 } else if (found(sql, start, "t")) { 1136 repl = 1; 1137 } else if (found(sql, start, "d")) { 1138 repl = 1; 1139 } else if (found(sql, start, "params")) { 1140 repl = 1; 1141 } 1142 for (i = start; repl > 0; i++, repl--) { 1143 chars[i] = ' '; 1144 } 1145 break; 1146 case '}': 1147 if (--level < 0) { 1148 throw Message.getSyntaxError(sql, i); 1149 } 1150 chars[i] = ' '; 1151 break; 1152 } 1153 } 1154 if (level != 0) { 1155 throw Message.getSyntaxError(sql, sql.length() - 1); 1156 } 1157 if (chars != null) { 1158 sql = new String (chars); 1159 } 1160 return sql; 1161 } 1162 1163 private void checkRunOver(int i, int len, String sql) throws SQLException { 1164 if(i >= len) { 1165 throw Message.getSyntaxError(sql, i); 1166 } 1167 } 1168 1169 private boolean found(String sql, int start, String other) { 1170 return sql.regionMatches(true, start, other, 0, other.length()); 1171 } 1172 1173 private void checkTypeAndConcurrency(int resultSetType, int resultSetConcurrency) throws SQLException { 1174 } 1182 1183 private void checkHoldability(int resultSetHoldability) throws SQLException { 1184 if(resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT && 1187 resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT) { 1188 throw Message.getInvalidValueException("" + resultSetHoldability, "resultSetHoldability"); 1189 } 1190 } 1192 1193 void checkClosed() throws SQLException { 1194 if (session == null) { 1195 throw Message.getSQLException(Message.OBJECT_CLOSED); 1196 } 1197 if(session.isClosed()) { 1198 throw Message.getSQLException(Message.DATABASE_CALLED_AT_SHUTDOWN); 1199 } 1200 } 1201 1202 String getURL() throws SQLException { 1203 checkClosed(); 1204 return url; 1205 } 1206 1207 String getUser() throws SQLException { 1208 checkClosed(); 1209 return user; 1210 } 1211 1212 protected void finalize() { 1213 if(!Constants.RUN_FINALIZERS) { 1214 return; 1215 } 1216 if(isInternal) { 1217 return; 1218 } 1219 if (session != null) { 1220 trace.error("Connection not closed", openStackTrace); 1221 try { 1222 close(); 1223 } catch (SQLException e) { 1224 trace.debug("finalize", e); 1225 } 1226 } 1227 } 1228 1229 private void rollbackInternal() throws SQLException { 1230 rollback = prepareCommand("ROLLBACK", rollback); 1231 rollback.executeUpdate(); 1232 } 1233 1234 1237 public int getPowerOffCount() { 1238 return (session == null || session.isClosed()) ? 0 : session.getPowerOffCount(); 1239 } 1240 1241 1244 public void setPowerOffCount(int count) throws SQLException { 1245 if(session != null) { 1246 session.setPowerOffCount(count); 1247 } 1248 } 1249 1250 1253 public void setExecutingStatement(Statement stat) { 1254 executingStatement = stat; 1255 } 1256 1257 ResultSet getGeneratedKeys(JdbcStatement statement) throws SQLException { 1258 checkClosed(); 1259 getGeneratedKeys = prepareCommand("CALL IDENTITY()", getGeneratedKeys); 1260 ResultInterface result = getGeneratedKeys.executeQuery(0, false); 1261 int id = getNextId(TraceObject.RESULT_SET); 1262 if(debug()) { 1263 debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id); 1264 debugCodeCall("executeQuery", "CALL IDENTITY()"); 1265 } 1266 ResultSet rs = new JdbcResultSet(session, this, statement, result, id, false); 1267 return rs; 1268 } 1269 1270 1275 public Clob createClob() throws SQLException { 1276 try { 1277 int id = getNextId(TraceObject.CLOB); 1278 debugCodeAssign("Clob", TraceObject.CLOB, id); 1279 debugCodeCall("createClob"); 1280 checkClosed(); 1281 ValueLob v = ValueLob.createSmallLob(Value.CLOB, new byte[0]); 1282 return new JdbcClob(session, this, v, id); 1283 } catch(Throwable e) { 1284 throw logAndConvert(e); 1285 } 1286 } 1287 1288 1293 public Blob createBlob() throws SQLException { 1294 try { 1295 int id = getNextId(TraceObject.BLOB); 1296 debugCodeAssign("Blob", TraceObject.BLOB, id); 1297 debugCodeCall("createClob"); 1298 checkClosed(); 1299 ValueLob v = ValueLob.createSmallLob(Value.BLOB, new byte[0]); 1300 return new JdbcBlob(session, this, v, id); 1301 } catch(Throwable e) { 1302 throw logAndConvert(e); 1303 } 1304 } 1305 1306 1311 1326 1328 1332 1338 1340 1344 1350 1352 1356 1362 1364 1369 public synchronized boolean isValid(int timeout) { 1370 try { 1371 debugCodeCall("isValid", timeout); 1372 checkClosed(); 1373 getInternalAutoCommit(); 1374 return true; 1375 } catch(Throwable e) { 1376 logAndConvert(e); 1378 return false; 1379 } 1380 } 1381 1382 1386 1392 1394 1398 1404 1406 1410 1416 1418 1422 public String getClientInfo(String name) throws SQLException { 1423 throw Message.getUnsupportedException(); 1424 } 1425 1426 1430 1436 1438 1442 1448 1450 Value createClob(Reader x, long length) throws SQLException { 1451 if(x == null) { 1452 return ValueNull.INSTANCE; 1453 } 1454 if(length <= 0) { 1455 length = -1; 1456 } 1457 Value v = ValueLob.createClob(x, length, session.getDataHandler()); 1458 return v; 1459 } 1460 1461 Value createBlob(InputStream x, long length) throws SQLException { 1462 if(x == null) { 1463 return ValueNull.INSTANCE; 1464 } 1465 if(length <= 0) { 1466 length = -1; 1467 } 1468 Value v = ValueLob.createBlob(x, length, session.getDataHandler()); 1469 return v; 1470 } 1471 1472} 1473 | Popular Tags |