001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Bogdan Stefanescu 018 * Florent Guillaume 019 */ 020 021package org.nuxeo.ecm.core.query.sql.model; 022 023import java.io.Serializable; 024 025import org.nuxeo.ecm.core.api.NuxeoPrincipal; 026 027/** 028 * @author Bogdan Stefanescu 029 * @author Florent Guillaume 030 */ 031public class SQLQuery implements ASTNode { 032 033 private static final long serialVersionUID = 6383829486216039408L; 034 035 private String queryString; 036 037 public SelectClause select; 038 039 public final FromClause from; 040 041 public final WhereClause where; 042 043 public OrderByClause orderBy; 044 045 public final GroupByClause groupBy; 046 047 public final HavingClause having; 048 049 public long limit = 0; 050 051 public long offset = 0; 052 053 public SQLQuery() { 054 this(new SelectClause(), new FromClause(), null, null, null, null); 055 } 056 057 public SQLQuery(SelectClause select, FromClause from) { 058 this(select, from, null, null, null, null); 059 } 060 061 public SQLQuery(SelectClause select, FromClause from, WhereClause where) { 062 this(select, from, where, null, null, null); 063 } 064 065 public SQLQuery(SelectClause select, FromClause from, WhereClause where, OrderByClause orderBy) { 066 this(select, from, where, null, null, orderBy); 067 } 068 069 public SQLQuery(SelectClause select, FromClause from, WhereClause where, GroupByClause groupBy, 070 HavingClause having, OrderByClause orderBy) { 071 this.select = select; 072 this.from = from; 073 this.where = where; 074 this.groupBy = groupBy; 075 this.having = having; 076 this.orderBy = orderBy; 077 } 078 079 public SQLQuery(SelectClause select, FromClause from, WhereClause where, GroupByClause groupBy, 080 HavingClause having, OrderByClause orderBy, long limit, long offset) { 081 this.select = select; 082 this.from = from; 083 this.where = where; 084 this.groupBy = groupBy; 085 this.having = having; 086 this.orderBy = orderBy; 087 this.limit = limit; 088 this.offset = offset; 089 } 090 091 /** 092 * Copying constructor. Does not deep-copy the clauses though. 093 */ 094 public SQLQuery(SQLQuery other) { 095 select = other.select; 096 from = other.from; 097 where = other.where; 098 orderBy = other.orderBy; 099 groupBy = other.groupBy; 100 having = other.having; 101 limit = other.limit; 102 offset = other.offset; 103 } 104 105 public SQLQuery withPredicate(Predicate predicate) { 106 return new SQLQuery(select, from, new WhereClause(predicate), groupBy, having, orderBy, limit, offset); 107 } 108 109 public SelectClause getSelectClause() { 110 return select; 111 } 112 113 public FromClause getFromClause() { 114 return from; 115 } 116 117 public WhereClause getWhereClause() { 118 return where; 119 } 120 121 public OrderByClause getOrderByClause() { 122 return orderBy; 123 } 124 125 @Override 126 public void accept(IVisitor visitor) { 127 visitor.visitQuery(this); 128 } 129 130 @Override 131 // FIXME: not finished 132 public String toString() { 133 if (queryString != null) { 134 return queryString; 135 } 136 StringBuilder sb = new StringBuilder(); 137 sb.append("SELECT ").append(select).append(" FROM ").append(from); 138 if (where != null) { 139 sb.append(" WHERE ").append(where); 140 } 141 if (orderBy != null) { 142 sb.append(" ORDER BY ").append(orderBy); 143 } 144 return sb.toString(); 145 } 146 147 public void setLimit(long limit) { 148 this.limit = limit; 149 } 150 151 public void setOffset(long offset) { 152 this.offset = offset; 153 } 154 155 public long getLimit() { 156 return limit; 157 } 158 159 public long getOffset() { 160 return offset; 161 } 162 163 public String getQueryString() { 164 return queryString; 165 } 166 167 public void setQueryString(String queryString) { 168 this.queryString = queryString; 169 } 170 171 @Override 172 public boolean equals(Object obj) { 173 if (this == obj) { 174 return true; 175 } 176 if (obj == null) { 177 return false; 178 } 179 if (getClass() != obj.getClass()) { 180 return false; 181 } 182 SQLQuery other = (SQLQuery) obj; 183 if (select == null) { 184 if (other.select != null) { 185 return false; 186 } 187 } else if (!select.equals(other.select)) { 188 return false; 189 } 190 if (from == null) { 191 if (other.from != null) { 192 return false; 193 } 194 } else if (!from.equals(other.from)) { 195 return false; 196 } 197 if (where == null) { 198 if (other.where != null) { 199 return false; 200 } 201 } else if (!where.equals(other.where)) { 202 return false; 203 } 204 if (orderBy == null) { 205 if (other.orderBy != null) { 206 return false; 207 } 208 } else if (!orderBy.equals(other.orderBy)) { 209 return false; 210 } 211 if (groupBy == null) { 212 if (other.groupBy != null) { 213 return false; 214 } 215 } else if (!groupBy.equals(other.groupBy)) { 216 return false; 217 } 218 if (having == null) { 219 if (other.having != null) { 220 return false; 221 } 222 } else if (!having.equals(other.having)) { 223 return false; 224 } 225 if (limit != other.limit) { 226 return false; 227 } 228 if (offset != other.offset) { 229 return false; 230 } 231 return true; 232 } 233 234 @Override 235 public int hashCode() { 236 final int prime = 31; 237 int result = 1; 238 result = prime * result + (select == null ? 0 : select.hashCode()); 239 result = prime * result + (from == null ? 0 : from.hashCode()); 240 result = prime * result + (where == null ? 0 : where.hashCode()); 241 result = prime * result + (orderBy == null ? 0 : orderBy.hashCode()); 242 result = prime * result + (groupBy == null ? 0 : groupBy.hashCode()); 243 result = prime * result + (having == null ? 0 : having.hashCode()); 244 result = prime * result + (int) (limit ^ (limit >>> 32)); 245 result = prime * result + (int) (offset ^ (offset >>> 32)); 246 return result; 247 } 248 249 /** 250 * Interface for a class that can transform a {@link SQLQuery} into another. 251 */ 252 public interface Transformer { 253 254 Transformer IDENTITY = new IdentityTransformer(); 255 256 SQLQuery transform(NuxeoPrincipal principal, SQLQuery query); 257 } 258 259 public static class IdentityTransformer implements Transformer { 260 @Override 261 public SQLQuery transform(NuxeoPrincipal principal, SQLQuery query) { 262 return query; 263 } 264 } 265 266}