Package com.caucho.db.sql

Source Code of com.caucho.db.sql.SelectResultSetImpl

/*
* Copyright (c) 1998-2010 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*   Free SoftwareFoundation, Inc.
*   59 Temple Place, Suite 330
*   Boston, MA 02111-1307  USA
*
* @author Scott Ferguson
*/

package com.caucho.db.sql;

import com.caucho.db.ResultSetImpl;
import com.caucho.db.blob.BlobInputStream;
import com.caucho.db.block.BlockStore;
import com.caucho.db.table.Column;
import com.caucho.db.table.TableIterator;
import com.caucho.db.table.Column.ColumnType;
import com.caucho.sql.SQLExceptionWrapper;
import com.caucho.util.CharBuffer;
import com.caucho.util.FreeList;
import com.caucho.util.L10N;
import com.caucho.util.QDate;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.TempBuffer;
import com.caucho.vfs.TempStream;
import com.caucho.vfs.WriteStream;

import java.io.IOException;
import java.sql.SQLException;

public class SelectResultSetImpl extends ResultSetImpl {
  private static final L10N L = new L10N(SelectResultSetImpl.class);
 
  private static final FreeList<SelectResultSetImpl> _freeList =
    new FreeList<SelectResultSetImpl>(16);
 
  private final WriteStream _ws;
  private final TempBuffer _buf;
  private final ReadStream _rs;
  private final byte []_buffer;
  private final CharBuffer _cb;
  private final TempStream _ts;

  private static QDate _date = new QDate();
 
  private Expr []_exprs;
  private ColumnType []_types = new ColumnType[32];
  private int []_offsets = new int[32];
  private int []_lengths = new int[32];
  private BlockStore []_stores = new BlockStore[32];

  private TableIterator []_rows;

  private int _lastColumn;

  private SelectResultSetImpl()
  {
    _ws = new WriteStream();
    _ws.setReuseBuffer(true);
    _ts = new TempStream();
    _rs = new ReadStream();
    _rs.setReuseBuffer(true);
    _buf = TempBuffer.allocate();
    _buffer = _buf.getBuffer();
    _cb = new CharBuffer();

    _rows = new TableIterator[0];
  }

  public static SelectResultSetImpl create(Expr []exprs)
  {
    SelectResultSetImpl rs = _freeList.allocate();

    if (rs == null)
      rs = new SelectResultSetImpl();

    rs.init(exprs);

    return rs;
  }

  TableIterator []initRows(FromItem []fromItems)
  {
    if (_rows.length < fromItems.length)
      _rows = new TableIterator[fromItems.length];
     
    for (int i = 0; i < fromItems.length; i++) {
      if (_rows[i] == null)
  _rows[i] = new TableIterator();
      _rows[i].init(fromItems[i].getTable());
    }

    return _rows;
  }
   

  private void init(Expr []exprs)
  {
    _exprs = exprs;
   
    if (_offsets.length < _exprs.length) {
      _offsets = new int[exprs.length];
      _lengths = new int[exprs.length];
      _types = new ColumnType[exprs.length];
      _stores = new BlockStore[exprs.length];
    }

    for (int i = 0; i < exprs.length; i++) {
      _stores[i] = exprs[i].getTable();
    }
  }

  void initRead()
    throws IOException
  {
    _ts.openRead(_rs);
  }

  WriteStream getWriteStream()
  {
    _ts.openWrite();
    _ws.init(_ts);
   
    return _ws;
  }
 
  public boolean next()
    throws SQLException
  {
    try {
      ReadStream rs = _rs;

      _lastColumn = 0;
     
      int hasData = rs.read();
      if (hasData <= 0)
  return false;

      int length = 0;
      int fields = _exprs.length;

      byte []buffer = _buffer;
      for (int i = 0; i < fields; i++) {
  int type = rs.read();

  int sublen = 0;

  if (type < 0)
    return false;
     
  ColumnType cType = ColumnType.values()[type];

  switch (cType) {
  case NONE:
    sublen = -1;
    break;
   
  case VARCHAR:
    int l0 = rs.read();
    int l1 = rs.read();
    int l2 = rs.read();
    int l3 = rs.read();
 
    sublen = ((l0 << 24) +
        (l1 << 16) +
        (l2 << 8) +
        (l3));
    break;

  case INT:
    sublen = 4;
    break;
  case LONG:
  case DOUBLE:
  case DATE:
    sublen = 8;
    break;
   
  case BLOB:
    sublen = 128;
    break;
   
  default:
    throw new SQLException("Unknown column: " + type);
  }

  _types[i] = cType;
  _offsets[i] = length;
  _lengths[i] = sublen;

  if (sublen > 0) {
    rs.read(buffer, length, sublen);

    length += sublen;
  }
      }

      return true;
    } catch (IOException e) {
      throw new SQLExceptionWrapper(e);
    }
  }

  /**
   * Returns the column index with the given name.
   */
  public int findColumnIndex(String name)
    throws SQLException
  {
    for (int i = 0; i < _exprs.length; i++) {
      if (_exprs[i].getName().equals(name))
  return i + 1;
    }

    throw new SQLException(L.l("column `{0}' does not exist.", name));
  }

