001    package railo.runtime.type.query;
002    
003    import java.io.InputStream;
004    import java.io.Reader;
005    import java.math.BigDecimal;
006    import java.net.URL;
007    import java.sql.Array;
008    import java.sql.Blob;
009    import java.sql.Clob;
010    import java.sql.Date;
011    import java.sql.NClob;
012    import java.sql.PreparedStatement;
013    import java.sql.Ref;
014    import java.sql.ResultSet;
015    import java.sql.ResultSetMetaData;
016    import java.sql.RowId;
017    import java.sql.SQLException;
018    import java.sql.SQLFeatureNotSupportedException;
019    import java.sql.SQLWarning;
020    import java.sql.SQLXML;
021    import java.sql.Statement;
022    import java.sql.Time;
023    import java.sql.Timestamp;
024    import java.sql.Types;
025    import java.util.ArrayList;
026    import java.util.Calendar;
027    import java.util.HashMap;
028    import java.util.Iterator;
029    import java.util.LinkedHashMap;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.Map.Entry;
033    import java.util.TimeZone;
034    
035    import railo.commons.lang.StringUtil;
036    import railo.loader.engine.CFMLEngineFactory;
037    import railo.runtime.PageContext;
038    import railo.runtime.db.DatasourceConnection;
039    import railo.runtime.db.SQL;
040    import railo.runtime.db.SQLCaster;
041    import railo.runtime.db.SQLItem;
042    import railo.runtime.dump.DumpData;
043    import railo.runtime.dump.DumpProperties;
044    import railo.runtime.engine.ThreadLocalPageContext;
045    import railo.runtime.exp.ApplicationException;
046    import railo.runtime.exp.DatabaseException;
047    import railo.runtime.exp.ExpressionException;
048    import railo.runtime.exp.PageException;
049    import railo.runtime.exp.PageRuntimeException;
050    import railo.runtime.op.Caster;
051    import railo.runtime.type.ArrayImpl;
052    import railo.runtime.type.ArrayInt;
053    import railo.runtime.type.Collection;
054    import railo.runtime.type.KeyImpl;
055    import railo.runtime.type.Objects;
056    import railo.runtime.type.Query;
057    import railo.runtime.type.QueryColumn;
058    import railo.runtime.type.QueryColumnRef;
059    import railo.runtime.type.QueryImpl;
060    import railo.runtime.type.Struct;
061    import railo.runtime.type.StructImpl;
062    import railo.runtime.type.dt.DateTime;
063    import railo.runtime.type.it.CollectionIterator;
064    import railo.runtime.type.it.EntryIterator;
065    import railo.runtime.type.it.ForEachQueryIterator;
066    import railo.runtime.type.it.KeyIterator;
067    import railo.runtime.type.it.StringIterator;
068    import railo.runtime.type.util.KeyConstants;
069    import railo.runtime.type.util.QueryUtil;
070    
071    public class SimpleQuery implements Query, ResultSet, Objects {
072            
073            static final Object DEFAULT_VALUE = new Object();
074            private ResultSet res;
075            private ResultSetMetaData meta;
076            private Collection.Key[] columnNames;
077            private Map<String,SimpleQueryColumn> columns=new LinkedHashMap<String, SimpleQueryColumn>();
078            private int[] _types;
079            
080            private String name;
081            private String template;
082            private SQL sql;
083            private long exeTime;
084            private int recordcount;
085            private ArrayInt arrCurrentRow=new ArrayInt();
086            
087    
088            public SimpleQuery(DatasourceConnection dc,SQL sql,int maxrow, int fetchsize,int timeout, String name,String template,TimeZone tz) throws PageException {
089                    this.name=name;
090                    this.template=template;
091            this.sql=sql;
092                    
093            //ResultSet result=null;
094                    Statement stat=null;
095                    // check SQL Restrictions
096                    if(dc.getDatasource().hasSQLRestriction()) {
097                QueryUtil.checkSQLRestriction(dc,sql);
098            }
099                    
100                    //Stopwatch stopwatch=new Stopwatch(Stopwatch.UNIT_NANO);
101                    //stopwatch.start();
102                    long start=System.nanoTime();
103                    boolean hasResult=false;
104                    try {   
105                            SQLItem[] items=sql.getItems();
106                            if(items.length==0) {
107                            stat=dc.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
108                            setAttributes(stat,maxrow,fetchsize,timeout);
109                         // some driver do not support second argument
110                            hasResult=stat.execute(sql.getSQLString());
111                    }
112                    else {
113                            // some driver do not support second argument
114                            PreparedStatement preStat = dc.getPreparedStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
115                            stat=preStat;
116                        setAttributes(preStat,maxrow,fetchsize,timeout);
117                        setItems(tz,preStat,items);
118                            hasResult=preStat.execute();    
119                    }
120                            ResultSet res;
121                            
122                            do {
123                                    if(hasResult) {
124                                            res=stat.getResultSet();
125                                            init(res);
126                                            break;
127                                    }
128                                    throw new ApplicationException("Simple queries can only be used for queries returning a resultset");
129                            }
130                            while(true);
131                    } 
132                    catch (SQLException e) {
133                            throw new DatabaseException(e,sql,dc);
134                    } 
135                    catch (Throwable e) {
136                            throw Caster.toPageException(e);
137                    }
138                    exeTime= System.nanoTime()-start;
139            }
140            
141            private void setAttributes(Statement stat,int maxrow, int fetchsize,int timeout) throws SQLException {
142                    if(maxrow>-1) stat.setMaxRows(maxrow);
143            if(fetchsize>0)stat.setFetchSize(fetchsize);
144            if(timeout>0)stat.setQueryTimeout(timeout);
145            }
146            private void setItems(TimeZone tz,PreparedStatement preStat, SQLItem[] items) throws DatabaseException, PageException, SQLException {
147                    for(int i=0;i<items.length;i++) {
148                SQLCaster.setValue(tz,preStat,i+1,items[i]);
149            }
150            }
151            
152            private void init(ResultSet res) throws SQLException{
153                    this.res=res;
154                    this.meta=res.getMetaData();
155                    
156                    // init columns
157                    int columncount = meta.getColumnCount();
158                    List<Key> tmpKeys=new ArrayList<Key>();
159                    //List<Integer> tmpTypes=new ArrayList<Integer>();
160                    //int count=0;
161                    Collection.Key key;
162                    String columnName;
163                    int type;
164                    for(int i=0;i<columncount;i++) {
165                            try {
166                                    columnName=meta.getColumnName(i+1);
167                                    type=meta.getColumnType(i+1);
168                            } catch (SQLException e) {
169                                    throw toRuntimeExc(e);
170                            }
171                            if(StringUtil.isEmpty(columnName))columnName="column_"+i;
172                            key=KeyImpl.init(columnName);
173                            int index=tmpKeys.indexOf(key);
174                            if(index==-1) {
175                                    //mappings.put(key.getLowerString(), Caster.toInteger(i+1));
176                                    tmpKeys.add(key);
177                                    //tmpTypes.add(type);
178                                    columns.put(key.getLowerString(), new SimpleQueryColumn(this,res, key,type, i+1));
179                                    
180                                    //count++;
181                            }
182                            
183                    }
184                    columnNames=tmpKeys.toArray(new Key[tmpKeys.size()]);
185                    
186                    res.last();
187                    recordcount=res.getRow();
188                    res.beforeFirst();
189                    /*Iterator<Integer> it = tmpTypes.iterator();
190                    types=new int[tmpTypes.size()];
191                    int index=0;
192                    while(it.hasNext()){
193                            types[index++]=it.next();
194                    }*/
195                    
196                    
197            }
198    
199            @Override
200            public int executionTime() {
201                    return (int)exeTime;
202            }
203    
204            @Override
205            
206            public int getUpdateCount() {
207                    throw notSupported();
208            }
209    
210            @Override
211            public int size() {
212                    return columnNames.length;
213            }
214    
215            @Override
216            
217            public Key[] keys() {
218                    return columnNames;
219            }
220    
221            @Override
222            public Object removeEL(Key key) {
223                    throw notSupported();
224            }
225    
226            @Override
227            public Object remove(Key key) throws PageException {
228                    throw notSupported();
229            }
230    
231            @Override
232            public void clear() {
233                    throw notSupported();
234            }
235    
236            @Override
237            
238            public Object get(Key key, Object defaultValue) {
239                    int pid = getPid();
240                    return getAt(key, getCurrentrow(pid),pid,defaultValue);
241            }
242    
243            @Override
244            public Object get(String key, Object defaultValue) {
245                    return get(KeyImpl.init(key),defaultValue);
246            }
247    
248            @Override
249            public Object get(String key) throws PageException {
250                    return get(KeyImpl.init(key));
251            }
252    
253            @Override
254            
255            public Object get(Key key) throws PageException {
256                    int pid = getPid();
257                    return getAt(key, getCurrentrow(pid),pid);
258            }
259    
260            public Object getAt(Key key, int row, int pid, Object defaultValue) {
261                    char c=key.lowerCharAt(0);
262            if(c=='r') {
263                if(key.equals(KeyConstants._RECORDCOUNT)) return new Double(getRecordcount());
264            }
265            else if(c=='c') {
266                if(key.equals(KeyConstants._CURRENTROW)) return new Double(getCurrentrow(pid));
267                else if(key.equals(KeyConstants._COLUMNLIST)) return getColumnlist();
268            }
269            
270            SimpleQueryColumn column = columns.get(key.getLowerString());
271            if(column==null) return null;
272                    try {
273                            return column.get(row,defaultValue);
274                    } 
275                    catch (Throwable t) {
276                            return defaultValue;
277                    }
278            }
279    
280            public Object getAt(Key key, int row,int pid) throws PageException {
281                    Object res = getAt(key,row,pid,DEFAULT_VALUE);
282                    if(res!=DEFAULT_VALUE) return res;
283                    throw new DatabaseException("key ["+key+"] not found",null,null,null);
284            }
285    
286    
287            @Override
288            
289            public Object getAt(Key key, int row, Object defaultValue) {
290                    return getAt(key, row,getPid(),defaultValue);
291            }
292            
293            
294            public Object getAt(Key key, int row) throws PageException {
295                    Object res = getAt(key,row,getPid(),DEFAULT_VALUE);
296                    if(res!=DEFAULT_VALUE) return res;
297                    throw new DatabaseException("key ["+key+"] not found",null,null,null);
298            }
299    
300            public Object getAt(String key, int row, Object defaultValue) {
301                    return getAt(KeyImpl.init(key), row,defaultValue);
302            }
303    
304            @Override
305            
306            public Object getAt(String key, int row) throws PageException {
307                    return getAt(KeyImpl.init(key), row);
308            }
309    
310            
311            @Override
312            
313            public synchronized int removeRow(int row) throws PageException {
314                    throw notSupported();
315            }
316    
317            @Override
318            
319            public int removeRowEL(int row) {
320                    throw notSupported();
321            }
322    
323            @Override
324            
325            public QueryColumn removeColumn(String key) throws DatabaseException {
326                    throw notSupported();
327            }
328    
329            @Override
330            
331            public QueryColumn removeColumn(Key key) throws DatabaseException {
332                    throw notSupported();
333            }
334    
335            @Override
336            
337            public synchronized QueryColumn removeColumnEL(String key) {
338                    throw notSupported();
339            }
340    
341            @Override
342            
343            public QueryColumn removeColumnEL(Key key) {
344                    throw notSupported();
345            }
346    
347            @Override
348            
349            public Object setEL(String key, Object value) {
350                    throw notSupported();
351            }
352    
353            @Override
354            
355            public Object setEL(Key key, Object value) {
356                    throw notSupported();
357            }
358    
359            @Override
360            
361            public Object set(String key, Object value) throws PageException {
362                    throw notSupported();
363            }
364    
365            @Override
366            
367            public Object set(Key key, Object value) throws PageException {
368                    throw notSupported();
369            }
370    
371            @Override
372            
373            public Object setAt(String key, int row, Object value) throws PageException {
374                    throw notSupported();
375            }
376    
377            @Override
378            
379            public Object setAt(Key key, int row, Object value) throws PageException {
380                    throw notSupported();
381            }
382    
383            @Override
384            
385            public Object setAtEL(String key, int row, Object value) {
386                    throw notSupported();
387            }
388    
389            @Override
390            
391            public Object setAtEL(Key key, int row, Object value) {
392                    throw notSupported();
393            }
394    
395            @Override
396            
397            public synchronized boolean next() {
398                    return next(getPid());
399            }
400    
401            @Override
402            
403            public synchronized boolean next(int pid) {
404                    if(recordcount>=(arrCurrentRow.set(pid,arrCurrentRow.get(pid,0)+1))) {
405                            return true;
406                    }
407                    arrCurrentRow.set(pid,0);
408                    return false;
409            }
410    
411            @Override
412            
413            public synchronized void reset() {
414                    reset(getPid());
415            }
416    
417            @Override
418            
419            public synchronized void reset(int pid) {
420                    arrCurrentRow.set(pid,0);
421            }
422    
423            @Override
424            
425            public int getRecordcount() {
426                    return recordcount;
427            }
428    
429            @Override
430            
431            public synchronized int getCurrentrow(int pid) {
432                    return arrCurrentRow.get(pid, 1);
433            }
434    
435            public String getColumnlist(boolean upperCase) {
436                    Key[] columnNames = keys();
437                    StringBuffer sb=new StringBuffer();
438                    for(int i=0;i<columnNames.length;i++) {
439                            if(i>0)sb.append(',');
440                            sb.append(upperCase?columnNames[i].getUpperString():columnNames[i].getString());
441                    }
442                    return sb.toString();
443            }
444    
445            
446            public String getColumnlist() {
447                    return getColumnlist(true);
448            }
449    
450            public boolean go(int index) {
451                    return go(index,getPid());
452            }
453            
454            public boolean go(int index, int pid) {
455                    if(index>0 && index<=recordcount) {
456                            arrCurrentRow.set(pid, index);
457                            return true;
458                    }
459                    arrCurrentRow.set(pid, 0);
460                    return false;
461            }
462            
463            
464            
465            /*public synchronized boolean go(int index) {
466                    if(index==getCurrentrow()) return true;
467                    try {
468                            return res.absolute(index);
469                    } 
470                    catch (SQLException e) {
471                            throw toRuntimeExc(e);
472                    }
473            }
474            
475            public boolean go(int index, int pid) {
476                    return go(index);
477            }*/
478    
479            @Override
480            public boolean isEmpty() {
481                    return recordcount+columnNames.length==0;
482            }
483    
484            @Override
485            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
486                    return QueryUtil.toDumpData(this, pageContext, maxlevel, dp);
487            }
488    
489            @Override
490            
491            public void sort(String column) throws PageException {
492                    throw notSupported();
493            }
494    
495            @Override
496            
497            public void sort(Key column) throws PageException {
498                    throw notSupported();
499            }
500    
501            @Override
502            
503            public synchronized void sort(String strColumn, int order)
504                            throws PageException {
505                    throw notSupported();
506            }
507    
508            @Override
509            
510            public synchronized void sort(Key keyColumn, int order)
511                            throws PageException {
512                    throw notSupported();
513            }
514    
515            @Override
516            
517            public synchronized boolean addRow(int count) {
518                    throw notSupported();
519            }
520    
521            @Override
522            
523            public boolean addColumn(String columnName, railo.runtime.type.Array content)
524                            throws DatabaseException {
525                    throw notSupported();
526            }
527    
528            @Override
529            
530            public boolean addColumn(Key columnName, railo.runtime.type.Array content)
531                            throws PageException {
532                    throw notSupported();
533            }
534    
535            @Override
536            
537            public synchronized boolean addColumn(String columnName,
538                            railo.runtime.type.Array content, int type)
539                            throws DatabaseException {
540                    throw notSupported();
541            }
542    
543            @Override
544            
545            public boolean addColumn(Key columnName, railo.runtime.type.Array content,
546                            int type) throws DatabaseException {
547                    throw notSupported();
548            }
549    
550            @Override
551            
552            public Object clone() {
553                    return cloneQuery(true);
554            }
555    
556            @Override
557            
558            public Collection duplicate(boolean deepCopy) {
559                    return cloneQuery(deepCopy);
560            }
561    
562            public QueryImpl cloneQuery(boolean deepCopy) {
563                    return QueryImpl.cloneQuery(this, deepCopy);
564            }
565    
566            @Override
567    
568            public synchronized int[] getTypes() {
569                    if(_types==null) {
570                            _types=new int[columns.size()];
571                            int i=0;
572                            Iterator<Entry<String, SimpleQueryColumn>> it = columns.entrySet().iterator();
573                            while(it.hasNext()){
574                                    _types[i++]=it.next().getValue().getType();
575                            }
576                    }
577                    return _types;
578            }
579            @Override
580            
581            public synchronized Map getTypesAsMap() {
582                    Map<String,String> map=new HashMap<String,String>();
583                    Iterator<SimpleQueryColumn> it = columns.values().iterator();
584                    SimpleQueryColumn c;
585                    while(it.hasNext()){
586                            c=it.next();
587                            map.put(c.getKeyAsString(), c.getTypeAsString());
588                    }
589                    return map;
590            }
591    
592            @Override
593            
594            public QueryColumn getColumn(String key) throws DatabaseException {
595                    return getColumn(KeyImpl.init(key));
596            }
597    
598            @Override
599            
600            public QueryColumn getColumn(Key key) throws DatabaseException {
601                    QueryColumn rtn = getColumn(key,null);
602                    if(rtn!=null) return rtn;
603            throw new DatabaseException("key ["+key.getString()+"] not found in query, columns are ["+getColumnlist(false)+"]",null,null,null);
604            }
605    
606            @Override
607            public QueryColumn getColumn(String key, QueryColumn defaultValue) {
608                    return getColumn(KeyImpl.init(key),defaultValue);
609            }
610    
611            @Override
612            
613            public QueryColumn getColumn(Key key, QueryColumn defaultValue) {
614                    if(key.getString().length()>0) {
615                    char c=key.lowerCharAt(0);
616                    if(c=='r') {
617                        if(key.equals(KeyConstants._RECORDCOUNT)) return new QueryColumnRef(this,key,Types.INTEGER);
618                    }
619                    else if(c=='c') {
620                        if(key.equals(KeyConstants._CURRENTROW)) return new QueryColumnRef(this,key,Types.INTEGER);
621                        else if(key.equals(KeyConstants._COLUMNLIST)) return new QueryColumnRef(this,key,Types.INTEGER);
622                    }
623                    SimpleQueryColumn col = columns.get(key.getLowerString());
624                    if(col!=null) return col;
625                    
626                    }
627                    return defaultValue;
628            }
629    
630            @Override
631            
632            public synchronized void rename(Key columnName, Key newColumnName)
633                            throws ExpressionException {
634                    throw notSupported();
635                    //Integer index=mappings.get(columnName);
636                    //if(index==null) throw new ExpressionException("invalid column name definitions");     
637                    // TODO implement
638            }
639    
640            @Override
641            public String toString() {
642                    return res.toString();
643            }
644    
645            @Override
646            public void setExecutionTime(long exeTime) {
647                    throw notSupported();
648            }
649    
650            public synchronized boolean cutRowsTo(int maxrows) {
651                    throw notSupported();
652            }
653    
654            @Override
655            public void setCached(boolean isCached) {
656                    throw notSupported();
657            }
658    
659            @Override
660            public boolean isCached() {
661                    return false;
662            }
663    
664            @Override
665            public int addRow() {
666                    throw notSupported();
667            }
668    
669            public Key getColumnName(int columnIndex) {
670                    Iterator<SimpleQueryColumn> it = columns.values().iterator();
671                    SimpleQueryColumn c;
672                    while(it.hasNext()){
673                            c = it.next();
674                            if(c.getIndex()==columnIndex) return c.getKey();
675                    }
676                    return null;
677            }
678    
679            @Override
680            
681            public int getColumnIndex(String coulmnName) {
682                    SimpleQueryColumn col = columns.get(coulmnName.toLowerCase());
683                    if(col==null) return -1;
684                    return col.getIndex();
685            }
686    
687            @Override
688            
689            public String[] getColumns() {
690                    return getColumnNamesAsString();
691            }
692    
693            @Override
694            
695            public Key[] getColumnNames() {
696                    Key[] _columns=new Key[columnNames.length];
697                    for(int i=0;i<columnNames.length;i++){
698                            _columns[i]=columnNames[i];
699                    }
700                    return _columns;
701            }
702    
703            public void setColumnNames(Key[] trg) {
704                    throw notSupported();
705            }
706    
707            @Override
708            
709            public String[] getColumnNamesAsString() {
710                    String[] _columns=new String[columnNames.length];
711                    for(int i=0;i<columnNames.length;i++){
712                            _columns[i]=columnNames[i].getString();
713                    }
714                    return _columns;
715            }
716    
717            @Override
718            
719            public synchronized String getData(int row, int col) throws IndexOutOfBoundsException {
720                    try{
721                            int rowBefore=res.getRow();
722                            try{
723                                    res.absolute(row);
724                                    if(col<1 || col>columnNames.length) {
725                                            new IndexOutOfBoundsException("invalid column index to retrieve Data from query, valid index goes from 1 to "+columnNames.length);
726                                    }
727                                    return Caster.toString(get(columnNames[col]));
728                                    
729                            }
730                            finally{
731                                    res.absolute(rowBefore);
732                            }
733                    }
734                    catch(Throwable t){
735                            throw toRuntimeExc(t);
736                    }
737            }
738    
739            @Override
740            
741            public String getName() {
742                    return name;
743            }
744    
745            @Override
746            
747            public int getRowCount() {
748                    return getRecordcount();
749            }
750    
751            @Override
752            
753            public void setData(int row, int col, String value)
754                            throws IndexOutOfBoundsException {
755                    throw notSupported();
756            }
757    
758            @Override
759            
760            public boolean containsKey(String key) {
761                    return columns.get(key.toLowerCase())!=null;
762            }
763    
764            @Override
765            
766            public boolean containsKey(Key key) {
767                    return containsKey(key.getString());
768            }
769    
770            @Override
771            
772            public String castToString() throws ExpressionException {
773                    throw notSupported();
774            }
775    
776            @Override
777            
778            public String castToString(String defaultValue) {
779                    throw notSupported();
780            }
781    
782            @Override
783            
784            public boolean castToBooleanValue() throws ExpressionException {
785                    throw notSupported();
786            }
787    
788            @Override
789            
790            public Boolean castToBoolean(Boolean defaultValue) {
791                    throw notSupported();
792            }
793    
794            @Override
795            
796            public double castToDoubleValue() throws ExpressionException {
797                    throw notSupported();
798            }
799    
800            @Override
801            
802            public double castToDoubleValue(double defaultValue) {
803                    throw notSupported();
804            }
805    
806            @Override
807            
808            public DateTime castToDateTime() throws ExpressionException {
809                    throw notSupported();
810            }
811    
812            @Override
813            
814            public DateTime castToDateTime(DateTime defaultValue) {
815                    throw notSupported();
816            }
817    
818            @Override
819            
820            public int compareTo(boolean b) throws ExpressionException {
821                    throw notSupported();
822            }
823    
824            @Override
825            
826            public int compareTo(DateTime dt) throws PageException {
827                    throw notSupported();
828            }
829    
830            @Override
831            
832            public int compareTo(double d) throws PageException {
833                    throw notSupported();
834            }
835    
836            @Override
837            
838            public int compareTo(String str) throws PageException {
839                    throw notSupported();
840            }
841    
842            @Override
843            public synchronized railo.runtime.type.Array getMetaDataSimple() {
844                            railo.runtime.type.Array cols=new ArrayImpl();
845                    SimpleQueryColumn sqc;
846                    Struct column;
847                    Iterator<SimpleQueryColumn> it = columns.values().iterator();
848                    while(it.hasNext()){
849                            sqc=it.next();
850                            column=new StructImpl();
851                            column.setEL(KeyConstants._name,sqc.getKey());
852                            column.setEL("isCaseSensitive",Boolean.FALSE);
853                            column.setEL("typeName",sqc.getTypeAsString());
854                            cols.appendEL(column);
855                    }
856                    return cols;
857                }
858            
859            @Override
860            
861            public Object getObject(String columnName) throws SQLException {
862                    return res.getObject(toIndex(columnName));
863            }
864    
865            @Override
866            
867            public Object getObject(int columnIndex) throws SQLException {
868                    return res.getObject(columnIndex);
869            }
870    
871            @Override
872            
873            public String getString(int columnIndex) throws SQLException {
874                    return res.getString(columnIndex);
875            }
876    
877            @Override
878            
879            public String getString(String columnName) throws SQLException {
880                    return res.getString(toIndex(columnName));
881            }
882    
883            @Override
884            
885            public boolean getBoolean(int columnIndex) throws SQLException {
886                    return res.getBoolean(columnIndex);
887            }
888    
889            @Override
890            
891            public boolean getBoolean(String columnName) throws SQLException {
892                    return res.getBoolean(toIndex(columnName));
893            }
894    
895            @Override
896            
897            public Object call(PageContext pc, Key methodName, Object[] arguments)
898                            throws PageException {
899                    throw notSupported();
900            }
901    
902    
903            @Override
904            
905            public Object callWithNamedValues(PageContext pc, Key methodName,
906                            Struct args) throws PageException {
907                    throw notSupported();
908            }
909    
910            @Override       
911            public Object get(PageContext pc, Key key, Object defaultValue) {
912                    return getAt(key, getCurrentrow(pc.getId()), pc.getId(),defaultValue);
913            }
914    
915            @Override
916            public Object get(PageContext pc, Key key) throws PageException {
917                    return getAt(key, getCurrentrow(pc.getId()), pc.getId());
918            }
919    
920            public boolean isInitalized() {
921                    return true;
922            }
923    
924            @Override
925            
926            public Object set(PageContext pc, Key propertyName, Object value)
927                            throws PageException {
928                    throw notSupported();
929            }
930    
931    
932            @Override       
933            public Object setEL(PageContext pc, Key propertyName, Object value) {
934                    throw notSupported();
935            }
936    
937            @Override
938            public boolean wasNull() {
939                    try {
940                            return res.wasNull();
941                    } catch (SQLException e) {
942                            throw toRuntimeExc(e);
943                    }
944            }
945    
946            @Override
947            
948            public synchronized boolean absolute(int row) throws SQLException {
949                    return res.absolute(row);
950            }
951    
952            @Override
953            
954            public synchronized void afterLast() throws SQLException {
955                    res.afterLast();
956            }
957    
958            @Override
959            
960            public synchronized void beforeFirst() throws SQLException {
961                    res.beforeFirst();
962            }
963    
964            @Override
965            
966            public synchronized void cancelRowUpdates() throws SQLException {
967                    res.cancelRowUpdates();
968            }
969    
970            @Override
971            
972            public synchronized void clearWarnings() throws SQLException {
973                    res.clearWarnings();
974            }
975    
976            @Override
977            
978            public synchronized void close() throws SQLException {
979                    res.close();
980            }
981    
982            @Override
983            
984            public synchronized void deleteRow() throws SQLException {
985                    res.deleteRow();
986            }
987    
988            @Override
989            
990            public int findColumn(String columnName) throws SQLException {
991                    return res.findColumn(columnName);
992            }
993    
994            @Override
995            
996            public synchronized boolean first() throws SQLException {
997                    return res.first();
998            }
999    
1000            @Override
1001            
1002            public Array getArray(int i) throws SQLException {
1003                    return res.getArray(i);
1004            }
1005    
1006            @Override
1007            
1008            public Array getArray(String colName) throws SQLException {
1009                    return res.getArray(toIndex(colName));
1010            }
1011    
1012            @Override
1013            
1014            public InputStream getAsciiStream(int columnIndex) throws SQLException {
1015                    return res.getAsciiStream(columnIndex);
1016            }
1017    
1018            @Override
1019            
1020            public InputStream getAsciiStream(String columnName) throws SQLException {
1021                    return res.getAsciiStream(toIndex(columnName));
1022            }
1023    
1024            @Override
1025            
1026            public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
1027                    return res.getBigDecimal(columnIndex);
1028            }
1029    
1030            @Override
1031            
1032            public BigDecimal getBigDecimal(String columnName) throws SQLException {
1033                    return res.getBigDecimal(toIndex(columnName));
1034            }
1035    
1036            @Override
1037            
1038            public BigDecimal getBigDecimal(int columnIndex, int scale)
1039                            throws SQLException {
1040                    return res.getBigDecimal(columnIndex, scale);
1041            }
1042    
1043            @Override
1044            
1045            public BigDecimal getBigDecimal(String columnName, int scale)
1046                            throws SQLException {
1047                    return res.getBigDecimal(toIndex(columnName), scale);
1048            }
1049    
1050            @Override
1051            
1052            public InputStream getBinaryStream(int columnIndex) throws SQLException {
1053                    return res.getBinaryStream(columnIndex);
1054            }
1055    
1056            @Override
1057            
1058            public InputStream getBinaryStream(String columnName) throws SQLException {
1059                    return res.getBinaryStream(toIndex(columnName));
1060            }
1061    
1062            @Override
1063            
1064            public Blob getBlob(int i) throws SQLException {
1065                    return res.getBlob(i);
1066            }
1067    
1068            @Override
1069            
1070            public Blob getBlob(String colName) throws SQLException {
1071                    return res.getBlob(toIndex(colName));
1072            }
1073    
1074            @Override
1075            
1076            public byte getByte(int columnIndex) throws SQLException {
1077                    return res.getByte(columnIndex);
1078            }
1079    
1080            @Override
1081            
1082            public byte getByte(String columnName) throws SQLException {
1083                    return res.getByte(toIndex(columnName));
1084            }
1085    
1086            @Override
1087            
1088            public byte[] getBytes(int columnIndex) throws SQLException {
1089                    return res.getBytes(columnIndex);
1090            }
1091    
1092            @Override
1093            
1094            public byte[] getBytes(String columnName) throws SQLException {
1095                    return res.getBytes(toIndex(columnName));
1096            }
1097    
1098            @Override
1099            
1100            public Reader getCharacterStream(int columnIndex) throws SQLException {
1101                    return res.getCharacterStream(columnIndex);
1102            }
1103    
1104            @Override
1105            
1106            public Reader getCharacterStream(String columnName) throws SQLException {
1107                    return res.getCharacterStream(toIndex(columnName));
1108            }
1109    
1110            @Override
1111            
1112            public Clob getClob(int i) throws SQLException {
1113                    return res.getClob(i);
1114            }
1115    
1116            @Override
1117            
1118            public Clob getClob(String colName) throws SQLException {
1119                    return res.getClob(toIndex(colName));
1120            }
1121    
1122            @Override
1123            
1124            public int getConcurrency() throws SQLException {
1125                    return res.getConcurrency();
1126            }
1127    
1128            @Override
1129            
1130            public String getCursorName() throws SQLException {
1131                    return res.getCursorName();
1132            }
1133    
1134            @Override
1135            
1136            public Date getDate(int columnIndex) throws SQLException {
1137                    return res.getDate(columnIndex);
1138            }
1139    
1140            @Override
1141            
1142            public Date getDate(String columnName) throws SQLException {
1143                    return res.getDate(toIndex(columnName));
1144            }
1145    
1146            @Override
1147            
1148            public Date getDate(int columnIndex, Calendar cal) throws SQLException {
1149                    return res.getDate(columnIndex, cal);
1150            }
1151    
1152            @Override
1153            
1154            public Date getDate(String columnName, Calendar cal) throws SQLException {
1155                    return res.getDate(toIndex(columnName), cal);
1156            }
1157    
1158            @Override
1159            
1160            public double getDouble(int columnIndex) throws SQLException {
1161                    return res.getDouble(columnIndex);
1162            }
1163    
1164            @Override
1165            
1166            public double getDouble(String columnName) throws SQLException {
1167                    return res.getDouble(toIndex(columnName));
1168            }
1169    
1170            @Override
1171            
1172            public int getFetchDirection() throws SQLException {
1173                    return res.getFetchDirection();
1174            }
1175    
1176            @Override
1177            
1178            public int getFetchSize() throws SQLException {
1179                    return res.getFetchSize();
1180            }
1181    
1182            @Override
1183            
1184            public float getFloat(int columnIndex) throws SQLException {
1185                    return res.getFloat(columnIndex);
1186            }
1187    
1188            @Override
1189            
1190            public float getFloat(String columnName) throws SQLException {
1191                    return res.getFloat(toIndex(columnName));
1192            }
1193    
1194            @Override
1195            
1196            public int getInt(int columnIndex) throws SQLException {
1197                    return res.getInt(columnIndex);
1198            }
1199    
1200            @Override
1201            
1202            public int getInt(String columnName) throws SQLException {
1203                    return res.getInt(toIndex(columnName));
1204            }
1205    
1206            @Override
1207            
1208            public long getLong(int columnIndex) throws SQLException {
1209                    return res.getLong(columnIndex);
1210            }
1211    
1212            @Override
1213            
1214            public long getLong(String columnName) throws SQLException {
1215                    return res.getLong(toIndex(columnName));
1216            }
1217    
1218            @Override
1219            
1220            public Object getObject(int i, Map map) throws SQLException {
1221                    return res.getObject(i, map);
1222            }
1223    
1224            @Override
1225            
1226            public Object getObject(String colName, Map map) throws SQLException {
1227                    return res.getObject(toIndex(colName), map);
1228            }
1229    
1230            // used only with java 7, do not set @Override
1231            public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
1232                    return (T) QueryUtil.getObject(this,columnIndex, type);
1233            }
1234    
1235            // used only with java 7, do not set @Override
1236            public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
1237                    return (T) QueryUtil.getObject(this,columnLabel, type);
1238            }
1239            
1240            @Override
1241            
1242            public Ref getRef(int i) throws SQLException {
1243                    return res.getRef(i);
1244            }
1245    
1246            @Override
1247            
1248            public Ref getRef(String colName) throws SQLException {
1249                    return res.getRef(toIndex(colName));
1250            }
1251    
1252            @Override
1253            
1254            public int getRow() throws SQLException {
1255                    return res.getRow();
1256            }
1257    
1258            @Override
1259            
1260            public short getShort(int columnIndex) throws SQLException {
1261                    return res.getShort(columnIndex);
1262            }
1263    
1264            @Override
1265            
1266            public short getShort(String columnName) throws SQLException {
1267                    return res.getShort(toIndex(columnName));
1268            }
1269    
1270            @Override
1271            
1272            public Statement getStatement() throws SQLException {
1273                    return res.getStatement();
1274            }
1275    
1276            @Override
1277            
1278            public Time getTime(int columnIndex) throws SQLException {
1279                    return res.getTime(columnIndex);
1280            }
1281    
1282            @Override
1283            
1284            public Time getTime(String columnName) throws SQLException {
1285                    return res.getTime(toIndex(columnName));
1286            }
1287    
1288            @Override
1289            
1290            public Time getTime(int columnIndex, Calendar cal) throws SQLException {
1291                    return res.getTime(columnIndex, cal);
1292            }
1293    
1294            @Override
1295            
1296            public Time getTime(String columnName, Calendar cal) throws SQLException {
1297                    return res.getTime(toIndex(columnName), cal);
1298            }
1299    
1300            @Override
1301            
1302            public Timestamp getTimestamp(int columnIndex) throws SQLException {
1303                    return res.getTimestamp(columnIndex);
1304            }
1305    
1306            @Override
1307            
1308            public Timestamp getTimestamp(String columnName) throws SQLException {
1309                    return res.getTimestamp(toIndex(columnName));
1310            }
1311    
1312            @Override
1313            
1314            public Timestamp getTimestamp(int columnIndex, Calendar cal)
1315                            throws SQLException {
1316                    return res.getTimestamp(columnIndex, cal);
1317            }
1318    
1319            @Override
1320            
1321            public Timestamp getTimestamp(String columnName, Calendar cal)
1322                            throws SQLException {
1323                    return res.getTimestamp(toIndex(columnName), cal);
1324            }
1325    
1326            @Override
1327            
1328            public int getType() throws SQLException {
1329                    return res.getType();
1330            }
1331    
1332            @Override
1333            
1334            public URL getURL(int columnIndex) throws SQLException {
1335                    return res.getURL(columnIndex);
1336            }
1337    
1338            @Override
1339            
1340            public URL getURL(String columnName) throws SQLException {
1341                    return res.getURL(toIndex(columnName));
1342            }
1343    
1344            @Override
1345            
1346            public InputStream getUnicodeStream(int columnIndex) throws SQLException {
1347                    return res.getUnicodeStream(columnIndex);
1348            }
1349    
1350            @Override
1351            
1352            public InputStream getUnicodeStream(String columnName) throws SQLException {
1353                    return res.getUnicodeStream(toIndex(columnName));
1354            }
1355    
1356            @Override
1357            
1358            public SQLWarning getWarnings() throws SQLException {
1359                    return res.getWarnings();
1360            }
1361    
1362            @Override
1363            
1364            public void insertRow() throws SQLException {
1365                    res.insertRow();
1366            }
1367    
1368            @Override
1369            
1370            public boolean isAfterLast() throws SQLException {
1371                    return res.isAfterLast();
1372            }
1373    
1374            @Override
1375            
1376            public boolean isBeforeFirst() throws SQLException {
1377                    return res.isBeforeFirst();
1378            }
1379    
1380            @Override
1381            
1382            public boolean isFirst() throws SQLException {
1383                    return res.isFirst();
1384            }
1385    
1386            @Override
1387            
1388            public boolean isLast() throws SQLException {
1389                    return res.isLast();
1390            }
1391    
1392            @Override
1393            
1394            public boolean last() throws SQLException {
1395                    return res.last();
1396            }
1397    
1398            @Override
1399            
1400            public void moveToCurrentRow() throws SQLException {
1401                    res.moveToCurrentRow();
1402            }
1403    
1404            @Override
1405            
1406            public void moveToInsertRow() throws SQLException {
1407                    res.moveToInsertRow();
1408            }
1409    
1410            @Override
1411            
1412            public boolean previous() {
1413                    throw notSupported();
1414            }
1415    
1416            @Override
1417            
1418            public boolean previous(int pid) {
1419                    throw notSupported();
1420            }
1421    
1422            @Override
1423            
1424            public void refreshRow() throws SQLException {
1425                    res.refreshRow();
1426            }
1427    
1428            @Override
1429            
1430            public boolean relative(int rows) throws SQLException {
1431                    return res.relative(rows);
1432            }
1433    
1434            @Override
1435            
1436            public boolean rowDeleted() throws SQLException {
1437                    return res.rowDeleted();
1438            }
1439    
1440            @Override
1441            
1442            public boolean rowInserted() throws SQLException {
1443                    return res.rowInserted();
1444            }
1445    
1446            @Override
1447            
1448            public boolean rowUpdated() throws SQLException {
1449                    return res.rowUpdated();
1450            }
1451    
1452            @Override
1453            
1454            public void setFetchDirection(int direction) throws SQLException {
1455                    res.setFetchDirection(direction);
1456            }
1457    
1458            @Override
1459            
1460            public void setFetchSize(int rows) throws SQLException {
1461                    res.setFetchSize(rows);
1462            }
1463    
1464            @Override
1465            
1466            public void updateArray(int columnIndex, Array x) throws SQLException {
1467                    res.updateArray(columnIndex, x);
1468            }
1469    
1470            @Override
1471            
1472            public void updateArray(String columnName, Array x) throws SQLException {
1473                    res.updateArray(toIndex(columnName), x);
1474            }
1475    
1476            @Override
1477            
1478            public void updateAsciiStream(int columnIndex, InputStream x, int length)
1479                            throws SQLException {
1480                    res.updateAsciiStream(columnIndex, x, length);
1481            }
1482    
1483            @Override
1484            
1485            public void updateAsciiStream(String columnName, InputStream x, int length)
1486                            throws SQLException {
1487                    res.updateAsciiStream(toIndex(columnName), x, length);
1488            }
1489    
1490            @Override
1491            
1492            public void updateBigDecimal(int columnIndex, BigDecimal x)
1493                            throws SQLException {
1494                    res.updateBigDecimal(columnIndex, x);
1495            }
1496    
1497            @Override
1498            
1499            public void updateBigDecimal(String columnName, BigDecimal x)
1500                            throws SQLException {
1501                    res.updateBigDecimal(toIndex(columnName), x);
1502            }
1503    
1504            @Override
1505            
1506            public void updateBinaryStream(int columnIndex, InputStream x, int length)
1507                            throws SQLException {
1508                    res.updateBinaryStream(columnIndex, x, length);
1509            }
1510    
1511            @Override
1512            
1513            public void updateBinaryStream(String columnName, InputStream x, int length)
1514                            throws SQLException {
1515                    res.updateBinaryStream(toIndex(columnName), x, length);
1516            }
1517    
1518            @Override
1519            
1520            public void updateBlob(int columnIndex, Blob x) throws SQLException {
1521                    res.updateBlob(columnIndex, x);
1522            }
1523    
1524            @Override
1525            
1526            public void updateBlob(String columnName, Blob x) throws SQLException {
1527                    res.updateBlob(toIndex(columnName), x);
1528            }
1529    
1530            @Override
1531            
1532            public void updateBoolean(int columnIndex, boolean x) throws SQLException {
1533                    res.updateBoolean(columnIndex, x);
1534            }
1535    
1536            @Override
1537            
1538            public void updateBoolean(String columnName, boolean x) throws SQLException {
1539                    res.updateBoolean(toIndex(columnName), x);
1540            }
1541    
1542            @Override
1543            
1544            public void updateByte(int columnIndex, byte x) throws SQLException {
1545                    res.updateByte(columnIndex, x);
1546            }
1547    
1548            @Override
1549            
1550            public void updateByte(String columnName, byte x) throws SQLException {
1551                    res.updateByte(toIndex(columnName), x);
1552            }
1553    
1554            @Override
1555            
1556            public void updateBytes(int columnIndex, byte[] x) throws SQLException {
1557                    res.updateBytes(columnIndex, x);
1558            }
1559    
1560            @Override
1561            
1562            public void updateBytes(String columnName, byte[] x) throws SQLException {
1563                    res.updateBytes(toIndex(columnName), x);
1564            }
1565    
1566            @Override
1567            
1568            public void updateCharacterStream(int columnIndex, Reader reader, int length)
1569                            throws SQLException {
1570                    res.updateCharacterStream(columnIndex, reader, length);
1571            }
1572    
1573            @Override
1574            
1575            public void updateCharacterStream(String columnName, Reader reader,
1576                            int length) throws SQLException {
1577                    res.updateCharacterStream(toIndex(columnName), reader, length);
1578            }
1579    
1580            @Override
1581            
1582            public void updateClob(int columnIndex, Clob x) throws SQLException {
1583                    res.updateClob(columnIndex, x);
1584            }
1585    
1586            @Override
1587            
1588            public void updateClob(String columnName, Clob x) throws SQLException {
1589                    res.updateClob(toIndex(columnName), x);
1590            }
1591    
1592            @Override
1593            
1594            public void updateDate(int columnIndex, Date x) throws SQLException {
1595                    res.updateDate(columnIndex, x);
1596            }
1597    
1598            @Override
1599            
1600            public void updateDate(String columnName, Date x) throws SQLException {
1601                    res.updateDate(toIndex(columnName), x);
1602            }
1603    
1604            @Override
1605            
1606            public void updateDouble(int columnIndex, double x) throws SQLException {
1607                    res.updateDouble(columnIndex, x);
1608            }
1609    
1610            @Override
1611            
1612            public void updateDouble(String columnName, double x) throws SQLException {
1613                    res.updateDouble(toIndex(columnName), x);
1614            }
1615    
1616            @Override
1617            
1618            public void updateFloat(int columnIndex, float x) throws SQLException {
1619                    res.updateFloat(columnIndex, x);
1620            }
1621    
1622            @Override
1623            
1624            public void updateFloat(String columnName, float x) throws SQLException {
1625                    res.updateFloat(toIndex(columnName), x);
1626            }
1627    
1628            @Override
1629            
1630            public void updateInt(int columnIndex, int x) throws SQLException {
1631                    res.updateInt(columnIndex, x);
1632            }
1633    
1634            @Override
1635            
1636            public void updateInt(String columnName, int x) throws SQLException {
1637                    res.updateInt(toIndex(columnName), x);
1638            }
1639    
1640            @Override
1641            
1642            public void updateLong(int columnIndex, long x) throws SQLException {
1643                    res.updateLong(columnIndex, x);
1644            }
1645    
1646            @Override
1647            
1648            public void updateLong(String columnName, long x) throws SQLException {
1649                    res.updateLong(toIndex(columnName), x);
1650            }
1651    
1652            @Override
1653            
1654            public void updateNull(int columnIndex) throws SQLException {
1655                    res.updateNull(columnIndex);
1656            }
1657    
1658            @Override
1659            
1660            public void updateNull(String columnName) throws SQLException {
1661                    res.updateNull(toIndex(columnName));
1662            }
1663    
1664            @Override
1665            
1666            public void updateObject(int columnIndex, Object x) throws SQLException {
1667                    res.updateObject(columnIndex, x);
1668            }
1669    
1670            @Override
1671            
1672            public void updateObject(String columnName, Object x) throws SQLException {
1673                    res.updateObject(toIndex(columnName), x);
1674            }
1675    
1676            @Override
1677            
1678            public void updateObject(int columnIndex, Object x, int scale)
1679                            throws SQLException {
1680                    res.updateObject(columnIndex, x, scale);
1681            }
1682    
1683            @Override
1684            
1685            public void updateObject(String columnName, Object x, int scale)
1686                            throws SQLException {
1687                    res.updateObject(toIndex(columnName), x, scale);
1688            }
1689    
1690            @Override
1691            
1692            public void updateRef(int columnIndex, Ref x) throws SQLException {
1693                    res.updateRef(columnIndex, x);
1694            }
1695    
1696            @Override
1697            
1698            public void updateRef(String columnName, Ref x) throws SQLException {
1699                    res.updateRef(toIndex(columnName), x);
1700            }
1701    
1702            @Override
1703            
1704            public void updateRow() throws SQLException {
1705                    res.updateRow();
1706            }
1707    
1708            @Override
1709            
1710            public void updateShort(int columnIndex, short x) throws SQLException {
1711                    res.updateShort(columnIndex, x);
1712            }
1713    
1714            @Override
1715            
1716            public void updateShort(String columnName, short x) throws SQLException {
1717                    res.updateShort(toIndex(columnName), x);
1718            }
1719    
1720            @Override
1721            
1722            public void updateString(int columnIndex, String x) throws SQLException {
1723                    res.updateString(columnIndex, x);
1724            }
1725    
1726            @Override
1727            
1728            public void updateString(String columnName, String x) throws SQLException {
1729                    res.updateString(toIndex(columnName), x);
1730            }
1731    
1732            @Override
1733            
1734            public void updateTime(int columnIndex, Time x) throws SQLException {
1735                    res.updateTime(columnIndex, x);
1736            }
1737    
1738            @Override
1739            
1740            public void updateTime(String columnName, Time x) throws SQLException {
1741                    res.updateTime(toIndex(columnName), x);
1742            }
1743    
1744            @Override
1745            
1746            public void updateTimestamp(int columnIndex, Timestamp x)
1747                            throws SQLException {
1748                    res.updateTimestamp(columnIndex, x);
1749            }
1750    
1751            @Override
1752            
1753            public void updateTimestamp(String columnName, Timestamp x)
1754                            throws SQLException {
1755                    res.updateTimestamp(toIndex(columnName), x);
1756            }
1757    
1758            @Override
1759            
1760            public ResultSetMetaData getMetaData() throws SQLException {
1761                    return res.getMetaData();
1762            }
1763    
1764              @Override
1765            public Iterator<Collection.Key> keyIterator() {
1766                    return new KeyIterator(keys());
1767            }
1768        
1769        @Override
1770            public Iterator<String> keysAsStringIterator() {
1771            return new StringIterator(keys());
1772        }
1773            
1774            @Override
1775            public Iterator<Entry<Key, Object>> entryIterator() {
1776                    return new EntryIterator(this,keys());
1777            }
1778            
1779            @Override
1780            public Iterator<Object> valueIterator() {
1781                    return new CollectionIterator(keys(),this);
1782            }
1783            
1784            @Override
1785            
1786            public boolean equals(Object obj) {
1787                    return res.equals(obj);
1788            }
1789    
1790            @Override
1791            
1792            public int getHoldability() throws SQLException {
1793                    return res.getHoldability();
1794            }
1795    
1796            @Override
1797            
1798            public boolean isClosed() throws SQLException {
1799                    return res.isClosed();
1800            }
1801    
1802            @Override
1803            
1804            public void updateNString(int columnIndex, String nString)
1805                            throws SQLException {
1806                    res.updateNString(columnIndex, nString);
1807            }
1808    
1809            @Override
1810            
1811            public void updateNString(String columnLabel, String nString)
1812                            throws SQLException {
1813                    res.updateNString(toIndex(columnLabel), nString);
1814            }
1815    
1816            @Override
1817            
1818            public String getNString(int columnIndex) throws SQLException {
1819                    return res.getNString(columnIndex);
1820            }
1821    
1822            @Override
1823            
1824            public String getNString(String columnLabel) throws SQLException {
1825                    return res.getNString(toIndex(columnLabel));
1826            }
1827    
1828            @Override
1829            
1830            public Reader getNCharacterStream(int columnIndex) throws SQLException {
1831                    return res.getNCharacterStream(columnIndex);
1832            }
1833    
1834            @Override
1835            
1836            public Reader getNCharacterStream(String columnLabel) throws SQLException {
1837                    return res.getNCharacterStream(toIndex(columnLabel));
1838            }
1839    
1840            @Override
1841            
1842            public void updateNCharacterStream(int columnIndex, Reader x, long length)
1843                            throws SQLException {
1844                    res.updateNCharacterStream(columnIndex, x, length);
1845            }
1846    
1847            @Override
1848            
1849            public void updateNCharacterStream(String columnLabel, Reader reader,
1850                            long length) throws SQLException {
1851                    res.updateNCharacterStream(toIndex(columnLabel), reader, length);
1852            }
1853    
1854            @Override
1855            
1856            public void updateAsciiStream(int columnIndex, InputStream x, long length)
1857                            throws SQLException {
1858                    res.updateAsciiStream(columnIndex, x, length);
1859            }
1860    
1861            @Override
1862            
1863            public void updateBinaryStream(int columnIndex, InputStream x, long length)
1864                            throws SQLException {
1865                    res.updateBinaryStream(columnIndex, x, length);
1866            }
1867    
1868            @Override
1869            
1870            public void updateCharacterStream(int columnIndex, Reader x, long length)
1871                            throws SQLException {
1872                    res.updateCharacterStream(columnIndex, x, length);
1873            }
1874    
1875            @Override
1876            
1877            public void updateAsciiStream(String columnLabel, InputStream x, long length)
1878                            throws SQLException {
1879                    res.updateAsciiStream(toIndex(columnLabel), x, length);
1880            }
1881    
1882            @Override
1883            
1884            public void updateBinaryStream(String columnLabel, InputStream x,
1885                            long length) throws SQLException {
1886                    res.updateBinaryStream(toIndex(columnLabel), x, length);
1887            }
1888    
1889            @Override
1890            
1891            public void updateCharacterStream(String columnLabel, Reader reader,
1892                            long length) throws SQLException {
1893                    res.updateCharacterStream(toIndex(columnLabel), reader, length);
1894            }
1895    
1896            @Override
1897            
1898            public void updateBlob(int columnIndex, InputStream inputStream, long length)
1899                            throws SQLException {
1900                    res.updateBlob(columnIndex, inputStream, length);
1901            }
1902    
1903            @Override
1904            
1905            public void updateBlob(String columnLabel, InputStream inputStream,
1906                            long length) throws SQLException {
1907                    res.updateBlob(toIndex(columnLabel), inputStream, length);
1908            }
1909    
1910            @Override
1911            
1912            public void updateClob(int columnIndex, Reader reader, long length)
1913                            throws SQLException {
1914                    res.updateClob(columnIndex, reader, length);
1915            }
1916    
1917            @Override
1918            
1919            public void updateClob(String columnLabel, Reader reader, long length)
1920                            throws SQLException {
1921                    res.updateClob(toIndex(columnLabel), reader, length);
1922            }
1923    
1924            @Override
1925            
1926            public void updateNClob(int columnIndex, Reader reader, long length)
1927                            throws SQLException {
1928                    res.updateNClob(columnIndex, reader, length);
1929            }
1930    
1931            @Override
1932            
1933            public void updateNClob(String columnLabel, Reader reader, long length)
1934                            throws SQLException {
1935                    res.updateNClob(toIndex(columnLabel), reader, length);
1936            }
1937    
1938            @Override
1939            
1940            public void updateNCharacterStream(int columnIndex, Reader x)
1941                            throws SQLException {
1942                    res.updateNCharacterStream(columnIndex, x);
1943            }
1944    
1945            @Override
1946            
1947            public void updateNCharacterStream(String columnLabel, Reader reader)
1948                            throws SQLException {
1949                    res.updateNCharacterStream(toIndex(columnLabel), reader);
1950            }
1951    
1952            @Override
1953            
1954            public void updateAsciiStream(int columnIndex, InputStream x)
1955                            throws SQLException {
1956                    res.updateAsciiStream(columnIndex, x);
1957            }
1958    
1959            @Override
1960            
1961            public void updateBinaryStream(int columnIndex, InputStream x)
1962                            throws SQLException {
1963                    res.updateBinaryStream(columnIndex, x);
1964            }
1965    
1966            @Override
1967            
1968            public void updateCharacterStream(int columnIndex, Reader x)
1969                            throws SQLException {
1970                    res.updateCharacterStream(columnIndex, x);
1971            }
1972    
1973            @Override
1974            
1975            public void updateAsciiStream(String columnLabel, InputStream x)
1976                            throws SQLException {
1977                    res.updateAsciiStream(toIndex(columnLabel), x);
1978            }
1979    
1980            @Override
1981            
1982            public void updateBinaryStream(String columnLabel, InputStream x)
1983                            throws SQLException {
1984                    res.updateBinaryStream(columnLabel, x);
1985            }
1986    
1987            @Override
1988            
1989            public void updateCharacterStream(String columnLabel, Reader reader)
1990                            throws SQLException {
1991                    res.updateCharacterStream(toIndex(columnLabel), reader);
1992            }
1993    
1994            @Override
1995            
1996            public void updateBlob(int columnIndex, InputStream inputStream)
1997                            throws SQLException {
1998                    res.updateBlob(columnIndex, inputStream);
1999            }
2000    
2001            @Override
2002            
2003            public void updateBlob(String columnLabel, InputStream inputStream)
2004                            throws SQLException {
2005                    res.updateBlob(toIndex(columnLabel), inputStream);
2006            }
2007    
2008            @Override
2009            
2010            public void updateClob(int columnIndex, Reader reader) throws SQLException {
2011                    res.updateClob(columnIndex, reader);
2012            }
2013    
2014            @Override
2015            
2016            public void updateClob(String columnLabel, Reader reader)
2017                            throws SQLException {
2018                    res.updateClob(toIndex(columnLabel), reader);
2019            }
2020    
2021            @Override
2022            
2023            public void updateNClob(int columnIndex, Reader reader) throws SQLException {
2024                    res.updateNClob(columnIndex, reader);
2025            }
2026    
2027            @Override
2028            
2029            public void updateNClob(String columnLabel, Reader reader)
2030                            throws SQLException {
2031                    res.updateNClob(toIndex(columnLabel), reader);
2032            }
2033    
2034            @Override
2035            
2036            public <T> T unwrap(Class<T> iface) throws SQLException {
2037                    return res.unwrap(iface);
2038            }
2039    
2040            @Override
2041            
2042            public boolean isWrapperFor(Class<?> iface) throws SQLException {
2043                    return res.isWrapperFor(iface);
2044            }
2045    
2046            @Override
2047            
2048            public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
2049                    res.updateNClob(columnIndex, nClob);
2050            }
2051    
2052            @Override
2053            
2054            public void updateNClob(String columnLabel, NClob nClob)
2055                            throws SQLException {
2056                    res.updateNClob(toIndex(columnLabel), nClob);
2057            }
2058    
2059            @Override
2060            
2061            public NClob getNClob(int columnIndex) throws SQLException {
2062                    return res.getNClob(columnIndex);
2063            }
2064    
2065            @Override
2066            
2067            public NClob getNClob(String columnLabel) throws SQLException {
2068                    return res.getNClob(toIndex(columnLabel));
2069            }
2070    
2071            @Override
2072            
2073            public SQLXML getSQLXML(int columnIndex) throws SQLException {
2074                    return res.getSQLXML(columnIndex);
2075            }
2076    
2077            @Override
2078            
2079            public SQLXML getSQLXML(String columnLabel) throws SQLException {
2080                    return res.getSQLXML(toIndex(columnLabel));
2081            }
2082    
2083            @Override
2084            
2085            public void updateSQLXML(int columnIndex, SQLXML xmlObject)
2086                            throws SQLException {
2087                    res.updateSQLXML(columnIndex, xmlObject);
2088            }
2089    
2090            @Override
2091            
2092            public void updateSQLXML(String columnLabel, SQLXML xmlObject)
2093                            throws SQLException {
2094                    res.updateSQLXML(toIndex(columnLabel), xmlObject);
2095            }
2096    
2097            @Override
2098            
2099            public RowId getRowId(int columnIndex) throws SQLException {
2100                    return res.getRowId(columnIndex);
2101            }
2102    
2103            @Override
2104            
2105            public RowId getRowId(String columnLabel) throws SQLException {
2106                    return res.getRowId(toIndex(columnLabel));
2107            }
2108    
2109            @Override
2110            
2111            public void updateRowId(int columnIndex, RowId x) throws SQLException {
2112                    res.updateRowId(columnIndex, x);
2113            }
2114    
2115            @Override
2116            public void updateRowId(String columnLabel, RowId x) throws SQLException {
2117                    res.updateRowId(toIndex(columnLabel), x);
2118            }
2119    
2120            public synchronized void enableShowQueryUsage() {
2121                    throw notSupported();
2122            }
2123    
2124            public static PageRuntimeException notSupported() {
2125                    return toRuntimeExc(new SQLFeatureNotSupportedException("not supported"));
2126            }
2127    
2128            public static PageRuntimeException toRuntimeExc(Throwable t) {
2129                    return new PageRuntimeException(Caster.toPageException(t));
2130            }
2131    
2132            public static PageException toPageExc(Throwable t) {
2133                    return Caster.toPageException(t);
2134            }
2135    
2136            private int toIndex(String columnName) throws SQLException {
2137                    SimpleQueryColumn col = columns.get(columnName.toLowerCase());
2138                    if(col==null) throw new SQLException("There is no column with name ["+columnName+"], available columns are ["+getColumnlist()+"]");
2139                    return col.getIndex();
2140            }
2141            
2142            int getPid() {
2143                    
2144                    PageContext pc = ThreadLocalPageContext.get();
2145                    if(pc==null) {
2146                            pc=CFMLEngineFactory.getInstance().getThreadPageContext();
2147                            if(pc==null)throw new RuntimeException("cannot get pid for current thread");
2148                    }
2149                    return pc.getId();
2150            }
2151    
2152            @Override
2153            public Query getGeneratedKeys() {
2154                    return null;
2155            }
2156    
2157            @Override
2158            public SQL getSql() {
2159                    return sql;
2160            }
2161    
2162            @Override
2163            public String getTemplate() {
2164                    return template;
2165            }
2166    
2167            @Override
2168            public long getExecutionTime() {
2169                    return exeTime;
2170            }
2171            
2172            @Override
2173            public java.util.Iterator getIterator() {
2174                    return new ForEachQueryIterator(this, ThreadLocalPageContext.get().getId());
2175        }
2176    
2177    }