|
11 | 11 | import org.postgresql.core.Encoding;
|
12 | 12 |
|
13 | 13 | /**
|
14 |
| - * $Id: Connection.java,v 1.20 2001/07/21 18:56:17 momjian Exp $ |
| 14 | + * $Id: Connection.java,v 1.21 2001/07/30 14:51:19 momjian Exp $ |
15 | 15 | *
|
16 | 16 | * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
|
17 | 17 | * JDBC2 versions of the Connection class.
|
@@ -76,6 +76,11 @@ public abstract class Connection
|
76 | 76 | // Now handle notices as warnings, so things like "show" now work
|
77 | 77 | public SQLWarning firstWarning = null;
|
78 | 78 |
|
| 79 | + /** |
| 80 | + * Cache of the current isolation level |
| 81 | + */ |
| 82 | + private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED; |
| 83 | + |
79 | 84 | // The PID an cancellation key we get from the backend process
|
80 | 85 | public int pid;
|
81 | 86 | public int ckey;
|
@@ -788,7 +793,236 @@ private void initObjectTypes()
|
788 | 793 | */
|
789 | 794 | protected abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn,java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) throws SQLException;
|
790 | 795 |
|
791 |
| - public abstract void close() throws SQLException; |
| 796 | + /** |
| 797 | + * In some cases, it is desirable to immediately release a Connection's |
| 798 | + * database and JDBC resources instead of waiting for them to be |
| 799 | + * automatically released (cant think why off the top of my head) |
| 800 | + * |
| 801 | + * <B>Note:</B> A Connection is automatically closed when it is |
| 802 | + * garbage collected. Certain fatal errors also result in a closed |
| 803 | + * connection. |
| 804 | + * |
| 805 | + * @exception SQLException if a database access error occurs |
| 806 | + */ |
| 807 | + public void close() throws SQLException { |
| 808 | + if (pg_stream != null) { |
| 809 | + try { |
| 810 | + pg_stream.SendChar('X'); |
| 811 | + pg_stream.flush(); |
| 812 | + pg_stream.close(); |
| 813 | + } catch (IOException e) {} |
| 814 | + pg_stream = null; |
| 815 | + } |
| 816 | + } |
| 817 | + |
| 818 | + /** |
| 819 | + * A driver may convert the JDBC sql grammar into its system's |
| 820 | + * native SQL grammar prior to sending it; nativeSQL returns the |
| 821 | + * native form of the statement that the driver would have sent. |
| 822 | + * |
| 823 | + * @param sql a SQL statement that may contain one or more '?' |
| 824 | + * parameter placeholders |
| 825 | + * @return the native form of this statement |
| 826 | + * @exception SQLException if a database access error occurs |
| 827 | + */ |
| 828 | + public String nativeSQL(String sql) throws SQLException { |
| 829 | + return sql; |
| 830 | + } |
| 831 | + |
| 832 | + /** |
| 833 | + * The first warning reported by calls on this Connection is |
| 834 | + * returned. |
| 835 | + * |
| 836 | + * <B>Note:</B> Sebsequent warnings will be changed to this |
| 837 | + * SQLWarning |
| 838 | + * |
| 839 | + * @return the first SQLWarning or null |
| 840 | + * @exception SQLException if a database access error occurs |
| 841 | + */ |
| 842 | + public SQLWarning getWarnings() throws SQLException { |
| 843 | + return firstWarning; |
| 844 | + } |
| 845 | + |
| 846 | + /** |
| 847 | + * After this call, getWarnings returns null until a new warning |
| 848 | + * is reported for this connection. |
| 849 | + * |
| 850 | + * @exception SQLException if a database access error occurs |
| 851 | + */ |
| 852 | + public void clearWarnings() throws SQLException { |
| 853 | + firstWarning = null; |
| 854 | + } |
| 855 | + |
| 856 | + |
| 857 | + /** |
| 858 | + * You can put a connection in read-only mode as a hunt to enable |
| 859 | + * database optimizations |
| 860 | + * |
| 861 | + * <B>Note:</B> setReadOnly cannot be called while in the middle |
| 862 | + * of a transaction |
| 863 | + * |
| 864 | + * @param readOnly - true enables read-only mode; false disables it |
| 865 | + * @exception SQLException if a database access error occurs |
| 866 | + */ |
| 867 | + public void setReadOnly(boolean readOnly) throws SQLException { |
| 868 | + this.readOnly = readOnly; |
| 869 | + } |
| 870 | + |
| 871 | + /** |
| 872 | + * Tests to see if the connection is in Read Only Mode. Note that |
| 873 | + * we cannot really put the database in read only mode, but we pretend |
| 874 | + * we can by returning the value of the readOnly flag |
| 875 | + * |
| 876 | + * @return true if the connection is read only |
| 877 | + * @exception SQLException if a database access error occurs |
| 878 | + */ |
| 879 | + public boolean isReadOnly() throws SQLException { |
| 880 | + return readOnly; |
| 881 | + } |
| 882 | + |
| 883 | + /** |
| 884 | + * If a connection is in auto-commit mode, than all its SQL |
| 885 | + * statements will be executed and committed as individual |
| 886 | + * transactions. Otherwise, its SQL statements are grouped |
| 887 | + * into transactions that are terminated by either commit() |
| 888 | + * or rollback(). By default, new connections are in auto- |
| 889 | + * commit mode. The commit occurs when the statement completes |
| 890 | + * or the next execute occurs, whichever comes first. In the |
| 891 | + * case of statements returning a ResultSet, the statement |
| 892 | + * completes when the last row of the ResultSet has been retrieved |
| 893 | + * or the ResultSet has been closed. In advanced cases, a single |
| 894 | + * statement may return multiple results as well as output parameter |
| 895 | + * values. Here the commit occurs when all results and output param |
| 896 | + * values have been retrieved. |
| 897 | + * |
| 898 | + * @param autoCommit - true enables auto-commit; false disables it |
| 899 | + * @exception SQLException if a database access error occurs |
| 900 | + */ |
| 901 | + public void setAutoCommit(boolean autoCommit) throws SQLException { |
| 902 | + if (this.autoCommit == autoCommit) |
| 903 | + return; |
| 904 | + if (autoCommit) |
| 905 | + ExecSQL("end"); |
| 906 | + else { |
| 907 | + ExecSQL("begin"); |
| 908 | + doIsolationLevel(); |
| 909 | + } |
| 910 | + this.autoCommit = autoCommit; |
| 911 | + } |
| 912 | + |
| 913 | + /** |
| 914 | + * gets the current auto-commit state |
| 915 | + * |
| 916 | + * @return Current state of the auto-commit mode |
| 917 | + * @exception SQLException (why?) |
| 918 | + * @see setAutoCommit |
| 919 | + */ |
| 920 | + public boolean getAutoCommit() throws SQLException { |
| 921 | + return this.autoCommit; |
| 922 | + } |
| 923 | + |
| 924 | + /** |
| 925 | + * The method commit() makes all changes made since the previous |
| 926 | + * commit/rollback permanent and releases any database locks currently |
| 927 | + * held by the Connection. This method should only be used when |
| 928 | + * auto-commit has been disabled. (If autoCommit == true, then we |
| 929 | + * just return anyhow) |
| 930 | + * |
| 931 | + * @exception SQLException if a database access error occurs |
| 932 | + * @see setAutoCommit |
| 933 | + */ |
| 934 | + public void commit() throws SQLException { |
| 935 | + if (autoCommit) |
| 936 | + return; |
| 937 | + ExecSQL("commit"); |
| 938 | + autoCommit = true; |
| 939 | + ExecSQL("begin"); |
| 940 | + doIsolationLevel(); |
| 941 | + autoCommit = false; |
| 942 | + } |
| 943 | + |
| 944 | + /** |
| 945 | + * The method rollback() drops all changes made since the previous |
| 946 | + * commit/rollback and releases any database locks currently held by |
| 947 | + * the Connection. |
| 948 | + * |
| 949 | + * @exception SQLException if a database access error occurs |
| 950 | + * @see commit |
| 951 | + */ |
| 952 | + public void rollback() throws SQLException { |
| 953 | + if (autoCommit) |
| 954 | + return; |
| 955 | + ExecSQL("rollback"); |
| 956 | + autoCommit = true; |
| 957 | + ExecSQL("begin"); |
| 958 | + doIsolationLevel(); |
| 959 | + autoCommit = false; |
| 960 | + } |
| 961 | + |
| 962 | + /** |
| 963 | + * Get this Connection's current transaction isolation mode. |
| 964 | + * |
| 965 | + * @return the current TRANSACTION_* mode value |
| 966 | + * @exception SQLException if a database access error occurs |
| 967 | + */ |
| 968 | + public int getTransactionIsolation() throws SQLException { |
| 969 | + clearWarnings(); |
| 970 | + ExecSQL("show xactisolevel"); |
| 971 | + |
| 972 | + SQLWarning warning = getWarnings(); |
| 973 | + if (warning != null) { |
| 974 | + String message = warning.getMessage(); |
| 975 | + clearWarnings(); |
| 976 | + if (message.indexOf("READ COMMITTED") != -1) |
| 977 | + return java.sql.Connection.TRANSACTION_READ_COMMITTED; |
| 978 | + else if (message.indexOf("READ UNCOMMITTED") != -1) |
| 979 | + return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; |
| 980 | + else if (message.indexOf("REPEATABLE READ") != -1) |
| 981 | + return java.sql.Connection.TRANSACTION_REPEATABLE_READ; |
| 982 | + else if (message.indexOf("SERIALIZABLE") != -1) |
| 983 | + return java.sql.Connection.TRANSACTION_SERIALIZABLE; |
| 984 | + } |
| 985 | + return java.sql.Connection.TRANSACTION_READ_COMMITTED; |
| 986 | + } |
| 987 | + |
| 988 | + /** |
| 989 | + * You can call this method to try to change the transaction |
| 990 | + * isolation level using one of the TRANSACTION_* values. |
| 991 | + * |
| 992 | + * <B>Note:</B> setTransactionIsolation cannot be called while |
| 993 | + * in the middle of a transaction |
| 994 | + * |
| 995 | + * @param level one of the TRANSACTION_* isolation values with |
| 996 | + * the exception of TRANSACTION_NONE; some databases may |
| 997 | + * not support other values |
| 998 | + * @exception SQLException if a database access error occurs |
| 999 | + * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel |
| 1000 | + */ |
| 1001 | + public void setTransactionIsolation(int level) throws SQLException { |
| 1002 | + isolationLevel = level; |
| 1003 | + doIsolationLevel(); |
| 1004 | + } |
| 1005 | + |
| 1006 | + /** |
| 1007 | + * Helper method used by setTransactionIsolation(), commit(), rollback() |
| 1008 | + * and setAutoCommit(). This sets the current isolation level. |
| 1009 | + */ |
| 1010 | + protected void doIsolationLevel() throws SQLException { |
| 1011 | + String q = "SET TRANSACTION ISOLATION LEVEL"; |
| 1012 | + |
| 1013 | + switch(isolationLevel) { |
| 1014 | + case java.sql.Connection.TRANSACTION_READ_COMMITTED: |
| 1015 | + ExecSQL(q + " READ COMMITTED"); |
| 1016 | + return; |
| 1017 | + |
| 1018 | + case java.sql.Connection.TRANSACTION_SERIALIZABLE: |
| 1019 | + ExecSQL(q + " SERIALIZABLE"); |
| 1020 | + return; |
| 1021 | + |
| 1022 | + default: |
| 1023 | + throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel)); |
| 1024 | + } |
| 1025 | + } |
792 | 1026 |
|
793 | 1027 | /**
|
794 | 1028 | * A sub-space of this Connection's database may be selected by
|
|
0 commit comments