diff options
author | Barry Lind <barry@xythos.com> | 2003-09-08 17:30:22 +0000 |
---|---|---|
committer | Barry Lind <barry@xythos.com> | 2003-09-08 17:30:22 +0000 |
commit | 0378a269f3ab3c44e67b14f96414b6ca95263263 (patch) | |
tree | e6067a398b5253387aa0555ddf88eab80d0e8b4e /src/interfaces/jdbc/org/postgresql/util/PSQLException.java | |
parent | e702b04cf41bf2df633cc72cd60b6f3019c912d0 (diff) | |
download | postgresql-0378a269f3ab3c44e67b14f96414b6ca95263263.tar.gz |
This set of changes applies a patch from KHO at redhat to add some SQLState
support to the jdbc driver.
That patch needed some work: it assumed the sqlcode in a server message was
fixed in its position, the patch lost the ability to pass exceptions, and the
patch missed a couple of places where server errors where being received.
In addition to fixing the above, I also added full support for the V3 protocol
error message syntax, I reversed the order of arguments in the PSQLException
constructor to more closely follow the constructors for SQLException, I changed
the new constructors that take PSQLState to take Object for additional
parameters as the old ones did.
Still todo are to add SQLState values to all existing exceptions thrown in the
driver and add support for parsing the V3 protocol format for notices.
Modified Files:
jdbc/build.xml jdbc/org/postgresql/Driver.java.in
jdbc/org/postgresql/errors.properties
jdbc/org/postgresql/core/Encoding.java
jdbc/org/postgresql/core/PGStream.java
jdbc/org/postgresql/core/QueryExecutor.java
jdbc/org/postgresql/fastpath/Fastpath.java
jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
jdbc/org/postgresql/util/MessageTranslator.java
jdbc/org/postgresql/util/PSQLException.java
Diffstat (limited to 'src/interfaces/jdbc/org/postgresql/util/PSQLException.java')
-rw-r--r-- | src/interfaces/jdbc/org/postgresql/util/PSQLException.java | 213 |
1 files changed, 156 insertions, 57 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/util/PSQLException.java b/src/interfaces/jdbc/org/postgresql/util/PSQLException.java index 84ccc60ca2..18b70dc86c 100644 --- a/src/interfaces/jdbc/org/postgresql/util/PSQLException.java +++ b/src/interfaces/jdbc/org/postgresql/util/PSQLException.java @@ -7,7 +7,7 @@ * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/Attic/PSQLException.java,v 1.12 2003/08/11 21:18:47 barry Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/Attic/PSQLException.java,v 1.13 2003/09/08 17:30:22 barry Exp $ * *------------------------------------------------------------------------- */ @@ -16,100 +16,194 @@ package org.postgresql.util; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.sql.SQLException; +import java.util.Hashtable; import org.postgresql.Driver; public class PSQLException extends SQLException { private String message; + private PSQLState state; - /* - * This provides the same functionality to SQLException - * @param error Error string - */ - public PSQLException(String error) + //-------start new constructors------- + + public PSQLException(String msg, PSQLState state) { - super(); - translate(error, null); + this.state = state; + translate(msg, null); if (Driver.logDebug) - Driver.debug("Exception: " + this); + Driver.debug("Exception: " + this); } - - /* - * A more generic entry point. - * @param error Error string or standard message id - * @param args Array of arguments - */ - public PSQLException(String error, Object[] args) + + public PSQLException(String msg, PSQLState state, Object[] argv) { - super(); - translate(error, args); + this.state = state; + translate(msg, argv); if (Driver.logDebug) Driver.debug("Exception: " + this); } - /* - * Helper version for 1 arg - */ - public PSQLException(String error, Object arg) + //Helper version for one arg + public PSQLException(String msg, PSQLState state, Object arg1) { - super(); + this.state = state; Object[] argv = new Object[1]; - argv[0] = arg; - translate(error, argv); + argv[0] = arg1; + translate(msg, argv); if (Driver.logDebug) Driver.debug("Exception: " + this); } + + //Helper version for two args + public PSQLException(String msg, PSQLState state, Object arg1, Object arg2) + { + this.state = state; + Object[] argv = new Object[2]; + argv[0] = arg1; + argv[1] = arg2; + translate(msg, argv); + if (Driver.logDebug) + Driver.debug("Exception: " + this); + } + + //-------end new constructors------- - /* - * Helper version for 1 arg. This is used for debug purposes only with - * some unusual Exception's. It allows the originiating Exceptions stack - * trace to be returned. - */ - public PSQLException(String error, Exception ex) + public static PSQLException parseServerError(String p_serverError) { - super(); + if (Driver.logDebug) + Driver.debug("Constructing exception from server message: " + p_serverError); + char[] l_chars = p_serverError.toCharArray(); + int l_pos = 0; + int l_length = l_chars.length; + Hashtable l_mesgParts = new Hashtable(); + while (l_pos < l_length) { + char l_mesgType = l_chars[l_pos]; + if (l_mesgType != '\0') { + l_pos++; + int l_startString = l_pos; + while (l_chars[l_pos] != '\0' && l_pos < l_length) { + l_pos++; + } + String l_mesgPart = new String(l_chars, l_startString, l_pos - l_startString); + l_mesgParts.put(new Character(l_mesgType),l_mesgPart); + } + l_pos++; + } - Object[] argv = new Object[1]; + //Now construct the message from what the server sent + //The general format is: + //SEVERITY: Message \n + // Detail: \n + // Hint: \n + // Position: \n + // Where: \n + // Location: File:Line:Routine \n + // SQLState: \n + // + //Normally only the message and detail is included. + //If INFO level logging is enabled then detail, hint, position and where are + //included. If DEBUG level logging is enabled then all information + //is included. - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintWriter pw = new PrintWriter(baos); - pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); - ex.printStackTrace(pw); - pw.println("End of Stack Trace"); - pw.flush(); - argv[0] = baos.toString(); - pw.close(); - baos.close(); - } - catch (Exception ioe) - { - argv[0] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); + StringBuffer l_totalMessage = new StringBuffer(); + String l_message = (String)l_mesgParts.get(MESSAGE_TYPE_S); + if (l_message != null) + l_totalMessage.append(l_message).append(": "); + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_M); + if (l_message != null) + l_totalMessage.append(l_message).append('\n'); + if (Driver.logInfo) { + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_D); + if (l_message != null) + l_totalMessage.append(" ").append(MessageTranslator.translate("postgresql.error.detail", l_message)).append('\n'); + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_H); + if (l_message != null) + l_totalMessage.append(" ").append(MessageTranslator.translate("postgresql.error.hint", l_message)).append('\n'); + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_P); + if (l_message != null) + l_totalMessage.append(" ").append(MessageTranslator.translate("postgresql.error.position", l_message)).append('\n'); + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_W); + if (l_message != null) + l_totalMessage.append(" ").append(MessageTranslator.translate("postgresql.error.where", l_message)).append('\n'); + } + if (Driver.logDebug) { + String l_file = (String)l_mesgParts.get(MESSAGE_TYPE_F); + String l_line = (String)l_mesgParts.get(MESSAGE_TYPE_L); + String l_routine = (String)l_mesgParts.get(MESSAGE_TYPE_R); + if (l_file != null || l_line != null || l_routine != null) + l_totalMessage.append(" ").append(MessageTranslator.translate("postgresql.error.location", l_file+":"+l_line+":"+l_routine)).append('\n'); + l_message = (String)l_mesgParts.get(MESSAGE_TYPE_C); + if (l_message != null) + l_totalMessage.append(" ").append("ServerSQLState: " + l_message).append('\n'); } - translate(error, argv); + PSQLException l_return = new PSQLException(l_totalMessage.toString(), PSQLState.UNKNOWN_STATE); + l_return.state = new PSQLState((String)l_mesgParts.get(MESSAGE_TYPE_C)); + return l_return; + } + + private static final Character MESSAGE_TYPE_S = new Character('S'); + private static final Character MESSAGE_TYPE_M = new Character('M'); + private static final Character MESSAGE_TYPE_D = new Character('D'); + private static final Character MESSAGE_TYPE_H = new Character('H'); + private static final Character MESSAGE_TYPE_P = new Character('P'); + private static final Character MESSAGE_TYPE_W = new Character('W'); + private static final Character MESSAGE_TYPE_F = new Character('F'); + private static final Character MESSAGE_TYPE_L = new Character('L'); + private static final Character MESSAGE_TYPE_R = new Character('R'); + private static final Character MESSAGE_TYPE_C = new Character('C'); + + /* + * This provides the same functionality to SQLException + * @param error Error string + */ + public PSQLException(String error) + { + translate(error, null); if (Driver.logDebug) Driver.debug("Exception: " + this); } /* - * Helper version for 2 args + * Helper version for 1 arg */ - public PSQLException(String error, Object arg1, Object arg2) + public PSQLException(String error, Object arg) { - super(); - Object[] argv = new Object[2]; - argv[0] = arg1; - argv[1] = arg2; + Object[] argv = new Object[1]; + argv[0] = arg; translate(error, argv); if (Driver.logDebug) Driver.debug("Exception: " + this); } - private void translate(String error, Object[] args) - { + + private void translate(String error, Object[] args) { + //We convert exception objects to Strings that + //contain the full stack trace + if (args != null) { + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Exception && !(args[i] instanceof PSQLException)) { + Exception ex = (Exception) args[i]; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(baos); + pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); + ex.printStackTrace(pw); + pw.println("End of Stack Trace"); + pw.flush(); + args[i] = baos.toString(); + pw.close(); + baos.close(); + } + catch (Exception ioe) + { + args[i] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); + } + } + } + } + message = MessageTranslator.translate(error, args); + } /* @@ -127,4 +221,9 @@ public class PSQLException extends SQLException { return message; } + + public String getSQLState() + { + return state.getState(); + } } |