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