001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.jdbc;
007:
008: import java.io.InputStream;
009: import java.io.OutputStream;
010: import java.io.Reader;
011: import java.io.Writer;
012: import java.sql.Clob;
013: import java.sql.SQLException;
014:
015: import org.h2.constant.ErrorCode;
016: import org.h2.engine.Constants;
017: import org.h2.engine.SessionInterface;
018: import org.h2.message.Message;
019: import org.h2.message.TraceObject;
020: import org.h2.util.IOUtils;
021: import org.h2.value.Value;
022:
023: //#ifdef JDK16
024: /*
025: import java.sql.NClob;
026: */
027: //#endif
028: /**
029: * Represents a CLOB value.
030: */
031: public class JdbcClob extends TraceObject implements Clob
032: //#ifdef JDK16
033: /*
034: , NClob
035: */
036: //#endif
037: {
038:
039: private Value value;
040: private JdbcConnection conn;
041:
042: /**
043: * INTERNAL
044: */
045: public JdbcClob(SessionInterface session, JdbcConnection conn,
046: Value value, int id) {
047: setTrace(session.getTrace(), TraceObject.CLOB, id);
048: this .conn = conn;
049: this .value = value;
050: }
051:
052: /**
053: * Returns the length.
054: *
055: * @return the length
056: */
057: public long length() throws SQLException {
058: try {
059: debugCodeCall("length");
060: checkClosed();
061: if (value.getType() == Value.CLOB) {
062: long precision = value.getPrecision();
063: if (precision > 0) {
064: return precision;
065: }
066: }
067: Reader in = value.getReader();
068: try {
069: long size = 0;
070: char[] buff = new char[Constants.FILE_BLOCK_SIZE];
071: while (true) {
072: int len = in.read(buff, 0,
073: Constants.FILE_BLOCK_SIZE);
074: if (len <= 0) {
075: break;
076: }
077: size += len;
078: }
079: return size;
080: } finally {
081: in.close();
082: }
083: } catch (Throwable e) {
084: throw logAndConvert(e);
085: }
086: }
087:
088: /**
089: * [Not supported] Truncates the object.
090: */
091: public void truncate(long len) throws SQLException {
092: debugCodeCall("truncate", len);
093: throw Message.getUnsupportedException();
094: }
095:
096: /**
097: * Returns the input stream.
098: *
099: * @return the input stream
100: */
101: public InputStream getAsciiStream() throws SQLException {
102: try {
103: debugCodeCall("getAsciiStream");
104: checkClosed();
105: String s = value.getString();
106: return IOUtils.getInputStream(s);
107: } catch (Throwable e) {
108: throw logAndConvert(e);
109: }
110: }
111:
112: /**
113: * [Not supported] Returns an output stream.
114: */
115: public OutputStream setAsciiStream(long pos) throws SQLException {
116: debugCodeCall("setAsciiStream", pos);
117: throw Message.getUnsupportedException();
118: }
119:
120: /**
121: * Returns the reader.
122: *
123: * @return the reader
124: */
125: public Reader getCharacterStream() throws SQLException {
126: try {
127: debugCodeCall("getCharacterStream");
128: checkClosed();
129: return value.getReader();
130: } catch (Throwable e) {
131: throw logAndConvert(e);
132: }
133: }
134:
135: /**
136: * [Not supported] Returns a writer starting from a given position.
137: */
138: public Writer setCharacterStream(long pos) throws SQLException {
139: debugCodeCall("setCharacterStream", pos);
140: throw Message.getUnsupportedException();
141: }
142:
143: /**
144: * Returns a substring.
145: *
146: * @param pos the position (the first character is at position 1)
147: * @param length the number of characters
148: * @return the string
149: */
150: public String getSubString(long pos, int length)
151: throws SQLException {
152: try {
153: debugCode("getSubString(" + pos + ", " + length + ");");
154: checkClosed();
155: if (pos < 1) {
156: throw Message.getInvalidValueException("pos", "" + pos);
157: }
158: if (length < 0) {
159: throw Message.getInvalidValueException("length", ""
160: + length);
161: }
162: StringBuffer buff = new StringBuffer(Math.min(4096, length));
163: Reader reader = value.getReader();
164: try {
165: IOUtils.skipFully(reader, pos - 1);
166: for (int i = 0; i < length; i++) {
167: int ch = reader.read();
168: if (ch < 0) {
169: break;
170: }
171: buff.append((char) ch);
172: }
173: } finally {
174: reader.close();
175: }
176: return buff.toString();
177: } catch (Throwable e) {
178: throw logAndConvert(e);
179: }
180: }
181:
182: /**
183: * [Not supported] Sets a substring.
184: */
185: public int setString(long pos, String str) throws SQLException {
186: debugCode("setString(" + pos + ", " + quote(str) + ");");
187: throw Message.getUnsupportedException();
188: }
189:
190: /**
191: * [Not supported] Sets a substring.
192: */
193: public int setString(long pos, String str, int offset, int len)
194: throws SQLException {
195: debugCode("setString(" + pos + ", " + quote(str) + ", "
196: + offset + ", " + len + ");");
197: throw Message.getUnsupportedException();
198: }
199:
200: /**
201: * [Not supported] Searches a pattern and return the position.
202: */
203: public long position(String pattern, long start)
204: throws SQLException {
205: debugCode("position(" + quote(pattern) + ", " + start + ");");
206: throw Message.getUnsupportedException();
207: }
208:
209: /**
210: * [Not supported] Searches a pattern and return the position.
211: */
212: public long position(Clob clobPattern, long start)
213: throws SQLException {
214: debugCode("position(clobPattern, " + start + ");");
215: throw Message.getUnsupportedException();
216: }
217:
218: /**
219: * Release all resources of this object.
220: */
221: public void free() throws SQLException {
222: debugCodeCall("free");
223: value = null;
224: }
225:
226: /**
227: * [Not supported] Returns the reader, starting from an offset.
228: */
229: public Reader getCharacterStream(long pos, long length)
230: throws SQLException {
231: debugCode("getCharacterStream(" + pos + ", " + length + ");");
232: throw Message.getUnsupportedException();
233: }
234:
235: private void checkClosed() throws SQLException {
236: conn.checkClosed();
237: if (value == null) {
238: throw Message.getSQLException(ErrorCode.OBJECT_CLOSED);
239: }
240: }
241:
242: /**
243: * INTERNAL
244: */
245: public String toString() {
246: return getTraceObjectName() + ": " + value.getSQL();
247: }
248:
249: }
|