EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [EmbedClob.java]

nameclass, %method, %block, %line, %
EmbedClob.java100% (1/1)67%  (10/15)94%  (806/860)92%  (206/225)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EmbedClob100% (1/1)67%  (10/15)94%  (806/860)92%  (206/225)
EmbedClob (DataValueDescriptor, EmbedConnection): void 100% (1/1)96%  (51/53)99%  (13.9/14)
finalize (): void 100% (1/1)100% (8/8)100% (3/3)
getAsciiStream (): InputStream 100% (1/1)100% (6/6)100% (1/1)
getCharacterStream (): Reader 100% (1/1)100% (43/43)100% (10/10)
getCharacterStreamAtPos (long, Object): UTF8Reader 100% (1/1)100% (38/38)100% (9/9)
getSubString (long, int): String 100% (1/1)99%  (139/141)97%  (32/33)
length (): long 100% (1/1)94%  (68/72)87%  (20/23)
noStateChangeLOB (Throwable): SQLException 100% (1/1)100% (15/15)100% (4/4)
position (Clob, long): long 100% (1/1)91%  (144/158)95%  (33.4/35)
position (String, long): long 100% (1/1)93%  (294/316)91%  (79.8/88)
setAsciiStream (long): OutputStream 0%   (0/1)0%   (0/2)0%   (0/1)
setCharacterStream (long): Writer 0%   (0/1)0%   (0/2)0%   (0/1)
setString (long, String): int 0%   (0/1)0%   (0/2)0%   (0/1)
setString (long, String, int, int): int 0%   (0/1)0%   (0/2)0%   (0/1)
truncate (long): void 0%   (0/1)0%   (0/2)0%   (0/1)

