/* Copyright (c) 2001-2019, 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.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Clob;
import java.sql.SQLException;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.FrameworkLogger;
import org.hsqldb.lib.java.JavaSystem;
/* $Id: JDBCClob.java 5968 2019-04-27 12:55:27Z fredt $ */
// campbell-burnet@users 2004-03/04-xx - doc 1.7.2 - javadocs updated; methods put in
// correct (historical, interface
// declared) order
// campbell-burnet@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
// campbell-burnet@users 2005-12-07 - patch 1.8.0.x - initial JDBC 4.0 support work
// campbell-burnet@users 2006-05-22 - doc 1.9.0 - full synch up to Mustang Build 84
// - patch 1.9.0 - setAsciiStream &
// setCharacterStream improvement
// patch 1.9.0
// - full synch up to Mustang b90
// - better bounds checking
The mapping in the Java™ programming language for the SQL CLOB
type.
An SQL CLOB
is a built-in type
that stores a Character Large Object as a column value in a row of
a database table.
By default drivers implement a Clob
object using an SQL
locator(CLOB)
, which means that a Clob
object
contains a logical pointer to the SQL CLOB
data rather than
the data itself. A Clob
object is valid for the duration
of the transaction in which it was created.
The Clob
interface 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. Methods in the interfaces ResultSet
, CallableStatement
, and PreparedStatement
, such as getClob
and setClob
allow a programmer to
access an SQL CLOB
value. In addition, this interface
has methods for updating a CLOB
value.
All methods on the Clob
interface must be fully implemented if the
JDBC driver supports the data type.
HSQLDB-Specific Information:
Previous to 2.0, the HSQLDB driver did not implement Clob using an SQL
locator(CLOB). That is, an HSQLDB Clob object did not contain a logical
pointer to SQL CLOB data; rather it directly contained a representation of
the data (a String). As a result, an HSQLDB Clob object was itself
valid beyond the duration of the transaction in which is was created,
although it did not necessarily represent a corresponding value
on the database. Also, the interface methods for updating a CLOB value
were unsupported, with the exception of the truncate method,
in that it could be used to truncate the local value.
Starting with 2.0, the HSQLDB driver fully supports both local and remote
SQL CLOB data implementations, meaning that an HSQLDB Clob object may contain a logical pointer to remote SQL CLOB data (see
JDBCClobClient
) or it may directly contain a local representation of the data (as implemented in this class). In particular, when the product is built under JDK 1.6+ and the Clob instance is constructed as a result of calling JDBCConnection.createClob(), then the resulting Clob instance is initially disconnected (is not bound to the transaction scope of the vending Connection object), the data is contained directly and all interface methods for updating the CLOB value are supported for local use until the first invocation of free(); otherwise, an HSQLDB Clob's implementation is determined at runtime by the driver, it is typically not valid beyond the duration of the transaction in which is was created, and there no standard way to query whether it represents a local or remote value.
Author: Campbell Burnet (campbell-burnet@users dot sourceforge.net) Version: 2.5.0 Since: JDK 1.2, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* The mapping in the Java™ programming language for the SQL <code>CLOB</code> type.
* An SQL <code>CLOB</code> is a built-in type
* that stores a Character Large Object as a column value in a row of
* a database table.
* By default drivers implement a <code>Clob</code> object using an SQL
* <code>locator(CLOB)</code>, which means that a <code>Clob</code> object
* contains a logical pointer to the SQL <code>CLOB</code> data rather than
* the data itself. A <code>Clob</code> object is valid for the duration
* of the transaction in which it was created.
* <P>The <code>Clob</code> interface provides methods for getting the
* length of an SQL <code>CLOB</code> (Character Large Object) value,
* for materializing a <code>CLOB</code> value on the client, and for
* searching for a substring or <code>CLOB</code> object within a
* <code>CLOB</code> value.
* Methods in the interfaces {@link java.sql.ResultSet},
* {@link java.sql.CallableStatement}, and {@link java.sql.PreparedStatement}, such as
* <code>getClob</code> and <code>setClob</code> allow a programmer to
* access an SQL <code>CLOB</code> value. In addition, this interface
* has methods for updating a <code>CLOB</code> value.
* <p>
* All methods on the <code>Clob</code> interface must be fully implemented if the
* JDBC driver supports the data type.
*
* <!-- start Release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Previous to 2.0, the HSQLDB driver did not implement Clob using an SQL
* locator(CLOB). That is, an HSQLDB Clob object did not contain a logical
* pointer to SQL CLOB data; rather it directly contained a representation of
* the data (a String). As a result, an HSQLDB Clob object was itself
* valid beyond the duration of the transaction in which is was created,
* although it did not necessarily represent a corresponding value
* on the database. Also, the interface methods for updating a CLOB value
* were unsupported, with the exception of the truncate method,
* in that it could be used to truncate the local value. <p>
*
* Starting with 2.0, the HSQLDB driver fully supports both local and remote
* SQL CLOB data implementations, meaning that an HSQLDB Clob object <em>may</em>
* contain a logical pointer to remote SQL CLOB data (see {@link JDBCClobClient
* JDBCClobClient}) or it may directly contain a local representation of the
* data (as implemented in this class). In particular, when the product is built
* under JDK 1.6+ and the Clob instance is constructed as a result of calling
* JDBCConnection.createClob(), then the resulting Clob instance is initially
* disconnected (is not bound to the transaction scope of the vending Connection
* object), the data is contained directly and all interface methods for
* updating the CLOB value are supported for local use until the first
* invocation of free(); otherwise, an HSQLDB Clob's implementation is
* determined at runtime by the driver, it is typically not valid beyond
* the duration of the transaction in which is was created, and there no
* standard way to query whether it represents a local or remote value.<p>
*
* </div>
* <!-- end release-specific documentation -->
*
* @author Campbell Burnet (campbell-burnet@users dot sourceforge.net)
* @version 2.5.0
* @since JDK 1.2, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public class JDBCClob implements Clob {
private static final FrameworkLogger LOG =
FrameworkLogger.getLog(JDBCClob.class);
Retrieves the number of characters
in the CLOB
value
designated by this Clob
object.
Throws: - SQLException – if there is an error accessing the
length of the
CLOB
value - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: length of the CLOB
in characters Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves the number of characters
* in the <code>CLOB</code> value
* designated by this <code>Clob</code> object.
*
* @return length of the <code>CLOB</code> in characters
* @exception SQLException if there is an error accessing the
* length of the <code>CLOB</code> value
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long length() throws SQLException {
return getData().length();
}
Retrieves a copy of the specified substring
in the CLOB
value
designated by this Clob
object.
The substring begins at position
pos
and has up to length
consecutive
characters.
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. This class observes the second policy.
Note
This method uses String.substring(int, int)
.
Depending on implementation (typically JDK 6 and earlier releases), the
returned value may be sharing the underlying (and possibly much larger)
character buffer. Depending on factors such as hardware acceleration for
array copies, the average length and number of sub-strings taken, and so
on, this may or may not result in faster operation and
non-trivial memory savings. On the other hand, Oracle / OpenJDK 7, it
was decided that the memory leak implications outweigh the benefits
of buffer sharing for most use cases on modern hardware.
It is left up to any client of this method to determine if this is a
potential factor relative to the target runtime and to decide how to
handle space-time trade-offs (i.e. whether to make an isolated copy of
the returned substring or risk that more memory remains allocated than
is absolutely required).
Params: - pos – the first character of the substring to be extracted.
The first character is at position 1.
- length – the number of consecutive characters to be copied;
JDBC 4.1[ the value for length must be 0 or greater]
Throws: - SQLException – if there is an error accessing the
CLOB
value; if pos is less than 1 JDBC 4.1[or length is
less than 0] - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: a String
that is the specified substring in
the CLOB
value designated by this Clob
object Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves a copy of the specified substring
* in the <code>CLOB</code> value
* designated by this <code>Clob</code> object.
* The substring begins at position
* <code>pos</code> and has up to <code>length</code> consecutive
* characters.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* The official specification above is ambiguous in that it does not
* precisely indicate the policy to be observed when
* {@code pos > this.length() - length}. One policy would be to retrieve
* the characters from {@code pos} to {@code this.length()}. Another would
* be to throw an exception. This class observes the second policy. <p>
*
* <b>Note</b><p>
*
* This method uses {@link java.lang.String#substring(int, int)}.
* <p>
* Depending on implementation (typically JDK 6 and earlier releases), the
* returned value may be sharing the underlying (and possibly much larger)
* character buffer. Depending on factors such as hardware acceleration for
* array copies, the average length and number of sub-strings taken, and so
* on, this <em>may or may not</em> result in faster operation and
* non-trivial memory savings. On the other hand, Oracle / OpenJDK 7, it
* was decided that the memory leak implications outweigh the benefits
* of buffer sharing for most use cases on modern hardware.
* <p>
* It is left up to any client of this method to determine if this is a
* potential factor relative to the target runtime and to decide how to
* handle space-time trade-offs (i.e. whether to make an isolated copy of
* the returned substring or risk that more memory remains allocated than
* is absolutely required).
* </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;
* JDBC 4.1[ the value for length must be 0 or greater]
* @return a <code>String</code> that is the specified substring in
* the <code>CLOB</code> value designated by this <code>Clob</code> object
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value; if pos is less than 1 JDBC 4.1[or length is
* less than 0]
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2, HSQLDB 1.7.2
*/
public String getSubString(final long pos,
final int length) throws SQLException {
final String data = getData();
final int dlen = data.length();
if (pos == MIN_POS && length == dlen) {
return data;
}
if (pos < MIN_POS || pos > dlen) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
final long index = pos - 1;
if (length < 0 || length > dlen - index) {
throw JDBCUtil.outOfRangeArgument("length: " + length);
}
return data.substring((int) index, (int) index + length);
}
Retrieves the CLOB
value designated by this Clob
object as a java.io.Reader
object (or as a stream of
characters).
Throws: - SQLException – if there is an error accessing the
CLOB
value - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
See Also: Returns: a java.io.Reader
object containing the
CLOB
data Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
* object as a <code>java.io.Reader</code> object (or as a stream of
* characters).
*
* @return a <code>java.io.Reader</code> object containing the
* <code>CLOB</code> data
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #setCharacterStream
* @since JDK 1.2, HSQLDB 1.7.2
*/
public java.io.Reader getCharacterStream() throws SQLException {
return new StringReader(getData());
}
Retrieves the CLOB
value designated by this Clob
object as an ASCII stream.
Throws: - SQLException – if there is an error accessing the
CLOB
value - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
See Also: Returns: a java.io.InputStream
object containing the
CLOB
data Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves the <code>CLOB</code> value designated by this <code>Clob</code>
* object as an ASCII stream.
*
* @return a <code>java.io.InputStream</code> object containing the
* <code>CLOB</code> data
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #setAsciiStream
* @since JDK 1.2, HSQLDB 1.7.2
*/
public java.io.InputStream getAsciiStream() throws SQLException {
try {
return new ByteArrayInputStream(
getData().getBytes(JavaSystem.CS_US_ASCII));
} catch (Throwable e) {
throw JDBCUtil.sqlException(e);
}
}
Retrieves the character position at which the specified substring
searchstr
appears in the SQL CLOB
value
represented by this Clob
object. The search
begins at position start
.
Params: - searchstr – the substring for which to search
- start – the position at which to begin searching; the first position
is 1
Throws: - SQLException – if there is an error accessing the
CLOB
value or if start is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: the position at which the substring appears or -1 if it is not
present; the first position is 1 Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves the character position at which the specified substring
* <code>searchstr</code> appears in the SQL <code>CLOB</code> value
* represented by this <code>Clob</code> object. The search
* begins at position <code>start</code>.
*
* @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</code> value or if start is less than 1
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long position(final String searchstr,
long start) throws SQLException {
final String data = getData();
if (start < MIN_POS) {
throw JDBCUtil.outOfRangeArgument("start: " + start);
}
if (searchstr == null || start > MAX_POS) {
return -1;
}
final int position = data.indexOf(searchstr, (int) start - 1);
return (position == -1) ? -1
: position + 1;
}
Retrieves the character position at which the specified
Clob
object searchstr
appears in this
Clob
object. The search begins at position
start
.
Params: - searchstr – the
Clob
object for which to search - start – the position at which to begin searching; the first
position is 1
Throws: - SQLException – if there is an error accessing the
CLOB
value or if start is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: the position at which the Clob
object appears
or -1 if it is not present; the first position is 1 Since: JDK 1.2, HSQLDB 1.7.2
/**
* Retrieves the character position at which the specified
* <code>Clob</code> object <code>searchstr</code> appears in this
* <code>Clob</code> object. The search begins at position
* <code>start</code>.
*
* @param searchstr the <code>Clob</code> 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</code> 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</code> value or if start is less than 1
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2, HSQLDB 1.7.2
*/
public long position(final Clob searchstr,
final long start) throws SQLException {
final String data = getData();
if (start < MIN_POS) {
throw JDBCUtil.outOfRangeArgument("start: " + start);
}
if (searchstr == null) {
return -1;
}
final long dlen = data.length();
final long sslen = searchstr.length();
final long startIndex = start - 1;
// 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 (startIndex > dlen - sslen) {
return -1;
}
// by now, we know sslen and startIndex are both < Integer.MAX_VALUE
String pattern;
if (searchstr instanceof JDBCClob) {
pattern = ((JDBCClob) searchstr).getData();
} else {
pattern = searchstr.getSubString(1L, (int) sslen);
}
final int index = data.indexOf(pattern, (int) startIndex);
return (index == -1) ? -1
: index + 1;
}
//---------------------------- jdbc 3.0 -----------------------------------
Writes the given Java String
to the CLOB
value that this Clob
object designates at the position
pos
. The string will overwrite the existing characters
in the Clob
object starting at the position
pos
. If the end of the Clob
value is reached
while writing the given string, then the length of the Clob
value will be increased to accommodate the extra characters.
Note: If the value specified for pos
is greater then the length+1 of the CLOB
value then the
behavior is undefined. Some JDBC drivers may throw a
SQLException
while other drivers may support this
operation.
HSQLDB-Specific Information:
Starting with HSQLDB 2.0 this feature is supported.
When built under JDK 1.6+ and the Clob instance is constructed as a
result of calling JDBCConnection.createClob(), this operation affects
only the client-side value; it has no effect upon a value stored in the
database because JDBCConnection.createClob() constructs disconnected,
initially empty Clob instances. To propagate the Clob value to a database
in this case, it is required to supply the Clob instance to an updating
or inserting setXXX method of a Prepared or Callable Statement, or to
supply the Clob instance to an updateXXX method of an updateable
ResultSet.
Implementation Notes:
No attempt is made to ensure precise thread safety. Instead, volatile
member field and local variable snapshot isolation semantics are
implemented. This is expected to eliminate most issues related
to race conditions, with the possible exception of concurrent
invocation of free().
In general, if an application may perform concurrent JDBCClob
modifications and the integrity of the application depends on total order
Clob modification semantics, then such operations should be synchronized
on an appropriate monitor.
When the value specified for pos
is greater then the
length+1, then the CLOB value is extended in length to accept the
written characters and the undefined region up to @{code pos} is filled
with with space (' ') characters.
Params: - pos – the position at which to start writing to the
CLOB
value that this Clob
object represents;
The first position is 1 - str – the string to be written to the
CLOB
value that this Clob
designates
Throws: - SQLException – if there is an error accessing the
CLOB
value or if pos is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: the number of characters written Since: JDK 1.4, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* Writes the given Java <code>String</code> to the <code>CLOB</code>
* value that this <code>Clob</code> object designates at the position
* <code>pos</code>. The string will overwrite the existing characters
* in the <code>Clob</code> object starting at the position
* <code>pos</code>. If the end of the <code>Clob</code> value is reached
* while writing the given string, then the length of the <code>Clob</code>
* value will be increased to accommodate the extra characters.
* <p>
* <b>Note:</b> If the value specified for <code>pos</code>
* is greater then the length+1 of the <code>CLOB</code> value then the
* behavior is undefined. Some JDBC drivers may throw a
* <code>SQLException</code> while other drivers may support this
* operation.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 2.0 this feature is supported. <p>
*
* When built under JDK 1.6+ and the Clob instance is constructed as a
* result of calling JDBCConnection.createClob(), this operation affects
* only the client-side value; it has no effect upon a value stored in the
* database because JDBCConnection.createClob() constructs disconnected,
* initially empty Clob instances. To propagate the Clob value to a database
* in this case, it is required to supply the Clob instance to an updating
* or inserting setXXX method of a Prepared or Callable Statement, or to
* supply the Clob instance to an updateXXX method of an updateable
* ResultSet. <p>
*
* <b>Implementation Notes:</b><p>
*
* No attempt is made to ensure precise thread safety. Instead, volatile
* member field and local variable snapshot isolation semantics are
* implemented. This is expected to eliminate most issues related
* to race conditions, with the possible exception of concurrent
* invocation of free(). <p>
*
* In general, if an application may perform concurrent JDBCClob
* modifications and the integrity of the application depends on total order
* Clob modification semantics, then such operations should be synchronized
* on an appropriate monitor.<p>
*
* When the value specified for <code>pos</code> is greater then the
* length+1, then the CLOB value is extended in length to accept the
* written characters and the undefined region up to @{code pos} is filled
* with with space (' ') characters.
*
*
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to the <code>CLOB</code>
* value that this <code>Clob</code> object represents;
* The first position is 1
* @param str the string to be written to the <code>CLOB</code>
* value that this <code>Clob</code> designates
* @return the number of characters written
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value or if pos is less than 1
*
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.4, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public int setString(long pos, String str) throws SQLException {
return setString(pos, str, 0, str == null ? 0
: str.length());
}
Writes len
characters of str
, starting
at character offset
, to the CLOB
value
that this Clob
represents. The string will overwrite the existing characters
in the Clob
object starting at the position
pos
. If the end of the Clob
value is reached
while writing the given string, then the length of the Clob
value will be increased to accommodate the extra characters.
Note: If the value specified for pos
is greater then the length+1 of the CLOB
value then the
behavior is undefined. Some JDBC drivers may throw a
SQLException
while other drivers may support this
operation.
HSQLDB-Specific Information:
Starting with HSQLDB 2.0 this feature is supported.
When built under JDK 1.6+ and the Clob instance is constructed as a
result of calling JDBCConnection.createClob(), this operation affects
only the client-side value; it has no effect upon a value stored in a
database because JDBCConnection.createClob() constructs disconnected,
initially empty Clob instances. To propagate the Clob value to a database
in this case, it is required to supply the Clob instance to an updating
or inserting setXXX method of a Prepared or Callable Statement, or to
supply the Clob instance to an updateXXX method of an updateable
ResultSet.
Implementation Notes:
If the value specified for pos
is greater than the length of the CLOB
value, then
the CLOB
value is extended in length to accept the
written characters and the undefined region up to pos
is
filled with space (' ') characters.
No attempt is made to ensure precise thread safety. Instead, volatile
member field and local variable snapshot isolation semantics are
implemented. This is expected to eliminate most issues related
to race conditions, with the possible exception of concurrent
invocation of free().
In general, if an application may perform concurrent JDBCClob
modifications and the integrity of the application depends on total order
Clob modification semantics, then such operations should be synchronized
on an appropriate monitor.
Params: - pos – the position at which to start writing to this
CLOB
object; The first position is 1 - str – the string to be written to the
CLOB
value that this Clob
object represents - offset – the offset into
str
to start reading
the characters to be written - len – the number of characters to be written
Throws: - SQLException – if there is an error accessing the
CLOB
value or if pos is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: the number of characters written Since: JDK 1.4, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* Writes <code>len</code> characters of <code>str</code>, starting
* at character <code>offset</code>, to the <code>CLOB</code> value
* that this <code>Clob</code> represents. The string will overwrite the existing characters
* in the <code>Clob</code> object starting at the position
* <code>pos</code>. If the end of the <code>Clob</code> value is reached
* while writing the given string, then the length of the <code>Clob</code>
* value will be increased to accommodate the extra characters.
* <p>
* <b>Note:</b> If the value specified for <code>pos</code>
* is greater then the length+1 of the <code>CLOB</code> value then the
* behavior is undefined. Some JDBC drivers may throw a
* <code>SQLException</code> while other drivers may support this
* operation.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 2.0 this feature is supported. <p>
*
* When built under JDK 1.6+ and the Clob instance is constructed as a
* result of calling JDBCConnection.createClob(), this operation affects
* only the client-side value; it has no effect upon a value stored in a
* database because JDBCConnection.createClob() constructs disconnected,
* initially empty Clob instances. To propagate the Clob value to a database
* in this case, it is required to supply the Clob instance to an updating
* or inserting setXXX method of a Prepared or Callable Statement, or to
* supply the Clob instance to an updateXXX method of an updateable
* ResultSet. <p>
*
* <b>Implementation Notes:</b><p>
*
* If the value specified for <code>pos</code>
* is greater than the length of the <code>CLOB</code> value, then
* the <code>CLOB</code> value is extended in length to accept the
* written characters and the undefined region up to <code>pos</code> is
* filled with space (' ') characters.<p>
*
* No attempt is made to ensure precise thread safety. Instead, volatile
* member field and local variable snapshot isolation semantics are
* implemented. This is expected to eliminate most issues related
* to race conditions, with the possible exception of concurrent
* invocation of free(). <p>
*
* In general, if an application may perform concurrent JDBCClob
* modifications and the integrity of the application depends on total order
* Clob modification semantics, then such operations should be synchronized
* on an appropriate monitor.<p>
*
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to this
* <code>CLOB</code> object; The first position is 1
* @param str the string to be written to the <code>CLOB</code>
* value that this <code>Clob</code> object represents
* @param offset the offset into <code>str</code> 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</code> value or if pos is less than 1
*
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.4, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public int setString(final long pos, final String str, final int offset,
final int len) throws SQLException {
checkReadonly();
final String data = getData();
if (str == null) {
throw JDBCUtil.nullArgument("str");
}
final int strlen = str.length();
final int dlen = data.length();
final int ipos = (int) (pos - 1);
if (offset == 0 && len == strlen && ipos == 0 && len >= dlen) {
setData(str);
return len;
}
if (offset < 0 || offset > strlen) {
throw JDBCUtil.outOfRangeArgument("offset: " + offset);
}
if (len < 0 || len > strlen - offset) {
throw JDBCUtil.outOfRangeArgument("len: " + len);
}
if (pos < MIN_POS || (pos - MIN_POS) > (Integer.MAX_VALUE - len)) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
final long endPos = (pos + len);
char[] chars;
if (pos > dlen) {
// 1.) 'datachars' + '\32\32\32...' + substring
chars = new char[(int) endPos - 1];
data.getChars(0, dlen, chars, 0);
for (int i = dlen; i < ipos; i++) {
chars[i] = ' ';
}
str.getChars(offset, offset + len, chars, ipos);
} else if (endPos > dlen) {
// 2.) 'datach...' + substring
chars = new char[(int) endPos - 1];
data.getChars(0, ipos, chars, 0);
str.getChars(offset, offset + len, chars, ipos);
} else {
// 3.) 'dat' + substring + 'rs'
chars = new char[dlen];
data.getChars(0, ipos, chars, 0);
str.getChars(offset, offset + len, chars, ipos);
final int dataOffset = ipos + len;
data.getChars(dataOffset, dlen, chars, dataOffset);
}
setData(new String(chars));
return len;
}
Retrieves a stream to be used to write ASCII characters to the
CLOB
value that this Clob
object represents,
starting at position pos
. Characters written to the stream
will overwrite the existing characters
in the Clob
object starting at the position
pos
. If the end of the Clob
value is reached
while writing characters to the stream, then the length of the Clob
value will be increased to accommodate the extra characters.
Note: If the value specified for pos
is greater than the length of the CLOB
value, then the
behavior is undefined. Some JDBC drivers may throw a
SQLException
while other drivers may support this
operation.
HSQLDB-Specific Information:
Starting with HSQLDB 2.0 this feature is supported.
When built under JDK 1.6+ and the Clob instance is constructed as a
result of calling JDBCConnection.createClob(), this operation affects
only the client-side value; it has no effect upon a value stored in a
database because JDBCConnection.createClob() constructs disconnected,
initially empty Clob instances. To propagate the Clob value to a database
in this case, it is required to supply the Clob instance to an updating
or inserting setXXX method of a Prepared or Callable Statement, or to
supply the Clob instance to an updateXXX method of an updatable
ResultSet.
Implementation Notes:
The data written to the stream does not appear in this
Clob until the stream is closed.
When the stream is closed, if the value specified for pos
is greater than the length of the CLOB
value, then
the CLOB
value is extended in length to accept the
written characters and the undefined region up to pos
is
filled with space (' ') characters.
Also, no attempt is made to ensure precise thread safety. Instead,
volatile member field and local variable snapshot isolation semantics
are implemented. This is expected to eliminate most issues related
to race conditions, with the possible exception of concurrent
invocation of free().
In general, if an application may perform concurrent JDBCClob
modifications and the integrity of the application depends on total order
Clob modification semantics, then such operations should be synchronized
on an appropriate monitor.
Params: - pos – the position at which to start writing to this
CLOB
object; The first position is 1
Throws: - SQLException – if there is an error accessing the
CLOB
value or if pos is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
See Also: Returns: the stream to which ASCII encoded characters can be written Since: JDK 1.4, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* Retrieves a stream to be used to write ASCII characters to the
* <code>CLOB</code> value that this <code>Clob</code> object represents,
* starting at position <code>pos</code>. Characters written to the stream
* will overwrite the existing characters
* in the <code>Clob</code> object starting at the position
* <code>pos</code>. If the end of the <code>Clob</code> value is reached
* while writing characters to the stream, then the length of the <code>Clob</code>
* value will be increased to accommodate the extra characters.
* <p>
* <b>Note:</b> If the value specified for <code>pos</code>
* is greater than the length of the <code>CLOB</code> value, then the
* behavior is undefined. Some JDBC drivers may throw a
* <code>SQLException</code> while other drivers may support this
* operation.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 2.0 this feature is supported. <p>
*
* When built under JDK 1.6+ and the Clob instance is constructed as a
* result of calling JDBCConnection.createClob(), this operation affects
* only the client-side value; it has no effect upon a value stored in a
* database because JDBCConnection.createClob() constructs disconnected,
* initially empty Clob instances. To propagate the Clob value to a database
* in this case, it is required to supply the Clob instance to an updating
* or inserting setXXX method of a Prepared or Callable Statement, or to
* supply the Clob instance to an updateXXX method of an updatable
* ResultSet. <p>
*
* <b>Implementation Notes:</b><p>
*
* The data written to the stream does not appear in this
* Clob until the stream is closed. <p>
*
* When the stream is closed, if the value specified for <code>pos</code>
* is greater than the length of the <code>CLOB</code> value, then
* the <code>CLOB</code> value is extended in length to accept the
* written characters and the undefined region up to <code>pos</code> is
* filled with space (' ') characters. <p>
*
* Also, no attempt is made to ensure precise thread safety. Instead,
* volatile member field and local variable snapshot isolation semantics
* are implemented. This is expected to eliminate most issues related
* to race conditions, with the possible exception of concurrent
* invocation of free(). <p>
*
* In general, if an application may perform concurrent JDBCClob
* modifications and the integrity of the application depends on total order
* Clob modification semantics, then such operations should be synchronized
* on an appropriate monitor.<p>
*
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to this
* <code>CLOB</code> object; The first position is 1
* @return the stream to which ASCII encoded characters can be written
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value or if pos is less than 1
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getAsciiStream
*
* @since JDK 1.4, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public java.io.OutputStream setAsciiStream(final long pos)
throws SQLException {
checkReadonly();
checkClosed();
if (pos < MIN_POS || pos > MAX_POS) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
return new java.io.ByteArrayOutputStream() {
boolean closed = false;
public synchronized void close() throws java.io.IOException {
if (closed) {
return;
}
closed = true;
final byte[] bytes = super.buf;
final int length = super.count;
super.buf = null;
super.count = 0;
try {
final String str = new String(bytes, 0, length,
JavaSystem.CS_US_ASCII);
JDBCClob.this.setString(pos, str);
} catch (Throwable e) {
throw JavaSystem.toIOException(e);
}
}
};
}
Retrieves a stream to be used to write a stream of Unicode characters
to the CLOB
value that this Clob
object
represents, at position pos
. Characters written to the stream
will overwrite the existing characters
in the Clob
object starting at the position
pos
. If the end of the Clob
value is reached
while writing characters to the stream, then the length of the Clob
value will be increased to accommodate the extra characters.
Note: If the value specified for pos
is greater then the length+1 of the CLOB
value then the
behavior is undefined. Some JDBC drivers may throw a
SQLException
while other drivers may support this
operation.
HSQLDB-Specific Information:
Starting with HSQLDB 2.0 this feature is supported.
When built under JDK 1.6+ and the Clob instance is constructed as a
result of calling JDBCConnection.createClob(), this operation affects
only the client-side value; it has no effect upon a value stored in a
database because JDBCConnection.createClob() constructs disconnected,
initially empty Clob instances. To propagate the Clob value to a database
in this case, it is required to supply the Clob instance to an updating
or inserting setXXX method of a Prepared or Callable Statement, or to
supply the Clob instance to an updateXXX method of an updateable
ResultSet.
Implementation Notes:
The data written to the stream does not appear in this
Clob until the stream is closed.
When the stream is closed, if the value specified for pos
is greater than the length of the CLOB
value, then
the CLOB
value is extended in length to accept the
written characters and the undefined region up to pos
is
filled with space (' ') characters.
Also, no attempt is made to ensure precise thread safety. Instead,
volatile member field and local variable snapshot isolation semantics
are implemented. This is expected to eliminate most issues related
to race conditions, with the possible exception of concurrent
invocation of free().
In general, if an application may perform concurrent JDBCClob
modifications and the integrity of the application depends on
total order Clob modification semantics, then such operations
should be synchronized on an appropriate monitor.
Params: - pos – the position at which to start writing to the
CLOB
value; The first position is 1
Throws: - SQLException – if there is an error accessing the
CLOB
value or if pos
is less than 1 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
See Also: Returns: a stream to which Unicode encoded characters can be written Since: JDK 1.4, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* Retrieves a stream to be used to write a stream of Unicode characters
* to the <code>CLOB</code> value that this <code>Clob</code> object
* represents, at position <code>pos</code>. Characters written to the stream
* will overwrite the existing characters
* in the <code>Clob</code> object starting at the position
* <code>pos</code>. If the end of the <code>Clob</code> value is reached
* while writing characters to the stream, then the length of the <code>Clob</code>
* value will be increased to accommodate the extra characters.
* <p>
* <b>Note:</b> If the value specified for <code>pos</code>
* is greater then the length+1 of the <code>CLOB</code> value then the
* behavior is undefined. Some JDBC drivers may throw a
* <code>SQLException</code> while other drivers may support this
* operation.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 2.0 this feature is supported. <p>
*
* When built under JDK 1.6+ and the Clob instance is constructed as a
* result of calling JDBCConnection.createClob(), this operation affects
* only the client-side value; it has no effect upon a value stored in a
* database because JDBCConnection.createClob() constructs disconnected,
* initially empty Clob instances. To propagate the Clob value to a database
* in this case, it is required to supply the Clob instance to an updating
* or inserting setXXX method of a Prepared or Callable Statement, or to
* supply the Clob instance to an updateXXX method of an updateable
* ResultSet. <p>
*
* <b>Implementation Notes:</b><p>
*
* The data written to the stream does not appear in this
* Clob until the stream is closed. <p>
*
* When the stream is closed, if the value specified for <code>pos</code>
* is greater than the length of the <code>CLOB</code> value, then
* the <code>CLOB</code> value is extended in length to accept the
* written characters and the undefined region up to <code>pos</code> is
* filled with space (' ') characters. <p>
*
* Also, no attempt is made to ensure precise thread safety. Instead,
* volatile member field and local variable snapshot isolation semantics
* are implemented. This is expected to eliminate most issues related
* to race conditions, with the possible exception of concurrent
* invocation of free(). <p>
*
* In general, if an application may perform concurrent JDBCClob
* modifications and the integrity of the application depends on
* total order Clob modification semantics, then such operations
* should be synchronized on an appropriate monitor.<p>
*
* </div>
* <!-- end release-specific documentation -->
*
* @param pos the position at which to start writing to the
* <code>CLOB</code> value; The first position is 1
*
* @return a stream to which Unicode encoded characters can be written
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value or if {@code pos} is less than 1
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getCharacterStream
*
* @since JDK 1.4, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public java.io.Writer setCharacterStream(final long pos)
throws SQLException {
checkReadonly();
checkClosed();
if (pos < MIN_POS || pos > MAX_POS) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
return new java.io.StringWriter() {
private boolean closed = false;
public synchronized void close() throws java.io.IOException {
if (closed) {
return;
}
closed = true;
final StringBuffer sb = super.getBuffer();
try {
JDBCClob.this.setStringBuffer(pos, sb, 0, sb.length());
} catch (SQLException se) {
throw JavaSystem.toIOException(se);
} finally {
sb.setLength(0);
sb.trimToSize();
}
}
};
}
Truncates the CLOB
value that this Clob
designates to have a length of len
characters.
Note: If the value specified for len
is greater than the length of the CLOB
value, then the
behavior is undefined. Some JDBC drivers may throw a
SQLException
while other drivers may support this
operation.
HSQLDB-Specific Information:
Starting with HSQLDB 2.0 this feature is fully supported.
When built under JDK 1.6+ and the Clob instance is constructed as a
result of calling JDBCConnection.createClob(), this operation affects
only the client-side value; it has no effect upon a value stored in a
database because JDBCConnection.createClob() constructs disconnected,
initially empty Blob instances. To propagate the truncated Clob value to
a database in this case, it is required to supply the Clob instance to
an updating or inserting setXXX method of a Prepared or Callable
Statement, or to supply the Blob instance to an updateXXX method of an
updateable ResultSet.
Implementation Notes:
HSQLDB throws an SQLException if the specified len is greater than the value returned by length
.
Params: - len – the length, in characters, to which the
CLOB
value
should be truncated
Throws: - SQLException – if there is an error accessing the
CLOB
value or if len is less than 0 - SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Since: JDK 1.4, HSQLDB 1.7.2 @revised JDK 1.6, HSQLDB 2.0
/**
* Truncates the <code>CLOB</code> value that this <code>Clob</code>
* designates to have a length of <code>len</code>
* characters.
* <p>
* <b>Note:</b> If the value specified for <code>len</code>
* is greater than the length of the <code>CLOB</code> value, then the
* behavior is undefined. Some JDBC drivers may throw a
* <code>SQLException</code> while other drivers may support this
* operation.
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 2.0 this feature is fully supported. <p>
*
* When built under JDK 1.6+ and the Clob instance is constructed as a
* result of calling JDBCConnection.createClob(), this operation affects
* only the client-side value; it has no effect upon a value stored in a
* database because JDBCConnection.createClob() constructs disconnected,
* initially empty Blob instances. To propagate the truncated Clob value to
* a database in this case, it is required to supply the Clob instance to
* an updating or inserting setXXX method of a Prepared or Callable
* Statement, or to supply the Blob instance to an updateXXX method of an
* updateable ResultSet. <p>
*
* <b>Implementation Notes:</b> <p>
*
* HSQLDB throws an SQLException if the specified <tt>len</tt> is greater
* than the value returned by {@link #length() length}. <p>
*
* </div>
* <!-- end release-specific documentation -->
*
* @param len the length, in characters, to which the <code>CLOB</code> value
* should be truncated
* @exception SQLException if there is an error accessing the
* <code>CLOB</code> value or if len is less than 0
*
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.4, HSQLDB 1.7.2
* @revised JDK 1.6, HSQLDB 2.0
*/
public void truncate(final long len) throws SQLException {
checkReadonly();
final String data = getData();
final long dlen = data.length();
if (len == dlen) {
return;
}
if (len < 0 || len > dlen) {
throw JDBCUtil.outOfRangeArgument("len: " + len);
}
setData(data.substring(0, (int) len));
}
//------------------------- JDBC 4.0 -----------------------------------
This method frees the Clob
object and releases the resources the resources
that it holds. The object is invalid once the free
method
is called.
After free
has been called, any attempt to invoke a
method other than free
will result in a SQLException
being thrown. If free
is called multiple times, the subsequent
calls to free
are treated as a no-op.
Throws: - SQLException – if an error occurs releasing
the Clob's resources
- SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Since: JDK 1.6, HSQLDB 2.0
/**
* This method frees the <code>Clob</code> object and releases the resources the resources
* that it holds. The object is invalid once the <code>free</code> method
* is called.
* <p>
* After <code>free</code> has been called, any attempt to invoke a
* method other than <code>free</code> will result in a <code>SQLException</code>
* being thrown. If <code>free</code> is called multiple times, the subsequent
* calls to <code>free</code> are treated as a no-op.
* <p>
* @throws SQLException if an error occurs releasing
* the Clob's resources
*
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.6, HSQLDB 2.0
*/
public synchronized void free() throws SQLException {
m_closed = true;
m_data = null;
}
Returns a Reader
object that contains a partial Clob
value, starting
with the character specified by pos, which is length characters in length.
Params: - pos – the offset to the first character of the partial value to
be retrieved. The first character in the Clob is at position 1.
- length – the length in characters of the partial value to be retrieved.
Throws: - SQLException – if pos is less than 1 or if pos is greater than the number of
characters in the
Clob
or if pos + length is greater than the number of
characters in the Clob
- SQLFeatureNotSupportedException – if the JDBC driver does not support
this method
Returns: Reader
through which the partial Clob
value can be read.Since: JDK 1.6, HSQLDB 2.0
/**
* Returns a <code>Reader</code> object that contains a partial <code>Clob</code> value, starting
* with the character specified by pos, which is length characters in length.
*
* @param pos the offset to the first character of the partial value to
* be retrieved. The first character in the Clob is at position 1.
* @param length the length in characters of the partial value to be retrieved.
* @return <code>Reader</code> through which the partial <code>Clob</code> value can be read.
* @throws SQLException if pos is less than 1 or if pos is greater than the number of
* characters in the <code>Clob</code> or if pos + length is greater than the number of
* characters in the <code>Clob</code>
*
* @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.6, HSQLDB 2.0
*/
public Reader getCharacterStream(long pos,
long length) throws SQLException {
if (length > Integer.MAX_VALUE) {
throw JDBCUtil.outOfRangeArgument("length: " + length);
}
final String data = getData();
final int dlen = data.length();
if (pos == MIN_POS && length == dlen) {
return new StringReader(data);
}
if (pos < MIN_POS || pos > dlen) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
final long startIndex = pos - 1;
if (length < 0 || length > dlen - startIndex) {
throw JDBCUtil.outOfRangeArgument("length: " + length);
}
final int endIndex = (int) (startIndex + length); // exclusive
final char[] chars = new char[(int) length];
data.getChars((int) startIndex, endIndex, chars, 0);
return new CharArrayReader(chars);
}
// ---------------------- internal implementation --------------------------
private static final long MIN_POS = 1L;
private static final long MAX_POS = 1L + (long) Integer.MAX_VALUE;
private boolean m_closed;
private String m_data;
private final boolean m_createdByConnection;
Constructs a new, read-only JDBCClob object wrapping the given character
sequence.
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
external 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.
Params: - data – the character sequence representing the Clob value
Throws: - SQLException – if the argument is null
/**
* Constructs a new, read-only 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
* external 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 JDBCUtil.nullArgument();
}
m_data = data;
m_createdByConnection = false;
}
Constructs a new, empty (zero-length), read/write JDBCClob object.
/**
* Constructs a new, empty (zero-length), read/write JDBCClob object.
*/
protected JDBCClob() {
m_data = "";
m_createdByConnection = true;
}
protected void checkReadonly() throws SQLException {
if (!m_createdByConnection) {
throw JDBCUtil.sqlException(ErrorCode.X_25006,
"Clob is read-only");
}
}
protected synchronized void checkClosed() throws SQLException {
if (m_closed) {
throw JDBCUtil.sqlException(ErrorCode.X_07501);
}
}
synchronized String getData() throws SQLException {
checkClosed();
return m_data;
}
private synchronized void setData(String data) throws SQLException {
checkClosed();
m_data = data;
}
Behaviour is identical to setString(long, String, int, int)
. Params: - pos – the position at which to start writing to this
CLOB
object; The first position is 1 - sb – the buffer to be written to the
CLOB
value that this Clob
object represents - offset – the offset into
sb
to start reading
the characters to be written - len – the number of characters to be written
Throws: - SQLException – if there is an error accessing the
CLOB
value or if pos is less than 1
Returns: the number of characters written
/**
* Behaviour is identical to {@link #setString(long, java.lang.String, int, int)}.
*
* @param pos the position at which to start writing to this
* <code>CLOB</code> object; The first position is 1
* @param sb the buffer to be written to the <code>CLOB</code>
* value that this <code>Clob</code> object represents
* @param offset the offset into <code>sb</code> 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</code> value or if pos is less than 1
*/
public int setStringBuffer(final long pos, final StringBuffer sb,
final int offset,
final int len) throws SQLException {
checkReadonly();
String data = getData();
if (sb == null) {
throw JDBCUtil.nullArgument("sb");
}
final int strlen = sb.length();
final int dlen = data.length();
final int ipos = (int) (pos - 1);
if (offset == 0 && len == strlen && ipos == 0 && len >= dlen) {
setData(sb.toString());
return len;
}
if (offset < 0 || offset > strlen) {
throw JDBCUtil.outOfRangeArgument("offset: " + offset);
}
if (len > strlen - offset) {
throw JDBCUtil.outOfRangeArgument("len: " + len);
}
if (pos < MIN_POS || (pos - MIN_POS) > (Integer.MAX_VALUE - len)) {
throw JDBCUtil.outOfRangeArgument("pos: " + pos);
}
final long endPos = (pos + len);
char[] chars;
if (pos > dlen) {
// 1.) 'datachars' + '\32\32\32...' + substring
chars = new char[(int) endPos - 1];
data.getChars(0, dlen, chars, 0);
for (int i = dlen; i < ipos; i++) {
chars[i] = ' ';
}
sb.getChars(offset, offset + len, chars, ipos);
} else if (endPos > dlen) {
// 2.) 'datach...' + substring
chars = new char[(int) endPos - 1];
data.getChars(0, ipos, chars, 0);
sb.getChars(offset, offset + len, chars, ipos);
} else {
// 3.) 'dat' + substring + 'rs'
chars = new char[dlen];
data.getChars(0, ipos, chars, 0);
sb.getChars(offset, offset + len, chars, ipos);
final int dataOffset = ipos + len;
data.getChars(dataOffset, dlen, chars, dataOffset);
}
setData(new String(chars));
return len;
}
}