1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package java.sql;
19
20import java.io.Serializable;
21import java.util.Iterator;
22import java.util.NoSuchElementException;
23
24/**
25 * An exception that indicates a failed JDBC operation.
26 * It provides the following information about problems encountered with
27 * database access:
28 * <ul>
29 *   <li>A message string.</li>
30 *   <li>A {@code SQLState} error description string following either
31 * <a href="http://en.wikipedia.org/wiki/SQL:1999">SQL 99</a> or X/OPEN {@code SQLState}
32 * conventions. {@link DatabaseMetaData#getSQLStateType} exposes the specific convention in
33 * use.</li>
34 *   <li>A database-specific error code.</li>
35 *   <li>The next exception in the chain.</li>
36 * </ul>
37 *
38 * @see DatabaseMetaData
39 */
40public class SQLException extends Exception implements Serializable, Iterable<Throwable> {
41
42    private static final long serialVersionUID = 2135244094396331484L;
43
44    private String SQLState = null;
45
46    private int vendorCode = 0;
47
48    private SQLException next = null;
49
50    /**
51     * Creates an {@code SQLException} object. The reason string is set to
52     * {@code null}, the {@code SQLState} string is set to {@code null} and the
53     * error code is set to 0.
54     */
55    public SQLException() {
56    }
57
58    /**
59     * Creates an {@code SQLException} object. The reason string is set to the given
60     * reason string, the {@code SQLState} string is set to {@code null} and the error code is
61     * set to 0.
62     *
63     * @param theReason
64     *            the string to use as the Reason string
65     */
66    public SQLException(String theReason) {
67        this(theReason, null, 0);
68    }
69
70    /**
71     * Creates an {@code SQLException} object. The reason string is set to the
72     * given reason string, the {@code SQLState} string is set to the given
73     * {@code SQLState} string and the error code is set to 0.
74     *
75     * @param theReason
76     *            the string to use as the reason string.
77     * @param theSQLState
78     *            the string to use as the {@code SQLState} string.
79     */
80    public SQLException(String theReason, String theSQLState) {
81        this(theReason, theSQLState, 0);
82    }
83
84    /**
85     * Creates an {@code SQLException} object. The reason string is set to the
86     * given reason string, the {@code SQLState} string is set to the given
87     * {@code SQLState} string and the error code is set to the given error code
88     * value.
89     *
90     * @param theReason
91     *            the string to use as the reason string.
92     * @param theSQLState
93     *            the string to use as the {@code SQLState} string.
94     * @param theErrorCode
95     *            the integer value for the error code.
96     */
97    public SQLException(String theReason, String theSQLState, int theErrorCode) {
98        super(theReason);
99        SQLState = theSQLState;
100        vendorCode = theErrorCode;
101    }
102
103    /**
104     * Creates an SQLException object. The Reason string is set to the null if
105     * cause == null or cause.toString() if cause!=null,and the cause Throwable
106     * object is set to the given cause Throwable object.
107     *
108     * @param theCause
109     *            the Throwable object for the underlying reason this
110     *            SQLException
111     *
112     * @since 1.6
113     */
114    public SQLException(Throwable theCause) {
115        this(theCause == null ? null : theCause.toString(), null, 0, theCause);
116    }
117
118    /**
119     * Creates an SQLException object. The Reason string is set to the given and
120     * the cause Throwable object is set to the given cause Throwable object.
121     *
122     * @param theReason
123     *            the string to use as the Reason string
124     * @param theCause
125     *            the Throwable object for the underlying reason this
126     *            SQLException
127     *
128     * @since 1.6
129     */
130    public SQLException(String theReason, Throwable theCause) {
131        super(theReason, theCause);
132    }
133
134    /**
135     * Creates an SQLException object. The Reason string is set to the given
136     * reason string, the SQLState string is set to the given SQLState string
137     * and the cause Throwable object is set to the given cause Throwable
138     * object.
139     *
140     * @param theReason
141     *            the string to use as the Reason string
142     * @param theSQLState
143     *            the string to use as the SQLState string
144     * @param theCause
145     *            the Throwable object for the underlying reason this
146     *            SQLException
147     * @since 1.6
148     */
149    public SQLException(String theReason, String theSQLState, Throwable theCause) {
150        super(theReason, theCause);
151        SQLState = theSQLState;
152    }
153
154    /**
155     * Creates an SQLException object. The Reason string is set to the given
156     * reason string, the SQLState string is set to the given SQLState string ,
157     * the Error Code is set to the given error code value, and the cause
158     * Throwable object is set to the given cause Throwable object.
159     *
160     * @param theReason
161     *            the string to use as the Reason string
162     * @param theSQLState
163     *            the string to use as the SQLState string
164     * @param theErrorCode
165     *            the integer value for the error code
166     * @param theCause
167     *            the Throwable object for the underlying reason this
168     *            SQLException
169     * @since 1.6
170     */
171    public SQLException(String theReason, String theSQLState, int theErrorCode,
172            Throwable theCause) {
173        this(theReason, theSQLState, theCause);
174        vendorCode = theErrorCode;
175    }
176
177    /**
178     * Returns the integer error code for this {@code SQLException}.
179     *
180     * @return The integer error code for this {@code SQLException}. The meaning
181     *         of the code is specific to the vendor of the database.
182     */
183    public int getErrorCode() {
184        return vendorCode;
185    }
186
187    /**
188     * Retrieves the {@code SQLException} chained to this {@code SQLException},
189     * if any.
190     *
191     * @return The {@code SQLException} chained to this {@code SQLException}.
192     *         {@code null} if there is no {@code SQLException} chained to this
193     *         {@code SQLException}.
194     */
195    public SQLException getNextException() {
196        return next;
197    }
198
199    /**
200     * Retrieves the {@code SQLState} description string for this {@code
201     * SQLException} object.
202     *
203     * @return The {@code SQLState} string for this {@code SQLException} object.
204     *         This is an error description string which follows either the SQL
205     *         99 conventions or the X/OPEN {@code SQLstate} conventions. The
206     *         potential values of the {@code SQLState} string are described in
207     *         each of the specifications. Which of the conventions is being
208     *         used by the {@code SQLState} string can be discovered by using
209     *         the {@code getSQLStateType} method of the {@code
210     *         DatabaseMetaData} interface.
211     */
212    public String getSQLState() {
213        return SQLState;
214    }
215
216    /**
217     * Obsolete. Appends {@code ex} to the end of this chain.
218     */
219    public void setNextException(SQLException ex) {
220        if (next != null) {
221            next.setNextException(ex);
222        } else {
223            next = ex;
224        }
225    }
226
227    /**
228     * Obsolete. {@link #getCause()} should be used instead of this iterator. Returns an iterator
229     * over the exceptions added with {@link #setNextException}.
230     */
231    public Iterator<Throwable> iterator() {
232        return new InternalIterator(this);
233    }
234
235    private static class InternalIterator implements Iterator<Throwable> {
236
237        private SQLException current;
238
239        InternalIterator(SQLException e) {
240            current = e;
241        }
242
243        public boolean hasNext() {
244            return current != null;
245        }
246
247        public Throwable next() {
248            if (current == null) {
249                throw new NoSuchElementException();
250            }
251            SQLException ret = current;
252            current = current.next;
253            return ret;
254        }
255
256        public void remove() {
257            throw new UnsupportedOperationException();
258        }
259    }
260}
261