1 /*
2 Copyright (c) 2008 Health Market Science, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 USA
18
19 You can contact Health Market Science at info@healthmarketscience.com
20 or at the following address:
21
22 Health Market Science
23 2700 Horizon Drive
24 Suite 200
25 King of Prussia, PA 19406
26 */
27
28 package com.healthmarketscience.sqlbuilder;
29
30 import java.io.IOException;
31
32 import com.healthmarketscience.common.util.AppendableExt;
33
34 /**
35 * Outputs combination expressions joined by a given mathematical operation (+,
36 * -, *, /) or string operation (||) <code>"(<expr1> <exprOp> <expr2> <exprOp> <expr3> ...)"</code>. Only outputs non-empty
37 * expressions in the expression list.
38 *
39 * @author James Ahlborn
40 */
41 public class ComboExpression extends Expression
42 {
43 /**
44 * Enum representing the combo mathematical operations supported in a SQL
45 * expression, e.g. <code>"(<expr1> <exprOp> <expr2> <exprOp> <expr3> ...)"</code>.
46 */
47 public enum Op
48 {
49 ADD(" + "),
50 SUBTRACT(" - "),
51 MULTIPLY(" * "),
52 DIVIDE(" / "),
53 CONCATENATE(" || ");
54
55 private final String _opStr;
56
57 private Op(String opStr) {
58 _opStr = opStr;
59 }
60
61 @Override
62 public String toString() { return _opStr; }
63 }
64
65
66 private SqlObjectList<Expression> _expressions;
67
68 public ComboExpression(Op comboOp) {
69 this(comboOp, (Object[])null);
70 }
71
72 /**
73 * {@code Object} -> {@code Expression} conversions handled by
74 * {@link Converter#CUSTOM_TO_EXPRESSION}.
75 */
76 public ComboExpression(Op comboOp, Object... expressions) {
77 this((Object)comboOp, expressions);
78 }
79
80 /**
81 * {@code Object} -> {@code Expression} conversions handled by
82 * {@link Converter#CUSTOM_TO_EXPRESSION}.
83 */
84 public ComboExpression(Object comboOpStr, Object... expressions) {
85 _expressions = SqlObjectList.create(comboOpStr.toString());
86 _expressions.addObjects(Converter.CUSTOM_TO_EXPRESSION, expressions);
87 }
88
89 @Override
90 protected void collectSchemaObjects(ValidationContext vContext) {
91 _expressions.collectSchemaObjects(vContext);
92 }
93
94 @Override
95 public boolean isEmpty() {
96 return areEmpty(_expressions);
97 }
98
99 @Override
100 public boolean hasParens() {
101 return hasParens(_expressions);
102 }
103
104 /**
105 * Adds the given expression to the list of expression (wrapped
106 * appropriately).
107 * <p>
108 * {@code Object} -> {@code Expression} conversions handled by
109 * {@link Converter#CUSTOM_TO_EXPRESSION}.
110 */
111 public ComboExpression addExpression(Object expr) {
112 return addExpressions(expr);
113 }
114
115 /**
116 * Adds the given expressions to the list of expressions (wrapped
117 * appropriately).
118 * <p>
119 * {@code Object} -> {@code Expression} conversions handled by
120 * {@link Converter#CUSTOM_TO_EXPRESSION}.
121 */
122 public ComboExpression addExpressions(Object... exprs) {
123 _expressions.addObjects(Converter.CUSTOM_TO_EXPRESSION, exprs);
124 return this;
125 }
126
127 @Override
128 public void appendTo(AppendableExt app) throws IOException
129 {
130 appendNestedClauses(app, _expressions);
131 }
132
133
134 /**
135 * Convenience method for generating a ComboExpression for joining
136 * expressions using '+'.
137 */
138 public static ComboExpression add() {
139 return new ComboExpression(Op.ADD);
140 }
141
142 /**
143 * Convenience method for generating a ComboExpression for joining
144 * the given expressions using '+'.
145 *
146 * {@code Object} -> {@code Expression} conversions handled by
147 * {@link Converter#CUSTOM_TO_EXPRESSION}.
148 */
149 public static ComboExpression add(Object... expressions) {
150 return new ComboExpression(Op.ADD, expressions);
151 }
152
153 /**
154 * Convenience method for generating a ComboExpression for joining
155 * expressions using '-'.
156 */
157 public static ComboExpression subtract() {
158 return new ComboExpression(Op.SUBTRACT);
159 }
160
161 /**
162 * Convenience method for generating a ComboExpression for joining
163 * the given expressions using '-'.
164 *
165 * {@code Object} -> {@code Expression} conversions handled by
166 * {@link Converter#CUSTOM_TO_EXPRESSION}.
167 */
168 public static ComboExpression subtract(Object... expressions) {
169 return new ComboExpression(Op.SUBTRACT, expressions);
170 }
171
172 /**
173 * Convenience method for generating a ComboExpression for joining
174 * expressions using '*'.
175 */
176 public static ComboExpression multiply() {
177 return new ComboExpression(Op.MULTIPLY);
178 }
179
180 /**
181 * Convenience method for generating a ComboExpression for joining
182 * the given expressions using '*'.
183 *
184 * {@code Object} -> {@code Expression} conversions handled by
185 * {@link Converter#CUSTOM_TO_EXPRESSION}.
186 */
187 public static ComboExpression multiply(Object... expressions) {
188 return new ComboExpression(Op.MULTIPLY, expressions);
189 }
190
191 /**
192 * Convenience method for generating a ComboExpression for joining
193 * expressions using '/'.
194 */
195 public static ComboExpression divide() {
196 return new ComboExpression(Op.DIVIDE);
197 }
198
199 /**
200 * Convenience method for generating a ComboExpression for joining
201 * the given expressions using '/'.
202 *
203 * {@code Object} -> {@code Expression} conversions handled by
204 * {@link Converter#CUSTOM_TO_EXPRESSION}.
205 */
206 public static ComboExpression divide(Object... expressions) {
207 return new ComboExpression(Op.DIVIDE, expressions);
208 }
209
210 /**
211 * Convenience method for generating a ComboExpression for joining
212 * expressions using '||'.
213 */
214 public static ComboExpression concatenate() {
215 return new ComboExpression(Op.CONCATENATE);
216 }
217
218 /**
219 * Convenience method for generating a ComboExpression for joining
220 * the given expressions using '||'.
221 *
222 * {@code Object} -> {@code Expression} conversions handled by
223 * {@link Converter#CUSTOM_TO_EXPRESSION}.
224 */
225 public static ComboExpression concatenate(Object... expressions) {
226 return new ComboExpression(Op.CONCATENATE, expressions);
227 }
228
229 }