KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > db > sql > SelectResultSetImpl


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  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.db.sql;
30
31 import com.caucho.db.ResultSetImpl;
32 import com.caucho.db.store.BlobInputStream;
33 import com.caucho.db.store.Store;
34 import com.caucho.db.table.Column;
35 import com.caucho.db.table.TableIterator;
36 import com.caucho.sql.SQLExceptionWrapper;
37 import com.caucho.util.CharBuffer;
38 import com.caucho.util.FreeList;
39 import com.caucho.util.L10N;
40 import com.caucho.util.QDate;
41 import com.caucho.vfs.ReadStream;
42 import com.caucho.vfs.TempBuffer;
43 import com.caucho.vfs.TempStream;
44 import com.caucho.vfs.WriteStream;
45
46 import java.io.IOException JavaDoc;
47 import java.sql.SQLException JavaDoc;
48
49 public class SelectResultSetImpl extends ResultSetImpl {
50   private static final L10N L = new L10N(SelectResultSetImpl.class);
51   
52   private static final FreeList<SelectResultSetImpl> _freeList =
53     new FreeList<SelectResultSetImpl>(16);
54   
55   private final WriteStream _ws;
56   private final TempBuffer _buf;
57   private final ReadStream _rs;
58   private final byte []_buffer;
59   private final CharBuffer _cb;
60   private final TempStream _ts;
61
62   private static QDate _date = new QDate();
63   
64   private Expr []_exprs;
65   private int []_types = new int[32];
66   private int []_offsets = new int[32];
67   private int []_lengths = new int[32];
68   private Store []_stores = new Store[32];
69
70   private TableIterator []_rows;
71   private int _rowLength;
72
73   private int _lastColumn;
74
75   private SelectResultSetImpl()
76   {
77     _ws = new WriteStream();
78     _ws.setReuseBuffer(true);
79     _ts = new TempStream();
80     _rs = new ReadStream();
81     _rs.setReuseBuffer(true);
82     _buf = TempBuffer.allocate();
83     _buffer = _buf.getBuffer();
84     _cb = new CharBuffer();
85
86     _rows = new TableIterator[0];
87   }
88
89   public static SelectResultSetImpl create(Expr []exprs)
90   {
91     SelectResultSetImpl rs = _freeList.allocate();
92
93     if (rs == null)
94       rs = new SelectResultSetImpl();
95
96     rs.init(exprs);
97
98     return rs;
99   }
100
101   TableIterator []initRows(FromItem []fromItems)
102   {
103     if (_rows.length < fromItems.length)
104       _rows = new TableIterator[fromItems.length];
105       
106     for (int i = 0; i < fromItems.length; i++) {
107       if (_rows[i] == null)
108     _rows[i] = new TableIterator();
109       _rows[i].init(fromItems[i].getTable());
110     }
111
112     return _rows;
113   }
114     
115
116   private void init(Expr []exprs)
117   {
118     _exprs = exprs;
119     
120     if (_offsets.length < _exprs.length) {
121       _offsets = new int[exprs.length];
122       _lengths = new int[exprs.length];
123       _types = new int[exprs.length];
124       _stores = new Store[exprs.length];
125     }
126
127     for (int i = 0; i < exprs.length; i++) {
128       _stores[i] = exprs[i].getTable();
129     }
130   }
131
132   void initRead()
133     throws IOException JavaDoc
134   {
135     _ts.openRead(_rs, true);
136   }
137
138   WriteStream getWriteStream()
139   {
140     _ts.openWrite();
141     _ws.init(_ts);
142     
143     return _ws;
144   }
145   
146   public boolean next()
147     throws SQLException JavaDoc
148   {
149     try {
150       ReadStream rs = _rs;
151
152       _lastColumn = 0;
153       
154       int hasData = rs.read();
155       if (hasData <= 0)
156     return false;
157
158       int length = 0;
159       int fields = _exprs.length;
160
161       byte []buffer = _buffer;
162       for (int i = 0; i < fields; i++) {
163     int type = rs.read();
164
165     int sublen = 0;
166
167     switch (type) {
168     case Column.NONE:
169       sublen = -1;
170       break;
171       
172     case Column.VARCHAR:
173       int l0 = rs.read();
174       int l1 = rs.read();
175       int l2 = rs.read();
176       int l3 = rs.read();
177     
178       sublen = ((l0 << 24) +
179             (l1 << 16) +
180             (l2 << 8) +
181             (l3));
182       break;
183
184     case Column.INT:
185       sublen = 4;
186       break;
187     case Column.LONG:
188     case Column.DOUBLE:
189     case Column.DATE:
190       sublen = 8;
191       break;
192       
193     case Column.BLOB:
194       sublen = 128;
195       break;
196       
197     default:
198       throw new SQLException JavaDoc("Unknown column: " + type);
199     }
200
201     _types[i] = type;
202     _offsets[i] = length;
203     _lengths[i] = sublen;
204
205     if (sublen > 0) {
206       rs.read(buffer, length, sublen);
207
208       length += sublen;
209     }
210       }
211
212       return true;
213     } catch (IOException JavaDoc e) {
214       throw new SQLExceptionWrapper(e);
215     }
216   }
217
218   /**
219    * Returns the column index with the given name.
220    */

221   public int findColumnIndex(String JavaDoc name)
222     throws SQLException JavaDoc
223   {
224     for (int i = 0; i < _exprs.length; i++) {
225       if (_exprs[i].getName().equals(name))
226     return i + 1;
227     }
228
229     throw new SQLException JavaDoc(L.l("column `{0}' does not exist.", name));
230   }
231
232   /**
233    * Returns the string value of the given index.
234    */

235   public String JavaDoc getString(int index)
236     throws SQLException JavaDoc
237   {
238     _lastColumn = index;
239     
240     byte []buffer = _buffer;
241     int offset = _offsets[index];
242     int length = _lengths[index];
243     
244     switch (_types[index]) {
245     case Column.NONE:
246       return null;
247       
248     case Column.INT:
249       {
250     int value = (((buffer[offset] & 0xff) << 24) +
251              ((buffer[offset + 1] & 0xff) << 16) +
252              ((buffer[offset + 2] & 0xff) << 8) +
253              ((buffer[offset + 3] & 0xff)));
254
255     return String.valueOf(value);
256       }
257       
258     case Column.LONG:
259       {
260     long value = (((buffer[offset + 0] & 0xffL) << 56) +
261               ((buffer[offset + 1] & 0xffL) << 48) +
262               ((buffer[offset + 2] & 0xffL) << 40) +
263               ((buffer[offset + 3] & 0xffL) << 32) +
264               ((buffer[offset + 4] & 0xffL) << 24) +
265               ((buffer[offset + 5] & 0xffL) << 16) +
266               ((buffer[offset + 6] & 0xffL) << 8) +
267               ((buffer[offset + 7] & 0xffL)));
268     return String.valueOf(value);
269       }
270       
271     case Column.DOUBLE:
272       {
273     long value = (((buffer[offset + 0] & 0xffL) << 56) +
274               ((buffer[offset + 1] & 0xffL) << 48) +
275               ((buffer[offset + 2] & 0xffL) << 40) +
276               ((buffer[offset + 3] & 0xffL) << 32) +
277               ((buffer[offset + 4] & 0xffL) << 24) +
278               ((buffer[offset + 5] & 0xffL) << 16) +
279               ((buffer[offset + 6] & 0xffL) << 8) +
280               ((buffer[offset + 7] & 0xffL)));
281     return String.valueOf(Double.longBitsToDouble(value));
282       }
283       
284     case Column.DATE:
285       {
286     long value = (((buffer[offset + 0] & 0xffL) << 56) +
287               ((buffer[offset + 1] & 0xffL) << 48) +
288               ((buffer[offset + 2] & 0xffL) << 40) +
289               ((buffer[offset + 3] & 0xffL) << 32) +
290               ((buffer[offset + 4] & 0xffL) << 24) +
291               ((buffer[offset + 5] & 0xffL) << 16) +
292               ((buffer[offset + 6] & 0xffL) << 8) +
293               ((buffer[offset + 7] & 0xffL)));
294     return QDate.formatGMT(value);
295       }
296
297     case Column.VARCHAR:
298       return getStringValue(index);
299
300     case Column.BLOB:
301       return getBlobString(index);
302
303     default:
304       return null;
305     }
306   }
307
308   /**
309    * Returns the string value for the result set.
310    */

311   private String JavaDoc getStringValue(int index)
312     throws SQLException JavaDoc
313   {
314     _lastColumn = index;
315     
316     int length = _lengths[index];
317     int offset = _offsets[index];
318     
319     if (length < 0)
320       return null;
321
322     CharBuffer cb = _cb;
323     cb.clear();
324
325     byte []buffer = _buffer;
326     for (; length > 0; length--) {
327       cb.append((char) buffer[offset++]);
328     }
329
330     return cb.toString();
331   }
332
333   /**
334    * Returns the string value for the result set.
335    */

336   private String JavaDoc getBlobString(int index)
337     throws SQLException JavaDoc
338   {
339     _lastColumn = index;
340     
341     int offset = _offsets[index];
342
343     CharBuffer cb = _cb;
344     cb.clear();
345
346     BlobInputStream is = null;
347     try {
348       is = new BlobInputStream(_stores[index], _buffer, offset);
349
350       int ch;
351       while ((ch = is.read()) >= 0) {
352     if (ch < 0x80)
353       cb.append((char) ch);
354       }
355     } catch (IOException JavaDoc e) {
356       throw new SQLExceptionWrapper(e);
357     }
358
359     return cb.toString();
360   }
361
362   public int getInt(int index)
363     throws SQLException JavaDoc
364   {
365     _lastColumn = index;
366     
367     byte []buffer = _buffer;
368     int offset = _offsets[index];
369     int length = _lengths[index];
370     
371     switch (_types[index]) {
372     case Column.NONE:
373       return 0;
374       
375     case Column.INT:
376       return (((buffer[offset + 0] & 0xff) << 24) +
377           ((buffer[offset + 1] & 0xff) << 16) +
378           ((buffer[offset + 2] & 0xff) << 8) +
379           ((buffer[offset + 3] & 0xff)));
380       
381     case Column.LONG:
382       {
383     long value = (((buffer[offset + 0] & 0xffL) << 56) +
384               ((buffer[offset + 1] & 0xffL) << 48) +
385               ((buffer[offset + 2] & 0xffL) << 40) +
386               ((buffer[offset + 3] & 0xffL) << 32) +
387               ((buffer[offset + 4] & 0xffL) << 24) +
388               ((buffer[offset + 5] & 0xffL) << 16) +
389               ((buffer[offset + 6] & 0xffL) << 8) +
390               ((buffer[offset + 7] & 0xffL)));
391     return (int) value;
392       }
393       
394     case Column.DOUBLE:
395       {
396     long value = (((buffer[offset + 0] & 0xffL) << 56) +
397               ((buffer[offset + 1] & 0xffL) << 48) +
398               ((buffer[offset + 2] & 0xffL) << 40) +
399               ((buffer[offset + 3] & 0xffL) << 32) +
400               ((buffer[offset + 4] & 0xffL) << 24) +
401               ((buffer[offset + 5] & 0xffL) << 16) +
402               ((buffer[offset + 6] & 0xffL) << 8) +
403               ((buffer[offset + 7] & 0xffL)));
404     return (int) Double.longBitsToDouble(value);
405       }
406
407     case Column.VARCHAR:
408       return Integer.parseInt(getString(index));
409
410     default:
411       return 0;
412     }
413   }
414
415   public long getLong(int index)
416     throws SQLException JavaDoc
417   {
418     _lastColumn = index;
419     
420     byte []buffer = _buffer;
421     int offset = _offsets[index];
422     int length = _lengths[index];
423     
424     switch (_types[index]) {
425     case Column.NONE:
426       return 0;
427       
428     case Column.INT:
429       return (((buffer[offset] & 0xff) << 24) +
430           ((buffer[offset + 1] & 0xff) << 16) +
431           ((buffer[offset + 2] & 0xff) << 8) +
432           ((buffer[offset + 3] & 0xff)));
433       
434     case Column.LONG:
435     case Column.DATE:
436       {
437     long value = (((buffer[offset + 0] & 0xffL) << 56) +
438               ((buffer[offset + 1] & 0xffL) << 48) +
439               ((buffer[offset + 2] & 0xffL) << 40) +
440               ((buffer[offset + 3] & 0xffL) << 32) +
441               ((buffer[offset + 4] & 0xffL) << 24) +
442               ((buffer[offset + 5] & 0xffL) << 16) +
443               ((buffer[offset + 6] & 0xffL) << 8) +
444               ((buffer[offset + 7] & 0xffL)));
445     return value;
446       }
447       
448     case Column.DOUBLE:
449       {
450     long value = (((buffer[offset + 0] & 0xffL) << 56) +
451               ((buffer[offset + 1] & 0xffL) << 48) +
452               ((buffer[offset + 2] & 0xffL) << 40) +
453               ((buffer[offset + 3] & 0xffL) << 32) +
454               ((buffer[offset + 4] & 0xffL) << 24) +
455               ((buffer[offset + 5] & 0xffL) << 16) +
456               ((buffer[offset + 6] & 0xffL) << 8) +
457               ((buffer[offset + 7] & 0xffL)));
458     return (long) Double.longBitsToDouble(value);
459       }
460
461     case Column.VARCHAR:
462       return Long.parseLong(getString(index));
463
464     default:
465       return 0;
466     }
467   }
468
469   /**
470    * Returns a double value from this column.
471    */

472   public double getDouble(int index)
473     throws SQLException JavaDoc
474   {
475     _lastColumn = index;
476     
477     byte []buffer = _buffer;
478     int offset = _offsets[index];
479     int length = _lengths[index];
480     
481     switch (_types[index]) {
482     case Column.NONE:
483       return 0;
484       
485     case Column.INT:
486       return (((buffer[offset + 0] & 0xff) << 24) +
487           ((buffer[offset + 1] & 0xff) << 16) +
488           ((buffer[offset + 2] & 0xff) << 8) +
489           ((buffer[offset + 3] & 0xff)));
490       
491     case Column.LONG:
492       {
493     long value = (((buffer[offset + 0] & 0xffL) << 56) +
494               ((buffer[offset + 1] & 0xffL) << 48) +
495               ((buffer[offset + 2] & 0xffL) << 40) +
496               ((buffer[offset + 3] & 0xffL) << 32) +
497               ((buffer[offset + 4] & 0xffL) << 24) +
498               ((buffer[offset + 5] & 0xffL) << 16) +
499               ((buffer[offset + 6] & 0xffL) << 8) +
500               ((buffer[offset + 7] & 0xffL)));
501     return value;
502       }
503       
504     case Column.DOUBLE:
505       {
506     long value = (((buffer[offset + 0] & 0xffL) << 56) +
507               ((buffer[offset + 1] & 0xffL) << 48) +
508               ((buffer[offset + 2] & 0xffL) << 40) +
509               ((buffer[offset + 3] & 0xffL) << 32) +
510               ((buffer[offset + 4] & 0xffL) << 24) +
511               ((buffer[offset + 5] & 0xffL) << 16) +
512               ((buffer[offset + 6] & 0xffL) << 8) +
513               ((buffer[offset + 7] & 0xffL)));
514     return Double.longBitsToDouble(value);
515       }
516
517     case Column.VARCHAR:
518       return Double.parseDouble(getString(index));
519
520     default:
521       return 0;
522     }
523   }
524
525   public long getDate(int index)
526     throws SQLException JavaDoc
527   {
528     _lastColumn = index;
529     
530     byte []buffer = _buffer;
531     int offset = _offsets[index];
532     int length = _lengths[index];
533     
534     switch (_types[index]) {
535     case Column.NONE:
536       return 0;
537       
538     case Column.LONG:
539     case Column.DATE:
540       {
541     long value = (((buffer[offset + 0] & 0xffL) << 56) +
542               ((buffer[offset + 1] & 0xffL) << 48) +
543               ((buffer[offset + 2] & 0xffL) << 40) +
544               ((buffer[offset + 3] & 0xffL) << 32) +
545               ((buffer[offset + 4] & 0xffL) << 24) +
546               ((buffer[offset + 5] & 0xffL) << 16) +
547               ((buffer[offset + 6] & 0xffL) << 8) +
548               ((buffer[offset + 7] & 0xffL)));
549     return value;
550       }
551
552     case Column.VARCHAR:
553     case Column.BLOB:
554       {
555     String JavaDoc value = getString(index);
556     
557     if (value == null)
558       return 0;
559     
560     synchronized (_date) {
561       try {
562         return _date.parseDate(value);
563       } catch (Exception JavaDoc e) {
564         throw new SQLExceptionWrapper(e);
565       }
566     }
567       }
568
569     default:
570       throw new SQLException JavaDoc("unknown type:" + _types[index]);
571     }
572   }
573
574   /**
575    * Returns true if the last column read was null.
576    */

577   public boolean wasNull()
578   {
579     if (_lastColumn < 0)
580       return false;
581     else
582       return _lengths[_lastColumn] < 0;
583   }
584   
585   public void close()
586   {
587     _freeList.free(this);
588   }
589 }
590
Popular Tags