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; 024import java.security.Principal; 025 026/** 027 * @author Bogdan Stefanescu 028 * @author Florent Guillaume 029 */ 030public class SQLQuery implements ASTNode { 031 032 private static final long serialVersionUID = 6383829486216039408L; 033 034 private String queryString; 035 036 public SelectClause select; 037 038 public final FromClause from; 039 040 public final WhereClause where; 041 042 public OrderByClause orderBy; 043 044 public final GroupByClause groupBy; 045 046 public final HavingClause having; 047 048 public long limit = 0; 049 050 public long offset = 0; 051 052 public SQLQuery() { 053 this(new SelectClause(), new FromClause(), null, null, null, null); 054 } 055 056 public SQLQuery(SelectClause select, FromClause from) { 057 this(select, from, null, null, null, null); 058 } 059 060 public SQLQuery(SelectClause select, FromClause from, WhereClause where) { 061 this(select, from, where, null, null, null); 062 } 063 064 public SQLQuery(SelectClause select, FromClause from, WhereClause where, OrderByClause orderBy) { 065 this(select, from, where, null, null, orderBy); 066 } 067 068 public SQLQuery(SelectClause select, FromClause from, WhereClause where, GroupByClause groupBy, 069 HavingClause having, OrderByClause orderBy) { 070 this.select = select; 071 this.from = from; 072 this.where = where; 073 this.groupBy = groupBy; 074 this.having = having; 075 this.orderBy = orderBy; 076 } 077 078 public SQLQuery(SelectClause select, FromClause from, WhereClause where, GroupByClause groupBy, 079 HavingClause having, OrderByClause orderBy, long limit, long offset) { 080 this.select = select; 081 this.from = from; 082 this.where = where; 083 this.groupBy = groupBy; 084 this.having = having; 085 this.orderBy = orderBy; 086 this.limit = limit; 087 this.offset = offset; 088 } 089 090 /** 091 * Copying constructor. Does not deep-copy the clauses though. 092 */ 093 public SQLQuery(SQLQuery other) { 094 select = other.select; 095 from = other.from; 096 where = other.where; 097 orderBy = other.orderBy; 098 groupBy = other.groupBy; 099 having = other.having; 100 limit = other.limit; 101 offset = other.offset; 102 } 103 104 public SQLQuery withWhereExpression(Expression whereExpression) { 105 return new SQLQuery(select, from, new WhereClause(whereExpression), groupBy, having, orderBy, limit, offset); 106 } 107 108 public SelectClause getSelectClause() { 109 return select; 110 } 111 112 public FromClause getFromClause() { 113 return from; 114 } 115 116 public WhereClause getWhereClause() { 117 return where; 118 } 119 120 public OrderByClause getOrderByClause() { 121 return orderBy; 122 } 123 124 @Override 125 public void accept(IVisitor visitor) { 126 visitor.visitQuery(this); 127 } 128 129 @Override 130 // FIXME: not finished 131 public String toString() { 132 if (queryString != null) { 133 return queryString; 134 } 135 StringBuilder buf = new StringBuilder(); 136 buf.append("SELECT ").append(select).append(" FROM ").append(from); 137 if (where != null) { 138 buf.append(" WHERE ").append(where); 139 } 140 if (orderBy != null) { 141 buf.append(" ORDER BY ").append(orderBy); 142 } 143 return buf.toString(); 144 } 145 146 public void setLimit(long limit) { 147 this.limit = limit; 148 } 149 150 public void setOffset(long offset) { 151 this.offset = offset; 152 } 153 154 public long getLimit() { 155 return limit; 156 } 157 158 public long getOffset() { 159 return offset; 160 } 161 162 public String getQueryString() { 163 return queryString; 164 } 165 166 public void setQueryString(String queryString) { 167 this.queryString = queryString; 168 } 169 170 @Override 171 public boolean equals(Object obj) { 172 if (this == obj) { 173 return true; 174 } 175 if (obj == null) { 176 return false; 177 } 178 if (getClass() != obj.getClass()) { 179 return false; 180 } 181 SQLQuery other = (SQLQuery) obj; 182 if (select == null) { 183 if (other.select != null) { 184 return false; 185 } 186 } else if (!select.equals(other.select)) { 187 return false; 188 } 189 if (from == null) { 190 if (other.from != null) { 191 return false; 192 } 193 } else if (!from.equals(other.from)) { 194 return false; 195 } 196 if (where == null) { 197 if (other.where != null) { 198 return false; 199 } 200 } else if (!where.equals(other.where)) { 201 return false; 202 } 203 if (orderBy == null) { 204 if (other.orderBy != null) { 205 return false; 206 } 207 } else if (!orderBy.equals(other.orderBy)) { 208 return false; 209 } 210 if (groupBy == null) { 211 if (other.groupBy != null) { 212 return false; 213 } 214 } else if (!groupBy.equals(other.groupBy)) { 215 return false; 216 } 217 if (having == null) { 218 if (other.having != null) { 219 return false; 220 } 221 } else if (!having.equals(other.having)) { 222 return false; 223 } 224 if (limit != other.limit) { 225 return false; 226 } 227 if (offset != other.offset) { 228 return false; 229 } 230 return true; 231 } 232 233 @Override 234 public int hashCode() { 235 final int prime = 31; 236 int result = 1; 237 result = prime * result + (select == null ? 0 : select.hashCode()); 238 result = prime * result + (from == null ? 0 : from.hashCode()); 239 result = prime * result + (where == null ? 0 : where.hashCode()); 240 result = prime * result + (orderBy == null ? 0 : orderBy.hashCode()); 241 result = prime * result + (groupBy == null ? 0 : groupBy.hashCode()); 242 result = prime * result + (having == null ? 0 : having.hashCode()); 243 result = prime * result + (int) (limit ^ (limit >>> 32)); 244 result = prime * result + (int) (offset ^ (offset >>> 32)); 245 return result; 246 } 247 248 /** 249 * Interface for a class that can transform a {@link SQLQuery} into another. 250 */ 251 public interface Transformer extends Serializable { 252 253 Transformer IDENTITY = new IdentityTransformer(); 254 255 SQLQuery transform(Principal principal, SQLQuery query); 256 } 257 258 public static class IdentityTransformer implements Transformer { 259 private static final long serialVersionUID = 1L; 260 261 @Override 262 public SQLQuery transform(Principal principal, SQLQuery query) { 263 return query; 264 } 265 } 266 267}