package railo.runtime.type.query;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import railo.commons.lang.StringUtil;
import railo.loader.engine.CFMLEngineFactory;
import railo.runtime.PageContext;
import railo.runtime.db.DatasourceConnection;
import railo.runtime.db.SQL;
import railo.runtime.db.SQLCaster;
import railo.runtime.db.SQLItem;
import railo.runtime.dump.DumpData;
import railo.runtime.dump.DumpProperties;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PageRuntimeException;
import railo.runtime.op.Caster;
import railo.runtime.type.ArrayImpl;
import railo.runtime.type.ArrayInt;
import railo.runtime.type.Collection;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Objects;
import railo.runtime.type.Query;
import railo.runtime.type.QueryColumn;
import railo.runtime.type.QueryColumnRef;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.it.CollectionIterator;
import railo.runtime.type.it.EntryIterator;
import railo.runtime.type.it.ForEachQueryIterator;
import railo.runtime.type.it.KeyIterator;
import railo.runtime.type.it.StringIterator;
import railo.runtime.type.util.KeyConstants;
import railo.runtime.type.util.QueryUtil;
public class SimpleQuery implements Query, ResultSet, Objects {
static final Object DEFAULT_VALUE = new Object();
private ResultSet res;
private ResultSetMetaData meta;
private Collection.Key[] columnNames;
private Map<String,SimpleQueryColumn> columns=new LinkedHashMap<String, SimpleQueryColumn>();
private int[] _types;
private String name;
private String template;
private SQL sql;
private long exeTime;
private int recordcount;
private ArrayInt arrCurrentRow=new ArrayInt();
public SimpleQuery(DatasourceConnection dc,SQL sql,int maxrow, int fetchsize,int timeout, String name,String template,TimeZone tz) throws PageException {
this.name=name;
this.template=template;
this.sql=sql;
//ResultSet result=null;
Statement stat=null;
// check SQL Restrictions
if(dc.getDatasource().hasSQLRestriction()) {
QueryUtil.checkSQLRestriction(dc,sql);
}
//Stopwatch stopwatch=new Stopwatch(Stopwatch.UNIT_NANO);
//stopwatch.start();
long start=System.nanoTime();
boolean hasResult=false;
try {
SQLItem[] items=sql.getItems();
if(items.length==0) {
stat=dc.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
setAttributes(stat,maxrow,fetchsize,timeout);
// some driver do not support second argument
hasResult=stat.execute(sql.getSQLString());
}
else {
// some driver do not support second argument
PreparedStatement preStat = dc.getPreparedStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
stat=preStat;
setAttributes(preStat,maxrow,fetchsize,timeout);
setItems(tz,preStat,items);
hasResult=preStat.execute();
}
ResultSet res;
do {
if(hasResult) {
res=stat.getResultSet();
init(res);
break;
}
throw new ApplicationException("Simple queries can only be used for queries returning a resultset");
}
while(true);
}
catch (SQLException e) {
throw new DatabaseException(e,sql,dc);
}
catch (Throwable e) {
throw Caster.toPageException(e);
}
exeTime= System.nanoTime()-start;
}
private void setAttributes(Statement stat,int maxrow, int fetchsize,int timeout) throws SQLException {
if(maxrow>-1) stat.setMaxRows(maxrow);
if(fetchsize>0)stat.setFetchSize(fetchsize);
if(timeout>0)stat.setQueryTimeout(timeout);
}
private void setItems(TimeZone tz,PreparedStatement preStat, SQLItem[] items) throws DatabaseException, PageException, SQLException {
for(int i=0;i<items.length;i++) {
SQLCaster.setValue(tz,preStat,i+1,items[i]);
}
}
private void init(ResultSet res) throws SQLException{
this.res=res;
this.meta=res.getMetaData();
// init columns
int columncount = meta.getColumnCount();
List<Key> tmpKeys=new ArrayList<Key>();
//List<Integer> tmpTypes=new ArrayList<Integer>();
//int count=0;
Collection.Key key;
String columnName;
int type;
for(int i=0;i<columncount;i++) {
try {
columnName=meta.getColumnName(i+1);
type=meta.getColumnType(i+1);
} catch (SQLException e) {
throw toRuntimeExc(e);
}
if(StringUtil.isEmpty(columnName))columnName="column_"+i;
key=KeyImpl.init(columnName);
int index=tmpKeys.indexOf(key);
if(index==-1) {
//mappings.put(key.getLowerString(), Caster.toInteger(i+1));
tmpKeys.add(key);
//tmpTypes.add(type);
columns.put(key.getLowerString(), new SimpleQueryColumn(this,res, key,type, i+1));
//count++;
}
}
columnNames=tmpKeys.toArray(new Key[tmpKeys.size()]);
res.last();
recordcount=res.getRow();
res.beforeFirst();
/*Iterator<Integer> it = tmpTypes.iterator();
types=new int[tmpTypes.size()];
int index=0;
while(it.hasNext()){
types[index++]=it.next();
}*/
}
@Override
public int executionTime() {
return (int)exeTime;
}
@Override
public int getUpdateCount() {
throw notSupported();
}
@Override
public int size() {
return columnNames.length;
}
@Override
public Key[] keys() {
return columnNames;
}
@Override
public Object removeEL(Key key) {
throw notSupported();
}
@Override
public Object remove(Key key) throws PageException {
throw notSupported();
}
@Override
public void clear() {
throw notSupported();
}
@Override
public Object get(Key key, Object defaultValue) {
int pid = getPid();
return getAt(key, getCurrentrow(pid),pid,defaultValue);
}
@Override
public Object get(String key, Object defaultValue) {
return get(KeyImpl.init(key),defaultValue);
}
@Override
public Object get(String key) throws PageException {
return get(KeyImpl.init(key));
}
@Override
public Object get(Key key) throws PageException {
int pid = getPid();
return getAt(key, getCurrentrow(pid),pid);
}
public Object getAt(Key key, int row, int pid, Object defaultValue) {
char c=key.lowerCharAt(0);
if(c=='r') {
if(key.equals(KeyConstants._RECORDCOUNT)) return new Double(getRecordcount());
}
else if(c=='c') {
if(key.equals(KeyConstants._CURRENTROW)) return new Double(getCurrentrow(pid));
else if(key.equals(KeyConstants._COLUMNLIST)) return getColumnlist();
}
SimpleQueryColumn column = columns.get(key.getLowerString());
if(column==null) return null;
try {
return column.get(row,defaultValue);
}
catch (Throwable t) {
return defaultValue;
}
}
public Object getAt(Key key, int row,int pid) throws PageException {
Object res = getAt(key,row,pid,DEFAULT_VALUE);
if(res!=DEFAULT_VALUE) return res;
throw new DatabaseException("key ["+key+"] not found",null,null,null);
}
@Override
public Object getAt(Key key, int row, Object defaultValue) {
return getAt(key, row,getPid(),defaultValue);
}
public Object getAt(Key key, int row) throws PageException {
Object res = getAt(key,row,getPid(),DEFAULT_VALUE);
if(res!=DEFAULT_VALUE) return res;
throw new DatabaseException("key ["+key+"] not found",null,null,null);
}
public Object getAt(String key, int row, Object defaultValue) {
return getAt(KeyImpl.init(key), row,defaultValue);
}
@Override
public Object getAt(String key, int row) throws PageException {
return getAt(KeyImpl.init(key), row);
}
@Override
public synchronized int removeRow(int row) throws PageException {
throw notSupported();
}
@Override
public int removeRowEL(int row) {
throw notSupported();
}
@Override
public QueryColumn removeColumn(String key) throws DatabaseException {
throw notSupported();
}
@Override
public QueryColumn removeColumn(Key key) throws DatabaseException {
throw notSupported();
}
@Override
public synchronized QueryColumn removeColumnEL(String key) {
throw notSupported();
}
@Override
public QueryColumn removeColumnEL(Key key) {
throw notSupported();
}
@Override
public Object setEL(String key, Object value) {
throw notSupported();
}
@Override
public Object setEL(Key key, Object value) {
throw notSupported();
}
@Override
public Object set(String key, Object value) throws PageException {
throw notSupported();
}
@Override
public Object set(Key key, Object value) throws PageException {
throw notSupported();
}
@Override
public Object setAt(String key, int row, Object value) throws PageException {
throw notSupported();
}
@Override
public Object setAt(Key key, int row, Object value) throws PageException {
throw notSupported();
}
@Override
public Object setAtEL(String key, int row, Object value) {
throw notSupported();
}
@Override
public Object setAtEL(Key key, int row, Object value) {
throw notSupported();
}
@Override
public synchronized boolean next() {
return next(getPid());
}
@Override
public synchronized boolean next(int pid) {
if(recordcount>=(arrCurrentRow.set(pid,arrCurrentRow.get(pid,0)+1))) {
return true;
}
arrCurrentRow.set(pid,0);
return false;
}
@Override
public synchronized void reset() {
reset(getPid());
}
@Override
public synchronized void reset(int pid) {
arrCurrentRow.set(pid,0);
}
@Override
public int getRecordcount() {
return recordcount;
}
@Override
public synchronized int getCurrentrow(int pid) {
return arrCurrentRow.get(pid, 1);
}
public String getColumnlist(boolean upperCase) {
Key[] columnNames = keys();
StringBuffer sb=new StringBuffer();
for(int i=0;i<columnNames.length;i++) {
if(i>0)sb.append(',');
sb.append(upperCase?columnNames[i].getUpperString():columnNames[i].getString());
}
return sb.toString();
}
public String getColumnlist() {
return getColumnlist(true);
}
public boolean go(int index) {
return go(index,getPid());
}
public boolean go(int index, int pid) {
if(index>0 && index<=recordcount) {
arrCurrentRow.set(pid, index);
return true;
}
arrCurrentRow.set(pid, 0);
return false;
}
/*public synchronized boolean go(int index) {
if(index==getCurrentrow()) return true;
try {
return res.absolute(index);
}
catch (SQLException e) {
throw toRuntimeExc(e);
}
}
public boolean go(int index, int pid) {
return go(index);
}*/
@Override
public boolean isEmpty() {
return recordcount+columnNames.length==0;
}
@Override
public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
return QueryUtil.toDumpData(this, pageContext, maxlevel, dp);
}
@Override
public void sort(String column) throws PageException {
throw notSupported();
}
@Override
public void sort(Key column) throws PageException {
throw notSupported();
}
@Override
public synchronized void sort(String strColumn, int order)
throws PageException {
throw notSupported();
}
@Override
public synchronized void sort(Key keyColumn, int order)
throws PageException {
throw notSupported();
}
@Override
public synchronized boolean addRow(int count) {
throw notSupported();
}
@Override
public boolean addColumn(String columnName, railo.runtime.type.Array content)
throws DatabaseException {
throw notSupported();
}
@Override
public boolean addColumn(Key columnName, railo.runtime.type.Array content)
throws PageException {
throw notSupported();
}
@Override
public synchronized boolean addColumn(String columnName,
railo.runtime.type.Array content, int type)
throws DatabaseException {
throw notSupported();
}
@Override
public boolean addColumn(Key columnName, railo.runtime.type.Array content,
int type) throws DatabaseException {
throw notSupported();
}
@Override
public Object clone() {
return cloneQuery(true);
}
@Override
public Collection duplicate(boolean deepCopy) {
return cloneQuery(deepCopy);
}
public QueryImpl cloneQuery(boolean deepCopy) {
return QueryImpl.cloneQuery(this, deepCopy);
}
@Override
public synchronized int[] getTypes() {
if(_types==null) {
_types=new int[columns.size()];
int i=0;
Iterator<Entry<String, SimpleQueryColumn>> it = columns.entrySet().iterator();
while(it.hasNext()){
_types[i++]=it.next().getValue().getType();
}
}
return _types;
}
@Override
public synchronized Map getTypesAsMap() {
Map<String,String> map=new HashMap<String,String>();
Iterator<SimpleQueryColumn> it = columns.values().iterator();
SimpleQueryColumn c;
while(it.hasNext()){
c=it.next();
map.put(c.getKeyAsString(), c.getTypeAsString());
}
return map;
}
@Override
public QueryColumn getColumn(String key) throws DatabaseException {
return getColumn(KeyImpl.init(key));
}
@Override
public QueryColumn getColumn(Key key) throws DatabaseException {
QueryColumn rtn = getColumn(key,null);
if(rtn!=null) return rtn;
throw new DatabaseException("key ["+key.getString()+"] not found in query, columns are ["+getColumnlist(false)+"]",null,null,null);
}
@Override
public QueryColumn getColumn(String key, QueryColumn defaultValue) {
return getColumn(KeyImpl.init(key),defaultValue);
}
@Override
public QueryColumn getColumn(Key key, QueryColumn defaultValue) {
if(key.getString().length()>0) {
char c=key.lowerCharAt(0);
if(c=='r') {
if(key.equals(KeyConstants._RECORDCOUNT)) return new QueryColumnRef(this,key,Types.INTEGER);
}
else if(c=='c') {
if(key.equals(KeyConstants._CURRENTROW)) return new QueryColumnRef(this,key,Types.INTEGER);
else if(key.equals(KeyConstants._COLUMNLIST)) return new QueryColumnRef(this,key,Types.INTEGER);
}
SimpleQueryColumn col = columns.get(key.getLowerString());
if(col!=null) return col;
}
return defaultValue;
}
@Override
public synchronized void rename(Key columnName, Key newColumnName)
throws ExpressionException {
throw notSupported();
//Integer index=mappings.get(columnName);
//if(index==null) throw new ExpressionException("invalid column name definitions");
// TODO implement
}
@Override
public String toString() {
return res.toString();
}
@Override
public void setExecutionTime(long exeTime) {
throw notSupported();
}
public synchronized boolean cutRowsTo(int maxrows) {
throw notSupported();
}
@Override
public void setCached(boolean isCached) {
throw notSupported();
}
@Override
public boolean isCached() {
return false;
}
@Override
public int addRow() {
throw notSupported();
}
public Key getColumnName(int columnIndex) {
Iterator<SimpleQueryColumn> it = columns.values().iterator();
SimpleQueryColumn c;
while(it.hasNext()){
c = it.next();
if(c.getIndex()==columnIndex) return c.getKey();
}
return null;
}
@Override
public int getColumnIndex(String coulmnName) {
SimpleQueryColumn col = columns.get(coulmnName.toLowerCase());
if(col==null) return -1;
return col.getIndex();
}
@Override
public String[] getColumns() {
return getColumnNamesAsString();
}
@Override
public Key[] getColumnNames() {
Key[] _columns=new Key[columnNames.length];
for(int i=0;i<columnNames.length;i++){
_columns[i]=columnNames[i];
}
return _columns;
}
public void setColumnNames(Key[] trg) {
throw notSupported();
}
@Override
public String[] getColumnNamesAsString() {
String[] _columns=new String[columnNames.length];
for(int i=0;i<columnNames.length;i++){
_columns[i]=columnNames[i].getString();
}
return _columns;
}
@Override
public synchronized String getData(int row, int col) throws IndexOutOfBoundsException {
try{
int rowBefore=res.getRow();
try{
res.absolute(row);
if(col<1 || col>columnNames.length) {
new IndexOutOfBoundsException("invalid column index to retrieve Data from query, valid index goes from 1 to "+columnNames.length);
}
return Caster.toString(get(columnNames[col]));
}
finally{
res.absolute(rowBefore);
}
}
catch(Throwable t){
throw toRuntimeExc(t);
}
}
@Override
public String getName() {
return name;
}
@Override
public int getRowCount() {
return getRecordcount();
}
@Override
public void setData(int row, int col, String value)
throws IndexOutOfBoundsException {
throw notSupported();
}
@Override
public boolean containsKey(String key) {
return columns.get(key.toLowerCase())!=null;
}
@Override
public boolean containsKey(Key key) {
return containsKey(key.getString());
}
@Override
public String castToString() throws ExpressionException {
throw notSupported();
}
@Override
public String castToString(String defaultValue) {
throw notSupported();
}
@Override
public boolean castToBooleanValue() throws ExpressionException {
throw notSupported();
}
@Override
public Boolean castToBoolean(Boolean defaultValue) {
throw notSupported();
}
@Override
public double castToDoubleValue() throws ExpressionException {
throw notSupported();
}
@Override
public double castToDoubleValue(double defaultValue) {
throw notSupported();
}
@Override
public DateTime castToDateTime() throws ExpressionException {
throw notSupported();
}
@Override
public DateTime castToDateTime(DateTime defaultValue) {
throw notSupported();
}
@Override
public int compareTo(boolean b) throws ExpressionException {
throw notSupported();
}
@Override
public int compareTo(DateTime dt) throws PageException {
throw notSupported();
}
@Override
public int compareTo(double d) throws PageException {
throw notSupported();
}
@Override
public int compareTo(String str) throws PageException {
throw notSupported();
}
@Override
public synchronized railo.runtime.type.Array getMetaDataSimple() {
railo.runtime.type.Array cols=new ArrayImpl();
SimpleQueryColumn sqc;
Struct column;
Iterator<SimpleQueryColumn> it = columns.values().iterator();
while(it.hasNext()){
sqc=it.next();
column=new StructImpl();
column.setEL(KeyConstants._name,sqc.getKey());
column.setEL("isCaseSensitive",Boolean.FALSE);
column.setEL("typeName",sqc.getTypeAsString());
cols.appendEL(column);
}
return cols;
}
@Override
public Object getObject(String columnName) throws SQLException {
return res.getObject(toIndex(columnName));
}
@Override
public Object getObject(int columnIndex) throws SQLException {
return res.getObject(columnIndex);
}
@Override
public String getString(int columnIndex) throws SQLException {
return res.getString(columnIndex);
}
@Override
public String getString(String columnName) throws SQLException {
return res.getString(toIndex(columnName));
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
return res.getBoolean(columnIndex);
}
@Override
public boolean getBoolean(String columnName) throws SQLException {
return res.getBoolean(toIndex(columnName));
}
@Override
public Object call(PageContext pc, Key methodName, Object[] arguments)
throws PageException {
throw notSupported();
}
@Override
public Object callWithNamedValues(PageContext pc, Key methodName,
Struct args) throws PageException {
throw notSupported();
}
@Override
public Object get(PageContext pc, Key key, Object defaultValue) {
return getAt(key, getCurrentrow(pc.getId()), pc.getId(),defaultValue);
}
@Override
public Object get(PageContext pc, Key key) throws PageException {
return getAt(key, getCurrentrow(pc.getId()), pc.getId());
}
public boolean isInitalized() {
return true;
}
@Override
public Object set(PageContext pc, Key propertyName, Object value)
throws PageException {
throw notSupported();
}
@Override
public Object setEL(PageContext pc, Key propertyName, Object value) {
throw notSupported();
}
@Override
public boolean wasNull() {
try {
return res.wasNull();
} catch (SQLException e) {
throw toRuntimeExc(e);
}
}
@Override
public synchronized boolean absolute(int row) throws SQLException {
return res.absolute(row);
}
@Override
public synchronized void afterLast() throws SQLException {
res.afterLast();
}
@Override
public synchronized void beforeFirst() throws SQLException {
res.beforeFirst();
}
@Override
public synchronized void cancelRowUpdates() throws SQLException {
res.cancelRowUpdates();
}
@Override
public synchronized void clearWarnings() throws SQLException {
res.clearWarnings();
}
@Override
public synchronized void close() throws SQLException {
res.close();
}
@Override
public synchronized void deleteRow() throws SQLException {
res.deleteRow();
}
@Override
public int findColumn(String columnName) throws SQLException {
return res.findColumn(columnName);
}
@Override
public synchronized boolean first() throws SQLException {
return res.first();
}
@Override
public Array getArray(int i) throws SQLException {
return res.getArray(i);
}
@Override
public Array getArray(String colName) throws SQLException {
return res.getArray(toIndex(colName));
}
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
return res.getAsciiStream(columnIndex);
}
@Override
public InputStream getAsciiStream(String columnName) throws SQLException {
return res.getAsciiStream(toIndex(columnName));
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
return res.getBigDecimal(columnIndex);
}
@Override
public BigDecimal getBigDecimal(String columnName) throws SQLException {
return res.getBigDecimal(toIndex(columnName));
}
@Override
public BigDecimal getBigDecimal(int columnIndex, int scale)
throws SQLException {
return res.getBigDecimal(columnIndex, scale);
}
@Override
public BigDecimal getBigDecimal(String columnName, int scale)
throws SQLException {
return res.getBigDecimal(toIndex(columnName), scale);
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
return res.getBinaryStream(columnIndex);
}
@Override
public InputStream getBinaryStream(String columnName) throws SQLException {
return res.getBinaryStream(toIndex(columnName));
}
@Override
public Blob getBlob(int i) throws SQLException {
return res.getBlob(i);
}
@Override
public Blob getBlob(String colName) throws SQLException {
return res.getBlob(toIndex(colName));
}
@Override
public byte getByte(int columnIndex) throws SQLException {
return res.getByte(columnIndex);
}
@Override
public byte getByte(String columnName) throws SQLException {
return res.getByte(toIndex(columnName));
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
return res.getBytes(columnIndex);
}
@Override
public byte[] getBytes(String columnName) throws SQLException {
return res.getBytes(toIndex(columnName));
}
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
return res.getCharacterStream(columnIndex);
}
@Override
public Reader getCharacterStream(String columnName) throws SQLException {
return res.getCharacterStream(toIndex(columnName));
}
@Override
public Clob getClob(int i) throws SQLException {
return res.getClob(i);
}
@Override
public Clob getClob(String colName) throws SQLException {
return res.getClob(toIndex(colName));
}
@Override
public int getConcurrency() throws SQLException {
return res.getConcurrency();
}
@Override
public String getCursorName() throws SQLException {
return res.getCursorName();
}
@Override
public Date getDate(int columnIndex) throws SQLException {
return res.getDate(columnIndex);
}
@Override
public Date getDate(String columnName) throws SQLException {
return res.getDate(toIndex(columnName));
}
@Override
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
return res.getDate(columnIndex, cal);
}
@Override
public Date getDate(String columnName, Calendar cal) throws SQLException {
return res.getDate(toIndex(columnName), cal);
}
@Override
public double getDouble(int columnIndex) throws SQLException {
return res.getDouble(columnIndex);
}
@Override
public double getDouble(String columnName) throws SQLException {
return res.getDouble(toIndex(columnName));
}
@Override
public int getFetchDirection() throws SQLException {
return res.getFetchDirection();
}
@Override
public int getFetchSize() throws SQLException {
return res.getFetchSize();
}
@Override
public float getFloat(int columnIndex) throws SQLException {
return res.getFloat(columnIndex);
}
@Override
public float getFloat(String columnName) throws SQLException {
return res.getFloat(toIndex(columnName));
}
@Override
public int getInt(int columnIndex) throws SQLException {
return res.getInt(columnIndex);
}
@Override
public int getInt(String columnName) throws SQLException {
return res.getInt(toIndex(columnName));
}
@Override
public long getLong(int columnIndex) throws SQLException {
return res.getLong(columnIndex);
}
@Override
public long getLong(String columnName) throws SQLException {
return res.getLong(toIndex(columnName));
}
@Override
public Object getObject(int i, Map map) throws SQLException {
return res.getObject(i, map);
}
@Override
public Object getObject(String colName, Map map) throws SQLException {
return res.getObject(toIndex(colName), map);
}
// used only with java 7, do not set @Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
return (T) QueryUtil.getObject(this,columnIndex, type);
}
// used only with java 7, do not set @Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
return (T) QueryUtil.getObject(this,columnLabel, type);
}
@Override
public Ref getRef(int i) throws SQLException {
return res.getRef(i);
}
@Override
public Ref getRef(String colName) throws SQLException {
return res.getRef(toIndex(colName));
}
@Override
public int getRow() throws SQLException {
return res.getRow();
}
@Override
public short getShort(int columnIndex) throws SQLException {
return res.getShort(columnIndex);
}
@Override
public short getShort(String columnName) throws SQLException {
return res.getShort(toIndex(columnName));
}
@Override
public Statement getStatement() throws SQLException {
return res.getStatement();
}
@Override
public Time getTime(int columnIndex) throws SQLException {
return res.getTime(columnIndex);
}
@Override
public Time getTime(String columnName) throws SQLException {
return res.getTime(toIndex(columnName));
}
@Override
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
return res.getTime(columnIndex, cal);
}
@Override
public Time getTime(String columnName, Calendar cal) throws SQLException {
return res.getTime(toIndex(columnName), cal);
}
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
return res.getTimestamp(columnIndex);
}
@Override
public Timestamp getTimestamp(String columnName) throws SQLException {
return res.getTimestamp(toIndex(columnName));
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal)
throws SQLException {
return res.getTimestamp(columnIndex, cal);
}
@Override
public Timestamp getTimestamp(String columnName, Calendar cal)
throws SQLException {
return res.getTimestamp(toIndex(columnName), cal);
}
@Override
public int getType() throws SQLException {
return res.getType();
}
@Override
public URL getURL(int columnIndex) throws SQLException {
return res.getURL(columnIndex);
}
@Override
public URL getURL(String columnName) throws SQLException {
return res.getURL(toIndex(columnName));
}
@Override
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
return res.getUnicodeStream(columnIndex);
}
@Override
public InputStream getUnicodeStream(String columnName) throws SQLException {
return res.getUnicodeStream(toIndex(columnName));
}
@Override
public SQLWarning getWarnings() throws SQLException {
return res.getWarnings();
}
@Override
public void insertRow() throws SQLException {
res.insertRow();
}
@Override
public boolean isAfterLast() throws SQLException {
return res.isAfterLast();
}
@Override
public boolean isBeforeFirst() throws SQLException {
return res.isBeforeFirst();
}
@Override
public boolean isFirst() throws SQLException {
return res.isFirst();
}
@Override
public boolean isLast() throws SQLException {
return res.isLast();
}
@Override
public boolean last() throws SQLException {
return res.last();
}
@Override
public void moveToCurrentRow() throws SQLException {
res.moveToCurrentRow();
}
@Override
public void moveToInsertRow() throws SQLException {
res.moveToInsertRow();
}
@Override
public boolean previous() {
throw notSupported();
}
@Override
public boolean previous(int pid) {
throw notSupported();
}
@Override
public void refreshRow() throws SQLException {
res.refreshRow();
}
@Override
public boolean relative(int rows) throws SQLException {
return res.relative(rows);
}
@Override
public boolean rowDeleted() throws SQLException {
return res.rowDeleted();
}
@Override
public boolean rowInserted() throws SQLException {
return res.rowInserted();
}
@Override
public boolean rowUpdated() throws SQLException {
return res.rowUpdated();
}
@Override
public void setFetchDirection(int direction) throws SQLException {
res.setFetchDirection(direction);
}
@Override
public void setFetchSize(int rows) throws SQLException {
res.setFetchSize(rows);
}
@Override
public void updateArray(int columnIndex, Array x) throws SQLException {
res.updateArray(columnIndex, x);
}
@Override
public void updateArray(String columnName, Array x) throws SQLException {
res.updateArray(toIndex(columnName), x);
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length)
throws SQLException {
res.updateAsciiStream(columnIndex, x, length);
}
@Override
public void updateAsciiStream(String columnName, InputStream x, int length)
throws SQLException {
res.updateAsciiStream(toIndex(columnName), x, length);
}
@Override
public void updateBigDecimal(int columnIndex, BigDecimal x)
throws SQLException {
res.updateBigDecimal(columnIndex, x);
}
@Override
public void updateBigDecimal(String columnName, BigDecimal x)
throws SQLException {
res.updateBigDecimal(toIndex(columnName), x);
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length)
throws SQLException {
res.updateBinaryStream(columnIndex, x, length);
}
@Override
public void updateBinaryStream(String columnName, InputStream x, int length)
throws SQLException {
res.updateBinaryStream(toIndex(columnName), x, length);
}
@Override
public void updateBlob(int columnIndex, Blob x) throws SQLException {
res.updateBlob(columnIndex, x);
}
@Override
public void updateBlob(String columnName, Blob x) throws SQLException {
res.updateBlob(toIndex(columnName), x);
}
@Override
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
res.updateBoolean(columnIndex, x);
}
@Override
public void updateBoolean(String columnName, boolean x) throws SQLException {
res.updateBoolean(toIndex(columnName), x);
}
@Override
public void updateByte(int columnIndex, byte x) throws SQLException {
res.updateByte(columnIndex, x);
}
@Override
public void updateByte(String columnName, byte x) throws SQLException {
res.updateByte(toIndex(columnName), x);
}
@Override
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
res.updateBytes(columnIndex, x);
}
@Override
public void updateBytes(String columnName, byte[] x) throws SQLException {
res.updateBytes(toIndex(columnName), x);
}
@Override
public void updateCharacterStream(int columnIndex, Reader reader, int length)
throws SQLException {
res.updateCharacterStream(columnIndex, reader, length);
}
@Override
public void updateCharacterStream(String columnName, Reader reader,
int length) throws SQLException {
res.updateCharacterStream(toIndex(columnName), reader, length);
}
@Override
public void updateClob(int columnIndex, Clob x) throws SQLException {
res.updateClob(columnIndex, x);
}
@Override
public void updateClob(String columnName, Clob x) throws SQLException {
res.updateClob(toIndex(columnName), x);
}
@Override
public void updateDate(int columnIndex, Date x) throws SQLException {
res.updateDate(columnIndex, x);
}
@Override
public void updateDate(String columnName, Date x) throws SQLException {
res.updateDate(toIndex(columnName), x);
}
@Override
public void updateDouble(int columnIndex, double x) throws SQLException {
res.updateDouble(columnIndex, x);
}
@Override
public void updateDouble(String columnName, double x) throws SQLException {
res.updateDouble(toIndex(columnName), x);
}
@Override
public void updateFloat(int columnIndex, float x) throws SQLException {
res.updateFloat(columnIndex, x);
}
@Override
public void updateFloat(String columnName, float x) throws SQLException {
res.updateFloat(toIndex(columnName), x);
}
@Override
public void updateInt(int columnIndex, int x) throws SQLException {
res.updateInt(columnIndex, x);
}
@Override
public void updateInt(String columnName, int x) throws SQLException {
res.updateInt(toIndex(columnName), x);
}
@Override
public void updateLong(int columnIndex, long x) throws SQLException {
res.updateLong(columnIndex, x);
}
@Override
public void updateLong(String columnName, long x) throws SQLException {
res.updateLong(toIndex(columnName), x);
}
@Override
public void updateNull(int columnIndex) throws SQLException {
res.updateNull(columnIndex);
}
@Override
public void updateNull(String columnName) throws SQLException {
res.updateNull(toIndex(columnName));
}
@Override
public void updateObject(int columnIndex, Object x) throws SQLException {
res.updateObject(columnIndex, x);
}
@Override
public void updateObject(String columnName, Object x) throws SQLException {
res.updateObject(toIndex(columnName), x);
}
@Override
public void updateObject(int columnIndex, Object x, int scale)
throws SQLException {
res.updateObject(columnIndex, x, scale);
}
@Override
public void updateObject(String columnName, Object x, int scale)
throws SQLException {
res.updateObject(toIndex(columnName), x, scale);
}
@Override
public void updateRef(int columnIndex, Ref x) throws SQLException {
res.updateRef(columnIndex, x);
}
@Override
public void updateRef(String columnName, Ref x) throws SQLException {
res.updateRef(toIndex(columnName), x);
}
@Override
public void updateRow() throws SQLException {
res.updateRow();
}
@Override
public void updateShort(int columnIndex, short x) throws SQLException {
res.updateShort(columnIndex, x);
}
@Override
public void updateShort(String columnName, short x) throws SQLException {
res.updateShort(toIndex(columnName), x);
}
@Override
public void updateString(int columnIndex, String x) throws SQLException {
res.updateString(columnIndex, x);
}
@Override
public void updateString(String columnName, String x) throws SQLException {
res.updateString(toIndex(columnName), x);
}
@Override
public void updateTime(int columnIndex, Time x) throws SQLException {
res.updateTime(columnIndex, x);
}
@Override
public void updateTime(String columnName, Time x) throws SQLException {
res.updateTime(toIndex(columnName), x);
}
@Override
public void updateTimestamp(int columnIndex, Timestamp x)
throws SQLException {
res.updateTimestamp(columnIndex, x);
}
@Override
public void updateTimestamp(String columnName, Timestamp x)
throws SQLException {
res.updateTimestamp(toIndex(columnName), x);
}
@Override
public ResultSetMetaData getMetaData() throws SQLException {
return res.getMetaData();
}
@Override
public Iterator<Collection.Key> keyIterator() {
return new KeyIterator(keys());
}
@Override
public Iterator<String> keysAsStringIterator() {
return new StringIterator(keys());
}
@Override
public Iterator<Entry<Key, Object>> entryIterator() {
return new EntryIterator(this,keys());
}
@Override
public Iterator<Object> valueIterator() {
return new CollectionIterator(keys(),this);
}
@Override
public boolean equals(Object obj) {
return res.equals(obj);
}
@Override
public int getHoldability() throws SQLException {
return res.getHoldability();
}
@Override
public boolean isClosed() throws SQLException {
return res.isClosed();
}
@Override
public void updateNString(int columnIndex, String nString)
throws SQLException {
res.updateNString(columnIndex, nString);
}
@Override
public void updateNString(String columnLabel, String nString)
throws SQLException {
res.updateNString(toIndex(columnLabel), nString);
}
@Override
public String getNString(int columnIndex) throws SQLException {
return res.getNString(columnIndex);
}
@Override
public String getNString(String columnLabel) throws SQLException {
return res.getNString(toIndex(columnLabel));
}
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
return res.getNCharacterStream(columnIndex);
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
return res.getNCharacterStream(toIndex(columnLabel));
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x, long length)
throws SQLException {
res.updateNCharacterStream(columnIndex, x, length);
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader,
long length) throws SQLException {
res.updateNCharacterStream(toIndex(columnLabel), reader, length);
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, long length)
throws SQLException {
res.updateAsciiStream(columnIndex, x, length);
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, long length)
throws SQLException {
res.updateBinaryStream(columnIndex, x, length);
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, long length)
throws SQLException {
res.updateCharacterStream(columnIndex, x, length);
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, long length)
throws SQLException {
res.updateAsciiStream(toIndex(columnLabel), x, length);
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x,
long length) throws SQLException {
res.updateBinaryStream(toIndex(columnLabel), x, length);
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader,
long length) throws SQLException {
res.updateCharacterStream(toIndex(columnLabel), reader, length);
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream, long length)
throws SQLException {
res.updateBlob(columnIndex, inputStream, length);
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream,
long length) throws SQLException {
res.updateBlob(toIndex(columnLabel), inputStream, length);
}
@Override
public void updateClob(int columnIndex, Reader reader, long length)
throws SQLException {
res.updateClob(columnIndex, reader, length);
}
@Override
public void updateClob(String columnLabel, Reader reader, long length)
throws SQLException {
res.updateClob(toIndex(columnLabel), reader, length);
}
@Override
public void updateNClob(int columnIndex, Reader reader, long length)
throws SQLException {
res.updateNClob(columnIndex, reader, length);
}
@Override
public void updateNClob(String columnLabel, Reader reader, long length)
throws SQLException {
res.updateNClob(toIndex(columnLabel), reader, length);
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x)
throws SQLException {
res.updateNCharacterStream(columnIndex, x);
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader)
throws SQLException {
res.updateNCharacterStream(toIndex(columnLabel), reader);
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x)
throws SQLException {
res.updateAsciiStream(columnIndex, x);
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x)
throws SQLException {
res.updateBinaryStream(columnIndex, x);
}
@Override
public void updateCharacterStream(int columnIndex, Reader x)
throws SQLException {
res.updateCharacterStream(columnIndex, x);
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x)
throws SQLException {
res.updateAsciiStream(toIndex(columnLabel), x);
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x)
throws SQLException {
res.updateBinaryStream(columnLabel, x);
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader)
throws SQLException {
res.updateCharacterStream(toIndex(columnLabel), reader);
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream)
throws SQLException {
res.updateBlob(columnIndex, inputStream);
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream)
throws SQLException {
res.updateBlob(toIndex(columnLabel), inputStream);
}
@Override
public void updateClob(int columnIndex, Reader reader) throws SQLException {
res.updateClob(columnIndex, reader);
}
@Override
public void updateClob(String columnLabel, Reader reader)
throws SQLException {
res.updateClob(toIndex(columnLabel), reader);
}
@Override
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
res.updateNClob(columnIndex, reader);
}
@Override
public void updateNClob(String columnLabel, Reader reader)
throws SQLException {
res.updateNClob(toIndex(columnLabel), reader);
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return res.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return res.isWrapperFor(iface);
}
@Override
public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
res.updateNClob(columnIndex, nClob);
}
@Override
public void updateNClob(String columnLabel, NClob nClob)
throws SQLException {
res.updateNClob(toIndex(columnLabel), nClob);
}
@Override
public NClob getNClob(int columnIndex) throws SQLException {
return res.getNClob(columnIndex);
}
@Override
public NClob getNClob(String columnLabel) throws SQLException {
return res.getNClob(toIndex(columnLabel));
}
@Override
public SQLXML getSQLXML(int columnIndex) throws SQLException {
return res.getSQLXML(columnIndex);
}
@Override
public SQLXML getSQLXML(String columnLabel) throws SQLException {
return res.getSQLXML(toIndex(columnLabel));
}
@Override
public void updateSQLXML(int columnIndex, SQLXML xmlObject)
throws SQLException {
res.updateSQLXML(columnIndex, xmlObject);
}
@Override
public void updateSQLXML(String columnLabel, SQLXML xmlObject)
throws SQLException {
res.updateSQLXML(toIndex(columnLabel), xmlObject);
}
@Override
public RowId getRowId(int columnIndex) throws SQLException {
return res.getRowId(columnIndex);
}
@Override
public RowId getRowId(String columnLabel) throws SQLException {
return res.getRowId(toIndex(columnLabel));
}
@Override
public void updateRowId(int columnIndex, RowId x) throws SQLException {
res.updateRowId(columnIndex, x);
}
@Override
public void updateRowId(String columnLabel, RowId x) throws SQLException {
res.updateRowId(toIndex(columnLabel), x);
}
public synchronized void enableShowQueryUsage() {
throw notSupported();
}
public static PageRuntimeException notSupported() {
return toRuntimeExc(new SQLFeatureNotSupportedException("not supported"));
}
public static PageRuntimeException toRuntimeExc(Throwable t) {
return new PageRuntimeException(Caster.toPageException(t));
}
public static PageException toPageExc(Throwable t) {
return Caster.toPageException(t);
}
private int toIndex(String columnName) throws SQLException {
SimpleQueryColumn col = columns.get(columnName.toLowerCase());
if(col==null) throw new SQLException("There is no column with name ["+columnName+"], available columns are ["+getColumnlist()+"]");
return col.getIndex();
}
int getPid() {
PageContext pc = ThreadLocalPageContext.get();
if(pc==null) {
pc=CFMLEngineFactory.getInstance().getThreadPageContext();
if(pc==null)throw new RuntimeException("cannot get pid for current thread");
}
return pc.getId();
}
@Override
public Query getGeneratedKeys() {
return null;
}
@Override
public SQL getSql() {
return sql;
}
@Override
public String getTemplate() {
return template;
}
@Override
public long getExecutionTime() {
return exeTime;
}
@Override
public java.util.Iterator getIterator() {
return new ForEachQueryIterator(this, ThreadLocalPageContext.get().getId());
}
}