package railo.runtime.functions.query; import java.util.Iterator; import java.util.Map.Entry; import railo.commons.lang.StringUtil; import railo.runtime.PageContext; import railo.runtime.exp.DatabaseException; import railo.runtime.exp.FunctionException; import railo.runtime.exp.PageException; import railo.runtime.functions.BIF; import railo.runtime.op.Caster; import railo.runtime.op.Decision; import railo.runtime.type.Array; import railo.runtime.type.ArrayImpl; import railo.runtime.type.Collection.Key; import railo.runtime.type.Query; import railo.runtime.type.QueryImpl; import railo.runtime.type.Struct; import railo.runtime.type.util.ListUtil; import railo.runtime.type.util.QueryUtil; /** * Implements the CFML Function querynew */ public final class QueryNew extends BIF { private static final long serialVersionUID = -4313766961671090938L; public static railo.runtime.type.Query call(PageContext pc , String columnList) throws DatabaseException { return new QueryImpl(ListUtil.listToArrayTrim(columnList,","),0,"query"); } public static railo.runtime.type.Query call(PageContext pc , String columnList, String columnTypeList) throws PageException { if(StringUtil.isEmpty(columnTypeList)) return call(pc, columnList); return new QueryImpl(ListUtil.listToArrayTrim(columnList,","),ListUtil.listToArrayTrim(columnTypeList,","),0,"query"); } public static railo.runtime.type.Query call(PageContext pc , String strColumnList, String strColumnTypeList, Object data) throws PageException { Array columnList = ListUtil.listToArrayTrim(strColumnList,","); railo.runtime.type.Query qry; if(StringUtil.isEmpty(strColumnTypeList)) qry= new QueryImpl(columnList,0,"query"); else qry= new QueryImpl(columnList,ListUtil.listToArrayTrim(strColumnTypeList,","),0,"query"); if(data==null) return qry; return populate(pc, qry, data); } @Override public Object invoke(PageContext pc, Object[] args) throws PageException { if(args.length==1)return call(pc,Caster.toString(args[0])); if(args.length==2)return call(pc,Caster.toString(args[0]),Caster.toString(args[1])); return call(pc,Caster.toString(args[0]),Caster.toString(args[1]),args[2]); } public static Query populate(PageContext pc, Query qry,Object data) throws PageException { if(Decision.isArray(data)) return _populate(pc,qry,Caster.toArray(data)); else if(Decision.isStruct(data)) return _populate(pc,qry,Caster.toStruct(data)); else throw new FunctionException(pc, "QueryNew", 3, "data", "the date must be defined as array of structs , array of arrays or struct of arrays"); } private static Query _populate(PageContext pc, Query qry,Struct data) throws PageException { Iterator<Entry<Key, Object>> it = data.entryIterator(); Entry<Key, Object> e; Object v; Array arr; int rows = qry.getRecordcount(); while(it.hasNext()){ e = it.next(); if(qry.getColumn(e.getKey(),null)!=null) { v=e.getValue(); arr = Caster.toArray(v,null); if(arr==null) arr=new ArrayImpl(new Object[]{v}); populateColumn(qry,e.getKey(),arr,rows); } } return qry; } private static void populateColumn(Query qry, Key column, Array data,int rows) throws PageException { Iterator<?> it = data.valueIterator(); int row=rows; while(it.hasNext()){ row++; if(row>qry.getRecordcount()) qry.addRow(); qry.setAt(column, row, it.next()); } } private static Query _populate(PageContext pc, Query qry,Array data) throws PageException { /* * 3 types of structures are supported * array - ["Urs","Weber"] * array of struct - [{firstname="Urs",lastname="Weber"},{firstname="Peter",lastname="Mueller"}] * array of array - [["Urs","Weber"],["Peter","Mueller"]] */ // check if the array only contains simple values or mixed Iterator<?> it = data.valueIterator(); Object o; boolean hasSimpleValues=false; while(it.hasNext()){ o=it.next(); if(!Decision.isStruct(o) && !Decision.isArray(o)) hasSimpleValues=true; } if(hasSimpleValues) { qry.addRow(); populateRow(qry, data); } else { it = data.valueIterator(); while(it.hasNext()){ o=it.next(); qry.addRow(); if(Decision.isStruct(o))populateRow(qry,Caster.toStruct(o)); else if(Decision.isArray(o))populateRow(qry,Caster.toArray(o)); else { populateRow(qry,new ArrayImpl(new Object[]{o})); } } } return qry; } private static void populateRow(Query qry, Struct data) throws PageException { Key[] columns = QueryUtil.getColumnNames(qry); int row=qry.getRecordcount(); Object value; for(int i=0;i<columns.length;i++){ value=data.get(columns[i],null); if(value!=null) qry.setAt(columns[i], row, value); } } private static void populateRow(Query qry, Array data) throws PageException { Iterator<?> it = data.valueIterator(); Key[] columns = QueryUtil.getColumnNames(qry); int row=qry.getRecordcount(); int index=-1; while(it.hasNext()){ index++; if(index>=columns.length) break; qry.setAt(columns[index], row, it.next()); } } }