  /**
   * Returns the string value of the given index.
   */
  public String getString(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    byte []buffer = _buffer;
    int offset = _offsets[index];
    int length = _lengths[index];
   
    switch (_types[index]) {
    case NONE:
      return null;
     
    case INT:
      {
  int value = (((buffer[offset] & 0xff) << 24) +
         ((buffer[offset + 1] & 0xff) << 16) +
         ((buffer[offset + 2] & 0xff) << 8) +
         ((buffer[offset + 3] & 0xff)));

  return String.valueOf(value);
      }
     
    case LONG:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return String.valueOf(value);
      }
     
    case DOUBLE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return String.valueOf(Double.longBitsToDouble(value));
      }
     
    case DATE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return QDate.formatGMT(value);
      }

    case VARCHAR:
      return getStringValue(index);

    case BLOB:
      return getBlobString(index);

    default:
      return null;
    }
  }

  /**
   * Returns the string value for the result set.
   */
  private String getStringValue(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    int length = _lengths[index];
    int offset = _offsets[index];
   
    if (length < 0)
      return null;

    CharBuffer cb = _cb;
    cb.clear();

    byte []buffer = _buffer;
    for (; length > 0; length--) {
      cb.append((char) buffer[offset++]);
    }

    return cb.toString();
  }

  /**
   * Returns the string value for the result set.
   */
  private String getBlobString(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    int offset = _offsets[index];

    CharBuffer cb = _cb;
    cb.clear();

    BlobInputStream is = null;
    try {
      is = new BlobInputStream(_stores[index], _buffer, offset);

      int ch;
      while ((ch = is.read()) >= 0) {
  if (ch < 0x80)
    cb.append((char) ch);
      }
    } catch (IOException e) {
      throw new SQLExceptionWrapper(e);
    }

    return cb.toString();
  }

  public int getInt(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    byte []buffer = _buffer;
    int offset = _offsets[index];
    int length = _lengths[index];
   
    switch (_types[index]) {
    case NONE:
      return 0;
     
    case INT:
      return (((buffer[offset + 0] & 0xff) << 24) +
        ((buffer[offset + 1] & 0xff) << 16) +
        ((buffer[offset + 2] & 0xff) << 8) +
        ((buffer[offset + 3] & 0xff)));
     
    case LONG:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return (int) value;
      }
     
    case DOUBLE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return (int) Double.longBitsToDouble(value);
      }

    case VARCHAR:
      return Integer.parseInt(getString(index));

    default:
      return 0;
    }
  }

  public long getLong(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    byte []buffer = _buffer;
    int offset = _offsets[index];
    int length = _lengths[index];
   
    switch (_types[index]) {
    case NONE:
      return 0;
     
    case INT:
      return (((buffer[offset] & 0xff) << 24) +
        ((buffer[offset + 1] & 0xff) << 16) +
        ((buffer[offset + 2] & 0xff) << 8) +
        ((buffer[offset + 3] & 0xff)));
     
    case LONG:
    case DATE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return value;
      }
     
    case DOUBLE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return (long) Double.longBitsToDouble(value);
      }

    case VARCHAR:
      return Long.parseLong(getString(index));

    default:
      return 0;
    }
  }

  /**
   * Returns a double value from this column.
   */
  public double getDouble(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    byte []buffer = _buffer;
    int offset = _offsets[index];
    int length = _lengths[index];
   
    switch (_types[index]) {
    case NONE:
      return 0;
     
    case INT:
      return (((buffer[offset + 0] & 0xff) << 24) +
        ((buffer[offset + 1] & 0xff) << 16) +
        ((buffer[offset + 2] & 0xff) << 8) +
        ((buffer[offset + 3] & 0xff)));
     
    case LONG:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return value;
      }
     
    case DOUBLE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return Double.longBitsToDouble(value);
      }

    case VARCHAR:
      return Double.parseDouble(getString(index));

    default:
      return 0;
    }
  }

  public long getDate(int index)
    throws SQLException
  {
    _lastColumn = index;
   
    byte []buffer = _buffer;
    int offset = _offsets[index];
    int length = _lengths[index];
   
    switch (_types[index]) {
    case NONE:
      return 0;
     
    case LONG:
    case DATE:
      {
  long value = (((buffer[offset + 0] & 0xffL) << 56) +
          ((buffer[offset + 1] & 0xffL) << 48) +
          ((buffer[offset + 2] & 0xffL) << 40) +
          ((buffer[offset + 3] & 0xffL) << 32) +
          ((buffer[offset + 4] & 0xffL) << 24) +
          ((buffer[offset + 5] & 0xffL) << 16) +
          ((buffer[offset + 6] & 0xffL) << 8) +
          ((buffer[offset + 7] & 0xffL)));
  return value;
      }

    case VARCHAR:
    case BLOB:
      {
  String value = getString(index);
 
  if (value == null)
    return 0;
 
  synchronized (_date) {
    try {
      return _date.parseDate(value);
    } catch (Exception e) {
      throw new SQLExceptionWrapper(e);
    }
  }
      }

    default:
      throw new SQLException("unknown type:" + _types[index]);
    }
  }

  /**
   * Returns true if the last column read was null.
   */
  public boolean wasNull()
  {
    if (_lastColumn < 0)
      return false;
    else
      return _lengths[_lastColumn] < 0;
  }
 
  public void close()
  {
    _freeList.free(this);
  }
}
TOP

Related Classes of com.caucho.db.sql.SelectResultSetImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.