/******************************************************************************* * Copyright (c) 2005-2011, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.rgw.tools; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; /** * <p> * Simple translator class for SQLExceptions. Currently translating to * <li> * {@link JdbcLinkResourceException} for connection problems, or resource problems on the database</li> * <li> * {@link JdbcLinkSyntaxException} for problems with the syntax of the SQL statement</li> * <li> * {@link JdbcLinkConcurrencyException} for problems with concurrent access</li> * </p> * <p> * Translation Sets based on the SQLStateSQLExceptionTranslator class of the spring framework. * </p> * * @author thomas * */ public class JdbcLinkExceptionTranslation { private static final Set<String> BAD_SQL_GRAMMAR_CODES = new HashSet<String>(8); private static final Set<String> DATA_INTEGRITY_VIOLATION_CODES = new HashSet<String>(8); private static final Set<String> DATA_ACCESS_RESOURCE_FAILURE_CODES = new HashSet<String>(8); private static final Set<String> TRANSIENT_DATA_ACCESS_RESOURCE_CODES = new HashSet<String>(8); private static final Set<String> CONCURRENCY_FAILURE_CODES = new HashSet<String>(4); static { BAD_SQL_GRAMMAR_CODES.add("07"); // Dynamic SQL error BAD_SQL_GRAMMAR_CODES.add("21"); // Cardinality violation BAD_SQL_GRAMMAR_CODES.add("2A"); // Syntax error direct SQL BAD_SQL_GRAMMAR_CODES.add("37"); // Syntax error dynamic SQL BAD_SQL_GRAMMAR_CODES.add("42"); // General SQL syntax error BAD_SQL_GRAMMAR_CODES.add("65"); // Oracle: unknown identifier BAD_SQL_GRAMMAR_CODES.add("S0"); // MySQL uses this - from ODBC error codes? DATA_INTEGRITY_VIOLATION_CODES.add("01"); // Data truncation DATA_INTEGRITY_VIOLATION_CODES.add("02"); // No data found DATA_INTEGRITY_VIOLATION_CODES.add("22"); // Value out of range DATA_INTEGRITY_VIOLATION_CODES.add("23"); // Integrity constraint violation DATA_INTEGRITY_VIOLATION_CODES.add("27"); // Triggered data change violation DATA_INTEGRITY_VIOLATION_CODES.add("44"); // With check violation DATA_ACCESS_RESOURCE_FAILURE_CODES.add("08"); // Connection exception DATA_ACCESS_RESOURCE_FAILURE_CODES.add("53"); // PostgreSQL: insufficient resources (e.g. // disk full) DATA_ACCESS_RESOURCE_FAILURE_CODES.add("54"); // PostgreSQL: program limit exceeded (e.g. // statement too complex) DATA_ACCESS_RESOURCE_FAILURE_CODES.add("57"); // DB2: out-of-memory exception / database not // started DATA_ACCESS_RESOURCE_FAILURE_CODES.add("58"); // DB2: unexpected system error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JW"); // Sybase: internal I/O error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JZ"); // Sybase: unexpected I/O error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("S1"); // DB2: communication failure CONCURRENCY_FAILURE_CODES.add("40"); // Transaction rollback CONCURRENCY_FAILURE_CODES.add("61"); // Oracle: deadlock } public static JdbcLinkException translateException(Exception ex){ if (ex instanceof SQLException) { return translateSQLException(null, (SQLException) ex); } return new JdbcLinkException(null, ex); } public static JdbcLinkException translateException(String message, Exception ex){ if (ex instanceof SQLException) { return translateSQLException(message, (SQLException) ex); } return new JdbcLinkException(message, ex); } private static JdbcLinkException translateSQLException(String message, SQLException sql){ String state = sql.getSQLState(); if (state != null && state.length() >= 2) { String stateClass = state.substring(0, 2); if (BAD_SQL_GRAMMAR_CODES.contains(stateClass)) { return new JdbcLinkSyntaxException(message + " (SQLState: " + state + ")", sql); } else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(stateClass)) { return new JdbcLinkResourceException(message + " (SQLState: " + state + ")", sql); } else if (CONCURRENCY_FAILURE_CODES.contains(stateClass)) { return new JdbcLinkConcurrencyException(message + " (SQLState: " + state + ")", sql); } } return new JdbcLinkException(message + " (SQLState: " + state + ")", sql); } }