KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > db > table > BlobColumn


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source 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, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.db.table;
31
32 import com.caucho.db.sql.Expr;
33 import com.caucho.db.sql.QueryContext;
34 import com.caucho.db.sql.SelectResult;
35 import com.caucho.db.store.BlobInputStream;
36 import com.caucho.db.store.BlobOutputStream;
37 import com.caucho.db.store.Inode;
38 import com.caucho.db.store.Transaction;
39
40 import java.io.IOException JavaDoc;
41 import java.io.InputStream JavaDoc;
42 import java.sql.SQLException JavaDoc;
43 import java.util.logging.Level JavaDoc;
44
45 class BlobColumn extends Column {
46   /**
47    * Creates an inode column.
48    *
49    * @param columnOffset the offset within the row
50    * @param maxLength the maximum length of the string
51    */

52   BlobColumn(Row row, String JavaDoc name)
53   {
54     super(row, name);
55   }
56
57   /**
58    * Returns the type code for the column.
59    */

60   public int getTypeCode()
61   {
62     return BLOB;
63   }
64
65   /**
66    * Returns the java type.
67    */

68   public Class JavaDoc getJavaType()
69   {
70     return java.sql.Blob JavaDoc.class;
71   }
72
73   /**
74    * Returns the declaration size
75    */

76   public int getDeclarationSize()
77   {
78     return 128;
79   }
80
81   /**
82    * Returns the column's size.
83    */

84   public int getLength()
85   {
86     return 128;
87   }
88
89   /**
90    * Sets the string value.
91    *
92    * @param block the buffer to store the row
93    * @param rowOffset the offset into the row
94    * @param str the string value
95    */

96   void setString(Transaction xa,
97          byte []block, int rowOffset, String JavaDoc str)
98   {
99     if (str == null) {
100       setNull(block, rowOffset);
101       return;
102     }
103
104     if (! isNull(block, rowOffset)) {
105       long length = Inode.readLong(block, rowOffset + _columnOffset);
106
107       if (Table.INLINE_BLOB_SIZE <= length) {
108     Inode inode = new Inode();
109     inode.init(getTable(), xa, block, rowOffset + _columnOffset);
110     xa.addDeleteInode(inode);
111       }
112     }
113
114     setNonNull(block, rowOffset);
115
116     try {
117       BlobOutputStream os;
118       os = new BlobOutputStream(xa, getTable(),
119                 block, rowOffset + _columnOffset);
120
121       int length = str.length();
122       for (int i = 0; i < length; i++) {
123     int ch = str.charAt(i);
124
125     if (ch < 0x80)
126       os.write(ch);
127     else if (ch < 0x800) {
128       os.write(0xc0 + (ch >> 6));
129       os.write(0x80 + (ch & 0x3f));
130     }
131     else {
132       os.write(0xe0 + (ch >> 12));
133       os.write(0x80 + ((ch >> 6) & 0x3f));
134       os.write(0x80 + (ch & 0x3f));
135     }
136       }
137
138       os.close();
139     } catch (IOException JavaDoc e) {
140       log.log(Level.WARNING, e.toString(), e);
141     }
142   }
143
144   /**
145    * Sets the string value.
146    *
147    * @param block the buffer to store the row
148    * @param rowOffset the offset into the row
149    * @param str the string value
150    */

151   private void setStream(Transaction xa,
152              byte []block, int rowOffset,
153              InputStream value)
154   {
155     if (value == null) {
156       setNull(block, rowOffset);
157       return;
158     }
159
160     if (! isNull(block, rowOffset)) {
161       long length = Inode.readLong(block, rowOffset + _columnOffset);
162
163       if (Table.INLINE_BLOB_SIZE <= length) {
164     Inode inode = new Inode();
165     inode.init(getTable(), xa, block, rowOffset + _columnOffset);
166     xa.addDeleteInode(inode);
167       }
168     }
169
170     setNonNull(block, rowOffset);
171
172     try {
173       BlobOutputStream os;
174       os = new BlobOutputStream(xa, getTable(),
175                 block, rowOffset + _columnOffset);
176
177       int data;
178       while ((data = value.read()) >= 0) {
179     os.write(data);
180       }
181
182       os.close();
183       value.close();
184     } catch (IOException JavaDoc e) {
185       log.log(Level.WARNING, e.toString(), e);
186     }
187   }
188   
189   /**
190    * Deleting the row, based on the column.
191    *
192    * @param block the block's buffer
193    * @param rowOffset the offset of the row in the block
194    * @param expr the expression to store
195    */

196   @Override JavaDoc
197   void delete(Transaction xa, byte []block, int rowOffset)
198     throws SQLException JavaDoc
199   {
200     if (! isNull(block, rowOffset)) {
201       long length = Inode.readLong(block, rowOffset + _columnOffset);
202
203       if (length < Table.INLINE_BLOB_SIZE)
204     return;
205       
206       Inode inode = new Inode();
207       inode.init(getTable(), xa, block, rowOffset + _columnOffset);
208       xa.addDeleteInode(inode);
209     }
210   }
211
212   @Override JavaDoc
213   public String JavaDoc getString(byte []block, int rowOffset)
214   {
215     if (isNull(block, rowOffset))
216       return null;
217
218     try {
219       BlobInputStream is;
220       is = new BlobInputStream(getTable(), block, rowOffset + _columnOffset);
221
222       int ch;
223       StringBuilder JavaDoc cb = new StringBuilder JavaDoc();
224
225       while ((ch = is.read()) >= 0) {
226     if (ch < 0x80)
227       cb.append((char) ch);
228     else if ((ch & 0xe0) == 0xc0) {
229       int ch1 = is.read();
230       
231       cb.append((char) (((ch & 0x3f) << 6) +
232                 (ch1 & 0x3f)));
233     }
234     else {
235       int ch1 = is.read();
236       int ch2 = is.read();
237       
238       cb.append((char) (((ch & 0xf) << 12) +
239                 ((ch1 & 0x3f) << 6) +
240                 ((ch2 & 0x3f))));
241     }
242       }
243
244       is.close();
245
246       return cb.toString();
247     } catch (IOException JavaDoc e) {
248       log.log(Level.WARNING, e.toString(), e);
249     }
250     
251     return null;
252   }
253
254   /**
255    * Sets based on an iterator.
256    */

257   public void set(Transaction xa,
258           TableIterator iter, Expr expr, QueryContext context)
259     throws SQLException JavaDoc
260   {
261     byte []block = iter.getBuffer();
262     int rowOffset = iter.getRowOffset();
263
264     if (expr.isNull(null))
265       setNull(block, rowOffset);
266     else if (expr.isBinaryStream())
267       setStream(xa, block, rowOffset, expr.evalStream(context));
268     else
269       setString(xa, block, rowOffset, expr.evalString(context));
270     
271     iter.setDirty();
272   }
273   
274   /**
275    * Sets the column based on an expression.
276    *
277    * @param block the block's buffer
278    * @param rowOffset the offset of the row in the block
279    * @param expr the expression to store
280    */

281   void setExpr(Transaction xa,
282            byte []block, int rowOffset,
283            Expr expr, QueryContext context)
284     throws SQLException JavaDoc
285   {
286     if (expr.isNull(null)) {
287       setNull(block, rowOffset);
288     }
289     else if (expr.isBinaryStream()) {
290       setStream(xa, block, rowOffset, expr.evalStream(context));
291     }
292     else {
293       setString(xa, block, rowOffset, expr.evalString(context));
294     }
295   }
296
297   /**
298    * Returns true if the items in the given rows match.
299    */

300   public boolean isEqual(byte []block1, int rowOffset1,
301              byte []block2, int rowOffset2)
302   {
303     if (isNull(block1, rowOffset1) != isNull(block2, rowOffset2))
304       return false;
305
306     int startOffset1 = rowOffset1 + _columnOffset;
307
308     int startOffset2 = rowOffset2 + _columnOffset;
309
310     for (int i = 128 - 1; i >= 0; i--) {
311       if (block1[startOffset1 + i] != block2[startOffset2 + i])
312     return false;
313     }
314
315     return true;
316   }
317
318   /**
319    * Returns true if the bytes match.
320    */

321   public boolean isEqual(byte []block, int rowOffset,
322              byte []buffer, int offset, int length)
323   {
324     if (isNull(block, rowOffset))
325       return false;
326
327     return false;
328   }
329   
330   public boolean isEqual(byte []block, int rowOffset, String JavaDoc value)
331   {
332     if (value == null)
333       return isNull(block, rowOffset);
334     else if (isNull(block, rowOffset))
335       return false;
336     
337     return false;
338   }
339
340   /**
341    * Evaluates the column to a stream.
342    */

343   @Override JavaDoc
344   public void evalToResult(byte []block, int rowOffset, SelectResult result)
345   {
346     if (isNull(block, rowOffset)) {
347       result.writeNull();
348       return;
349     }
350
351     result.writeBlob(block, rowOffset + _columnOffset);
352   }
353
354   public String JavaDoc toString()
355   {
356     return "BlobColumn[" + getName() + "]";
357   }
358 }
359
Popular Tags