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.sql; 020 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024 025import lucee.runtime.exp.DatabaseException; 026import lucee.runtime.sql.exp.Column; 027import lucee.runtime.sql.exp.Expression; 028import lucee.runtime.sql.exp.op.Operation; 029import lucee.runtime.sql.exp.value.ValueNumber; 030 031public class Selects { 032 033 private List<Column> orderbys=new ArrayList<Column>(); 034 private List<Select> selects=new ArrayList<Select>(); 035 036 037 038 public void addOrderByExpression(Column exp) { 039 this.orderbys.add(exp); 040 } 041 042 /** 043 * @return the orderbys 044 */ 045 public Column[] getOrderbys() { 046 if(orderbys==null) return new Column[0]; 047 return orderbys.toArray(new Column[orderbys.size()]); 048 } 049 050 public void addSelect(Select select) { 051 selects.add(select); 052 } 053 054 public Select[] getSelects() { 055 if(selects==null) return new Select[0]; 056 return selects.toArray(new Select[selects.size()]); 057 } 058 059 060 @Override 061 062 public String toString() { 063 return _toString(this); 064 } 065 public static String _toString(Selects __selects) { 066 Select[] _selects = __selects.getSelects(); 067 Select s; 068 StringBuffer sb=new StringBuffer(); 069 070 for(int y=0;y<_selects.length;y++) { 071 s = _selects[y]; 072 073 if(y>0) { 074 if(s.isUnionDistinct())sb.append("union distinct\n\n"); 075 else sb.append("union\n\n"); 076 } 077 078 sb.append("select\n\t"); 079 080 if(s.isDistinct()) sb.append("distinct\n\t"); 081 ValueNumber top = s.getTop(); 082 if(top!=null) sb.append("top "+top.getString()+"\n\t"); 083 // select 084 Expression[] sels = s.getSelects(); 085 Expression exp; 086 boolean first=true; 087 for(int i=0;i<sels.length;i++) { 088 if(!first)sb.append("\t,"); 089 exp=sels[i]; 090 sb.append(exp.toString(false)+"\n"); 091 first=false; 092 } 093 094 // from 095 sb.append("from\n\t"); 096 Column[] forms = s.getFroms(); 097 first=true; 098 for(int i=0;i<forms.length;i++) { 099 if(!first)sb.append("\t,"); 100 exp=forms[i]; 101 sb.append(exp.toString(false)+"\n"); 102 first=false; 103 } 104 105 // where 106 if(s.getWhere()!=null){ 107 sb.append("where \n\t"); 108 sb.append(s.getWhere().toString(true)); 109 sb.append("\n"); 110 } 111 112 // group by 113 Column[] gbs = s.getGroupbys(); 114 if(gbs.length>0) { 115 sb.append("group by\n\t"); 116 first=true; 117 for(int i=0;i<gbs.length;i++) { 118 if(!first)sb.append("\t,"); 119 exp=gbs[i]; 120 sb.append(exp.toString(false)+"\n"); 121 first=false; 122 } 123 } 124 125 126 // having 127 Operation having = s.getHaving(); 128 if(having!=null){ 129 sb.append("having \n\t"); 130 sb.append(having.toString(true)); 131 sb.append("\n"); 132 } 133 134 } 135 136 // order by 137 if(__selects.orderbys!=null && __selects.orderbys.size()>0) { 138 sb.append("order by\n\t"); 139 Iterator<Column> it = __selects.orderbys.iterator(); 140 Expression exp; 141 boolean first = true; 142 while(it.hasNext()) { 143 if(!first)sb.append("\t,"); 144 exp=it.next(); 145 sb.append(exp.toString(false)+" "+(exp.isDirectionBackward()?"DESC":"ASC")+"\n"); 146 first=false; 147 } 148 } 149 return sb.toString(); 150 } 151 152 public Column[] getTables() { 153 Iterator<Select> it = selects.iterator(); 154 Select s; 155 ArrayList<Column> rtn=new ArrayList<Column>(); 156 Column[] froms; 157 while(it.hasNext()) { 158 s=it.next(); 159 froms = s.getFroms(); 160 for(int i=0;i<froms.length;i++) { 161 rtn.add(froms[i]); 162 } 163 } 164 return rtn.toArray(new Column[rtn.size()]); 165 } 166 167 public boolean isDistinct() { 168 Select s; 169 int len=selects.size(); 170 if(len==1) { 171 s=selects.get(0); 172 return s.isDistinct(); 173 } 174 for(int i=1;i<len;i++) { 175 s=selects.get(i); 176 if(!s.isUnionDistinct()) return false; 177 } 178 return true; 179 } 180 public Column[] getDistincts() throws DatabaseException { 181 List<Column> columns=new ArrayList<Column>(); 182 Select s; 183 int len=selects.size(); 184 if(len==1) { 185 s=selects.get(0); 186 Expression[] _selects = s.getSelects(); 187 for(int i=0;i<_selects.length;i++){ 188 if(_selects[i] instanceof Column) { 189 columns.add((Column) _selects[i]); 190 } 191 } 192 return columns.toArray(new Column[columns.size()]); 193 } 194 throw new DatabaseException("not supported for Union distinct",null,null,null); 195 } 196}