001    package railo.runtime.type.query;
002    
003    import java.io.IOException;
004    import java.sql.ResultSet;
005    import java.sql.SQLException;
006    import java.sql.Types;
007    import java.util.Iterator;
008    import java.util.Map.Entry;
009    import java.util.TimeZone;
010    
011    import railo.commons.sql.SQLUtil;
012    import railo.runtime.PageContext;
013    import railo.runtime.db.CFTypes;
014    import railo.runtime.dump.DumpData;
015    import railo.runtime.dump.DumpProperties;
016    import railo.runtime.engine.ThreadLocalPageContext;
017    import railo.runtime.exp.DatabaseException;
018    import railo.runtime.exp.PageException;
019    import railo.runtime.op.Caster;
020    import railo.runtime.query.caster.Cast;
021    import railo.runtime.type.Collection;
022    import railo.runtime.type.KeyImpl;
023    import railo.runtime.type.QueryColumn;
024    import railo.runtime.type.QueryImpl;
025    import railo.runtime.type.dt.DateTime;
026    import railo.runtime.type.it.EntryIterator;
027    import railo.runtime.type.scope.Undefined;
028    
029    public class SimpleQueryColumn implements QueryColumn {
030    
031            private static final long serialVersionUID = 288731277532671308L;
032    
033            private SimpleQuery qry;
034            private Key key;
035            private int type;
036            private ResultSet res;
037            private Cast cast;
038            private int index;
039            private Object[] data;
040    
041            public SimpleQueryColumn(SimpleQuery qry, ResultSet res, Collection.Key key, int type, int index) {
042                    this.qry=qry;
043                    this.res=res;
044                    this.key=key;
045                    this.index=index;
046                    
047                    try {
048                            switch(type){
049                            case Types.TIMESTAMP:
050                                    cast=Cast.TIMESTAMP;
051                            break;
052                            case Types.TIME:
053                                    cast=Cast.TIME;
054                            break;
055                            case Types.DATE:
056                                    cast=Cast.DATE;
057                            break;
058                            case Types.CLOB:
059                                    cast=Cast.CLOB;
060                            break;
061                            case Types.BLOB:
062                                    cast=Cast.BLOB;
063                            break;
064                            case Types.BIT:
065                                    cast=Cast.BIT;
066                            break;
067                            case Types.ARRAY:
068                                    cast=Cast.ARRAY;
069                            break;
070                            case CFTypes.OPAQUE:
071                                    if(SQLUtil.isOracle(res.getStatement().getConnection()))
072                                    cast=Cast.ORACLE_OPAQUE;
073                            else 
074                                    cast=Cast.OTHER;
075                            break;
076                            default:
077                                    cast=Cast.OTHER;
078                            break;
079                            }
080                    }
081                    catch (Exception e) {
082                            throw SimpleQuery.toRuntimeExc(e);
083                    }
084            }
085    
086            public Object get(Key key, Object defaultValue) {
087                    int row=Caster.toIntValue(key,Integer.MIN_VALUE);
088                    if(row==Integer.MIN_VALUE) {
089                            Object child=getChildElement(key,null);
090                    if(child!=null) return child;
091                return defaultValue;
092            }
093                return get(row,defaultValue);
094            }
095            
096            public Object get(Key key) throws PageException {
097                    int row=Caster.toIntValue(key,Integer.MIN_VALUE);
098                    if(row==Integer.MIN_VALUE) {
099                            Object child=getChildElement(key,null);
100                    if(child!=null) return child;
101                throw new DatabaseException("key ["+key+"] not found",null,null,null);
102            }
103                return get(row);
104            }
105            
106            
107            private Object getChildElement(Key key, Object defaultValue) {
108            PageContext pc = ThreadLocalPageContext.get();
109                    // column and query has same name
110                    if(key.equals(this.key)) {
111                    return get(qry.getCurrentrow(pc.getId()),defaultValue);
112            }
113            // get it from undefined scope
114                    if(pc!=null){
115                            Undefined undefined = pc.undefinedScope();
116                            boolean old = undefined.setAllowImplicidQueryCall(false);
117                            Object sister = undefined.get(this.key,null);
118                            undefined.setAllowImplicidQueryCall(old);
119                            if(sister!=null){
120                                    try {
121                                            return pc.get(sister, key);
122                                    } catch (PageException e) {
123                                            return defaultValue;
124                                    }
125                            }
126                    }
127            return defaultValue;
128            }
129            
130            public int size() {
131                    throw SimpleQuery.notSupported();
132            }
133    
134            
135            public Key[] keys() {
136                    throw SimpleQuery.notSupported();
137            }
138    
139            
140            public Object remove(Key key) throws PageException {
141                    throw SimpleQuery.notSupported();
142            }
143    
144            
145            public Object removeEL(Key key) {
146                    throw SimpleQuery.notSupported();
147            }
148    
149            
150            public void clear() {
151                    throw SimpleQuery.notSupported();
152            }
153    
154    
155            
156            public Object get(String key) throws PageException {
157                    return get(KeyImpl.init(key));
158            }
159            
160            public Object get(String key, Object defaultValue) {
161                    return get(KeyImpl.init(key),defaultValue);
162            }
163    
164            public Object set(String key, Object value) throws PageException {
165                    throw SimpleQuery.notSupported();
166            }
167    
168            
169            public Object set(Key key, Object value) throws PageException {
170                    throw SimpleQuery.notSupported();
171            }
172    
173            
174            public Object setEL(String key, Object value) {
175                    throw SimpleQuery.notSupported();
176            }
177    
178            
179            public Object setEL(Key key, Object value) {
180                    throw SimpleQuery.notSupported();
181            }
182    
183            
184            public Collection duplicate(boolean deepCopy) {
185                    throw SimpleQuery.notSupported();
186            }
187    
188            
189            public boolean containsKey(String key) {
190                    throw SimpleQuery.notSupported();
191            }
192    
193            
194            public boolean containsKey(Key key) {
195                    throw SimpleQuery.notSupported();
196            }
197    
198            
199            @Override
200            public DumpData toDumpData(PageContext pageContext, int maxlevel,
201                            DumpProperties properties) {
202                    throw SimpleQuery.notSupported();
203            }
204    
205            @Override
206            public Iterator<Collection.Key> keyIterator() {
207                    throw SimpleQuery.notSupported();
208            }
209        
210        @Override
211            public Iterator<String> keysAsStringIterator() {
212            throw SimpleQuery.notSupported();
213        }
214            
215            @Override
216            public Iterator<Entry<Key, Object>> entryIterator() {
217                    return new EntryIterator(this,keys());
218            }
219    
220            
221            public Iterator<Object> valueIterator() {
222                    throw SimpleQuery.notSupported();
223            }
224    
225            
226            public String castToString() throws PageException {
227                    // TODO Auto-generated method stub
228                    return Caster.toString(get(key));
229            }
230    
231            
232            public String castToString(String defaultValue) {
233                    return Caster.toString(get(key,defaultValue),defaultValue);
234            }
235    
236            
237            public boolean castToBooleanValue() throws PageException {
238                    return Caster.toBoolean(get(key));
239            }
240    
241            
242            public Boolean castToBoolean(Boolean defaultValue) {
243                    return Caster.toBoolean(get(key,defaultValue),defaultValue);
244            }
245    
246            
247            public double castToDoubleValue() throws PageException {
248                    return Caster.toDoubleValue(get(key));
249            }
250    
251            
252            public double castToDoubleValue(double defaultValue) {
253                    return Caster.toDoubleValue(get(key,defaultValue),defaultValue);
254            }
255    
256            
257            public DateTime castToDateTime() throws PageException {
258                    return Caster.toDate(get(key), false, null);
259            }
260    
261            
262            public DateTime castToDateTime(DateTime defaultValue) {
263                    return Caster.toDate(get(key,defaultValue), false, null, defaultValue);
264            }
265    
266            
267            public int compareTo(String str) throws PageException {
268                    throw SimpleQuery.notSupported();
269            }
270    
271            
272            public int compareTo(boolean b) throws PageException {
273                    throw SimpleQuery.notSupported();
274            }
275    
276            
277            public int compareTo(double d) throws PageException {
278                    throw SimpleQuery.notSupported();
279            }
280    
281            
282            public int compareTo(DateTime dt) throws PageException {
283                    throw SimpleQuery.notSupported();
284            }
285    
286            
287            public String getKeyAsString() {
288                    return key.getString();
289            }
290    
291            
292            public Key getKey() {
293                    return key;
294            }
295    
296            
297            public Object get(PageContext pc) throws PageException {
298                    return get(key);
299            }
300    
301            
302            public Object get(PageContext pc, Object defaultValue) {
303                    return get(key,defaultValue);
304            }
305    
306            
307            public Object set(PageContext pc, Object value) throws PageException {
308                    throw SimpleQuery.notSupported();
309            }
310    
311            
312            public Object setEL(PageContext pc, Object value) {
313                    throw SimpleQuery.notSupported();
314            }
315    
316            
317            public Object remove(PageContext pc) throws PageException {
318                    throw SimpleQuery.notSupported();
319            }
320    
321            
322            public Object removeEL(PageContext pc) {
323                    throw SimpleQuery.notSupported();
324            }
325    
326            
327            public Object touch(PageContext pc) throws PageException {
328                    throw SimpleQuery.notSupported();
329            }
330    
331            
332            public Object touchEL(PageContext pc) {
333                    throw SimpleQuery.notSupported();
334            }
335    
336            
337            public Object getParent() {
338                    return qry;
339            }
340    
341            
342            public Object remove(int row) throws PageException {
343                    throw SimpleQuery.notSupported();
344            }
345    
346            
347            public Object removeRow(int row) throws PageException {
348                    throw SimpleQuery.notSupported();
349            }
350    
351            
352            public Object removeEL(int row) {
353                    throw SimpleQuery.notSupported();
354            }
355    
356            @Override
357            public synchronized Object get(int row) throws PageException {
358                    Object sv = getStoredValue(row);
359                    if(sv!=SimpleQuery.DEFAULT_VALUE) return sv;
360                    
361                    try {
362                            if(row!=res.getRow()) {
363                                    res.absolute(row);
364                            }
365                            return _get(row);
366                    }
367                    catch (Throwable t) {
368                            throw Caster.toPageException(t);
369                    }
370            }
371    
372            @Override
373            public synchronized Object get(int row, Object defaultValue) {
374                    Object sv = getStoredValue(row);
375                    if(sv!=SimpleQuery.DEFAULT_VALUE) return sv;
376                    
377                    try {
378                            if(row!=res.getRow()) {
379                                    res.absolute(row);
380                            }
381                            return _get(row);
382                    }
383                    catch (Throwable t) {
384                            return defaultValue;
385                    }
386            }
387            
388            private synchronized Object getStoredValue(int row) {
389                    if(data==null) return SimpleQuery.DEFAULT_VALUE;
390                    return data[row-1];
391            }
392            
393            private synchronized Object _get(int row) throws SQLException, IOException {
394                    if(data==null) {
395                            data=new Object[qry.getRecordcount()];
396                            for(int i=0;i<data.length;i++){
397                                    data[i]=SimpleQuery.DEFAULT_VALUE;
398                            }
399                            
400                    }
401                    return data[row-1]=cast.toCFType(null, type, res, index);
402            }
403    
404            
405            public Object set(int row, Object value) throws PageException {
406                    throw SimpleQuery.notSupported();
407            }
408    
409            
410            public void add(Object value) {
411                    throw SimpleQuery.notSupported();
412            }
413    
414            
415            public Object setEL(int row, Object value) {
416                    throw SimpleQuery.notSupported();
417            }
418    
419            
420            public void addRow(int count) {
421                    throw SimpleQuery.notSupported();
422            }
423    
424            
425            public int getType() {
426                    return type;
427            }
428    
429            
430            public String getTypeAsString() {
431                    return QueryImpl.getColumTypeName(type);
432            }
433    
434            
435            public void cutRowsTo(int maxrows) {
436                    throw SimpleQuery.notSupported();
437    
438            }
439            
440            public Object clone() {
441                    throw SimpleQuery.notSupported();
442            }
443    
444    
445            public int getIndex() {
446                    return index;
447            }
448            
449            @Override
450            public java.util.Iterator<String> getIterator() {
451            return keysAsStringIterator();
452        }
453    }