comparison src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java @ 172:60063c67f9e7 embedded

Merged with default
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Tue, 19 Sep 2017 13:49:34 +0200 (2017-09-19)
parents 08bc9009d190 1e49fc74dba4
children 5b13ccaba741
comparison
equal deleted inserted replaced
171:0f95fee3cf29 172:60063c67f9e7
9 package nl.cwi.monetdb.jdbc; 9 package nl.cwi.monetdb.jdbc;
10 10
11 import java.io.*; 11 import java.io.*;
12 import java.sql.Clob; 12 import java.sql.Clob;
13 import java.sql.SQLException; 13 import java.sql.SQLException;
14 import java.sql.SQLFeatureNotSupportedException;
14 15
15 /** 16 /**
16 * The MonetClob class implements the {@link java.sql.Clob} interface. Because 17 * The MonetClob class implements the {@link java.sql.Clob} interface. Because
17 * MonetDB/SQL currently has no support for streams, this class is a 18 * MonetDB/SQL currently has no support for streams, this class is a
18 * shallow wrapper of a {@link StringBuilder}. It is more or less supplied to 19 * shallow wrapper of a {@link StringBuilder}. It is more or less supplied to
22 * <b>Use of this class is highly discouraged.</b> 23 * <b>Use of this class is highly discouraged.</b>
23 * 24 *
24 * @author Fabian Groffen 25 * @author Fabian Groffen
25 */ 26 */
26 public class MonetClob implements Clob, Serializable, Comparable<MonetClob> { 27 public class MonetClob implements Clob, Serializable, Comparable<MonetClob> {
27 28
28 private final StringBuilder buffer; 29 private final StringBuilder buffer;
29 30
30 public MonetClob(String in) { 31 public MonetClob(String in) {
31 buffer = new StringBuilder(in); 32 if(in != null)
33 buffer = new StringBuilder(in);
34 else
35 buffer = null;
32 } 36 }
33 37
34 public MonetClob(char[] toParse, int startPosition, int count) { 38 public MonetClob(char[] toParse, int startPosition, int count) {
35 buffer = new StringBuilder(new String(toParse, startPosition, count)); 39 buffer = new StringBuilder(new String(toParse, startPosition, count));
36 } 40 }
37 41
42 /* internal utility method */
43 private void checkBufIsNotNull() throws SQLException {
44 if (buffer == null)
45 throw new SQLException("This MonetClob has been freed", "M1M20");
46 }
47
38 //== begin interface Clob 48 //== begin interface Clob
39 49
40 /** 50 /**
41 * This method frees the Clob object and releases the resources the resources that it holds. The object is invalid 51 * This method frees the Clob object and releases the resources the resources that it holds. The object is invalid
42 * once the free method is called. 52 * once the free method is called.
43 * 53 *
44 * After free has been called, any attempt to invoke a method other than free will result in a SQLException being 54 * After free has been called, any attempt to invoke a method other than free will result in a SQLException being
45 * thrown. If free is called multiple times, the subsequent calls to free are treated as a no-op. 55 * thrown. If free is called multiple times, the subsequent calls to free are treated as a no-op.
46 */ 56 */
47 @Override 57 @Override
48 public void free() { 58 public void free() {
49 buffer.setLength(0); 59 if (buffer != null)
60 buffer.setLength(0);
50 } 61 }
51 62
52 /** 63 /**
53 * Retrieves the CLOB value designated by this Clob object as an ascii stream. 64 * Retrieves the CLOB value designated by this Clob object as an ascii stream.
54 * 65 *
55 * @return a java.io.InputStream object containing the CLOB data 66 * @return a java.io.InputStream object containing the CLOB data
56 * @throws SQLException if there is an error accessing the CLOB value 67 * @throws SQLException if there is an error accessing the CLOB value
57 */ 68 */
58 @Override 69 @Override
59 public InputStream getAsciiStream() throws SQLException { 70 public InputStream getAsciiStream() throws SQLException {
71 checkBufIsNotNull();
60 if (buffer.length() == 0) 72 if (buffer.length() == 0)
61 throw new SQLException("This Clob has been freed", "M1M20"); 73 throw new SQLException("This Clob has been freed", "M1M20");
62 return new ByteArrayInputStream(buffer.toString().getBytes()); 74 return new ByteArrayInputStream(buffer.toString().getBytes());
63 } 75 }
64 76
69 * @return a java.io.Reader object containing the CLOB data 81 * @return a java.io.Reader object containing the CLOB data
70 * @throws SQLException if there is an error accessing the CLOB value 82 * @throws SQLException if there is an error accessing the CLOB value
71 */ 83 */
72 @Override 84 @Override
73 public Reader getCharacterStream() throws SQLException { 85 public Reader getCharacterStream() throws SQLException {
74 if (buffer.length() == 0) 86 checkBufIsNotNull();
75 throw new SQLException("This Clob has been freed", "M1M20"); 87 return new StringReader(buffer.toString());
76 return new StringReader(buffer.toString());
77 } 88 }
78 89
79 /** 90 /**
80 * Returns a Reader object that contains a partial Clob value, starting with the character specified by pos, which 91 * Returns a Reader object that contains a partial Clob value, starting with the character specified by pos, which
81 * is length characters in length. 92 * is length characters in length.
86 * @return Reader through which the partial Clob value can be read. 97 * @return Reader through which the partial Clob value can be read.
87 * @throws SQLException if there is an error accessing the CLOB value 98 * @throws SQLException if there is an error accessing the CLOB value
88 */ 99 */
89 @Override 100 @Override
90 public Reader getCharacterStream(long pos, long length) throws SQLException { 101 public Reader getCharacterStream(long pos, long length) throws SQLException {
91 if (buffer.length() == 0) 102 checkBufIsNotNull();
92 throw new SQLException("This Clob has been freed", "M1M20"); 103 return new StringReader(getSubString(pos, (int)length));
93 return new StringReader(buffer.substring((int)(pos - 1), (int)(pos - 1 + length)));
94 } 104 }
95 105
96 /** 106 /**
97 * Retrieves a copy of the specified substring in the CLOB value designated by this Clob object. The substring 107 * Retrieves a copy of the specified substring in the CLOB value designated by this Clob object. The substring
98 * begins at position pos and has up to length consecutive characters. 108 * begins at position pos and has up to length consecutive characters.
102 * @return a String that is the specified substring in the CLOB value designated by this Clob object 112 * @return a String that is the specified substring in the CLOB value designated by this Clob object
103 * @throws SQLException if there is an error accessing the CLOB value 113 * @throws SQLException if there is an error accessing the CLOB value
104 */ 114 */
105 @Override 115 @Override
106 public String getSubString(long pos, int length) throws SQLException { 116 public String getSubString(long pos, int length) throws SQLException {
107 if (buffer.length() == 0) 117 checkBufIsNotNull();
108 throw new SQLException("This Clob has been freed", "M1M20");
109 try { 118 try {
110 return buffer.substring((int)(pos - 1), (int)(pos - 1 + length)); 119 return buffer.substring((int)(pos - 1), (int)(pos - 1 + length));
111 } catch (IndexOutOfBoundsException e) { 120 } catch (IndexOutOfBoundsException e) {
112 throw new SQLException(e.getMessage()); 121 throw new SQLException(e.getMessage());
113 } 122 }
119 * @return length of the CLOB in characters 128 * @return length of the CLOB in characters
120 * @throws SQLException if there is an error accessing the length of the CLOB value 129 * @throws SQLException if there is an error accessing the length of the CLOB value
121 */ 130 */
122 @Override 131 @Override
123 public long length() throws SQLException { 132 public long length() throws SQLException {
124 if (buffer.length() == 0) 133 checkBufIsNotNull();
125 throw new SQLException("This Clob has been freed", "M1M20"); 134 return (long)buffer.length();
126 return (long) buffer.length();
127 } 135 }
128 136
129 /** 137 /**
130 * Retrieves the character position at which the specified Clob object searchstr appears in this Clob object. 138 * Retrieves the character position at which the specified Clob object searchstr appears in this Clob object.
131 * The search begins at position start. 139 * The search begins at position start.
135 * @return the position at which the Clob object appears or -1 if it is not present; the first position is 1 143 * @return the position at which the Clob object appears or -1 if it is not present; the first position is 1
136 * @throws SQLException if there is an error accessing the CLOB value 144 * @throws SQLException if there is an error accessing the CLOB value
137 */ 145 */
138 @Override 146 @Override
139 public long position(Clob searchstr, long start) throws SQLException { 147 public long position(Clob searchstr, long start) throws SQLException {
148 checkBufIsNotNull();
140 return position(searchstr.getSubString(1L, (int)(searchstr.length())), start); 149 return position(searchstr.getSubString(1L, (int)(searchstr.length())), start);
141 } 150 }
142 151
143 /** 152 /**
144 * Retrieves the character position at which the specified substring searchstr appears in the SQL CLOB value 153 * Retrieves the character position at which the specified substring searchstr appears in the SQL CLOB value
149 * @return the position at which the substring appears or -1 if it is not present; the first position is 1 158 * @return the position at which the substring appears or -1 if it is not present; the first position is 1
150 * @throws SQLException if there is an error accessing the CLOB value 159 * @throws SQLException if there is an error accessing the CLOB value
151 */ 160 */
152 @Override 161 @Override
153 public long position(String searchstr, long start) throws SQLException { 162 public long position(String searchstr, long start) throws SQLException {
154 if (buffer.length() == 0) 163 checkBufIsNotNull();
155 throw new SQLException("This Clob has been freed", "M1M20");
156 return (long)(buffer.indexOf(searchstr, (int)(start - 1))); 164 return (long)(buffer.indexOf(searchstr, (int)(start - 1)));
157 } 165 }
158 166
159 @Override 167 @Override
160 public OutputStream setAsciiStream(long pos) throws SQLException { 168 public OutputStream setAsciiStream(long pos) throws SQLException {
161 if (buffer.length() == 0) 169 throw new SQLFeatureNotSupportedException("Method setAsciiStream(long pos) not supported", "0A000");
162 throw new SQLException("This Clob has been freed", "M1M20");
163 throw new SQLException("Operation setAsciiStream(long pos) currently not supported", "0A000");
164 } 170 }
165 171
166 @Override 172 @Override
167 public Writer setCharacterStream(long pos) throws SQLException { 173 public Writer setCharacterStream(long pos) throws SQLException {
168 if (buffer.length() == 0) 174 throw new SQLFeatureNotSupportedException("Method setCharacterStream(long pos) not supported", "0A000");
169 throw new SQLException("This Clob has been freed", "M1M20");
170 throw new SQLException("Operation setCharacterStream(long pos) currently not supported", "0A000");
171 } 175 }
172 176
173 /** 177 /**
174 * Writes the given Java String to the CLOB value that this Clob object designates at the position pos. 178 * Writes the given Java String to the CLOB value that this Clob object designates at the position pos.
175 * 179 *
193 * @return the number of characters written 197 * @return the number of characters written
194 * @throws SQLException if there is an error accessing the CLOB value 198 * @throws SQLException if there is an error accessing the CLOB value
195 */ 199 */
196 @Override 200 @Override
197 public int setString(long pos, String str, int offset, int len) throws SQLException { 201 public int setString(long pos, String str, int offset, int len) throws SQLException {
198 if (buffer.length() == 0) 202 checkBufIsNotNull();
199 throw new SQLException("This Clob has been freed", "M1M20");
200
201 int buflen = buffer.length(); 203 int buflen = buffer.length();
202 int retlen = Math.min(buflen, (int)(pos - 1 + len)); 204 int retlen = Math.min(buflen, (int)(pos - 1 + len));
203
204 if (retlen > 0) { 205 if (retlen > 0) {
205 buffer.replace((int)(pos - 1), (int)(pos + retlen), str.substring(offset - 1, (offset + len))); 206 buffer.replace((int)(pos - 1), (int)(pos + retlen), str.substring(offset - 1, (offset + len)));
206 return retlen; 207 return retlen;
207 } else { 208 } else {
208 return 0; 209 return 0;
215 * @param len the length, in bytes, to which the CLOB value should be truncated 216 * @param len the length, in bytes, to which the CLOB value should be truncated
216 * @throws SQLException if there is an error accessing the CLOB value 217 * @throws SQLException if there is an error accessing the CLOB value
217 */ 218 */
218 @Override 219 @Override
219 public void truncate(long len) throws SQLException { 220 public void truncate(long len) throws SQLException {
220 if (buffer.length() == 0) 221 checkBufIsNotNull();
221 throw new SQLException("This Clob has been freed", "M1M20");
222 buffer.setLength((int) len); 222 buffer.setLength((int) len);
223 } 223 }
224 224
225 /** 225 /**
226 * Returns the String behind this Clob. This is a MonetClob extension that does not violate nor is described in 226 * Returns the String behind this Clob. This is a MonetClob extension that does not violate nor is described in
228 * 228 *
229 * @return the String this Clob wraps. 229 * @return the String this Clob wraps.
230 */ 230 */
231 @Override 231 @Override
232 public String toString() { 232 public String toString() {
233 if (buffer.length() == 0) 233 if (buffer == null || buffer.length() == 0)
234 return "<a freed MonetClob instance>"; 234 return "null";
235 return buffer.toString(); 235 return buffer.toString();
236 } 236 }
237 237
238 /** 238 /**
239 * Overriding the equals method for the byte array. 239 * Overriding the equals method for the byte array.
245 245
246 /** 246 /**
247 * Overriding the hashCode method for the byte array. 247 * Overriding the hashCode method for the byte array.
248 */ 248 */
249 @Override 249 @Override
250 public int hashCode() { return this.buffer.toString().hashCode(); } 250 public int hashCode() {
251 if (buffer == null || buffer.length() == 0)
252 return 0;
253 return this.buffer.toString().hashCode();
254 }
251 255
252 /** 256 /**
253 * Adding the compare to method. 257 * Adding the compare to method.
254 */ 258 */
255 @Override 259 @Override