001: /*
002:
003: Derby - Class org.apache.derby.iapi.types.SQLClob
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.types;
023:
024: import org.apache.derby.iapi.types.DataValueDescriptor;
025: import org.apache.derby.iapi.types.TypeId;
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.reference.SQLState;
029: import org.apache.derby.iapi.services.io.StoredFormatIds;
030:
031: import org.apache.derby.iapi.services.sanity.SanityManager;
032:
033: import java.sql.Blob;
034: import java.sql.Clob;
035: import java.sql.Date;
036: import java.sql.SQLException;
037: import java.sql.Time;
038: import java.sql.Timestamp;
039: import java.util.Calendar;
040:
041: /**
042: * SQLClob uses SQLVarchar by inheritance.
043: * It satisfies the DataValueDescriptor interfaces (i.e., OrderableDataType). It implements a String
044: * holder, e.g. for storing a column value; it can be specified
045: * when constructed to not allow nulls. Nullability cannot be changed
046: * after construction.
047: * <p>
048: * Because OrderableDataType is a subclass of DataType,
049: * SQLLongvarchar can play a role in either a DataType/ValueRow
050: * or a OrderableDataType/KeyRow, interchangeably.
051: */
052: public class SQLClob extends SQLVarchar {
053: /*
054: * DataValueDescriptor interface.
055: *
056: * These are actually all implemented in the super-class, but we need
057: * to duplicate some of them here so they can be called by byte-code
058: * generation, which needs to know the class the method appears in.
059: */
060:
061: public String getTypeName() {
062: return TypeId.CLOB_NAME;
063: }
064:
065: /*
066: * DataValueDescriptor interface
067: */
068:
069: /** @see DataValueDescriptor#getClone */
070: public DataValueDescriptor getClone() {
071: try {
072: return new SQLClob(getString());
073: } catch (StandardException se) {
074: if (SanityManager.DEBUG)
075: SanityManager.THROWASSERT("Unexpected exception " + se);
076: return null;
077: }
078: }
079:
080: /**
081: * @see DataValueDescriptor#getNewNull
082: *
083: */
084: public DataValueDescriptor getNewNull() {
085: return new SQLClob();
086: }
087:
088: /*
089: * Storable interface, implies Externalizable, TypedFormat
090: */
091:
092: /**
093: Return my format identifier.
094:
095: @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
096: */
097: public int getTypeFormatId() {
098: return StoredFormatIds.SQL_CLOB_ID;
099: }
100:
101: /*
102: * constructors
103: */
104:
105: public SQLClob() {
106: }
107:
108: public SQLClob(String val) {
109: super (val);
110: }
111:
112: /*
113: * DataValueDescriptor interface
114: */
115:
116: /* @see DataValueDescriptor#typePrecedence */
117: public int typePrecedence() {
118: return TypeId.CLOB_PRECEDENCE;
119: }
120:
121: /*
122: ** disable conversions to/from most types for CLOB.
123: ** TEMP - real fix is to re-work class hierachy so
124: ** that CLOB is towards the root, not at the leaf.
125: */
126:
127: public Object getObject() throws StandardException {
128: throw dataTypeConversion("java.lang.Object");
129: }
130:
131: public boolean getBoolean() throws StandardException {
132: throw dataTypeConversion("boolean");
133: }
134:
135: public byte getByte() throws StandardException {
136: throw dataTypeConversion("byte");
137: }
138:
139: public short getShort() throws StandardException {
140: throw dataTypeConversion("short");
141: }
142:
143: public int getInt() throws StandardException {
144: throw dataTypeConversion("int");
145: }
146:
147: public long getLong() throws StandardException {
148: throw dataTypeConversion("long");
149: }
150:
151: public float getFloat() throws StandardException {
152: throw dataTypeConversion("float");
153: }
154:
155: public double getDouble() throws StandardException {
156: throw dataTypeConversion("double");
157: }
158:
159: public int typeToBigDecimal() throws StandardException {
160: throw dataTypeConversion("java.math.BigDecimal");
161: }
162:
163: public byte[] getBytes() throws StandardException {
164: throw dataTypeConversion("byte[]");
165: }
166:
167: public Date getDate(java.util.Calendar cal)
168: throws StandardException {
169: throw dataTypeConversion("java.sql.Date");
170: }
171:
172: public Time getTime(java.util.Calendar cal)
173: throws StandardException {
174: throw dataTypeConversion("java.sql.Time");
175: }
176:
177: public Timestamp getTimestamp(java.util.Calendar cal)
178: throws StandardException {
179: throw dataTypeConversion("java.sql.Timestamp");
180: }
181:
182: /**
183: * Gets a trace representation of the CLOB for debugging.
184: *
185: * @return a trace representation of the CLOB.
186: */
187: public final String getTraceString() throws StandardException {
188: // Check if the value is SQL NULL.
189: if (isNull()) {
190: return "NULL";
191: }
192:
193: // Check if we have a stream.
194: if (getStream() != null) {
195: return ("CLOB(" + getStream().toString() + ")");
196: }
197:
198: return ("CLOB(" + getLength() + ")");
199: }
200:
201: /**
202: * Normalization method - this method may be called when putting
203: * a value into a SQLClob, for example, when inserting into a SQLClob
204: * column. See NormalizeResultSet in execution.
205: * Per the SQL standard ,if the clob column is not big enough to
206: * hold the value being inserted,truncation error will result
207: * if there are trailing non-blanks. Truncation of trailing blanks
208: * is allowed.
209: * @param desiredType The type to normalize the source column to
210: * @param sourceValue The value to normalize
211: *
212: *
213: * @exception StandardException Thrown for null into
214: * non-nullable column, and for
215: * truncation error
216: */
217:
218: public void normalize(DataTypeDescriptor desiredType,
219: DataValueDescriptor sourceValue) throws StandardException {
220: // if sourceValue is of type clob, and has a stream,
221: // dont materialize it here (as the goal of using a stream is to
222: // not have to materialize whole object in memory in the server),
223: // but instead truncation checks will be done when data is streamed in.
224: // (see ReaderToUTF8Stream)
225: // if sourceValue is not a stream, then follow the same
226: // protocol as varchar type for normalization
227: if (sourceValue instanceof SQLClob) {
228: SQLClob clob = (SQLClob) sourceValue;
229: if (clob.stream != null) {
230: copyState(clob);
231: return;
232: }
233: }
234:
235: super .normalize(desiredType, sourceValue);
236: }
237:
238: public void setValue(Time theValue, Calendar cal)
239: throws StandardException {
240: throwLangSetMismatch("java.sql.Time");
241: }
242:
243: public void setValue(Timestamp theValue, Calendar cal)
244: throws StandardException {
245: throwLangSetMismatch("java.sql.Timestamp");
246: }
247:
248: public void setValue(Date theValue, Calendar cal)
249: throws StandardException {
250: throwLangSetMismatch("java.sql.Date");
251: }
252:
253: public void setBigDecimal(Number bigDecimal)
254: throws StandardException {
255: throwLangSetMismatch("java.math.BigDecimal");
256: }
257:
258: public void setValue(int theValue) throws StandardException {
259: throwLangSetMismatch("int");
260: }
261:
262: public void setValue(double theValue) throws StandardException {
263: throwLangSetMismatch("double");
264: }
265:
266: public void setValue(float theValue) throws StandardException {
267: throwLangSetMismatch("float");
268: }
269:
270: public void setValue(short theValue) throws StandardException {
271: throwLangSetMismatch("short");
272: }
273:
274: public void setValue(long theValue) throws StandardException {
275: throwLangSetMismatch("long");
276: }
277:
278: public void setValue(byte theValue) throws StandardException {
279: throwLangSetMismatch("byte");
280: }
281:
282: public void setValue(boolean theValue) throws StandardException {
283: throwLangSetMismatch("boolean");
284: }
285:
286: public void setValue(byte[] theValue) throws StandardException {
287: throwLangSetMismatch("byte[]");
288: }
289:
290: /**
291: * Set the value from an non-null Java.sql.Clob object.
292: */
293: final void setObject(Object theValue) throws StandardException {
294: Clob vc = (Clob) theValue;
295:
296: try {
297: long vcl = vc.length();
298: if (vcl < 0L || vcl > Integer.MAX_VALUE)
299: throw this .outOfRange();
300:
301: setValue(new ReaderToUTF8Stream(vc.getCharacterStream(),
302: (int) vcl, 0, TypeId.CLOB_NAME), (int) vcl);
303:
304: } catch (SQLException e) {
305: throw dataTypeConversion("DAN-438-tmp");
306: }
307: }
308: }
|