1/*
2 
3   Derby - Class org.apache.derby.impl.jdbc.EmbedClob
4 
5   Copyright 2000, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21 
22package org.apache.derby.impl.jdbc;
23 
24import org.apache.derby.iapi.reference.SQLState;
25import org.apache.derby.iapi.error.StandardException;
26import org.apache.derby.iapi.services.sanity.SanityManager;
27import org.apache.derby.iapi.types.DataValueDescriptor;
28import org.apache.derby.iapi.types.Resetable;
29import org.apache.derby.impl.jdbc.ConnectionChild;
30import org.apache.derby.impl.jdbc.EmbedConnection;
31import org.apache.derby.impl.jdbc.Util;
32import org.apache.derby.impl.jdbc.UTF8Reader;
33import org.apache.derby.impl.jdbc.ReaderToAscii;
34 
35import java.io.InputStream;
36import java.io.InputStreamReader;
37import java.io.StringReader;
38import java.io.Reader;
39import java.io.IOException;
40import java.io.EOFException;
41import java.sql.SQLException;
42import java.sql.Clob;
43 
44/**
45    Implements java.sql.Clob (see the JDBC 2.0 spec).
46    A clob sits on top of a CHAR, VARCHAR or LONG VARCHAR column.
47    If its data is small (less than 1 page) it is a byte array taken from
48    the SQLChar class. If it is large (more than 1 page) it is a long column
49    in the database. The long column is accessed as a stream, and is implemented
50    in store as an OverflowInputStream.  The Resetable interface allows sending
51    messages to that stream to initialize itself (reopen its container and
52    lock the corresponding row) and to reset itself to the beginning.
53 
54    NOTE: In the case that the data is large, it is represented as a stream.
55    This stream can be returned to the user in the getAsciiStream() method.
56    This means that we have limited control over the state of the stream,
57    since the user can read bytes from it at any time.  Thus all methods
58    here reset the stream to the beginning before doing any work.
59    CAVEAT: The methods may not behave correctly if a user sets up
60    multiple threads and sucks data from the stream (returned from
61    getAsciiStream()) at the same time as calling the Clob methods.
62 
63  <P><B>Supports</B>
64   <UL>
65   <LI> JSR169 - no subsetting for java.sql.Clob
66   <LI> JDBC 2.0
67   <LI> JDBC 3.0 - no new dependencies on new JDBC 3.0 or JDK 1.4 classes,
68        new update methods can safely be added into implementation.
69   </UL>
70 */
71final class EmbedClob extends ConnectionChild implements Clob
72{
73    // clob is either a string or stream
74    private boolean         isString;
75    private InputStream     myStream;
76    private String          myString;
77    
78    //This boolean variable indicates whether the Clob object has
79    //been invalidated by calling free() on it
80    private boolean isValid = true;
81 
82    /**
83     * This constructor is used to create a empty Clob object. It is used by the
84     * Connection interface method createClob().
85     * 
86     * @param clobString A String object containing the data to be stores in the 
87     *        Clob.
88     *
89     * @param con The Connection object associated with this EmbedClob object.
90     *
91     */
92    
93    EmbedClob(String clobString,EmbedConnection con) {
94        super(con);
95        myString = clobString;
96        isString = true;
97    }
98    
99    /*
100    This constructor should only be called by EmbedResultSet.getClob
101    */
102    protected EmbedClob(DataValueDescriptor dvd, EmbedConnection con)
103        throws StandardException
104    {
105        super(con);
106        // if the underlying column is null, ResultSet.getClob will return null,
107        // never should get this far
108        if (SanityManager.DEBUG)
109            SanityManager.ASSERT(!dvd.isNull(), "clob is created on top of a null column");
110 
111        myStream = dvd.getStream();
112        if (myStream == null)
113        {
114            isString = true;
115           myString = dvd.getString();
116            if (SanityManager.DEBUG)
117                SanityManager.ASSERT(myString != null,"clob has a null value underneath");
118        }
119        else
120        {
121            /*
122             We are expecting this stream to be a FormatIdInputStream with an
123             OverflowInputStream inside. FormatIdInputStream implements
124             Resetable, as does OverflowInputStream. This should be the case
125             when retrieving data from a long column. However, SQLChar, which is
126             the class implementing the getStream() method for dvd.getStream(),
127             does not guarantee this for us. In particular, the logging system
128             (see StoredPage.logColumn) calls setStream with an argument that
129             is sometimes a RememberBytesInputStream on a SQLChar object
130             (e.g. see test repStreaming.sql). However, such a SQLChar
131             object is going to the log buffer, NOT back to the user, so it
132             should not break the ASSERT below.
133             */
134            if (SanityManager.DEBUG)
135                SanityManager.ASSERT(myStream instanceof Resetable);
136 
137            try {
138                ((Resetable) myStream).initStream();
139            } catch (StandardException se) {
140                if (se.getMessageId().equals(SQLState.DATA_CONTAINER_CLOSED)) {
141                    throw StandardException
142                            .newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
143                }
144            }
145        }
146    }
147 
148 
149  /**
150   * Returns the number of characters
151   * in the <code>CLOB</code> value
152   * designated by this <code>Clob</code> object.
153   * @return length of the <code>CLOB</code> in characters
154   * @exception SQLException if there is an error accessing the
155   * length of the <code>CLOB</code>
156   */
157 
158    public long length() throws SQLException
159    {
160        //call checkValidity to exit by throwing a SQLException if
161        //the Clob object has been freed by calling free() on it
162        checkValidity();
163        // if we have a string, not a stream
164        if (isString)
165            return myString.length();
166 
167 
168                Object synchronization = getConnectionSynchronization();
169        synchronized (synchronization)
170        {
171                        Reader clobReader = null;
172            setupContextStack();
173                        try {
174 
175                                clobReader = getCharacterStream();
176                long clobLength = 0;
177                for (;;)
178                {
179                    long size = clobReader.skip(32 * 1024);
180                    if (size == -1)
181                        break;
182                    clobLength += size;
183                }
184                                clobReader.close();
185                                clobReader = null;
186 
187                                return clobLength;
188                        }
189                        catch (Throwable t)
190                        {
191                                throw noStateChangeLOB(t);
192                        }
193                        finally
194                        {
195                                if (clobReader != null) {
196                                        try {
197                                                clobReader.close();
198                                        } catch (IOException ioe) {
199                                        }
200                                }
201                                restoreContextStack();
202                        }
203                }
204        }
205 
206  /**
207   * Returns a copy of the specified substring
208   * in the <code>CLOB</code> value
209   * designated by this <code>Clob</code> object.
210   * The substring begins at position
211   * <code>pos</code> and has up to <code>length</code> consecutive
212   * characters.
213   * @param pos the first character of the substring to be extracted.
214   *            The first character is at position 1.
215   * @param length the number of consecutive characters to be copied
216   * @return a <code>String</code> that is the specified substring in
217   *         the <code>CLOB</code> value designated by this <code>Clob</code> object
218   * @exception SQLException if there is an error accessing the
219   * <code>CLOB</code>
220 
221   NOTE: return the empty string if pos is too large
222   */
223 
224    public String getSubString(long pos, int length) throws SQLException
225    {
226        //call checkValidity to exit by throwing a SQLException if
227        //the Clob object has been freed by calling free() on it
228        checkValidity();
229        
230        if (pos < 1)
231            throw Util.generateCsSQLException(
232                SQLState.BLOB_BAD_POSITION, new Long(pos));
233        if (length <= 0)
234            throw Util.generateCsSQLException(
235                SQLState.BLOB_NONPOSITIVE_LENGTH, new Integer(length));
236 
237        // if we have a string, not a stream
238        if (isString)
239        {
240            int sLength = myString.length();
241            if (sLength < pos)
242                throw Util.generateCsSQLException(
243                    SQLState.BLOB_POSITION_TOO_LARGE, new Long(pos));
244            int endIndex = ((int) pos) + length - 1;
245            // cannot go over length of string, or we get an exception
246            return myString.substring(((int) pos) - 1, (sLength > endIndex ? endIndex : sLength));
247        }
248 
249                Object synchronization = getConnectionSynchronization();
250        synchronized (synchronization)
251        {
252            setupContextStack();
253 
254                        UTF8Reader clobReader = null;
255                        try {
256 
257                                clobReader = getCharacterStreamAtPos(pos, synchronization);
258                                if (clobReader == null)
259                                        throw StandardException.newException(SQLState.BLOB_POSITION_TOO_LARGE, new Long(pos));
260 
261                                StringBuffer sb = new StringBuffer(length);
262                                int remainToRead = length;
263                                while (remainToRead > 0) {
264 
265                                        int read = clobReader.readInto(sb, remainToRead);
266                                        if (read == -1)
267                                                break;
268 
269                                        remainToRead -= read;
270                                }
271                                clobReader.close();
272                                clobReader = null;
273 
274                                return sb.toString();
275                        }
276                        catch (Throwable t)
277                        {
278                                throw noStateChangeLOB(t);
279                        }
280                        finally
281                        {
282                                if (clobReader != null)
283                                        clobReader.close();
284                                restoreContextStack();
285                        }
286                }
287    }
288 
289 
290  /**
291   * Gets the <code>Clob</code> contents as a Unicode stream.
292   * @return a Unicode stream containing the <code>CLOB</code> data
293   * @exception SQLException if there is an error accessing the
294   * <code>CLOB</code>
295   */
296 
297    public java.io.Reader getCharacterStream() throws SQLException
298    {
299        //call checkValidity to exit by throwing a SQLException if
300        //the Clob object has been freed by calling free() on it
301        checkValidity();
302 
303        // if we have a string, not a stream
304        if (isString)
305        {
306            return new StringReader(myString);
307        }
308 
309 
310                Object synchronization = getConnectionSynchronization();
311        synchronized (synchronization)
312        {
313            setupContextStack();
314 
315                        try {
316                                return getCharacterStreamAtPos(1, synchronization);
317                        }
318                        catch (Throwable t)
319                        {
320                                throw noStateChangeLOB(t);
321                        }
322                        finally
323                        {
324                                restoreContextStack();
325                        }
326                }
327    }
328 
329 
330  /**
331   * Gets the <code>CLOB</code> value designated by this <code>Clob</code>
332   * object as a stream of Ascii bytes.
333   * @return an ascii stream containing the <code>CLOB</code> data
334   * @exception SQLException if there is an error accessing the
335   * <code>CLOB</code> value
336   */
337 
338    public java.io.InputStream getAsciiStream() throws SQLException
339    {
340                //call checkValidity to exit by throwing a SQLException if
341                //the Clob object has been freed by calling free() on it
342                checkValidity();
343                return new ReaderToAscii(getCharacterStream());
344    }
345 
346        private UTF8Reader getCharacterStreamAtPos(long position, Object synchronization)
347                throws IOException, StandardException
348        {
349        ((Resetable)myStream).resetStream();
350                UTF8Reader clobReader = new UTF8Reader(myStream, 0, this, synchronization);
351 
352                // skip to the correct position (pos is one based)
353                long remainToSkip = position - 1;
354                while (remainToSkip > 0) {
355                        long skipBy = clobReader.skip(remainToSkip);
356                        if (skipBy == -1)
357                                return null;
358 
359                        remainToSkip -= skipBy;
360                }
361 
362                return clobReader;
363        }
364 
365 
366  /**
367   * Determines the character position at which the specified substring
368   * <code>searchstr</code> appears in the <code>CLOB</code>.  The search
369   * begins at position <code>start</code>.
370   * @param searchStr the substring for which to search
371   * @param start the position at which to begin searching; the first position
372   *              is 1
373   * @return the position at which the substring appears, else -1; the first
374   *         position is 1
375   * @exception SQLException if there is an error accessing the
376   * <code>CLOB</code> value
377   */
378    public long position(String searchStr, long start)
379        throws SQLException
380    {
381        //call checkValidity to exit by throwing a SQLException if
382        //the Clob object has been freed by calling free() on it
383        checkValidity();
384        
385        boolean pushStack = false;
386        try
387        {
388            if (start < 1)
389                throw StandardException.newException(
390                    SQLState.BLOB_BAD_POSITION, new Long(start));
391            if (searchStr == null)
392                throw StandardException.newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
393            if (searchStr == "")
394                return start; // match DB2's SQL LOCATE function
395 
396            // if we have a string, not a stream
397            if (isString)
398            {
399                                // avoid truncation errors in the cast of start to an int.
400                                if (start > myString.length())
401                                        return -1;
402 
403                int result = myString.indexOf(searchStr, (int) start-1);
404                return result < 0 ? -1 : result + 1;
405            }
406            else // we have a stream
407            {
408                                Object synchronization = getConnectionSynchronization();
409                synchronized (synchronization)
410                {
411                    pushStack = !getEmbedConnection().isClosed();
412                    if (pushStack)
413                        setupContextStack();
414 
415                                        char[] tmpClob = new char[256];
416                                        int patternLength = searchStr.length();
417 
418restartPattern:
419                                        for (;;) {
420 
421                                        //System.out.println("RESET " + start);
422                                                UTF8Reader clobReader = getCharacterStreamAtPos(start, synchronization);
423                                                if (clobReader == null)
424                                                        return -1;
425 
426 
427 
428                                                // start of any match of the complete pattern.
429 
430                                                int patternIndex = 0;
431                                                char[] tmpPattern = null;
432                                                boolean needPattern = true;
433 
434                                                // how many characters of the patter segment we have matched
435                                                int matchCount = 0;
436 
437                                                long currentPosition = start;
438                                                int clobOffset = -1;
439                                                int read = -1;
440 
441                                                // absolute position of a possible match
442                                                long matchPosition = -1;
443 
444 
445                                                // absolute position of the next possible match
446                                                long nextBestMatchPosition = -1;
447                                                //System.out.println("restartPattern: " + start);
448 
449 
450search:
451                                                for (;;)
452                                                {
453                                                        //System.out.println("search: " + needPattern + " -- " + clobOffset);
454                                                        if (needPattern) {
455 
456                                                                String tmpPatternS;
457                                                                if ((patternLength - patternIndex) > 256)
458                                                                        tmpPatternS = searchStr.substring(patternIndex, 256);
459                                                                else
460                                                                        tmpPatternS = searchStr;
461 
462                                                                tmpPattern = tmpPatternS.toCharArray();
463                                                                needPattern = false;
464                                                                matchCount = 0;
465 
466                                                        }
467 
468                                                        if (clobOffset == -1) {
469                                                                
470                                                                read = clobReader.read(tmpClob, 0, tmpClob.length);
471                                                        //System.out.println("MORE DATA " + read);
472                                                                if (read == -1)
473                                                                        return -1;
474 
475                                                                if (read == 0)
476                                                                        continue search;
477 
478                                                                clobOffset = 0;
479                                                        }
480 
481 
482                                                        // find matches within our two temp arrays.
483compareArrays:
484                                                        for (; clobOffset < read; clobOffset++) {
485 
486                                                                //System.out.println("compareArrays " + clobOffset);
487 
488                                                                char clobC = tmpClob[clobOffset];
489 
490 
491                                                                if (clobC == tmpPattern[matchCount])
492                                                                {
493                                                                        if (matchPosition == -1) {
494                                                                                matchPosition = currentPosition + clobOffset;
495                                                                        }
496 
497                                                                        matchCount++;
498 
499                                                                        // have we matched the entire pattern segment
500                                                                        if (matchCount == tmpPattern.length)
501                                                                        {
502                                                                                // move onto the next segment.
503                                                                                patternIndex += tmpPattern.length;
504                                                                                if (patternIndex == patternLength) {
505                                                                                        // complete match !!
506                                                                                        clobReader.close();
507                                                                                        //System.out.println("COMPLETE@" + matchPosition);
508                                                                                        return matchPosition;
509                                                                                }
510 
511                                                                                needPattern = true;
512                                                                                continue search;
513 
514                                                                        }
515 
516                                                                        if (clobC == tmpPattern[0]) {
517 
518                                                                                // save the next best start position.
519 
520                                                                                // must be the first character of the actual pattern
521                                                                                if (patternIndex == 0) {
522 
523                                                                                        // must not be just a repeat of the match of the first character
524                                                                                        if (matchCount != 1) {
525 
526                                                                                                // must not have a previous next best.
527 
528                                                                                                if (nextBestMatchPosition == -1) {
529                                                                                                        nextBestMatchPosition = currentPosition + clobOffset;
530                                                                                                }
531 
532                                                                                        }
533 
534                                                                                }
535                                                                        }
536 
537                                                                        continue compareArrays;
538                                                                }
539                                                                else
540                                                                {
541                                                                        // not a match
542                                                                        //
543                                                                        // 
544                                                                        if (matchPosition != -1) {
545                                                                                // failed after we matched some amount of the pattern
546                                                                                matchPosition = -1;
547 
548                                                                                // See if we found a next best match
549                                                                                if (nextBestMatchPosition == -1)
550                                                                                {
551                                                                                        // NO - just continue on, re-starting at this character
552 
553                                                                                        if (patternIndex != 0) {
554                                                                                                needPattern = true;
555                                                                                                continue search;
556                                                                                        }
557                                                                                }
558                                                                                else if (nextBestMatchPosition >= currentPosition)
559                                                                                {
560                                                                                        // restart in the current array
561                                                                                        clobOffset = (int) (nextBestMatchPosition - currentPosition);
562                                                                                        nextBestMatchPosition = -1;
563                                                                        
564                                                                                        if (patternIndex != 0) {
565                                                                                                needPattern = true;
566                                                                                                continue search;
567                                                                                        }
568                                                                                }
569                                                                                else
570                                                                                {
571                                                                                        clobReader.close();
572                                                                                        start = nextBestMatchPosition;
573                                                                                        continue restartPattern;
574                                                                                }
575 
576                                                                                clobOffset--; // since the continue will increment it
577                                                                                matchCount = 0;
578                                                                                continue compareArrays;
579                                                                        }
580                                                                        
581                                                                        // no current match, just continue
582                                                                }
583                                                        }
584 
585                                                        currentPosition += read;
586 
587                                                        // indicates we need to read more data
588                                                        clobOffset = -1;
589                                                }
590                                        }
591                                }
592            }
593        }
594        catch (Throwable t)
595        {
596                        throw noStateChangeLOB(t);
597        }
598        finally
599        {
600            if (pushStack)
601                restoreContextStack();
602        }
603 
604    }
605 
606 
607  /**
608   * Determines the character position at which the specified
609   * <code>Clob</code> object <code>searchstr</code> appears in this
610   * <code>Clob</code> object.  The search begins at position
611   * <code>start</code>.
612   * @param searchClob the <code>Clob</code> object for which to search
613   * @param start the position at which to begin searching; the first
614   *              position is 1
615   * @return the position at which the <code>Clob</code> object appears,
616   * else -1; the first position is 1
617   * @exception SQLException if there is an error accessing the
618   * <code>CLOB</code> value
619   */
620 
621    public long position(Clob searchClob, long start)
622        throws SQLException
623    {
624        //call checkValidity to exit by throwing a SQLException if
625        //the Clob object has been freed by calling free() on it
626        checkValidity();
627        
628        boolean pushStack = false;
629        try
630        {
631            if (start < 1)
632                throw StandardException.newException(
633                    SQLState.BLOB_BAD_POSITION, new Long(start));
634            if (searchClob == null)
635                throw StandardException.newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
636 
637            synchronized (getConnectionSynchronization())
638            {
639                                char[] subPatternChar = new char[256];
640 
641                                boolean seenOneCharacter = false;
642 
643                                //System.out.println("BEGIN CLOB SEARCH @ " + start);
644 
645restartScan:
646                                for (;;) {
647 
648                                        long firstPosition = -1;
649 
650                                        Reader patternReader = searchClob.getCharacterStream();
651 
652                                        //System.out.println("RESTART CLOB SEARCH @ " + start);
653 
654                                        try {
655 
656                                                for (;;) {
657 
658                                                        int read = patternReader.read(subPatternChar, 0, subPatternChar.length);
659                                                        if (read == -1) {
660                                                                //empty pattern
661                                                                if (!seenOneCharacter)
662                                                                        return start; // matches DB2 SQL LOCATE function
663 
664                                                                return firstPosition;
665                                                        }
666                                                        if (read == 0) {
667                                                                //System.out.println("STUCK IN READ 0 HELL");
668                                                                continue;
669                                                        }
670 
671                                                        seenOneCharacter = true;
672 
673                                                        String subPattern = new String(subPatternChar, 0, read);
674                                        //System.out.println("START CLOB SEARCH @ " + start + " -- " + subPattern);
675                                                        long position = position(subPattern, start);
676                                        //System.out.println("DONE SUB CLOB SEARCH @ " + start + " -- " + position);
677                                                        if (position == -1) {
678                                                                // never seen any match
679                                                                if (firstPosition == -1)
680                                                                        return -1;
681 
682                                                                start = firstPosition + 1;
683                                                                continue restartScan;
684                                                        }
685 
686                                                        if (firstPosition == -1)
687                                                                firstPosition = position;
688                                                        else if (position != start) {
689                                                                // must match at the first character of the segment
690                                                                start = firstPosition + 1;
691                                                                continue restartScan;
692                                                        }
693 
694                                                        // read is the length of the subPattern string
695                                                        start = position + read;
696                                        }
697                                        } finally {
698                                                patternReader.close();
699                                        }
700                                }
701            }
702        }
703        catch (Throwable t)
704        {
705                        throw noStateChangeLOB(t);
706        }
707        finally
708        {
709            if (pushStack)
710                restoreContextStack();
711        }
712 
713    }
714 
715 
716    /*
717     If we have a stream, release the resources associated with it.
718     */
719    protected void finalize()
720    {
721        // System.out.println("finalizer called");
722        if (!isString)
723            ((Resetable)myStream).closeStream();
724    }
725 
726 
727        /**
728    Following methods are for the new JDBC 3.0 methods in java.sql.Clob
729    (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
730    package, so we don't have to have a new class in Local30.
731    The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
732    so this will work fine in jdbc2.0 configuration.
733        */
734 
735        /////////////////////////////////////////////////////////////////////////
736        //
737        //        JDBC 3.0        -        New public methods
738        //
739        /////////////////////////////////////////////////////////////////////////
740 
741        /**
742    * JDBC 3.0
743    *
744    * Writes the given Java String to the CLOB value that this Clob object designates
745    * at the position pos.
746    *
747    * @param pos - the position at which to start writing to the CLOB value that
748    * this Clob object represents
749    * @return the number of characters written 
750    * @exception SQLException Feature not implemented for now.
751        */
752        public int setString(long pos, String parameterName)
753    throws SQLException
754        {
755                throw Util.notImplemented();
756        }
757 
758        /**
759    * JDBC 3.0
760    *
761    * Writes len characters of str, starting at character offset, to the CLOB value
762    * that this Clob represents.
763    *
764    * @param pos - the position at which to start writing to this Clob object
765    * @param str - the string to be written to the CLOB value that this Clob designates
766    * @param offset - the offset into str to start reading the characters to be written
767    * @param len - the number of characters to be written 
768    * @return the number of characters written
769    * @exception SQLException Feature not implemented for now.
770        */
771        public int setString(long pos, String str, int offset, int len)
772    throws SQLException
773        {
774                throw Util.notImplemented();
775        }
776 
777        /**
778    * JDBC 3.0
779    *
780    * Retrieves a stream to be used to write Ascii characters to the CLOB
781    * value that this Clob object represents, starting at position pos.
782    *
783    * @param pos - the position at which to start writing to this Clob object
784    * @return the stream to which ASCII encoded characters can be written 
785    * @exception SQLException Feature not implemented for now.
786        */
787        public java.io.OutputStream setAsciiStream(long pos)
788    throws SQLException
789        {
790                throw Util.notImplemented();
791        }
792 
793        /**
794    * JDBC 3.0
795    *
796    * Retrieves a stream to be used to write a stream of Unicode characters to the
797    * CLOB value that this Clob object represents, starting at position pos.
798    *
799    * @param pos - the position at which to start writing to this Clob object
800    * @return the stream to which Unicode encoded characters can be written 
801    * @exception SQLException Feature not implemented for now.
802        */
803        public java.io.Writer setCharacterStream(long pos)
804    throws SQLException
805        {
806                throw Util.notImplemented();
807        }
808 
809          /**
810    * JDBC 3.0
811    *
812    * Truncates the CLOB value that this Clob designates to have a length of len characters
813    *
814    * @param len - the length, in bytes, to which the CLOB value that this Blob
815    * value should be truncated
816    * @exception SQLException Feature not implemented for now.
817        */
818        public void truncate(long len)
819    throws SQLException
820        {
821                throw Util.notImplemented();
822        }
823 
824    /////////////////////////////////////////////////////////////////////////
825    //
826    //        JDBC 4.0        -        New public methods
827    //
828    /////////////////////////////////////////////////////////////////////////
829    /**
830     * This method frees the <code>Clob</code> object and releases the resources the resources
831     * that it holds.  The object is invalid once the <code>free</code> method
832     * is called. If <code>free</code> is called multiple times, the
833     * subsequent calls to <code>free</code> are treated as a no-op.
834     *
835     * @throws SQLException if an error occurs releasing
836     * the Clob's resources
837     */
838    public void free()
839        throws SQLException {
840        //calling free() on a already freed object is treated as a no-op
841        if (!isValid) return;
842        
843        //now that free has been called the Clob object is no longer
844        //valid
845        isValid = false;
846        
847        if (!isString)
848            ((Resetable)myStream).closeStream();
849        else
850            myString = null;
851    }
852 
853    public java.io.Reader getCharacterStream(long pos, long length)
854        throws SQLException {
855        throw Util.notImplemented();
856    }
857 
858        /*
859        **
860        */
861 
862        static SQLException noStateChangeLOB(Throwable t) {
863        if (t instanceof StandardException)
864        {
865            // container closed means the blob or clob was accessed after commit
866            if (((StandardException) t).getMessageId().equals(SQLState.DATA_CONTAINER_CLOSED))
867            {
868                t = StandardException.newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
869            }
870        }
871                return org.apache.derby.impl.jdbc.EmbedResultSet.noStateChangeException(t);
872        }
873        
874        /*
875         * Checks is isValid is true. If it is not true throws 
876         * a SQLException stating that a method has been called on
877         * an invalid LOB object
878         *
879         * throws SQLException if isValid is not true.
880         */
881        private void checkValidity() throws SQLException{
882            if(!isValid)
883                throw newSQLException(SQLState.LOB_OBJECT_INVALID);
884        }
885}

[all classes][org.apache.derby.impl.jdbc]
EMMA 2.0.5312 (C) Vladimir Roubtsov