KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > jdbc > EmbedClob


1 /*
2
3    Derby - Class org.apache.derby.impl.jdbc.EmbedClob
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22
23 package org.apache.derby.impl.jdbc;
24
25 import org.apache.derby.iapi.reference.SQLState;
26 import org.apache.derby.iapi.error.StandardException;
27 import org.apache.derby.iapi.services.sanity.SanityManager;
28 import org.apache.derby.iapi.types.DataValueDescriptor;
29 import org.apache.derby.iapi.types.Resetable;
30 import org.apache.derby.impl.jdbc.ConnectionChild;
31 import org.apache.derby.impl.jdbc.EmbedConnection;
32 import org.apache.derby.impl.jdbc.Util;
33 import org.apache.derby.impl.jdbc.UTF8Reader;
34 import org.apache.derby.impl.jdbc.ReaderToAscii;
35
36 import java.io.InputStream JavaDoc;
37 import java.io.InputStreamReader JavaDoc;
38 import java.io.StringReader JavaDoc;
39 import java.io.Reader JavaDoc;
40 import java.io.IOException JavaDoc;
41 import java.io.EOFException JavaDoc;
42 import java.sql.SQLException JavaDoc;
43 import java.sql.Clob JavaDoc;
44
45 /**
46     Implements java.sql.Clob (see the JDBC 2.0 spec).
47     A clob sits on top of a CHAR, VARCHAR or LONG VARCHAR column.
48     If its data is small (less than 1 page) it is a byte array taken from
49     the SQLChar class. If it is large (more than 1 page) it is a long column
50     in the database. The long column is accessed as a stream, and is implemented
51     in store as an OverflowInputStream. The Resetable interface allows sending
52     messages to that stream to initialize itself (reopen its container and
53     lock the corresponding row) and to reset itself to the beginning.
54
55     NOTE: In the case that the data is large, it is represented as a stream.
56     This stream can be returned to the user in the getAsciiStream() method.
57     This means that we have limited control over the state of the stream,
58     since the user can read bytes from it at any time. Thus all methods
59     here reset the stream to the beginning before doing any work.
60     CAVEAT: The methods may not behave correctly if a user sets up
61     multiple threads and sucks data from the stream (returned from
62     getAsciiStream()) at the same time as calling the Clob methods.
63
64   <P><B>Supports</B>
65    <UL>
66    <LI> JSR169 - no subsetting for java.sql.Clob
67    <LI> JDBC 2.0
68    <LI> JDBC 3.0 - no new dependencies on new JDBC 3.0 or JDK 1.4 classes,
69         new update methods can safely be added into implementation.
70    </UL>
71  */

