/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.type.query; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; import java.util.Map.Entry; import lucee.commons.lang.ExceptionUtil; import lucee.runtime.PageContext; import lucee.runtime.dump.DumpData; import lucee.runtime.dump.DumpProperties; import lucee.runtime.engine.ThreadLocalPageContext; import lucee.runtime.exp.DatabaseException; import lucee.runtime.exp.PageException; import lucee.runtime.op.Caster; import lucee.runtime.query.caster.Cast; import lucee.runtime.type.Collection; import lucee.runtime.type.KeyImpl; import lucee.runtime.type.QueryColumn; import lucee.runtime.type.QueryImpl; import lucee.runtime.type.dt.DateTime; import lucee.runtime.type.it.EntryIterator; import lucee.runtime.type.scope.Undefined; import lucee.runtime.type.util.QueryUtil; public class SimpleQueryColumn implements QueryColumn { private static final long serialVersionUID = 288731277532671308L; private SimpleQuery qry; private Key key; private int type; private ResultSet res; private Cast cast; private int index; //private Object[] data; public SimpleQueryColumn(SimpleQuery qry, ResultSet res, Collection.Key key, int type, int index) { this.qry=qry; this.res=res; this.key=key; this.index=index; try { cast=QueryUtil.toCast(res, type); } catch (Exception e) { throw SimpleQuery.toRuntimeExc(e); } } @Override public Object get(Key key, Object defaultValue) { int row=Caster.toIntValue(key,Integer.MIN_VALUE); if(row==Integer.MIN_VALUE) { Object child=getChildElement(key,null); if(child!=null) return child; return defaultValue; } return get(row,defaultValue); } @Override public Object get(Key key) throws PageException { int row=Caster.toIntValue(key,Integer.MIN_VALUE); if(row==Integer.MIN_VALUE) { Object child=getChildElement(key,null); if(child!=null) return child; throw new DatabaseException("key ["+key+"] not found",null,null,null); } return get(row); } private Object getChildElement(Key key, Object defaultValue) { PageContext pc = ThreadLocalPageContext.get(); // column and query has same name if(key.equals(this.key)) { return get(qry.getCurrentrow(pc.getId()),defaultValue); } // get it from undefined scope if(pc!=null){ Undefined undefined = pc.undefinedScope(); boolean old = undefined.setAllowImplicidQueryCall(false); Object sister = undefined.get(this.key,null); undefined.setAllowImplicidQueryCall(old); if(sister!=null){ try { return pc.get(sister, key); } catch (PageException e) { return defaultValue; } } } return defaultValue; } @Override public int size() { throw SimpleQuery.notSupported(); } @Override public Key[] keys() { throw SimpleQuery.notSupported(); } @Override public Object remove(Key key) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object removeEL(Key key) { throw SimpleQuery.notSupported(); } @Override public Object remove(Key key, Object defaultValue) { throw SimpleQuery.notSupported(); } @Override public void clear() { throw SimpleQuery.notSupported(); } @Override public Object get(String key) throws PageException { return get(KeyImpl.init(key)); } @Override public Object get(String key, Object defaultValue) { return get(KeyImpl.init(key),defaultValue); } @Override public Object set(String key, Object value) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object set(Key key, Object value) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object setEL(String key, Object value) { throw SimpleQuery.notSupported(); } @Override public Object setEL(Key key, Object value) { throw SimpleQuery.notSupported(); } @Override public Collection duplicate(boolean deepCopy) { throw SimpleQuery.notSupported(); } @Override public boolean containsKey(String key) { throw SimpleQuery.notSupported(); } @Override public boolean containsKey(Key key) { throw SimpleQuery.notSupported(); } @Override public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties properties) { throw SimpleQuery.notSupported(); } @Override public Iterator<Collection.Key> keyIterator() { throw SimpleQuery.notSupported(); } @Override public Iterator<String> keysAsStringIterator() { throw SimpleQuery.notSupported(); } @Override public Iterator<Entry<Key, Object>> entryIterator() { return new EntryIterator(this,keys()); } @Override public Iterator<Object> valueIterator() { throw SimpleQuery.notSupported(); } @Override public String castToString() throws PageException { // TODO Auto-generated method stub return Caster.toString(get(key)); } @Override public String castToString(String defaultValue) { return Caster.toString(get(key,defaultValue),defaultValue); } @Override public boolean castToBooleanValue() throws PageException { return Caster.toBoolean(get(key)); } @Override public Boolean castToBoolean(Boolean defaultValue) { return Caster.toBoolean(get(key,defaultValue),defaultValue); } @Override public double castToDoubleValue() throws PageException { return Caster.toDoubleValue(get(key)); } @Override public double castToDoubleValue(double defaultValue) { return Caster.toDoubleValue(get(key,defaultValue),true,defaultValue); } @Override public DateTime castToDateTime() throws PageException { return Caster.toDate(get(key), false, null); } @Override public DateTime castToDateTime(DateTime defaultValue) { return Caster.toDate(get(key,defaultValue), false, null, defaultValue); } @Override public int compareTo(String str) throws PageException { throw SimpleQuery.notSupported(); } @Override public int compareTo(boolean b) throws PageException { throw SimpleQuery.notSupported(); } @Override public int compareTo(double d) throws PageException { throw SimpleQuery.notSupported(); } @Override public int compareTo(DateTime dt) throws PageException { throw SimpleQuery.notSupported(); } @Override public String getKeyAsString() { return key.getString(); } @Override public Key getKey() { return key; } @Override public Object get(PageContext pc) throws PageException { return get(key); } @Override public Object get(PageContext pc, Object defaultValue) { return get(key,defaultValue); } @Override public Object set(PageContext pc, Object value) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object setEL(PageContext pc, Object value) { throw SimpleQuery.notSupported(); } @Override public Object remove(PageContext pc) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object removeEL(PageContext pc) { throw SimpleQuery.notSupported(); } @Override public Object touch(PageContext pc) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object touchEL(PageContext pc) { throw SimpleQuery.notSupported(); } @Override public Object getParent() { return qry; } @Override public Object remove(int row) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object removeRow(int row) throws PageException { throw SimpleQuery.notSupported(); } @Override public Object removeEL(int row) { throw SimpleQuery.notSupported(); } @Override public synchronized Object get(int row) throws PageException { //Object sv = getStoredValue(row); //if(sv!=SimpleQuery.DEFAULT_VALUE) return sv; try { if(row!=res.getRow()) { res.absolute(row); } return _get(row); } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); throw Caster.toPageException(t); } } @Override public synchronized Object get(int row, Object defaultValue) { //Object sv = getStoredValue(row); //if(sv!=SimpleQuery.DEFAULT_VALUE) return sv; try { if(row!=res.getRow()) { res.absolute(row); } return _get(row); } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); return defaultValue; } } /*private synchronized Object getStoredValue(int row) { if(data==null) return SimpleQuery.DEFAULT_VALUE; return data[row-1]; } private synchronized Object _get(int row) throws SQLException, IOException { if(data==null) { data=new Object[qry.getRecordcount()]; for(int i=0;i<data.length;i++){ data[i]=SimpleQuery.DEFAULT_VALUE; } } return data[row-1]=cast.toCFType(null, type, res, index); }*/ private Object _get(int row) throws SQLException, IOException { return cast.toCFType(null, res, index); } @Override public Object set(int row, Object value) throws PageException { throw SimpleQuery.notSupported(); } @Override public void add(Object value) { throw SimpleQuery.notSupported(); } @Override public Object setEL(int row, Object value) { throw SimpleQuery.notSupported(); } @Override public void addRow(int count) { throw SimpleQuery.notSupported(); } @Override public int getType() { return type; } @Override public String getTypeAsString() { return QueryImpl.getColumTypeName(type); } @Override public void cutRowsTo(int maxrows) { throw SimpleQuery.notSupported(); } @Override public Object clone() { throw SimpleQuery.notSupported(); } public int getIndex() { return index; } @Override public java.util.Iterator<String> getIterator() { return keysAsStringIterator(); } }