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