72 final class EmbedClob extends ConnectionChild implements Clob JavaDoc
73 {
74     // clob is either a string or stream
75
private boolean isString;
76     private InputStream JavaDoc myStream;
77     private String JavaDoc myString;
78     
79     //This boolean variable indicates whether the Clob object has
80
//been invalidated by calling free() on it
81
private boolean isValid = true;
82
83     /**
84      * This constructor is used to create a empty Clob object. It is used by the
85      * Connection interface method createClob().
86      *
87      * @param clobString A String object containing the data to be stores in the
88      * Clob.
89      *
90      * @param con The Connection object associated with this EmbedClob object.
91      *
92      */

93     
94     EmbedClob(String JavaDoc clobString,EmbedConnection con) {
95         super(con);
96         myString = clobString;
97         isString = true;
98     }
99     
100     /*
101     This constructor should only be called by EmbedResultSet.getClob
102     */

103     protected EmbedClob(DataValueDescriptor dvd, EmbedConnection con)
104         throws StandardException
105     {
106         super(con);
107         // if the underlying column is null, ResultSet.getClob will return null,
108
// never should get this far
109
if (SanityManager.DEBUG)
110             SanityManager.ASSERT(!dvd.isNull(), "clob is created on top of a null column");
111
112         myStream = dvd.getStream();
113         if (myStream == null)
114         {
115             isString = true;
116            myString = dvd.getString();
117             if (SanityManager.DEBUG)
118                 SanityManager.ASSERT(myString != null,"clob has a null value underneath");
119         }
120         else
121         {
122             /*
123              We are expecting this stream to be a FormatIdInputStream with an
124              OverflowInputStream inside. FormatIdInputStream implements
125              Resetable, as does OverflowInputStream. This should be the case
126              when retrieving data from a long column. However, SQLChar, which is
127              the class implementing the getStream() method for dvd.getStream(),
128              does not guarantee this for us. In particular, the logging system
129              (see StoredPage.logColumn) calls setStream with an argument that
130              is sometimes a RememberBytesInputStream on a SQLChar object
131              (e.g. see test repStreaming.sql). However, such a SQLChar
132              object is going to the log buffer, NOT back to the user, so it
133              should not break the ASSERT below.
134              */

135             if (SanityManager.DEBUG)
136                 SanityManager.ASSERT(myStream instanceof Resetable);
137
138             try {
139                 ((Resetable) myStream).initStream();
140             } catch (StandardException se) {
141                 if (se.getMessageId().equals(SQLState.DATA_CONTAINER_CLOSED)) {
142                     throw StandardException
143                             .newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
144                 }
145             }
146         }
147     }
148
149
150   /**
151    * Returns the number of characters
152    * in the <code>CLOB</code> value
153    * designated by this <code>Clob</code> object.
154    * @return length of the <code>CLOB</code> in characters
155    * @exception SQLException if there is an error accessing the
156    * length of the <code>CLOB</code>
157    */

158
159     public long length() throws SQLException JavaDoc
160     {
161         //call checkValidity to exit by throwing a SQLException if
162
//the Clob object has been freed by calling free() on it
163
checkValidity();
164         // if we have a string, not a stream
165
if (isString)
166             return myString.length();
167
168
169         Object JavaDoc synchronization = getConnectionSynchronization();
170         synchronized (synchronization)
171         {
172             Reader clobReader = null;
173             setupContextStack();
174             try {
175
176                 clobReader = getCharacterStream();
177                 long clobLength = 0;
178                 for (;;)
179                 {
180                     long size = clobReader.skip(32 * 1024);
181                     if (size == -1)
182                         break;
183                     clobLength += size;
184                 }
185                 clobReader.close();
186                 clobReader = null;
187
188                 return clobLength;
189             }
190             catch (Throwable JavaDoc t)
191             {
192                 throw noStateChangeLOB(t);
193             }
194             finally
195             {
196                 if (clobReader != null) {
197                     try {
198                         clobReader.close();
199                     } catch (IOException JavaDoc ioe) {
200                     }
201                 }
202                 restoreContextStack();
203             }
204         }
205     }
206
207   /**
208    * Returns a copy of the specified substring
209    * in the <code>CLOB</code> value
210    * designated by this <code>Clob</code> object.
211    * The substring begins at position
212    * <code>pos</code> and has up to <code>length</code> consecutive
213    * characters. The starting position must be between 1 and the length
214    * of the CLOB plus 1. This allows for zero-length CLOB values, from
215    * which only zero-length substrings can be returned.
216    * If a larger length is requested than there are characters available,
217    * characters from the start position to the end of the CLOB are returned.
218    * @param pos the first character of the substring to be extracted.
219    * The first character is at position 1.
220    * @param length the number of consecutive characters to be copied
221    * @return a <code>String</code> that is the specified substring in
222    * the <code>CLOB</code> value designated by this <code>Clob</code> object
223    * @exception SQLException if there is an error accessing the
224    * <code>CLOB</code>
225
226    * NOTE: If the starting position is the length of the CLOB plus 1,
227    * zero characters are returned regardless of the length requested.
228    */

229     public String JavaDoc getSubString(long pos, int length) throws SQLException JavaDoc
230     {
231         //call checkValidity to exit by throwing a SQLException if
232
//the Clob object has been freed by calling free() on it
233
checkValidity();
234         
235         if (pos < 1)
236             throw Util.generateCsSQLException(
237                 SQLState.BLOB_BAD_POSITION, new Long JavaDoc(pos));
238         if (length < 0)
239             throw Util.generateCsSQLException(
240                 SQLState.BLOB_NONPOSITIVE_LENGTH, new Integer JavaDoc(length));
241
242         // if we have a string, not a stream
243
if (isString)
244         {
245             int sLength = myString.length();
246             if (sLength + 1 < pos)
247                 throw Util.generateCsSQLException(
248                     SQLState.BLOB_POSITION_TOO_LARGE, new Long JavaDoc(pos));
249             int endIndex = ((int) pos) + length - 1;
250             // cannot go over length of string
251
return myString.substring(((int) pos) - 1, (sLength > endIndex ? endIndex : sLength));
252         }
253
254         Object JavaDoc synchronization = getConnectionSynchronization();
255         synchronized (synchronization)
256         {
257             setupContextStack();
258
259             UTF8Reader clobReader = null;
260             try {
261
262                 clobReader = getCharacterStreamAtPos(pos, synchronization);
263                 if (clobReader == null)
264                     throw StandardException.newException(SQLState.BLOB_POSITION_TOO_LARGE, new Long JavaDoc(pos));
265
266                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(length);
267                 int remainToRead = length;
268                 while (remainToRead > 0) {
269
270                     int read = clobReader.readInto(sb, remainToRead);
271                     if (read == -1)
272                         break;
273
274                     remainToRead -= read;
275                 }
276                 clobReader.close();
277                 clobReader = null;
278
279                 return sb.toString();
280             }
281             catch (Throwable JavaDoc t)
282             {
283                 throw noStateChangeLOB(t);
284             }
285             finally
286             {
287                 if (clobReader != null)
288                     clobReader.close();
289                 restoreContextStack();
290             }
291         }
292     }
293
294
295   /**
296    * Gets the <code>Clob</code> contents as a Unicode stream.
297    * @return a Unicode stream containing the <code>CLOB</code> data
298    * @exception SQLException if there is an error accessing the
299    * <code>CLOB</code>
300    */

301
302     public java.io.Reader JavaDoc getCharacterStream() throws SQLException JavaDoc
303     {
304         //call checkValidity to exit by throwing a SQLException if
305
//the Clob object has been freed by calling free() on it
306
checkValidity();
307
308         // if we have a string, not a stream
309
if (isString)
310         {
311             return new StringReader JavaDoc(myString);
312         }
313
314
315         Object JavaDoc synchronization = getConnectionSynchronization();
316         synchronized (synchronization)
317         {
318             setupContextStack();
319
320             try {
321                 return getCharacterStreamAtPos(1, synchronization);
322             }
323             catch (Throwable JavaDoc t)
324             {
325                 throw noStateChangeLOB(t);
326             }
327             finally
328             {
329                 restoreContextStack();
330             }
331         }
332     }
333
334
335   /**
336    * Gets the <code>CLOB</code> value designated by this <code>Clob</code>
337    * object as a stream of Ascii bytes.
338    * @return an ascii stream containing the <code>CLOB</code> data
339    * @exception SQLException if there is an error accessing the
340    * <code>CLOB</code> value
341    */

342
343     public java.io.InputStream JavaDoc getAsciiStream() throws SQLException JavaDoc
344     {
345                 //call checkValidity to exit by throwing a SQLException if
346
//the Clob object has been freed by calling free() on it
347
checkValidity();
348         return new ReaderToAscii(getCharacterStream());
349     }
350
351     private UTF8Reader getCharacterStreamAtPos(long position, Object JavaDoc synchronization)
352         throws IOException JavaDoc, StandardException
353     {
354         ((Resetable)myStream).resetStream();
355         UTF8Reader clobReader = new UTF8Reader(myStream, 0, this, synchronization);
356
357         // skip to the correct position (pos is one based)
358
long remainToSkip = position - 1;
359         while (remainToSkip > 0) {
360             long skipBy = clobReader.skip(remainToSkip);
361             if (skipBy == -1)
362                 return null;
363
364             remainToSkip -= skipBy;
365         }
366
367         return clobReader;
368     }
369
370
371   /**
372    * Determines the character position at which the specified substring
373    * <code>searchstr</code> appears in the <code>CLOB</code>. The search
374    * begins at position <code>start</code>.
375    * @param searchStr the substring for which to search
376    * @param start the position at which to begin searching; the first position
377    * is 1
378    * @return the position at which the substring appears, else -1; the first
379    * position is 1
380    * @exception SQLException if there is an error accessing the
381    * <code>CLOB</code> value
382    */

383     public long position(String JavaDoc searchStr, long start)
384         throws SQLException JavaDoc
385     {
386         //call checkValidity to exit by throwing a SQLException if
387
//the Clob object has been freed by calling free() on it
388
checkValidity();
389         
390         boolean pushStack = false;
391         try
392         {
393             if (start < 1)
394                 throw StandardException.newException(
395                     SQLState.BLOB_BAD_POSITION, new Long JavaDoc(start));
396             if (searchStr == null)
397                 throw StandardException.newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
398             if (searchStr == "")
399                 return start; // match DB2's SQL LOCATE function
400

401             // if we have a string, not a stream
402
if (isString)
403             {
404                 // avoid truncation errors in the cast of start to an int.
405
if (start > myString.length())
406                     return -1;
407
408                 int result = myString.indexOf(searchStr, (int) start-1);
409                 return result < 0 ? -1 : result + 1;
410             }
411             else // we have a stream
412
{
413                 Object JavaDoc synchronization = getConnectionSynchronization();
414                 synchronized (synchronization)
415                 {
416                     pushStack = !getEmbedConnection().isClosed();
417                     if (pushStack)
418                         setupContextStack();
419
420                     char[] tmpClob = new char[256];
421                     int patternLength = searchStr.length();
422
423 restartPattern:
424                     for (;;) {
425
426                     //System.out.println("RESET " + start);
427
UTF8Reader clobReader = getCharacterStreamAtPos(start, synchronization);
428                         if (clobReader == null)
429                             return -1;
430
431
432
433                         // start of any match of the complete pattern.
434

435                         int patternIndex = 0;
436                         char[] tmpPattern = null;
437                         boolean needPattern = true;
438
439                         // how many characters of the patter segment we have matched
440
int matchCount = 0;
441
442                         long currentPosition = start;
443                         int clobOffset = -1;
444                         int read = -1;
445
446                         // absolute position of a possible match
447
long matchPosition = -1;
448
449
450                         // absolute position of the next possible match
451
long nextBestMatchPosition = -1;
452                         //System.out.println("restartPattern: " + start);
453

454
455 search:
456                         for (;;)
457                         {
458                             //System.out.println("search: " + needPattern + " -- " + clobOffset);
459
if (needPattern) {
460
461                                 String JavaDoc tmpPatternS;
462                                 if ((patternLength - patternIndex) > 256)
463                                     tmpPatternS = searchStr.substring(patternIndex, 256);
464                                 else
465                                     tmpPatternS = searchStr;
466
467                                 tmpPattern = tmpPatternS.toCharArray();
468                                 needPattern = false;
469                                 matchCount = 0;
470
471                             }
472
473                             if (clobOffset == -1) {
474                                 
475                                 read = clobReader.read(tmpClob, 0, tmpClob.length);
476                             //System.out.println("MORE DATA " + read);
477
if (read == -1)
478                                     return -1;
479
480                                 if (read == 0)
481                                     continue search;
482
483                                 clobOffset = 0;
484                             }
485
486
487                             // find matches within our two temp arrays.
488
compareArrays:
489                             for (; clobOffset < read; clobOffset++) {
490
491                                 //System.out.println("compareArrays " + clobOffset);
492

493                                 char clobC = tmpClob[clobOffset];
494
495
496                                 if (clobC == tmpPattern[matchCount])
497                                 {
498                                     if (matchPosition == -1) {
499                                         matchPosition = currentPosition + clobOffset;
500                                     }
501
502                                     matchCount++;
503
504                                     // have we matched the entire pattern segment
505
if (matchCount == tmpPattern.length)
506                                     {
507                                         // move onto the next segment.
508
patternIndex += tmpPattern.length;
509                                         if (patternIndex == patternLength) {
510                                             // complete match !!
511
clobReader.close();
512                                             //System.out.println("COMPLETE@" + matchPosition);
513
return matchPosition;
514                                         }
515
516                                         needPattern = true;
517                                         continue search;
518
519                                     }
520
521                                     if (clobC == tmpPattern[0]) {
522
523                                         // save the next best start position.
524

525                                         // must be the first character of the actual pattern
526
if (patternIndex == 0) {
527
528                                             // must not be just a repeat of the match of the first character
529
if (matchCount != 1) {
530
531                                                 // must not have a previous next best.
532

533                                                 if (nextBestMatchPosition == -1) {
534                                                     nextBestMatchPosition = currentPosition + clobOffset;
535                                                 }
536
537                                             }
538
539                                         }
540                                     }
541
542                                     continue compareArrays;
543                                 }
544                                 else
545                                 {
546                                     // not a match
547
//
548
//
549
if (matchPosition != -1) {
550                                         // failed after we matched some amount of the pattern
551
matchPosition = -1;
552
553                                         // See if we found a next best match
554
if (nextBestMatchPosition == -1)
555                                         {
556                                             // NO - just continue on, re-starting at this character
557

558                                             if (patternIndex != 0) {
559                                                 needPattern = true;
560                                                 continue search;
561                                             }
562                                         }
563                                         else if (nextBestMatchPosition >= currentPosition)
564                                         {
565                                             // restart in the current array
566
clobOffset = (int) (nextBestMatchPosition - currentPosition);
567                                             nextBestMatchPosition = -1;
568                                     
569                                             if (patternIndex != 0) {
570                                                 needPattern = true;
571                                                 continue search;
572                                             }
573                                         }
574                                         else
575                                         {
576                                             clobReader.close();
577                                             start = nextBestMatchPosition;
578                                             continue restartPattern;
579                                         }
580
581                                         clobOffset--; // since the continue will increment it
582
matchCount = 0;
583                                         continue compareArrays;
584                                     }
585                                     
586                                     // no current match, just continue
587
}
588                             }
589
590                             currentPosition += read;
591
592                             // indicates we need to read more data
593
clobOffset = -1;
594                         }
595                     }
596                 }
597             }
598         }
599         catch (Throwable JavaDoc t)
600         {
601             throw noStateChangeLOB(t);
602         }
603         finally
604         {
605             if (pushStack)
606                 restoreContextStack();
607         }
608
609     }
610
611
612   /**
613    * Determines the character position at which the specified
614    * <code>Clob</code> object <code>searchstr</code> appears in this
615    * <code>Clob</code> object. The search begins at position
616    * <code>start</code>.
617    * @param searchClob the <code>Clob</code> object for which to search
618    * @param start the position at which to begin searching; the first
619    * position is 1
620    * @return the position at which the <code>Clob</code> object appears,
621    * else -1; the first position is 1
622    * @exception SQLException if there is an error accessing the
623    * <code>CLOB</code> value
624    */

625
626     public long position(Clob JavaDoc searchClob, long start)
627         throws SQLException JavaDoc
628     {
629         //call checkValidity to exit by throwing a SQLException if
630
//the Clob object has been freed by calling free() on it
631
checkValidity();
632         
633         boolean pushStack = false;
634         try
635         {
636             if (start < 1)
637                 throw StandardException.newException(
638                     SQLState.BLOB_BAD_POSITION, new Long JavaDoc(start));
639             if (searchClob == null)
640                 throw StandardException.newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
641
642             synchronized (getConnectionSynchronization())
643             {
644                 char[] subPatternChar = new char[256];
645
646                 boolean seenOneCharacter = false;
647
648                 //System.out.println("BEGIN CLOB SEARCH @ " + start);
649

650 restartScan:
651                 for (;;) {
652
653                     long firstPosition = -1;
654
655                     Reader patternReader = searchClob.getCharacterStream();
656
657                     //System.out.println("RESTART CLOB SEARCH @ " + start);
658

659                     try {
660
661                         for (;;) {
662
663                             int read = patternReader.read(subPatternChar, 0, subPatternChar.length);
664                             if (read == -1) {
665                                 //empty pattern
666
if (!seenOneCharacter)
667                                     return start; // matches DB2 SQL LOCATE function
668

669                                 return firstPosition;
670                             }
671                             if (read == 0) {
672                                 //System.out.println("STUCK IN READ 0 HELL");
673
continue;
674                             }
675
676                             seenOneCharacter = true;
677
678                             String JavaDoc subPattern = new String JavaDoc(subPatternChar, 0, read);
679                     //System.out.println("START CLOB SEARCH @ " + start + " -- " + subPattern);
680
long position = position(subPattern, start);
681                     //System.out.println("DONE SUB CLOB SEARCH @ " + start + " -- " + position);
682
if (position == -1) {
683                                 // never seen any match
684
if (firstPosition == -1)
685                                     return -1;
686
687                                 start = firstPosition + 1;
688                                 continue restartScan;
689                             }
690
691                             if (firstPosition == -1)
692                                 firstPosition = position;
693                             else if (position != start) {
694                                 // must match at the first character of the segment
695
start = firstPosition + 1;
696                                 continue restartScan;
697                             }
698
699                             // read is the length of the subPattern string
700
start = position + read;
701                     }
702                     } finally {
703                         patternReader.close();
704                     }
705                 }
706             }
707         }
708         catch (Throwable JavaDoc t)
709         {
710             throw noStateChangeLOB(t);
711         }
712         finally
713         {
714             if (pushStack)
715                 restoreContextStack();
716         }
717
718     }
719
720
721     /*
722      If we have a stream, release the resources associated with it.
723      */

724     protected void finalize()
725     {
726         // System.out.println("finalizer called");
727
if (!isString)
728             ((Resetable)myStream).closeStream();
729     }
730
731
732     /**
733     Following methods are for the new JDBC 3.0 methods in java.sql.Clob
734     (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
735     package, so we don't have to have a new class in Local30.
736     The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
737     so this will work fine in jdbc2.0 configuration.
738     */

739
740     /////////////////////////////////////////////////////////////////////////
741
//
742
// JDBC 3.0 - New public methods
743
//
744
/////////////////////////////////////////////////////////////////////////
745

746     /**
747     * JDBC 3.0
748     *
749     * Writes the given Java String to the CLOB value that this Clob object designates
750     * at the position pos.
751     *
752     * @param pos - the position at which to start writing to the CLOB value that
753     * this Clob object represents
754     * @return the number of characters written
755     * @exception SQLException Feature not implemented for now.
756     */

757     public int setString(long pos, String JavaDoc parameterName)
758     throws SQLException JavaDoc
759     {
760         throw Util.notImplemented();
761     }
762
763     /**
764     * JDBC 3.0
765     *
766     * Writes len characters of str, starting at character offset, to the CLOB value
767     * that this Clob represents.
768     *
769     * @param pos - the position at which to start writing to this Clob object
770     * @param str - the string to be written to the CLOB value that this Clob designates
771     * @param offset - the offset into str to start reading the characters to be written
772     * @param len - the number of characters to be written
773     * @return the number of characters written
774     * @exception SQLException Feature not implemented for now.
775     */

776     public int setString(long pos, String JavaDoc str, int offset, int len)
777     throws SQLException JavaDoc
778     {
779         throw Util.notImplemented();
780     }
781
782     /**
783     * JDBC 3.0
784     *
785     * Retrieves a stream to be used to write Ascii characters to the CLOB
786     * value that this Clob object represents, starting at position pos.
787     *
788     * @param pos - the position at which to start writing to this Clob object
789     * @return the stream to which ASCII encoded characters can be written
790     * @exception SQLException Feature not implemented for now.
791     */

792     public java.io.OutputStream JavaDoc setAsciiStream(long pos)
793     throws SQLException JavaDoc
794     {
795                 throw Util.notImplemented();
796     }
797
798     /**
799     * JDBC 3.0
800     *
801     * Retrieves a stream to be used to write a stream of Unicode characters to the
802     * CLOB value that this Clob object represents, starting at position pos.
803     *
804     * @param pos - the position at which to start writing to this Clob object
805     * @return the stream to which Unicode encoded characters can be written
806     * @exception SQLException Feature not implemented for now.
807     */

808     public java.io.Writer JavaDoc setCharacterStream(long pos)
809     throws SQLException JavaDoc
810     {
811         throw Util.notImplemented();
812     }
813
814     /**
815     * JDBC 3.0
816     *
817     * Truncates the CLOB value that this Clob designates to have a length of len characters
818     *
819     * @param len - the length, in bytes, to which the CLOB value that this Blob
820     * value should be truncated
821     * @exception SQLException Feature not implemented for now.
822     */

823     public void truncate(long len)
824     throws SQLException JavaDoc
825     {
826         throw Util.notImplemented();
827     }
828
829     /////////////////////////////////////////////////////////////////////////
830
//
831
// JDBC 4.0 - New public methods
832
//
833
/////////////////////////////////////////////////////////////////////////
834
/**
835      * This method frees the <code>Clob</code> object and releases the resources the resources
836      * that it holds. The object is invalid once the <code>free</code> method
837      * is called. If <code>free</code> is called multiple times, the
838      * subsequent calls to <code>free</code> are treated as a no-op.
839      *
840      * @throws SQLException if an error occurs releasing
841      * the Clob's resources
842      */

843     public void free()
844         throws SQLException JavaDoc {
845         //calling free() on a already freed object is treated as a no-op
846
if (!isValid) return;
847         
848         //now that free has been called the Clob object is no longer
849
//valid
850
isValid = false;
851         
852         if (!isString)
853             ((Resetable)myStream).closeStream();
854         else
855             myString = null;
856     }
857
858     public java.io.Reader JavaDoc getCharacterStream(long pos, long length)
859         throws SQLException JavaDoc {
860         throw Util.notImplemented();
861     }
862
863     /*
864     **
865     */

866
867     static SQLException JavaDoc noStateChangeLOB(Throwable JavaDoc t) {
868         if (t instanceof StandardException)
869         {
870             // container closed means the blob or clob was accessed after commit
871
if (((StandardException) t).getMessageId().equals(SQLState.DATA_CONTAINER_CLOSED))
872             {
873                 t = StandardException.newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
874             }
875         }
876         return org.apache.derby.impl.jdbc.EmbedResultSet.noStateChangeException(t);
877     }
878         
879         /*
880          * Checks is isValid is true. If it is not true throws
881          * a SQLException stating that a method has been called on
882          * an invalid LOB object
883          *
884          * throws SQLException if isValid is not true.
885          */

886         private void checkValidity() throws SQLException JavaDoc{
887             if(!isValid)
888                 throw newSQLException(SQLState.LOB_OBJECT_INVALID);
889         }
890 }
891
Popular Tags