Source Code Cross Referenced for EmbedBlob.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » jdbc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.jdbc.EmbedBlob
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.impl.jdbc;
023:
024:        import org.apache.derby.iapi.reference.SQLState;
025:        import org.apache.derby.iapi.error.StandardException;
026:        import org.apache.derby.iapi.services.sanity.SanityManager;
027:        import org.apache.derby.iapi.types.DataValueDescriptor;
028:        import org.apache.derby.iapi.types.Resetable;
029:        import org.apache.derby.impl.jdbc.ConnectionChild;
030:        import org.apache.derby.impl.jdbc.EmbedConnection;
031:        import org.apache.derby.impl.jdbc.Util;
032:        import org.apache.derby.iapi.services.io.NewByteArrayInputStream;
033:        import org.apache.derby.iapi.services.io.InputStreamUtil;
034:        import org.apache.derby.iapi.services.io.ArrayInputStream;
035:
036:        import java.sql.SQLException;
037:        import java.sql.Blob;
038:        import java.io.InputStream;
039:        import java.io.EOFException;
040:        import java.io.IOException;
041:
042:        /**
043:         Implements java.sql.Blob (see the JDBC 2.0 spec).
044:         A blob sits on top of a BINARY, VARBINARY or LONG VARBINARY column.
045:         If its data is small (less than 1 page) it is a byte array taken from
046:         the SQLBit class. If it is large (more than 1 page) it is a long column
047:         in the database. The long column is accessed as a stream, and is implemented
048:         in store as an OverflowInputStream.  The Resetable interface allows sending
049:         messages to that stream to initialize itself (reopen its container and
050:         lock the corresponding row) and to reset itself to the beginning. 
051:
052:         NOTE: In the case that the data is large, it is represented as a stream.
053:         This stream is returned to the user in the getBinaryStream() method.
054:         This means that we have limited control over the state of the stream,
055:         since the user can read bytes from it at any time.  Thus all methods
056:         here reset the stream to the beginning before doing any work.
057:         CAVEAT: The methods may not behave correctly if a user sets up
058:         multiple threads and sucks data from the stream (returned from
059:         getBinaryStream()) at the same time as calling the Blob methods.
060:
061:         <P><B>Supports</B>
062:         <UL>
063:         <LI> JSR169 - no subsetting for java.sql.Blob
064:         <LI> JDBC 2.0
065:         <LI> JDBC 3.0 - no new dependencies on new JDBC 3.0 or JDK 1.4 classes,
066:         new update methods can safely be added into implementation.
067:         </UL>
068:
069:         */
070:
071:        final class EmbedBlob extends ConnectionChild implements  Blob {
072:            // blob is either bytes or stream
073:            private boolean isBytes;
074:            private InputStream myStream;
075:
076:            /*
077:             * Length of the BLOB if known. Set to -1 if
078:             * the current length of the BLOB is not known.
079:             */
080:            private long myLength = -1;
081:
082:            private byte[] myBytes;
083:            // note: cannot control position of the stream since user can do a getBinaryStream
084:            private long pos;
085:            // this stream sits on top of myStream
086:            private BinaryToRawStream biStream;
087:
088:            // buffer for reading in blobs from a stream (long column)
089:            // and trashing them (to set the position of the stream etc.)
090:            private static int BLOB_BUF_SIZE = 4096;
091:            private byte buf[];
092:
093:            //This boolean variable indicates whether the Blob object has
094:            //been invalidated by calling free() on it
095:            private boolean isValid = true;
096:
097:            /**
098:             * This constructor is used to create a empty Blob object. It is used by the
099:             * Connection interface method createBlob().
100:             * 
101:             * @param blobBytes A byte array containing the data to be stores in the 
102:             *        Blob.
103:             *
104:             * @param con The EmbedConnection object associated with this Blob object.
105:             *
106:             */
107:
108:            EmbedBlob(byte[] blobBytes, EmbedConnection con) {
109:                super (con);
110:                myBytes = blobBytes;
111:                isBytes = true;
112:                myLength = myBytes.length;
113:            }
114:
115:            /*
116:              This constructor should only be called by EmbedResultSet.getBlob
117:             */
118:            protected EmbedBlob(DataValueDescriptor dvd, EmbedConnection con)
119:                    throws StandardException {
120:                super (con);
121:                // if the underlying column is null, ResultSet.getBlob will return null,
122:                // never should get this far
123:                if (SanityManager.DEBUG)
124:                    SanityManager.ASSERT(!dvd.isNull(),
125:                            "blob is created on top of a null column");
126:
127:                myStream = dvd.getStream();
128:                if (myStream == null) {
129:                    isBytes = true;
130:                    // copy bytes into memory so that blob can live after result set
131:                    // is closed
132:                    byte[] dvdBytes = dvd.getBytes();
133:
134:                    if (SanityManager.DEBUG)
135:                        SanityManager.ASSERT(dvdBytes != null,
136:                                "blob has a null value underneath");
137:
138:                    myLength = dvdBytes.length;
139:                    myBytes = new byte[dvdBytes.length];
140:                    System.arraycopy(dvdBytes, 0, myBytes, 0, dvdBytes.length);
141:                } else {
142:                    isBytes = false;
143:
144:                    /*
145:                     We are expecting this stream to be a FormatIdInputStream with an
146:                     OverflowInputStream inside. FormatIdInputStream implements
147:                     Resetable. This should be the case when retrieving
148:                     data from a long column. However, SQLBit, which is the class
149:                     implementing the getStream() method for dvd.getStream(), does not
150:                     guarantee this for us
151:                     */
152:                    if (SanityManager.DEBUG)
153:                        SanityManager.ASSERT(myStream instanceof  Resetable);
154:
155:                    try {
156:                        ((Resetable) myStream).initStream();
157:                    } catch (StandardException se) {
158:                        if (se.getMessageId().equals(
159:                                SQLState.DATA_CONTAINER_CLOSED)) {
160:                            throw StandardException
161:                                    .newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
162:                        }
163:                    }
164:                    // set up the buffer for trashing the bytes to set the position of
165:                    // the
166:                    // stream, only need a buffer when we have a long column
167:                    buf = new byte[BLOB_BUF_SIZE];
168:                }
169:                pos = 0;
170:            }
171:
172:            /*
173:                Sets the position of the stream to position newPos, where position 0 is
174:                the beginning of the stream.
175:
176:                @param newPos the position to set to
177:                @exception StandardException (BLOB_SETPOSITION_FAILED) throws this if
178:                the stream runs out before we get to newPos
179:             */
180:            private void setPosition(long newPos) throws StandardException,
181:                    IOException {
182:                if (SanityManager.DEBUG)
183:                    SanityManager.ASSERT(newPos >= 0);
184:                if (isBytes)
185:                    pos = newPos;
186:                else {
187:                    // Always resets the stream to the beginning first, because user can
188:                    // influence the state of the stream without letting us know.
189:                    ((Resetable) myStream).resetStream();
190:                    // PT could try to save creating a new object each time
191:                    biStream = new BinaryToRawStream(myStream, this );
192:                    pos = 0;
193:                    while (pos < newPos) {
194:                        int size = biStream.read(buf, 0, (int) Math.min(
195:                                (newPos - pos), (long) BLOB_BUF_SIZE));
196:                        if (size <= 0) // ran out of stream
197:                            throw StandardException
198:                                    .newException(SQLState.BLOB_LENGTH_TOO_LONG);
199:                        pos += size;
200:                    }
201:                }
202:            }
203:
204:            /*
205:                Reads one byte, either from the byte array or else from the stream.
206:             */
207:            private int read() throws IOException {
208:                int c;
209:                if (isBytes) {
210:                    if (pos >= myBytes.length)
211:                        return -1;
212:                    else
213:                        c = myBytes[(int) pos];
214:                } else
215:                    c = biStream.read();
216:                pos++;
217:                return c;
218:            }
219:
220:            /**
221:             * Returns the number of bytes in the <code>BLOB</code> value
222:             * designated by this <code>Blob</code> object.
223:             * @return length of the <code>BLOB</code> in bytes
224:             * @exception SQLException if there is an error accessing the
225:             * length of the <code>BLOB</code>
226:             */
227:            // PT stream part may get pushed to store
228:            public long length() throws SQLException {
229:                //call checkValidity to exit by throwing a SQLException if
230:                //the Blob object has been freed by calling free() on it
231:                checkValidity();
232:
233:                if (myLength != -1)
234:                    return myLength;
235:
236:                boolean pushStack = false;
237:                try {
238:                    // we have a stream
239:                    synchronized (getConnectionSynchronization()) {
240:                        pushStack = !getEmbedConnection().isClosed();
241:                        if (pushStack)
242:                            setupContextStack();
243:
244:                        setPosition(0);
245:                        // If possible get the length from the encoded
246:                        // length at the front of the raw stream.
247:                        if ((myLength = biStream.getLength()) != -1) {
248:                            biStream.close();
249:                            return myLength;
250:                        }
251:
252:                        // Otherwise have to read the entire stream!
253:                        for (;;) {
254:                            int size = biStream.read(buf);
255:                            if (size == -1)
256:                                break;
257:                            pos += size;
258:                        }
259:                        // Save for future uses.
260:                        myLength = pos;
261:                        biStream.close();
262:                        return pos;
263:                    }
264:                } catch (Throwable t) {
265:                    throw handleMyExceptions(t);
266:                } finally {
267:                    if (pushStack)
268:                        restoreContextStack();
269:                }
270:            }
271:
272:            /**
273:             * Returns as an array of bytes part or all of the <code>BLOB</code>
274:             * value that this <code>Blob</code> object designates.  The byte
275:             * array contains up to <code>length</code> consecutive bytes
276:             * starting at position <code>startPos</code>.
277:             * The starting position must be between 1 and the length
278:             * of the BLOB plus 1. This allows for zero-length BLOB values, from
279:             * which only zero-length byte arrays can be returned. 
280:             * If a larger length is requested than there are bytes available,
281:             * characters from the start position to the end of the BLOB are returned.
282:             * @param startPos the ordinal position of the first byte in the
283:             * <code>BLOB</code> value to be extracted; the first byte is at
284:             * position 1
285:             * @param length is the number of consecutive bytes to be copied
286:             * @return a byte array containing up to <code>length</code>
287:             * consecutive bytes from the <code>BLOB</code> value designated
288:             * by this <code>Blob</code> object, starting with the
289:             * byte at position <code>startPos</code>.
290:             * @exception SQLException if there is an error accessing the
291:             * <code>BLOB</code>
292:             * NOTE: If the starting position is the length of the BLOB plus 1,
293:             * zero bytess are returned regardless of the length requested.
294:             */
295:            public byte[] getBytes(long startPos, int length)
296:                    throws SQLException {
297:                //call checkValidity to exit by throwing a SQLException if
298:                //the Blob object has been freed by calling free() on it
299:                checkValidity();
300:
301:                boolean pushStack = false;
302:                try {
303:                    if (startPos < 1)
304:                        throw StandardException.newException(
305:                                SQLState.BLOB_BAD_POSITION, new Long(startPos));
306:                    if (length < 0)
307:                        throw StandardException.newException(
308:                                SQLState.BLOB_NONPOSITIVE_LENGTH, new Integer(
309:                                        length));
310:
311:                    byte[] result;
312:                    // if we have a byte array, not a stream
313:                    if (isBytes) {
314:                        // if blob length is less than pos bytes + 1, raise an exception
315:                        if (myBytes.length + 1 < startPos)
316:                            throw StandardException.newException(
317:                                    SQLState.BLOB_POSITION_TOO_LARGE, new Long(
318:                                            startPos));
319:                        // cannot go over length of array
320:                        int lengthFromPos = myBytes.length - (int) startPos + 1;
321:                        int actualLength = length > lengthFromPos ? lengthFromPos
322:                                : length;
323:                        result = new byte[actualLength];
324:                        System.arraycopy(myBytes, ((int) startPos) - 1, result,
325:                                0, actualLength);
326:                    } else // we have a stream
327:                    {
328:                        synchronized (getConnectionSynchronization()) {
329:                            pushStack = !getEmbedConnection().isClosed();
330:                            if (pushStack)
331:                                setupContextStack();
332:
333:                            setPosition(startPos - 1);
334:                            // read length bytes into a string
335:                            result = new byte[length];
336:                            int n = InputStreamUtil.readLoop(biStream, result,
337:                                    0, length);
338:                            pos += n;
339:                            /*
340:                             According to the spec, if there are only n < length bytes
341:                             to return, we should just return these bytes. Rather than
342:                             return them in an array of size length, where the trailing
343:                             bytes are not initialized, and the user cannot tell how
344:                             many bytes were actually returned, we should return an
345:                             array of n bytes.
346:                             */
347:                            if (n < length) {
348:                                byte[] result2 = new byte[n];
349:                                System.arraycopy(result, 0, result2, 0, n);
350:                                return result2;
351:                            }
352:                        }
353:                    }
354:                    return result;
355:                } catch (StandardException e) { // if this is a setPosition exception then we ran out of Blob
356:                    if (e.getMessageId().equals(SQLState.BLOB_LENGTH_TOO_LONG))
357:                        e = StandardException.newException(
358:                                SQLState.BLOB_POSITION_TOO_LARGE, new Long(
359:                                        startPos));
360:                    throw handleMyExceptions(e);
361:                } catch (Throwable t) {
362:                    throw handleMyExceptions(t);
363:                } finally {
364:                    if (pushStack)
365:                        restoreContextStack();
366:                }
367:
368:            }
369:
370:            /**
371:             * Retrieves the <code>BLOB</code> designated by this
372:             * <code>Blob</code> instance as a stream.
373:             * @return a stream containing the <code>BLOB</code> data
374:             * @exception SQLException if there is an error accessing the
375:             * <code>BLOB</code>
376:             */
377:            public java.io.InputStream getBinaryStream() throws SQLException {
378:                //call checkValidity to exit by throwing a SQLException if
379:                //the Blob object has been freed by calling free() on it
380:                checkValidity();
381:
382:                boolean pushStack = false;
383:                try {
384:                    // if we have byte array, not a stream
385:                    if (isBytes) {
386:                        return new NewByteArrayInputStream(myBytes);
387:                    } else {
388:                        // have a stream
389:
390:                        synchronized (getConnectionSynchronization()) {
391:                            pushStack = !getEmbedConnection().isClosed();
392:                            if (pushStack)
393:                                setupContextStack();
394:
395:                            setPosition(0);
396:                            return biStream;
397:                        }
398:                    }
399:                } catch (Throwable t) {
400:                    throw handleMyExceptions(t);
401:                } finally {
402:                    if (pushStack)
403:                        restoreContextStack();
404:                }
405:            }
406:
407:            /**
408:             * Determines the byte position at which the specified byte
409:             * <code>pattern</code> begins within the <code>BLOB</code>
410:             * value that this <code>Blob</code> object represents.  The
411:             * search for <code>pattern</code. begins at position
412:             * <code>start</code>
413:             * @param pattern the byte array for which to search
414:             * @param start the position at which to begin searching; the
415:             *        first position is 1
416:             * @return the position at which the pattern appears, else -1.
417:             * @exception SQLException if there is an error accessing the
418:             * <code>BLOB</code>
419:             */
420:            public long position(byte[] pattern, long start)
421:                    throws SQLException {
422:                //call checkValidity to exit by throwing a SQLException if
423:                //the Blob object has been freed by calling free() on it
424:                checkValidity();
425:
426:                boolean pushStack = false;
427:                try {
428:                    if (start < 1)
429:                        throw StandardException.newException(
430:                                SQLState.BLOB_BAD_POSITION, new Long(start));
431:                    if (pattern == null)
432:                        throw StandardException
433:                                .newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
434:                    if (pattern.length == 0)
435:                        return start; // match DB2's SQL LOCATE function
436:
437:                    synchronized (getConnectionSynchronization()) {
438:                        pushStack = !getEmbedConnection().isClosed();
439:                        if (pushStack)
440:                            setupContextStack();
441:
442:                        setPosition(start - 1);
443:                        // look for first character
444:                        int lookFor = pattern[0];
445:                        long curPos;
446:                        int c;
447:                        while (true) {
448:                            c = read();
449:                            if (c == -1) // run out of stream
450:                                return -1;
451:                            if (c == lookFor) {
452:                                curPos = pos;
453:                                if (checkMatch(pattern))
454:                                    return curPos;
455:                                else
456:                                    setPosition(curPos);
457:                            }
458:                        }
459:                    }
460:                } catch (StandardException e) { // if this is a setPosition exception then not found
461:                    if (e.getMessageId().equals(SQLState.BLOB_LENGTH_TOO_LONG))
462:                        return -1;
463:                    else
464:                        throw handleMyExceptions(e);
465:                } catch (Throwable t) {
466:                    throw handleMyExceptions(t);
467:                } finally {
468:                    if (pushStack)
469:                        restoreContextStack();
470:                }
471:
472:            }
473:
474:            /*
475:             check whether pattern (starting from the second byte) appears inside
476:             posStream (at the current position)
477:             @param posStream the stream to search inside
478:             @param pattern the byte array passed in by the user to search with
479:             @return true if match, false otherwise
480:             */
481:            private boolean checkMatch(byte[] pattern) throws IOException {
482:                // check whether rest matches
483:                // might improve performance by reading more
484:                for (int i = 1; i < pattern.length; i++) {
485:                    int b = read();
486:                    if ((b < 0) || (b != pattern[i])) // mismatch or stream runs out
487:                        return false;
488:                }
489:                return true;
490:            }
491:
492:            /**
493:             * Determines the byte position in the <code>BLOB</code> value
494:             * designated by this <code>Blob</code> object at which
495:             * <code>pattern</code> begins.  The search begins at position
496:             * <code>start</code>.
497:             * @param pattern the <code>Blob</code> object designating
498:             * the <code>BLOB</code> value for which to search
499:             * @param start the position in the <code>BLOB</code> value
500:             *        at which to begin searching; the first position is 1
501:             * @return the position at which the pattern begins, else -1
502:             * @exception SQLException if there is an error accessing the
503:             * <code>BLOB</code>
504:             */
505:            public long position(Blob pattern, long start) throws SQLException {
506:                //call checkValidity to exit by throwing a SQLException if
507:                //the Blob object has been freed by calling free() on it
508:                checkValidity();
509:
510:                boolean pushStack = false;
511:                try {
512:                    if (start < 1)
513:                        throw StandardException.newException(
514:                                SQLState.BLOB_BAD_POSITION, new Long(start));
515:                    if (pattern == null)
516:                        throw StandardException
517:                                .newException(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR);
518:                    synchronized (getConnectionSynchronization()) {
519:                        pushStack = !getEmbedConnection().isClosed();
520:                        if (pushStack)
521:                            setupContextStack();
522:
523:                        setPosition(start - 1);
524:                        // look for first character
525:                        byte[] b;
526:                        try { // pattern is not necessarily a cloudscape Blob
527:                            b = pattern.getBytes(1, 1);
528:                        } catch (SQLException e) {
529:                            throw StandardException
530:                                    .newException(SQLState.BLOB_UNABLE_TO_READ_PATTERN);
531:                        }
532:                        if (b == null || b.length < 1) // the 'empty' blob
533:                            return start; // match DB2's SQL LOCATE function
534:                        int lookFor = b[0];
535:                        int c;
536:                        long curPos;
537:                        while (true) {
538:                            c = read();
539:                            if (c == -1) // run out of stream
540:                                return -1;
541:                            if (c == lookFor) {
542:                                curPos = pos;
543:                                if (checkMatch(pattern))
544:                                    return curPos;
545:                                else
546:                                    setPosition(curPos);
547:                            }
548:                        }
549:                    }
550:                } catch (StandardException e) { // if this is a setPosition exception then not found
551:                    if (e.getMessageId().equals(SQLState.BLOB_LENGTH_TOO_LONG))
552:                        return -1;
553:                    else
554:                        throw handleMyExceptions(e);
555:                } catch (Throwable t) {
556:                    throw handleMyExceptions(t);
557:                } finally {
558:                    if (pushStack)
559:                        restoreContextStack();
560:                }
561:
562:            }
563:
564:            /*
565:             check whether pattern (starting from the second byte) appears inside
566:             posStream (at the current position)
567:             @param posStream the stream to search inside
568:             @param pattern the blob passed in by the user to search with
569:             @return true if match, false otherwise
570:             */
571:            private boolean checkMatch(Blob pattern) throws IOException {
572:                // check whether rest matches
573:                // might improve performance by reading buffer at a time
574:                InputStream pStream;
575:                try {
576:                    pStream = pattern.getBinaryStream();
577:                } catch (SQLException e) {
578:                    return false;
579:                }
580:                if (pStream == null)
581:                    return false;
582:                // throw away first character since we already read it in the calling
583:                // method
584:                int b1 = pStream.read();
585:                if (b1 < 0)
586:                    return false;
587:                while (true) {
588:                    b1 = pStream.read();
589:                    if (b1 < 0) // search blob runs out
590:                        return true;
591:                    int b2 = read();
592:                    if ((b1 != b2) || (b2 < 0)) // mismatch or stream runs out
593:                        return false;
594:                }
595:            }
596:
597:            /*
598:              Convert exceptions where needed before calling handleException to convert
599:              them to SQLExceptions.
600:             */
601:            private SQLException handleMyExceptions(Throwable t)
602:                    throws SQLException {
603:                if (t instanceof  StandardException) {
604:                    // container closed means the blob or clob was accessed after commit
605:                    if (((StandardException) t).getMessageId().equals(
606:                            SQLState.DATA_CONTAINER_CLOSED)) {
607:                        t = StandardException
608:                                .newException(SQLState.BLOB_ACCESSED_AFTER_COMMIT);
609:                    }
610:                }
611:                return handleException(t);
612:            }
613:
614:            /*
615:             If we have a stream, release the resources associated with it.
616:             */
617:            protected void finalize() {
618:                if (!isBytes)
619:                    ((Resetable) myStream).closeStream();
620:            }
621:
622:            /**
623:            Following methods are for the new JDBC 3.0 methods in java.sql.Blob
624:            (see the JDBC 3.0 spec). We have the JDBC 3.0 methods in Local20
625:            package, so we don't have to have a new class in Local30.
626:            The new JDBC 3.0 methods don't make use of any new JDBC3.0 classes and
627:            so this will work fine in jdbc2.0 configuration.
628:             */
629:
630:            /////////////////////////////////////////////////////////////////////////
631:            //
632:            //	JDBC 3.0	-	New public methods
633:            //
634:            /////////////////////////////////////////////////////////////////////////
635:            /**
636:             * JDBC 3.0
637:             *
638:             * Writes the given array of bytes to the BLOB value that this Blob object
639:             * represents, starting at position pos, and returns the number of bytes written.
640:             *
641:             * @param pos - the position in the BLOB object at which to start writing
642:             * @param bytes - the array of bytes to be written to the BLOB value that this
643:             * Blob object represents
644:             * @return the number of bytes written
645:             * @exception SQLException Feature not implemented for now.
646:             */
647:            public int setBytes(long pos, byte[] bytes) throws SQLException {
648:                throw Util.notImplemented();
649:            }
650:
651:            /**
652:             * JDBC 3.0
653:             *
654:             * Writes all or part of the given array of byte array to the BLOB value that
655:             * this Blob object represents and returns the number of bytes written.
656:             * Writing starts at position pos in the BLOB value; len bytes from the given
657:             * byte array are written.
658:             *
659:             * @param pos - the position in the BLOB object at which to start writing
660:             * @param bytes - the array of bytes to be written to the BLOB value that this
661:             * Blob object represents
662:             * @param offset - the offset into the array bytes at which to start reading
663:             * the bytes to be set
664:             * @param len - the number of bytes to be written to the BLOB value from the
665:             * array of bytes bytes
666:             * @return the number of bytes written
667:             * @exception SQLException Feature not implemented for now.
668:             */
669:            public int setBytes(long pos, byte[] bytes, int offset, int len)
670:                    throws SQLException {
671:                throw Util.notImplemented();
672:            }
673:
674:            /**
675:             * JDBC 3.0
676:             *
677:             * Retrieves a stream that can be used to write to the BLOB value that this
678:             * Blob object represents. The stream begins at position pos. 
679:             *
680:             * @param pos - the position in the BLOB object at which to start writing
681:             * @return a java.io.OutputStream object to which data can be written 
682:             * @exception SQLException Feature not implemented for now.
683:             */
684:            public java.io.OutputStream setBinaryStream(long pos)
685:                    throws SQLException {
686:                throw Util.notImplemented();
687:            }
688:
689:            /**
690:             * JDBC 3.0
691:             *
692:             * Truncates the BLOB value that this Blob object represents to be len bytes
693:             * in length.
694:             *
695:             * @param len - the length, in bytes, to which the BLOB value that this Blob
696:             * object represents should be truncated
697:             * @exception SQLException Feature not implemented for now.
698:             */
699:            public void truncate(long len) throws SQLException {
700:                throw Util.notImplemented();
701:            }
702:
703:            /////////////////////////////////////////////////////////////////////////
704:            //
705:            //	JDBC 4.0	-	New public methods
706:            //
707:            /////////////////////////////////////////////////////////////////////////
708:            /**
709:             * This method frees the <code>Blob</code> object and releases the resources that 
710:             * it holds. The object is invalid once the <code>free</code>
711:             * method is called. If <code>free</code> is called multiple times, the subsequent
712:             * calls to <code>free</code> are treated as a no-op.
713:             * 
714:             * @throws SQLException if an error occurs releasing
715:             * the Blob's resources
716:             */
717:            public void free() throws SQLException {
718:                //calling free() on a already freed object is treated as a no-op
719:                if (!isValid)
720:                    return;
721:
722:                //now that free has been called the Blob object is no longer
723:                //valid
724:                isValid = false;
725:
726:                //initialialize length to default value -1
727:                myLength = -1;
728:
729:                //if it is a stream then close it.
730:                //if a array of bytes then initialize it to null
731:                //to free up space
732:                if (!isBytes)
733:                    ((Resetable) myStream).closeStream();
734:                else
735:                    myBytes = null;
736:            }
737:
738:            /**
739:             * Returns an <code>InputStream</code> object that contains a partial 
740:             * <code>Blob</code> value, starting with the byte specified by pos, 
741:             * which is length bytes in length.
742:             *
743:             * @param pos the offset to the first byte of the partial value to be 
744:             *      retrieved. The first byte in the <code>Blob</code> is at 
745:             *      position 1
746:             * @param length the length in bytes of the partial value to be retrieved
747:             * @return through which the partial <code>Blob</code> value can be read. 
748:             * @throws SQLException if pos is less than 1 or if pos is greater than 
749:             *      the number of bytes in the <code>Blob</code> or if pos + length is
750:             *      greater than the number of bytes in the <code>Blob</code>
751:             */
752:            public InputStream getBinaryStream(long pos, long length)
753:                    throws SQLException {
754:                throw Util.notImplemented();
755:            }
756:
757:            /*
758:             * Checks is isValid is true. If it is not true throws 
759:             * a SQLException stating that a method has been called on
760:             * an invalid LOB object
761:             *
762:             * throws SQLException if isvalid is not true.
763:             */
764:            private void checkValidity() throws SQLException {
765:                if (!isValid)
766:                    throw newSQLException(SQLState.LOB_OBJECT_INVALID);
767:            }
768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.