Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/mysql/jdbc/Blob.java


1   /*
2    Copyright (C) 2002-2004 MySQL AB
3   
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of version 2 of the GNU General Public License as
6    published by the Free Software Foundation.
7    
8   
9    There are special exceptions to the terms and conditions of the GPL 
10   as it is applied to this software. View the full text of the 
11   exception exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
12   software distribution.
13  
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18  
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  
23   */
24  package com.mysql.jdbc;
25  
26  import java.io.ByteArrayInputStream;
27  import java.io.IOException;
28  import java.io.OutputStream;
29  import java.sql.SQLException;
30  
31  
32  /**
33   * The representation (mapping) in the JavaTM programming language  of an SQL
34   * BLOB value. An SQL BLOB is a built-in type that stores  a Binary Large
35   * Object as a column value in a row of a database  table. The driver
36   * implements Blob using an SQL locator(BLOB),  which means that a Blob object
37   * contains a logical pointer to the  SQL BLOB data rather than the data
38   * itself. A Blob object is valid  for the duration of the transaction in
39   * which is was created.   Methods in the interfaces ResultSet,
40   * CallableStatement, and  PreparedStatement, such as getBlob and setBlob
41   * allow a programmer  to access an SQL BLOB value. The Blob interface
42   * provides methods  for getting the length of an SQL BLOB (Binary Large
43   * Object) value,  for materializing a BLOB value on the client, and for
44   * determining  the position of a pattern of bytes within a BLOB value.   This
45   * class is new in the JDBC 2.0 API.
46   *
47   * @author Mark Matthews
48   *
49   * @version $Id: Blob.java,v 1.9.2.10 2004/08/09 22:15:12 mmatthew Exp $
50   */
51  public class Blob implements java.sql.Blob, OutputStreamWatcher {
52      //~ Instance fields --------------------------------------------------------
53  
54      /** The ResultSet that created this BLOB */
55      private ResultSet creatorResultSet;
56  
57      //
58      // This is a real brain-dead implementation of BLOB. Once I add
59      // streamability to the I/O for MySQL this will be more efficiently
60      // implemented (except for the position() method, ugh).
61      //
62  
63      /** The binary data that makes up this BLOB */
64      private byte[] binaryData = null;
65  
66      /** The column that this BLOB came from */
67      private int columnIndex;
68  
69      //~ Constructors -----------------------------------------------------------
70  
71      /**
72       * Creates a BLOB encapsulating the given binary data
73       */
74      Blob(byte[] data) {
75          setBinaryData(data);
76          this.creatorResultSet = null;
77          this.columnIndex = 0;
78      }
79  
80      /**
81       * Creates an updatable BLOB that can update in-place
82       * (not implemented yet).
83       */
84      Blob(byte[] data, ResultSet creatorResultSet, int columnIndex) {
85          setBinaryData(data);
86          this.creatorResultSet = creatorResultSet;
87          this.columnIndex = columnIndex;
88      }
89  
90      //~ Methods ----------------------------------------------------------------
91  
92      /**
93       * @see Blob#setBinaryStream(long)
94       */
95      public OutputStream setBinaryStream(long indexToWriteAt)
96          throws SQLException {
97          if (indexToWriteAt < 1) {
98              throw new SQLException("indexToWriteAt must be >= 1", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
99          }
100 
101         WatchableOutputStream bytesOut = new WatchableOutputStream();
102         bytesOut.setWatcher(this);
103 
104         if (indexToWriteAt > 0) {
105             bytesOut.write(this.binaryData, 0, (int) (indexToWriteAt - 1));
106         }
107 
108         return bytesOut;
109     }
110 
111     /**
112      * Retrieves the BLOB designated by this Blob instance as a stream.
113      *
114      * @return this BLOB represented as a binary stream of bytes.
115      *
116      * @throws SQLException if a database error occurs
117      */
118     public java.io.InputStream getBinaryStream() throws SQLException {
119         return new ByteArrayInputStream(getBinaryData());
120     }
121 
122     /**
123      * @see Blob#setBytes(long, byte[], int, int)
124      */
125     public int setBytes(long writeAt, byte[] bytes, int offset, int length)
126         throws SQLException {
127         OutputStream bytesOut = setBinaryStream(writeAt);
128 
129         try {
130             bytesOut.write(bytes, offset, length);
131         } catch (IOException ioEx) {
132             throw new SQLException("IO Error while writing bytes to blob",
133                 SQLError.SQL_STATE_GENERAL_ERROR);
134         } finally {
135             try {
136                 bytesOut.close();
137             } catch (IOException doNothing) {
138                 ; // do nothing
139             }
140         }
141 
142         return length;
143     }
144 
145     /**
146      * @see Blob#setBytes(long, byte[])
147      */
148     public int setBytes(long writeAt, byte[] bytes) throws SQLException {
149         return setBytes(writeAt, bytes, 0, bytes.length);
150     }
151 
152     /**
153      * Returns as an array of bytes, part or all of the BLOB value that this
154      * Blob object designates.
155      *
156      * @param pos where to start the part of the BLOB
157      * @param length the length of the part of the BLOB you want returned.
158      *
159      * @return the bytes stored in the blob starting at position
160      *         <code>pos</code> and having a length of <code>length</code>.
161      *
162      * @throws SQLException if a database error occurs
163      */
164     public byte[] getBytes(long pos, int length) throws SQLException {
165         if (pos < 1) {
166             throw new SQLException("Position 'pos' can not be < 1", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
167         }
168 
169         byte[] newData = new byte[length];
170         System.arraycopy(getBinaryData(), (int) (pos - 1), newData, 0, length);
171 
172         return newData;
173     }
174 
175     /**
176      * Returns the number of bytes in the BLOB value designated by this Blob
177      * object.
178      *
179      * @return the length of this blob
180      *
181      * @throws SQLException if a database error occurs
182      */
183     public long length() throws SQLException {
184         return getBinaryData().length;
185     }
186 
187     /**
188      * Finds the position of the given pattern in this BLOB.
189      *
190      * @param pattern the pattern to find
191      * @param start where to start finding the pattern
192      *
193      * @return the position where the pattern is found in the BLOB, -1 if not
194      *         found
195      *
196      * @throws SQLException if a database error occurs
197      */
198     public long position(java.sql.Blob pattern, long start)
199         throws SQLException {
200         return position(pattern.getBytes(0, (int) pattern.length()), start);
201     }
202 
203     /**
204      * @see java.sql.Blob#position(byte[], long)
205      */
206     public long position(byte[] pattern, long start) throws SQLException {
207         throw new SQLException("Not implemented");
208     }
209 
210     /**
211      * @see com.mysql.jdbc.OutputStreamWatcher#streamClosed(byte[])
212      */
213     public void streamClosed(WatchableOutputStream out) {
214       int streamSize = out.size();
215       
216       if (streamSize < this.binaryData.length) {
217         out.write(this.binaryData, streamSize, this.binaryData.length - streamSize);
218       }
219       
220         this.binaryData = out.toByteArray();
221     }
222 
223     /**
224      * @see Blob#truncate(long)
225      */
226     public void truncate(long arg0) throws SQLException {
227         throw new NotImplemented();
228     }
229 
230     private void setBinaryData(byte[] newBinaryData) {
231       this.binaryData = newBinaryData;
232     }
233 
234     private byte[] getBinaryData() {
235         return binaryData;
236     }
237 }