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 3726 2005-05-19 15:52:24 +0000 (Thu, 19 May 2005) 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 new SQLException(Messages.getString("Clob.6"), //$NON-NLS-1$ |
77 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
78 | } |
79 | |
80 | if (this.charData != null) { |
81 | if (((startPos - 1) + length) > this.charData.length()) { |
82 | throw new SQLException(Messages.getString("Clob.7"), //$NON-NLS-1$ |
83 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
84 | } |
85 | |
86 | return this.charData.substring((int) (startPos - 1), length); |
87 | } |
88 | |
89 | return null; |
90 | } |
91 | |
92 | /** |
93 | * @see java.sql.Clob#length() |
94 | */ |
95 | public long length() throws SQLException { |
96 | if (this.charData != null) { |
97 | return this.charData.length(); |
98 | } |
99 | |
100 | return 0; |
101 | } |
102 | |
103 | /** |
104 | * @see java.sql.Clob#position(Clob, long) |
105 | */ |
106 | public long position(java.sql.Clob arg0, long arg1) throws SQLException { |
107 | return position(arg0.getSubString(0L, (int) arg0.length()), arg1); |
108 | } |
109 | |
110 | /** |
111 | * @see java.sql.Clob#position(String, long) |
112 | */ |
113 | public long position(String stringToFind, long startPos) |
114 | throws SQLException { |
115 | if (startPos < 1) { |
116 | throw new SQLException( |
117 | Messages.getString("Clob.8") //$NON-NLS-1$ |
118 | + startPos + Messages.getString("Clob.9"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ |
119 | } |
120 | |
121 | if (this.charData != null) { |
122 | if ((startPos - 1) > this.charData.length()) { |
123 | throw new SQLException(Messages.getString("Clob.10"), //$NON-NLS-1$ |
124 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
125 | } |
126 | |
127 | int pos = this.charData.indexOf(stringToFind, (int) (startPos - 1)); |
128 | |
129 | return (pos == -1) ? (-1) : (pos + 1); |
130 | } |
131 | |
132 | return -1; |
133 | } |
134 | |
135 | /** |
136 | * @see java.sql.Clob#setAsciiStream(long) |
137 | */ |
138 | public OutputStream setAsciiStream(long indexToWriteAt) throws SQLException { |
139 | if (indexToWriteAt < 1) { |
140 | throw new SQLException(Messages.getString("Clob.0"), //$NON-NLS-1$ |
141 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
142 | } |
143 | |
144 | WatchableOutputStream bytesOut = new WatchableOutputStream(); |
145 | bytesOut.setWatcher(this); |
146 | |
147 | if (indexToWriteAt > 0) { |
148 | bytesOut.write(this.charData.getBytes(), 0, |
149 | (int) (indexToWriteAt - 1)); |
150 | } |
151 | |
152 | return bytesOut; |
153 | } |
154 | |
155 | /** |
156 | * @see java.sql.Clob#setCharacterStream(long) |
157 | */ |
158 | public Writer setCharacterStream(long indexToWriteAt) throws SQLException { |
159 | if (indexToWriteAt < 1) { |
160 | throw new SQLException(Messages.getString("Clob.1"), //$NON-NLS-1$ |
161 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
162 | } |
163 | |
164 | WatchableWriter writer = new WatchableWriter(); |
165 | writer.setWatcher(this); |
166 | |
167 | // |
168 | // Don't call write() if nothing to write... |
169 | // |
170 | if (indexToWriteAt > 1) { |
171 | writer.write(this.charData, 0, (int) (indexToWriteAt - 1)); |
172 | } |
173 | |
174 | return writer; |
175 | } |
176 | |
177 | /** |
178 | * @see java.sql.Clob#setString(long, String) |
179 | */ |
180 | public int setString(long pos, String str) throws SQLException { |
181 | if (pos < 1) { |
182 | throw new SQLException(Messages.getString("Clob.2"), //$NON-NLS-1$ |
183 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
184 | } |
185 | |
186 | if (str == null) { |
187 | throw new SQLException(Messages.getString("Clob.3"), //$NON-NLS-1$ |
188 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
189 | } |
190 | |
191 | StringBuffer charBuf = new StringBuffer(this.charData); |
192 | |
193 | pos--; |
194 | |
195 | int strLength = str.length(); |
196 | |
197 | charBuf.replace((int) pos, (int) (pos + strLength), str); |
198 | |
199 | this.charData = charBuf.toString(); |
200 | |
201 | return strLength; |
202 | } |
203 | |
204 | /** |
205 | * @see java.sql.Clob#setString(long, String, int, int) |
206 | */ |
207 | public int setString(long pos, String str, int offset, int len) |
208 | throws SQLException { |
209 | if (pos < 1) { |
210 | throw new SQLException(Messages.getString("Clob.4"), //$NON-NLS-1$ |
211 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
212 | } |
213 | |
214 | if (str == null) { |
215 | throw new SQLException(Messages.getString("Clob.5"), //$NON-NLS-1$ |
216 | SQLError.SQL_STATE_ILLEGAL_ARGUMENT); |
217 | } |
218 | |
219 | StringBuffer charBuf = new StringBuffer(this.charData); |
220 | |
221 | pos--; |
222 | |
223 | String replaceString = str.substring(offset, len); |
224 | |
225 | charBuf.replace((int) pos, (int) (pos + replaceString.length()), |
226 | replaceString); |
227 | |
228 | this.charData = charBuf.toString(); |
229 | |
230 | return len; |
231 | } |
232 | |
233 | /** |
234 | * @see com.mysql.jdbc.OutputStreamWatcher#streamClosed(byte[]) |
235 | */ |
236 | public void streamClosed(WatchableOutputStream out) { |
237 | int streamSize = out.size(); |
238 | |
239 | if (streamSize < this.charData.length()) { |
240 | try { |
241 | out.write(StringUtils |
242 | .getBytes(this.charData, null, null, false), |
243 | streamSize, this.charData.length() - streamSize); |
244 | } catch (SQLException ex) { |
245 | // |
246 | } |
247 | } |
248 | |
249 | this.charData = StringUtils.toAsciiString(out.toByteArray()); |
250 | } |
251 | |
252 | /** |
253 | * @see java.sql.Clob#truncate(long) |
254 | */ |
255 | public void truncate(long length) throws SQLException { |
256 | if (length > this.charData.length()) { |
257 | throw new SQLException( |
258 | Messages.getString("Clob.11") //$NON-NLS-1$ |
259 | + this.charData.length() |
260 | + Messages.getString("Clob.12") + length + Messages.getString("Clob.13")); //$NON-NLS-1$ //$NON-NLS-2$ |
261 | } |
262 | |
263 | this.charData = this.charData.substring(0, (int) length); |
264 | } |
265 | |
266 | /** |
267 | * @see com.mysql.jdbc.WriterWatcher#writerClosed(char[]) |
268 | */ |
269 | public void writerClosed(char[] charDataBeingWritten) { |
270 | this.charData = new String(charDataBeingWritten); |
271 | } |
272 | |
273 | /** |
274 | * @see com.mysql.jdbc.WriterWatcher#writerClosed(char[]) |
275 | */ |
276 | public void writerClosed(WatchableWriter out) { |
277 | int dataLength = out.size(); |
278 | |
279 | if (dataLength < this.charData.length()) { |
280 | out.write(this.charData, dataLength, this.charData.length() |
281 | - dataLength); |
282 | } |
283 | |
284 | this.charData = out.toString(); |
285 | } |
286 | } |