The HSQLDB jdbcClob.java source code
/* Copyright (c) 2001-2008, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.jdbc;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Clob;
import java.sql.SQLException;
import org.hsqldb.Trace;
import org.hsqldb.lib.AsciiStringInputStream;
// boucherb@users 2004-03/04-xx - doc 1.7.2 - javadocs updated; methods put in
// correct (historical, interface
// declared) order
// boucherb@users 2004-03/04-xx - patch 1.7.2 - null check for constructor (a
// null CLOB value is Java null,
// not a Clob object with null
// data);moderate thread safety;
// simplification; optimization
// of operations between jdbcClob
// instances
/**
* The mapping in the Java<sup>TM programming
* language for the SQL CLOB type. <p>
*
* Provides methods for getting the length of an SQL CLOB (Character Large
* Object) value, for materializing a CLOB value on the client, and for
* searching for a substring or CLOB object within a CLOB value. <p>
*
* <!-- start Release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* Including 1.8.x, the HSQLDB driver does not implement Clob using an SQL
* locator(CLOB). That is, an HSQLDB Clob object does not contain a logical
* pointer to SQL CLOB data; rather it directly contains an immutable
* representation of the data (a String object). As a result, an HSQLDB
* Clob object itself is valid beyond the duration of the transaction in which
* is was created, although it does not necessarily represent a corresponding
* value on the database. <p>
*
* Currently, the interface methods for updating a CLOB value are
* unsupported. However, the truncate method is supported for local use.
* </div>
* <!-- end release-specific documentation -->
*
* @author boucherb@users
* @version 1.7.2
* @since JDK 1.2, HSQLDB 1.7.2
*/
public final class jdbcClob implements Clob {
volatile String data;
/**
* Constructs a new jdbcClob object wrapping the given character
* sequence. <p>
*
* This constructor is used internally to retrieve result set values as
* Clob objects, yet it must be public to allow access from other packages.
* As such (in the interest of efficiency) this object maintains a reference
* to the given String object rather than making a copy and so it is
* gently suggested (in the interest of effective memory management) that
* extenal clients using this constructor either take pause to consider
* the implications or at least take care to provide a String object whose
* internal character buffer is not much larger than required to represent
* the value.
*
* @param data the character sequence representing the Clob value
* @throws SQLException if the argument is null
*/
public jdbcClob(final String data) throws SQLException {
if (data == null) {
throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, "null");
}
this.data = data;
}
/**
* Retrieves the number of characters in the <code>CLOB value
* designated by this <code>Clob object.
*
* @return length of the <code>CLOB in characters
* @exception SQLException if there is an error accessing the
* length of the <code>CLOB value
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long length() throws SQLException {
final String ldata = data;
return ldata.length();
}
/**
* Retrieves a copy of the specified substring in the <code>CLOB
* value designated by this <code>Clob object. The substring begins
* at position <code>pos and has up to length
* consecutive characters. <p>
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* The official specification above is ambiguous in that it does not
* precisely indicate the policy to be observed when
* pos > this.length() - length. One policy would be to retrieve the
* characters from pos to this.length(). Another would be to throw
* an exception. HSQLDB observes the later policy.
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the first character of the substring to be extracted.
* The first character is at position 1.
* @param length the number of consecutive characters to be copied
* @return a <code>String that is the specified substring in
* the <code>CLOB value designated by this
* <code>Clob object
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public String getSubString(long pos,
final int length) throws SQLException {
final String ldata = data;
final int dlen = ldata.length();
pos--;
if (pos < 0 || pos > dlen) {
Util.sqlException(Trace.INVALID_JDBC_ARGUMENT,
"pos: " + (pos + 1L));
}
if (length < 0 || length > dlen - pos) {
throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT,
"length: " + length);
}
if (pos == 0 && length == dlen) {
return ldata;
}
return ldata.substring((int) pos, (int) pos + length);
}
/**
* Retrieves the <code>CLOB value designated by this
* <code>Clob object as a java.io.Reader
object
* (or as a stream of characters).
*
* @return a <code>java.io.Reader object containing the
* <code>CLOB data
* @exception SQLException if there is an error accessing the
* <code>CLOB value
* @see #setCharacterStream
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public java.io.Reader getCharacterStream() throws SQLException {
final String ldata = data;
return new StringReader(ldata);
}
/**
* Retrieves the <code>CLOB value designated by this
* <code>Clob object as an ascii stream.
*
* @return a <code>java.io.InputStream object containing the
* <code>CLOB data
* @exception SQLException if there is an error accessing the
* <code>CLOB value
* @see #setAsciiStream
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public java.io.InputStream getAsciiStream() throws SQLException {
final String ldata = data;
return new AsciiStringInputStream(ldata);
}
/**
* Retrieves the character position at which the specified substring
* <code>searchstr appears in the SQL CLOB
value
* represented by this <code>Clob object. The search
* begins at position <code>start.
*
* @param searchstr the substring for which to search
* @param start the position at which to begin searching; the
* first position is 1
* @return the position at which the substring appears or -1 if it is not
* present; the first position is 1
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long position(final String searchstr,
long start) throws SQLException {
if (searchstr == null || start > Integer.MAX_VALUE) {
return -1;
}
final String ldata = data;
final int pos = ldata.indexOf(searchstr, (int) --start);
return (pos < 0) ? -1
: pos + 1;
}
/**
* Retrieves the character position at which the specified
* <code>Clob object searchstr
appears in this
* <code>Clob object. The search begins at position
* <code>start.
*
* @param searchstr the <code>Clob object for which to search
* @param start the position at which to begin searching; the first
* position is 1
* @return the position at which the <code>Clob object appears
* or -1 if it is not present; the first position is 1
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long position(final Clob searchstr,
long start) throws SQLException {
if (searchstr == null) {
return -1;
}
final String ldata = data;
final long dlen = ldata.length();
final long sslen = searchstr.length();
start--; //***** FOIRGOT THIS *******
// This is potentially much less expensive than materializing a large
// substring from some other vendor's CLOB. Indeed, we should probably
// do the comparison piecewise, using an in-memory buffer (or temp-files
// when available), if it is detected that the input CLOB is very long.
if (start > dlen - sslen) {
return -1;
}
// by now, we know sslen and start are both < Integer.MAX_VALUE
String s;
if (searchstr instanceof jdbcClob) {
s = ((jdbcClob) searchstr).data;
} else {
s = searchstr.getSubString(1L, (int) sslen);
}
final int pos = ldata.indexOf(s, (int) start);
return (pos < 0) ? -1
: pos + 1;
}
//---------------------------- jdbc 3.0 -----------------------------------
/**
* Writes the given Java <code>String to the CLOB
* value that this <code>Clob object designates at the position
* <code>pos.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* HSLQDB 1.7.2 does not support this feature. <p>
*
* Calling this method always throws an <code>SQLException.
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to the
* <code>CLOB value that this Clob
object
* represents
* @param str the string to be written to the <code>CLOB
* value that this <code>Clob designates
* @return the number of characters written
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.4, HSQLDB 1.7.2
*/
public int setString(long pos, String str) throws SQLException {
throw Util.notSupported();
}
/**
* Writes <code>len characters of str
, starting
* at character <code>offset, to the CLOB
value
* that this <code>Clob represents.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* HSLQDB 1.7.2 does not support this feature. <p>
*
* Calling this method always throws an <code>SQLException.
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to this
* <code>CLOB object
* @param str the string to be written to the <code>CLOB
* value that this <code>Clob object represents
* @param offset the offset into <code>str to start reading
* the characters to be written
* @param len the number of characters to be written
* @return the number of characters written
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.4, HSQLDB 1.7.2
*/
public int setString(long pos, String str, int offset,
int len) throws SQLException {
throw Util.notSupported();
}
/**
* Retrieves a stream to be used to write Ascii characters to the
* <code>CLOB value that this Clob
object represents,
* starting at position <code>pos.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* HSLQDB 1.7.2 does not support this feature. <p>
*
* Calling this method always throws an <code>SQLException.
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to this
* <code>CLOB object
* @return the stream to which ASCII encoded characters can be written
* @exception SQLException if there is an error accessing the
* <code>CLOB value
* @see #getAsciiStream
*
* @since JDK 1.4, HSQLDB 1.7.2
*/
public java.io.OutputStream setAsciiStream(long pos) throws SQLException {
throw Util.notSupported();
}
/**
* Retrieves a stream to be used to write a stream of Unicode characters
* to the <code>CLOB value that this Clob
object
* represents, at position <code>pos.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* HSLQDB 1.7.2 does not support this feature. <p>
*
* Calling this method always throws an <code>SQLException.
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to the
* <code>CLOB value
*
* @return a stream to which Unicode encoded characters can be written
* @exception SQLException if there is an error accessing the
* <code>CLOB value
* @see #getCharacterStream
*
* @since JDK 1.4, HSQLDB 1.7.2
*/
public java.io.Writer setCharacterStream(long pos) throws SQLException {
throw Util.notSupported();
}
/**
* Truncates the <code>CLOB value that this Clob
* designates to have a length of <code>len
* characters. <p>
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:
*
* This operation affects only the client-side value; it has no effect upon
* the value as it is stored in the database.
* </div>
* <!-- end release-specific documentation -->
*
* @param len the length, in bytes, to which the <code>CLOB value
* should be truncated
* @exception SQLException if there is an error accessing the
* <code>CLOB value
*
* @since JDK 1.4, HSQLDB 1.7.2
*/
public void truncate(final long len) throws SQLException {
final String ldata = data;
final long dlen = ldata.length();
if (len == dlen) {
// nothing has changed, so there's nothing to be done
} else if (len < 0 || len > dlen) {
throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT,
Long.toString(len));
} else {
// use new String() to ensure we get rid of slack
data = new String(ldata.substring(0, (int) len));
}
}
//#ifdef JAVA6
/*
public void free() throws SQLException
{
throw new UnsupportedOperationException("Not supported yet.");
}
public Reader getCharacterStream(long pos, long length) throws SQLException
{
throw new UnsupportedOperationException("Not supported yet.");
}
*/
//#endif JAVA6
}
Other HSQLDB examples (source code examples)
Here is a short list of links related to this HSQLDB jdbcClob.java source code file: