Mercurial > hg > monetdb-java
comparison src/main/java/org/monetdb/jdbc/MonetClob.java @ 391:f523727db392
Moved Java classes from packages starting with nl.cwi.monetdb.* to package org.monetdb.*
This naming complies to the Java Package Naming convention as MonetDB's main website is www.monetdb.org.
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 12 Nov 2020 22:02:01 +0100 |
parents | src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java@54137aeb1f92 |
children | bf9f6b6ecf40 |
comparison
equal
deleted
inserted
replaced
390:6199e0be3c6e | 391:f523727db392 |
---|---|
1 /* | |
2 * This Source Code Form is subject to the terms of the Mozilla Public | |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
5 * | |
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2020 MonetDB B.V. | |
7 */ | |
8 | |
9 package org.monetdb.jdbc; | |
10 | |
11 import java.io.InputStream; | |
12 import java.io.Reader; | |
13 import java.io.StringReader; | |
14 import java.sql.Clob; | |
15 import java.sql.SQLException; | |
16 import java.sql.SQLFeatureNotSupportedException; | |
17 | |
18 /** | |
19 * The MonetClob class implements the {@link java.sql.Clob} interface. | |
20 * | |
21 * Because MonetDB/SQL currently has no support for streams, this class is a | |
22 * shallow wrapper of a {@link StringBuilder}. It is more or less supplied to | |
23 * enable an application that depends on it to run. It may be obvious | |
24 * that it is a real resource expensive workaround that contradicts the | |
25 * sole reason for a Clob: avoidance of huge resource consumption. | |
26 * <b>Use of this class is highly discouraged.</b> | |
27 * | |
28 * @author Fabian Groffen | |
29 */ | |
30 public final class MonetClob implements Clob { | |
31 private StringBuilder buf; | |
32 | |
33 protected MonetClob(final String in) { | |
34 buf = new StringBuilder(in); | |
35 } | |
36 | |
37 /* internal utility method */ | |
38 private final void checkBufIsNotNull() throws SQLException { | |
39 if (buf == null) | |
40 throw new SQLException("This MonetClob has been freed", "M1M20"); | |
41 } | |
42 | |
43 //== begin interface Clob | |
44 | |
45 /** | |
46 * This method frees the Clob object and releases the resources the | |
47 * resources that it holds. The object is invalid once the free | |
48 * method is called. | |
49 * | |
50 * After free has been called, any attempt to invoke a method other | |
51 * than free will result in a SQLException being thrown. If free is | |
52 * called multiple times, the subsequent calls to free are treated | |
53 * as a no-op. | |
54 */ | |
55 @Override | |
56 public void free() { | |
57 buf = null; | |
58 } | |
59 | |
60 /** | |
61 * Retrieves the CLOB value designated by this Clob object as an | |
62 * ascii stream. | |
63 * | |
64 * @return a java.io.InputStream object containing the CLOB data | |
65 * @throws SQLException - if there is an error accessing the CLOB value | |
66 */ | |
67 @Override | |
68 public InputStream getAsciiStream() throws SQLException { | |
69 checkBufIsNotNull(); | |
70 return new java.io.ByteArrayInputStream(buf.toString().getBytes()); | |
71 } | |
72 | |
73 /** | |
74 * Retrieves the CLOB value designated by this Clob object as a | |
75 * java.io.Reader object (or as a stream of characters). | |
76 * | |
77 * @return a java.io.Reader object containing the CLOB data | |
78 * @throws SQLException - if there is an error accessing the CLOB value | |
79 */ | |
80 @Override | |
81 public Reader getCharacterStream() throws SQLException { | |
82 checkBufIsNotNull(); | |
83 return new StringReader(buf.toString()); | |
84 } | |
85 | |
86 /** | |
87 * Returns a Reader object that contains a partial Clob value, | |
88 * starting with the character specified by pos, which is length | |
89 * characters in length. | |
90 * | |
91 * @param pos the offset to the first character of the partial value | |
92 * to be retrieved. The first character in the Clob is at position 1. | |
93 * @param length the length in characters of the partial value to be retrieved. | |
94 * @return Reader through which the partial Clob value can be read. | |
95 * @throws SQLException - if pos is less than 1 | |
96 * or if pos is greater than the number of characters in the Clob | |
97 * or if pos + length is greater than the number of characters in the Clob | |
98 */ | |
99 @Override | |
100 public Reader getCharacterStream(final long pos, final long length) throws SQLException { | |
101 // as length will be casted to int, check it for too big value first | |
102 if (length < 0 || length > Integer.MAX_VALUE) { | |
103 throw new SQLException("Invalid length value: " + length, "M1M05"); | |
104 } | |
105 // buf and input argument pos will be checked in method getSubString(long, int) | |
106 return new StringReader(getSubString(pos, (int)length)); | |
107 } | |
108 | |
109 /** | |
110 * Retrieves a copy of the specified substring in the CLOB value | |
111 * designated by this Clob object. The substring begins at | |
112 * position pos and has up to length consecutive characters. | |
113 * | |
114 * @param pos the first character of the substring to be | |
115 * extracted. The first character is at position 1. | |
116 * @param length the number of consecutive characters to be copied | |
117 * @return a String that is the specified substring in the | |
118 * CLOB value designated by this Clob object | |
119 * @throws SQLException - if pos is less than 1 | |
120 * or if pos is greater than the number of characters in the Clob | |
121 * or if pos + length is greater than the number of characters in the Clob | |
122 * @throws SQLException - if there is an error accessing the CLOB value | |
123 */ | |
124 @Override | |
125 public String getSubString(final long pos, final int length) throws SQLException { | |
126 checkBufIsNotNull(); | |
127 if (pos == 1L && length == buf.length()) { | |
128 // the whole string is requested | |
129 return buf.toString(); | |
130 } | |
131 if (pos < 1 || pos > buf.length()) { | |
132 throw new SQLException("Invalid pos value: " + pos, "M1M05"); | |
133 } | |
134 if (length < 0 || pos -1 + length > buf.length()) { | |
135 throw new SQLException("Invalid length value: " + length, "M1M05"); | |
136 } | |
137 try { | |
138 return buf.substring((int)(pos - 1), (int)(pos - 1 + length)); | |
139 } catch (IndexOutOfBoundsException e) { | |
140 throw new SQLException(e.getMessage(), "M1M05"); | |
141 } | |
142 } | |
143 | |
144 /** | |
145 * Retrieves the number of characters in the CLOB value designated | |
146 * by this Clob object. | |
147 * | |
148 * @return length of the CLOB in characters | |
149 * @throws SQLException if there is an error accessing the length | |
150 * of the CLOB value | |
151 */ | |
152 @Override | |
153 public long length() throws SQLException { | |
154 checkBufIsNotNull(); | |
155 return (long)buf.length(); | |
156 } | |
157 | |
158 /** | |
159 * Retrieves the character position at which the specified Clob | |
160 * object searchstr appears in this Clob object. The search | |
161 * begins at position start. | |
162 * | |
163 * @param searchstr the Clob object for which to search | |
164 * @param start the position at which to begin searching; | |
165 * the first position is 1 | |
166 * @return the position at which the Clob object appears or | |
167 * -1 if it is not present; the first position is 1 | |
168 * @throws SQLException - if there is an error accessing the CLOB value | |
169 */ | |
170 @Override | |
171 public long position(final Clob searchstr, final long start) throws SQLException { | |
172 if (searchstr == null) { | |
173 throw new SQLException("Missing searchstr object", "M1M05"); | |
174 } | |
175 // buf and input argument start will be checked in method position(String, long) | |
176 return position(searchstr.toString(), start); | |
177 } | |
178 | |
179 /** | |
180 * Retrieves the character position at which the specified | |
181 * substring searchstr appears in the SQL CLOB value represented | |
182 * by this Clob object. The search begins at position start. | |
183 * | |
184 * @param searchstr the substring for which to search | |
185 * @param start the position at which to begin searching; | |
186 * the first position is 1 | |
187 * @return the position at which the substring appears or | |
188 * -1 if it is not present; the first position is 1 | |
189 * @throws SQLException - if there is an error accessing the CLOB value | |
190 */ | |
191 @Override | |
192 public long position(final String searchstr, final long start) throws SQLException { | |
193 checkBufIsNotNull(); | |
194 if (searchstr == null) { | |
195 throw new SQLException("Missing searchstr object", "M1M05"); | |
196 } | |
197 if (start < 1 || start > buf.length()) { | |
198 throw new SQLException("Invalid start value: " + start, "M1M05"); | |
199 } | |
200 return (long)(buf.indexOf(searchstr, (int)(start - 1))); | |
201 } | |
202 | |
203 /** | |
204 * Retrieves a stream to be used to write Ascii characters to the CLOB value that this | |
205 * Clob object represents, starting at position pos. Characters written to the stream | |
206 * will overwrite the existing characters in the Clob object starting at the position pos. | |
207 * If the end of the Clob value is reached while writing characters to the stream, | |
208 * then the length of the Clob value will be increased to accomodate the extra characters. | |
209 * | |
210 * Note: If the value specified for pos is greater then the length+1 of the CLOB value | |
211 * then the behavior is undefined. Some JDBC drivers may throw a SQLException while | |
212 * other drivers may support this operation. | |
213 * | |
214 * @param pos - the position at which to start writing to this CLOB object; The first position is 1 | |
215 * @return the stream to which ASCII encoded characters can be written | |
216 * @throws SQLException - if there is an error accessing the CLOB value or if pos is less than 1 | |
217 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method | |
218 */ | |
219 @Override | |
220 public java.io.OutputStream setAsciiStream(final long pos) throws SQLException { | |
221 throw MonetWrapper.newSQLFeatureNotSupportedException("setAsciiStream"); | |
222 } | |
223 | |
224 /** | |
225 * Retrieves a stream to be used to write a stream of Unicode characters to the CLOB value that | |
226 * this Clob object represents, starting at position pos. Characters written to the stream | |
227 * will overwrite the existing characters in the Clob object starting at the position pos. | |
228 * If the end of the Clob value is reached while writing characters to the stream, | |
229 * then the length of the Clob value will be increased to accomodate the extra characters. | |
230 * | |
231 * Note: If the value specified for pos is greater then the length+1 of the CLOB value | |
232 * then the behavior is undefined. Some JDBC drivers may throw a SQLException while | |
233 * other drivers may support this operation. | |
234 * | |
235 * @param pos - the position at which to start writing to this CLOB object; The first position is 1 | |
236 * @return the stream to which Unicode encoded characters can be written | |
237 * @throws SQLException - if there is an error accessing the CLOB value or if pos is less than 1 | |
238 * @throws SQLFeatureNotSupportedException - if the JDBC driver does not support this method | |
239 */ | |
240 @Override | |
241 public java.io.Writer setCharacterStream(final long pos) throws SQLException { | |
242 throw MonetWrapper.newSQLFeatureNotSupportedException("setCharacterStream"); | |
243 } | |
244 | |
245 /** | |
246 * Writes the given Java String to the CLOB value that this Clob object designates at the position pos. | |
247 * The string will overwrite the existing characters in the Clob object starting at the position pos. | |
248 * If the end of the Clob value is reached while writing the given string, | |
249 * then the length of the Clob value will be increased to accomodate the extra characters. | |
250 * | |
251 * @param pos the position at which to start writing to the CLOB value that this Clob object represents | |
252 * @param str the string to be written to the CLOB value that this Clob designates | |
253 * @return the number of characters written | |
254 * @throws SQLException if there is an error accessing the CLOB value or if pos is less than 1 | |
255 */ | |
256 @Override | |
257 public int setString(final long pos, final String str) throws SQLException { | |
258 // buf and input arguments will be checked in method setString(long, String, int, int) | |
259 final int len = (str != null) ? str.length() : 0; | |
260 return setString(pos, str, 0, len); | |
261 } | |
262 | |
263 /** | |
264 * Writes len characters of str, starting at character offset, to the CLOB value that this Clob represents. | |
265 * The string will overwrite the existing characters in the Clob object starting at the position pos. | |
266 * If the end of the Clob value is reached while writing the given string, | |
267 * then the length of the Clob value will be increased to accomodate the extra characters. | |
268 * | |
269 * @param pos the position at which to start writing to this CLOB object | |
270 * @param str the string to be written to the CLOB value that this Clob object represents | |
271 * @param offset the offset into str to start reading the characters to be written | |
272 * @param len the number of characters to be written | |
273 * @return the number of characters written | |
274 * @throws SQLException if there is an error accessing the CLOB value or if pos is less than 1 | |
275 */ | |
276 @Override | |
277 public int setString(final long pos, final String str, final int offset, final int len) | |
278 throws SQLException | |
279 { | |
280 checkBufIsNotNull(); | |
281 if (str == null) { | |
282 throw new SQLException("Missing str object", "M1M05"); | |
283 } | |
284 if (pos < 1 || pos > Integer.MAX_VALUE) { | |
285 throw new SQLException("Invalid pos value: " + pos, "M1M05"); | |
286 } | |
287 if (offset < 0 || offset > str.length()) { | |
288 throw new SQLException("Invalid offset value: " + offset, "M1M05"); | |
289 } | |
290 if (len < 1 || (offset + len) > str.length()) { | |
291 throw new SQLException("Invalid len value: " + len, "M1M05"); | |
292 } | |
293 if (((int) pos + len) > buf.capacity()) { | |
294 // enlarge the buffer before filling it | |
295 buf.ensureCapacity((int) pos + len); | |
296 } | |
297 buf.replace((int) pos - 1, (int) pos + len, str.substring(offset, (offset + len))); | |
298 return len; | |
299 } | |
300 | |
301 /** | |
302 * Truncates the CLOB value that this Clob designates to | |
303 * have a length of len characters. | |
304 * | |
305 * @param len the length, in bytes, to which the CLOB value should be truncated | |
306 * @throws SQLException if there is an error accessing the | |
307 * CLOB value or if len is less than 0 | |
308 */ | |
309 @Override | |
310 public void truncate(final long len) throws SQLException { | |
311 checkBufIsNotNull(); | |
312 if (len < 0 || len > buf.length()) { | |
313 throw new SQLException("Invalid len value: " + len, "M1M05"); | |
314 } | |
315 buf.setLength((int)len); | |
316 // reduce storage used for the character sequence. | |
317 buf.trimToSize(); | |
318 } | |
319 | |
320 | |
321 /** | |
322 * Returns a String from this MonetClob buf. | |
323 * | |
324 * @return the String this MonetClob wraps or empty string when this MonetClob was freed. | |
325 */ | |
326 public String toString() { | |
327 if (buf == null) | |
328 return ""; | |
329 return buf.toString(); | |
330 } | |
331 } |