001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.type;
020
021import java.util.Date;
022import java.util.Iterator;
023import java.util.Map.Entry;
024
025import lucee.runtime.PageContext;
026import lucee.runtime.config.NullSupportHelper;
027import lucee.runtime.dump.DumpData;
028import lucee.runtime.dump.DumpProperties;
029import lucee.runtime.dump.DumpUtil;
030import lucee.runtime.engine.ThreadLocalPageContext;
031import lucee.runtime.exp.DatabaseException;
032import lucee.runtime.exp.PageException;
033import lucee.runtime.op.Caster;
034import lucee.runtime.op.Operator;
035import lucee.runtime.op.date.DateCaster;
036import lucee.runtime.type.dt.DateTime;
037import lucee.runtime.type.it.EntryIterator;
038import lucee.runtime.type.it.KeyIterator;
039import lucee.runtime.type.it.StringIterator;
040import lucee.runtime.type.util.CollectionUtil;
041import lucee.runtime.type.util.QueryUtil;
042
043/**
044 * Recordcount Query Column
045 */
046public final class QueryColumnRef implements QueryColumn,Sizeable {
047    
048    private Query query;
049    private Collection.Key columnName;
050    private int type;
051
052    /**
053     * Constructor of the class
054     * @param query
055     * @param columnName 
056     * @param type 
057     */
058    public QueryColumnRef(Query query, Collection.Key columnName, int type) {
059        this.query=query;
060        this.columnName=columnName;
061        this.type=type;
062    }
063
064    @Override
065    public Object remove(int row) throws DatabaseException {
066        throw new DatabaseException("can't remove "+columnName+" at row "+row+" value from Query",null,null,null);
067    }
068
069    @Override
070    public Object removeEL(int row) {
071        return query.getAt(columnName,row,null);
072    }
073
074    @Override
075    public Object get(int row) throws PageException {
076        return query.getAt(columnName,row);
077    }
078    
079    /**
080     * touch a value, means if key dosent exist, it will created
081     * @param row
082     * @return matching value or created value
083     * @throws PageException
084     */
085    public Object touch(int row) throws PageException {
086        Object o= query.getAt(columnName,row,NullSupportHelper.NULL());
087        if(o!=NullSupportHelper.NULL()) return o;
088        return query.setAt(columnName,row,new StructImpl());
089    }
090    
091    public Object touchEL(int row) {
092        Object o= query.getAt(columnName,row,NullSupportHelper.NULL());
093        if(o!=NullSupportHelper.NULL()) return o;
094        return query.setAtEL(columnName,row,new StructImpl());
095    }
096
097    @Override
098    public Object get(int row, Object defaultValue) {
099        return query.getAt(columnName,row,defaultValue);
100    }
101
102    @Override
103    public Object set(int row, Object value) throws DatabaseException {
104        throw new DatabaseException("can't change "+columnName+" value from Query",null,null,null);
105    }
106
107    @Override
108    public Object setEL(int row, Object value) {
109        return query.getAt(columnName,row,null);
110    }
111
112    @Override
113    public void add(Object value) {}
114
115    @Override
116    public void addRow(int count) {}
117
118    @Override
119    public int getType() {
120        return type;
121    }
122
123    @Override
124    public String getTypeAsString() {
125        return QueryImpl.getColumTypeName(getType());
126    }
127
128    @Override
129    public void cutRowsTo(int maxrows) {}
130
131
132    @Override
133    public int size() {
134        return query.size();
135    }
136
137    @Override
138    public Collection.Key[] keys() {
139        Collection.Key[] k=new Collection.Key[size()];
140        for(int i=1;i<=k.length;i++) {
141            k[i-1]=KeyImpl.init(Caster.toString(i));
142        }
143        return k;
144    }
145
146        @Override
147        public Object remove(Collection.Key key) throws PageException {
148                throw new DatabaseException("can't remove "+key+" from Query",null,null,null);
149        }
150
151        @Override
152        public Object removeEL(Collection.Key key) {
153                return get(key,null);
154        }
155
156    @Override
157    public void clear() {}
158
159    @Override
160    public Object get(String key) throws PageException {
161        return get(Caster.toIntValue(key));
162    }
163
164        @Override
165        public Object get(Collection.Key key) throws PageException {
166                return get(Caster.toIntValue(key.getString()));
167        }
168
169    @Override
170    public Object get(String key, Object defaultValue) {
171        return get(Caster.toIntValue(key,query.getCurrentrow(ThreadLocalPageContext.get().getId())),defaultValue);
172    }
173
174        @Override
175        public Object get(Collection.Key key, Object defaultValue) {
176                return get(Caster.toIntValue(key,query.getCurrentrow(ThreadLocalPageContext.get().getId())),defaultValue);
177        }
178
179    @Override
180    public Object set(String key, Object value) throws PageException {
181        return set(Caster.toIntValue(key),value);
182    }
183
184        @Override
185        public Object set(Collection.Key key, Object value) throws PageException {
186                return set(Caster.toIntValue(key),value);
187        }
188
189    @Override
190    public Object setEL(String key, Object value) {
191        return setEL(Caster.toIntValue(key,query.getCurrentrow(ThreadLocalPageContext.get().getId())),value);
192    }
193
194        @Override
195        public Object setEL(Collection.Key key, Object value) {
196                return setEL(Caster.toIntValue(key,query.getCurrentrow(ThreadLocalPageContext.get().getId())),value);
197        }
198
199        @Override
200        public Iterator<Collection.Key> keyIterator() {
201        return new KeyIterator(keys());
202    }
203    
204        @Override
205        public Iterator<String> keysAsStringIterator() {
206        return new StringIterator(keys());
207    }
208        
209        @Override
210        public Iterator<Entry<Key, Object>> entryIterator() {
211                return new EntryIterator(this, keys());
212        }
213    
214        @Override
215        public Iterator<Object> valueIterator() {
216                return query.getColumn(columnName,null).valueIterator();
217        }
218
219    @Override
220    public boolean containsKey(String key) {
221        return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
222    }
223
224        @Override
225        public boolean containsKey(Collection.Key key) {
226                return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
227        }
228
229    @Override
230        public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
231            return DumpUtil.toDumpData(get(query.getCurrentrow(pageContext.getId()),null), pageContext,maxlevel,dp);
232    }
233
234    @Override
235    public String castToString() throws PageException {
236        return Caster.toString(get(query.getCurrentrow(ThreadLocalPageContext.get().getId())));
237    }
238
239        @Override
240        public String castToString(String defaultValue) {
241                Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
242                if(value==NullSupportHelper.NULL())return defaultValue;
243                return Caster.toString(value,defaultValue);
244        }
245
246    @Override
247    public boolean castToBooleanValue() throws PageException {
248        return Caster.toBooleanValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId())));
249    }
250    
251    @Override
252    public Boolean castToBoolean(Boolean defaultValue) {
253        Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
254                if(value==NullSupportHelper.NULL())return defaultValue;
255                return Caster.toBoolean(value,defaultValue);
256    }
257
258    @Override
259    public double castToDoubleValue() throws PageException {
260        return Caster.toDoubleValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId())));
261    }
262    
263    @Override
264    public double castToDoubleValue(double defaultValue) {
265        Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
266                if(value==NullSupportHelper.NULL())return defaultValue;
267                return Caster.toDoubleValue(value,true,defaultValue);
268    }
269
270    @Override
271    public DateTime castToDateTime() throws PageException {
272        return Caster.toDate(get(query.getCurrentrow(ThreadLocalPageContext.get().getId())),null);
273    }
274    
275    @Override
276    public DateTime castToDateTime(DateTime defaultValue) {
277        Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
278                if(value==NullSupportHelper.NULL())return defaultValue;
279                return DateCaster.toDateAdvanced(value,DateCaster.CONVERTING_TYPE_OFFSET,null,defaultValue);
280    }
281
282        @Override
283        public int compareTo(boolean b) throws PageException {
284                return Operator.compare(castToBooleanValue(), b);
285        }
286
287        @Override
288        public int compareTo(DateTime dt) throws PageException {
289                return Operator.compare((Date)castToDateTime(), (Date)dt);
290        }
291
292        @Override
293        public int compareTo(double d) throws PageException {
294                return Operator.compare(castToDoubleValue(), d);
295        }
296
297        @Override
298        public int compareTo(String str) throws PageException {
299                return Operator.compare(castToString(), str);
300        }
301
302    @Override
303    public String getKeyAsString() throws PageException {
304        return columnName.toString();
305    }
306
307    @Override
308    public Collection.Key getKey() throws PageException {
309        return columnName;
310    }
311
312    @Override
313    public Object get(PageContext pc) throws PageException {
314        return get(query.getCurrentrow(pc.getId()));
315    }
316    
317    @Override
318    public Object get(PageContext pc, Object defaultValue) {
319        return get(query.getCurrentrow(pc.getId()),defaultValue);
320    }
321
322    @Override
323    public Object removeRow(int row) throws DatabaseException {
324        throw new DatabaseException("can't remove row from Query",null,null,null);
325    }
326
327    @Override
328    public Object touch(PageContext pc) throws PageException {
329        return touch(query.getCurrentrow(pc.getId()));
330    }
331
332    @Override
333    public Object touchEL(PageContext pc) {
334        return touchEL(query.getCurrentrow(pc.getId()));
335    }
336
337    @Override
338    public Object set(PageContext pc, Object value) throws PageException {
339        return set(query.getCurrentrow(pc.getId()),value);
340    }
341    
342    @Override
343    public Object setEL(PageContext pc, Object value) {
344        return setEL(query.getCurrentrow(pc.getId()),value);
345    }
346
347    @Override
348    public Object remove(PageContext pc) throws PageException {
349        return remove(query.getCurrentrow(pc.getId()));
350    }
351
352    @Override
353    public Object removeEL(PageContext pc) {
354        return removeEL(query.getCurrentrow(pc.getId()));
355    }
356
357    @Override
358    public Object getParent() {
359        return query;
360    }
361
362    @Override
363    public Object clone() {
364        QueryColumn clone=new QueryColumnRef(query,columnName,type);
365        return clone;
366    }
367
368    @Override
369    public Collection duplicate(boolean deepCopy) {
370//               MUST muss deepCopy checken
371        QueryColumn clone=new QueryColumnRef(query,columnName,type);
372        return clone;
373    }
374        
375
376        @Override
377        public long sizeOf() {
378                return QueryUtil.sizeOf(this);
379        }
380        
381        @Override
382        public java.util.Iterator<String> getIterator() {
383        return keysAsStringIterator();
384    }
385        
386        @Override
387        public boolean equals(Object obj){
388                if(!(obj instanceof Collection)) return false;
389                return CollectionUtil.equals(this,(Collection)obj);
390        }
391        
392        /*@Override
393        public int hashCode() {
394                return CollectionUtil.hashCode(this);
395        }*/
396}