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 }