1 | /* |
2 | Copyright (C) 2002-2004 MySQL AB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of version 2 of the GNU General Public License as |
6 | published by the Free Software Foundation. |
7 | |
8 | There are special exceptions to the terms and conditions of the GPL |
9 | as it is applied to this software. View the full text of the |
10 | exception in file EXCEPTIONS-CONNECTOR-J in the directory of this |
11 | software distribution. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | |
22 | |
23 | |
24 | */ |
25 | package com.mysql.jdbc; |
26 | |
27 | import java.io.ByteArrayInputStream; |
28 | import java.io.InputStream; |
29 | import java.io.OutputStream; |
30 | import java.io.Reader; |
31 | import java.io.StringReader; |
32 | import java.io.Writer; |
33 | |
34 | import java.sql.SQLException; |
35 | |
36 | /** |
37 | * Simplistic implementation of java.sql.Clob for MySQL Connector/J |
38 | * |
39 | * @author Mark Matthews |
40 | * @version $Id: Clob.java 5417 2006-06-20 21:33:56 +0000 (Tue, 20 Jun 2006) mmatthews $ |
41 | */ |
42 | public class Clob implements java.sql.Clob, OutputStreamWatcher, WriterWatcher { |
43 | private String charData; |
44 | |
45 | Clob(String charDataInit) { |
46 | this.charData = charDataInit; |
47 | } |
48 | |
49 | /** |
50 | * @see java.sql.Clob#getAsciiStream() |
51 | */ |
52 | public InputStream getAsciiStream() throws SQLException { |
53 | if (this.charData != null) { |
54 | return new ByteArrayInputStream(this.charData.getBytes()); |
55 | } |
56 | |
57 | return null; |
58 | } |
59 | |
60 | /** |
61 | * @see java.sql.Clob#getCharacterStream() |
62 | */ |
63 | public Reader getCharacterStream() throws SQLException { |
64 | if (this.charData != null) { |
65 | return new StringReader(this.charData); |
66 | } |
67 | |
68 | return null; |
69 | } |
70 | |
71 | /** |
72 | * @see java.sql.Clob#getSubString(long, int) |
73 | */ |
74 | public String getSubString(long startPos, int length) throws SQLException { |
75 | if (startPos < 1) { |
76 | throw SQLError.createSQLException(Messages.getString("Clob.6"), //$NON-NLS-1$ |
77 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
78 | } |
79 | |
80 | int adjustedStartPos = (int)startPos - 1; |
81 | int adjustedEndIndex = adjustedStartPos + length; |
82 | |
83 | if (this.charData != null) { |
84 | if (adjustedEndIndex > this.charData.length()) { |
85 | throw SQLError.createSQLException(Messages.getString("Clob.7"), //$NON-NLS-1$ |
86 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
87 | } |
88 | |
89 | return this.charData.substring(adjustedStartPos, |
90 | adjustedEndIndex); |
91 | } |
92 | |
93 | return null; |
94 | } |
95 | |
96 | /** |
97 | * @see java.sql.Clob#length() |
98 | */ |
99 | public long length() throws SQLException { |
100 | if (this.charData != null) { |
101 | return this.charData.length(); |
102 | } |
103 | |
104 | return 0; |
105 | } |
106 | |
107 | /** |
108 | * @see java.sql.Clob#position(Clob, long) |
109 | */ |
110 | public long position(java.sql.Clob arg0, long arg1) throws SQLException { |
111 | return position(arg0.getSubString(0L, (int) arg0.length()), arg1); |
112 | } |
113 | |
114 | /** |
115 | * @see java.sql.Clob#position(String, long) |
116 | */ |
117 | public long position(String stringToFind, long startPos) |
118 | throws SQLException { |
119 | if (startPos < 1) { |
120 | throw SQLError.createSQLException( |
121 | Messages.getString("Clob.8") //$NON-NLS-1$ |
122 | + startPos + Messages.getString("Clob.9"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ |
123 | } |
124 | |
125 | if (this.charData != null) { |
126 | if ((startPos - 1) > this.charData.length()) { |
127 | throw SQLError.createSQLException(Messages.getString("Clob.10"), //$NON-NLS-1$ |
128 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
129 | } |
130 | |
131 | int pos = this.charData.indexOf(stringToFind, (int) (startPos - 1)); |
132 | |
133 | return (pos == -1) ? (-1) : (pos + 1); |
134 | } |
135 | |
136 | return -1; |
137 | } |
138 | |
139 | /** |
140 | * @see java.sql.Clob#setAsciiStream(long) |
141 | */ |
142 | public OutputStream setAsciiStream(long indexToWriteAt) throws SQLException { |
143 | if (indexToWriteAt < 1) { |
144 | throw SQLError.createSQLException(Messages.getString("Clob.0"), //$NON-NLS-1$ |
145 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
146 | } |
147 | |
148 | WatchableOutputStream bytesOut = new WatchableOutputStream(); |
149 | bytesOut.setWatcher(this); |
150 | |
151 | if (indexToWriteAt > 0) { |
152 | bytesOut.write(this.charData.getBytes(), 0, |
153 | (int) (indexToWriteAt - 1)); |
154 | } |
155 | |
156 | return bytesOut; |
157 | } |
158 | |
159 | /** |
160 | * @see java.sql.Clob#setCharacterStream(long) |
161 | */ |
162 | public Writer setCharacterStream(long indexToWriteAt) throws SQLException { |
163 | if (indexToWriteAt < 1) { |
164 | throw SQLError.createSQLException(Messages.getString("Clob.1"), //$NON-NLS-1$ |
165 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
166 | } |
167 | |
168 | WatchableWriter writer = new WatchableWriter(); |
169 | writer.setWatcher(this); |
170 | |
171 | // |
172 | // Don't call write() if nothing to write... |
173 | // |
174 | if (indexToWriteAt > 1) { |
175 | writer.write(this.charData, 0, (int) (indexToWriteAt - 1)); |
176 | } |
177 | |
178 | return writer; |
179 | } |
180 | |
181 | /** |
182 | * @see java.sql.Clob#setString(long, String) |
183 | */ |
184 | public int setString(long pos, String str) throws SQLException { |
185 | if (pos < 1) { |
186 | throw SQLError.createSQLException(Messages.getString("Clob.2"), //$NON-NLS-1$ |
187 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
188 | } |
189 | |
190 | if (str == null) { |
191 | throw SQLError.createSQLException(Messages.getString("Clob.3"), //$NON-NLS-1$ |
192 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
193 | } |
194 | |
195 | StringBuffer charBuf = new StringBuffer(this.charData); |
196 | |
197 | pos--; |
198 | |
199 | int strLength = str.length(); |
200 | |
201 | charBuf.replace((int) pos, (int) (pos + strLength), str); |
202 | |
203 | this.charData = charBuf.toString(); |
204 | |
205 | return strLength; |
206 | } |
207 | |
208 | /** |
209 | * @see java.sql.Clob#setString(long, String, int, int) |
210 | */ |
211 | public int setString(long pos, String str, int offset, int len) |
212 | throws SQLException { |
213 | if (pos < 1) { |
214 | throw SQLError.createSQLException(Messages.getString("Clob.4"), //$NON-NLS-1$ |
215 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
216 | } |
217 | |
218 | if (str == null) { |
219 | throw SQLError.createSQLException(Messages.getString("Clob.5"), //$NON-NLS-1$ |
220 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
221 | } |
222 | |
223 | StringBuffer charBuf = new StringBuffer(this.charData); |
224 | |
225 | pos--; |
226 | |
227 | String replaceString = str.substring(offset, len); |
228 | |
229 | charBuf.replace((int) pos, (int) (pos + replaceString.length()), |
230 | replaceString); |
231 | |
232 | this.charData = charBuf.toString(); |
233 | |
234 | return len; |
235 | } |
236 | |
237 | /** |
238 | * @see com.mysql.jdbc.OutputStreamWatcher#streamClosed(byte[]) |
239 | */ |
240 | public void streamClosed(WatchableOutputStream out) { |
241 | int streamSize = out.size(); |
242 | |
243 | if (streamSize < this.charData.length()) { |
244 | try { |
245 | out.write(StringUtils |
246 | .getBytes(this.charData, null, null, false, null), |
247 | streamSize, this.charData.length() - streamSize); |
248 | } catch (SQLException ex) { |
249 | // |
250 | } |
251 | } |
252 | |
253 | this.charData = StringUtils.toAsciiString(out.toByteArray()); |
254 | } |
255 | |
256 | /** |
257 | * @see java.sql.Clob#truncate(long) |
258 | */ |
259 | public void truncate(long length) throws SQLException { |
260 | if (length > this.charData.length()) { |
261 | throw SQLError.createSQLException( |
262 | Messages.getString("Clob.11") //$NON-NLS-1$ |
263 | + this.charData.length() |
264 | + Messages.getString("Clob.12") + length + Messages.getString("Clob.13")); //$NON-NLS-1$ //$NON-NLS-2$ |
265 | } |
266 | |
267 | this.charData = this.charData.substring(0, (int) length); |
268 | } |
269 | |
270 | /** |
271 | * @see com.mysql.jdbc.WriterWatcher#writerClosed(char[]) |
272 | */ |
273 | public void writerClosed(char[] charDataBeingWritten) { |
274 | this.charData = new String(charDataBeingWritten); |
275 | } |
276 | |
277 | /** |
278 | * @see com.mysql.jdbc.WriterWatcher#writerClosed(char[]) |
279 | */ |
280 | public void writerClosed(WatchableWriter out) { |
281 | int dataLength = out.size(); |
282 | |
283 | if (dataLength < this.charData.length()) { |
284 | out.write(this.charData, dataLength, this.charData.length() |
285 | - dataLength); |
286 | } |
287 | |
288 | this.charData = out.toString(); |
289 | } |
290 | } |