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