001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: Update.java 3648 2007-01-29 12:16:16Z gbevin $
007: */
008: package com.uwyn.rife.database.queries;
009:
010: import com.uwyn.rife.database.Datasource;
011: import com.uwyn.rife.database.capabilities.Capabilities;
012: import com.uwyn.rife.database.exceptions.DbQueryException;
013: import com.uwyn.rife.database.exceptions.FieldsRequiredException;
014: import com.uwyn.rife.database.exceptions.TableNameRequiredException;
015: import com.uwyn.rife.database.exceptions.UnsupportedSqlFeatureException;
016: import com.uwyn.rife.database.types.SqlNull;
017: import com.uwyn.rife.site.Constrained;
018: import com.uwyn.rife.site.ConstrainedUtils;
019: import com.uwyn.rife.template.Template;
020: import com.uwyn.rife.template.TemplateFactory;
021: import com.uwyn.rife.tools.StringUtils;
022: import java.util.ArrayList;
023: import java.util.LinkedHashMap;
024: import java.util.Map;
025: import java.util.Set;
026:
027: /**
028: * Object representation of a SQL "UPDATE" query.
029: *
030: * <p>This object may be used to dynamically construct a SQL statement in a
031: * database-independent fashion. After it is finished, it may be executed using
032: * {@link com.uwyn.rife.database.DbQueryManager#executeUpdate(Query)
033: * DbQueryManager.executeUpdate()}.
034: *
035: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
036: * @author Steven Grimm (koreth[remove] at midwinter dot com)
037: * @version $Revision: 3648 $
038: * @since 1.0
039: */
040: public class Update extends AbstractWhereQuery<Update> implements
041: Cloneable {
042: private String mHint = null;
043: private String mTable = null;
044: private Map<String, Object> mFields = null;
045:
046: public Update(Datasource datasource) {
047: super (datasource);
048:
049: if (null == datasource)
050: throw new IllegalArgumentException(
051: "datasource can't be null.");
052:
053: clear();
054: }
055:
056: public void clear() {
057: super .clear();
058:
059: mHint = null;
060: mFields = new LinkedHashMap<String, Object>();
061: mTable = null;
062:
063: assert 0 == mFields.size();
064: }
065:
066: public String getHint() {
067: return mHint;
068: }
069:
070: public String getTable() {
071: return mTable;
072: }
073:
074: public Map<String, Object> getFields() {
075: return mFields;
076: }
077:
078: public Capabilities getCapabilities() {
079: return null;
080: }
081:
082: public String getSql() {
083: if (null == mSql) {
084: if (null == mTable) {
085: throw new TableNameRequiredException("Update");
086: } else if (0 == mFields.size()) {
087: throw new FieldsRequiredException("Update");
088: } else {
089: Template template = TemplateFactory.SQL.get("sql."
090: + StringUtils.encodeClassname(mDatasource
091: .getAliasedDriver()) + ".update");
092:
093: if (mHint != null) {
094: if (!template.hasValueId("HINT")) {
095: throw new UnsupportedSqlFeatureException(
096: "HINT", mDatasource.getAliasedDriver());
097: }
098: template.setValue("EXPRESSION", mHint);
099: template.setBlock("HINT", "HINT");
100: }
101:
102: template.setValue("TABLE", mTable);
103:
104: if (mFields.size() > 0) {
105: ArrayList<String> set_list = new ArrayList<String>();
106:
107: for (String field : mFields.keySet()) {
108: template.setValue("NAME", field);
109: template.setValue("V", mFields.get(field)
110: .toString());
111: set_list.add(template.getBlock("SET"));
112: }
113: template.setValue("SET", StringUtils.join(set_list,
114: template.getBlock("SEPERATOR")));
115: }
116:
117: if (mWhere != null && mWhere.length() > 0) {
118: template.setValue("CONDITION", mWhere);
119: template.setValue("WHERE", template
120: .getBlock("WHERE"));
121: }
122:
123: mSql = template.getBlock("QUERY");
124:
125: assert mSql != null;
126: assert mSql.length() > 0;
127: }
128: }
129:
130: return mSql;
131: }
132:
133: public Update hint(String hint) {
134: clearGenerated();
135: mHint = hint;
136:
137: return this ;
138: }
139:
140: public Update table(String table) {
141: if (null == table)
142: throw new IllegalArgumentException("table can't be null.");
143: if (0 == table.length())
144: throw new IllegalArgumentException("table can't be empty.");
145:
146: clearGenerated();
147: mTable = table;
148:
149: return this ;
150: }
151:
152: public Update fieldSubselect(Select query) {
153: _fieldSubselect(query);
154:
155: return this ;
156: }
157:
158: protected Update _field(String field, Object value) {
159: assert field != null;
160: assert field.length() > 0;
161:
162: clearGenerated();
163: if (null == value) {
164: mFields.put(field, SqlNull.NULL);
165: } else {
166: mFields.put(field, value);
167: }
168:
169: return this ;
170: }
171:
172: public Update fieldParameter(String field) {
173: return fieldParameter(field, field);
174: }
175:
176: public Update fieldParameter(String field, String alias) {
177: if (null == field)
178: throw new IllegalArgumentException("field can't be null.");
179: if (0 == field.length())
180: throw new IllegalArgumentException("field can't be empty.");
181: if (null == alias)
182: throw new IllegalArgumentException("alias can't be null.");
183: if (0 == alias.length())
184: throw new IllegalArgumentException("alias can't be empty.");
185:
186: clearGenerated();
187:
188: addFieldParameter(alias);
189:
190: return _field(field, "?");
191: }
192:
193: public Update field(String field, char value) {
194: return field(field, new Character(value));
195: }
196:
197: public Update field(String field, boolean value) {
198: return field(field, Boolean.valueOf(value));
199: }
200:
201: public Update field(String field, byte value) {
202: return field(field, new Byte(value));
203: }
204:
205: public Update field(String field, double value) {
206: return field(field, new Double(value));
207: }
208:
209: public Update field(String field, float value) {
210: return field(field, new Float(value));
211: }
212:
213: public Update field(String field, int value) {
214: return field(field, new Integer(value));
215: }
216:
217: public Update field(String field, long value) {
218: return field(field, new Long(value));
219: }
220:
221: public Update field(String field, short value) {
222: return field(field, new Short(value));
223: }
224:
225: public Update field(String field, Select query) {
226: if (null == query)
227: throw new IllegalArgumentException("query can't be null.");
228:
229: StringBuilder buffer = new StringBuilder();
230:
231: buffer.append("(");
232: buffer.append(query.toString());
233: buffer.append(")");
234:
235: fieldCustom(field, buffer.toString());
236:
237: _fieldSubselect(query);
238:
239: return this ;
240: }
241:
242: public Update fieldCustom(String field, String expression) {
243: if (null == field)
244: throw new IllegalArgumentException("field can't be null.");
245: if (0 == field.length())
246: throw new IllegalArgumentException("field can't be empty.");
247:
248: if (null == expression) {
249: return _field(field, null);
250: } else {
251: return _field(field, expression);
252: }
253: }
254:
255: public Update field(String field, Object value) {
256: if (null == field)
257: throw new IllegalArgumentException("field can't be null.");
258: if (0 == field.length())
259: throw new IllegalArgumentException("field can't be empty.");
260:
261: if (null == value) {
262: return _field(field, null);
263: } else {
264: return _field(field, mDatasource.getSqlConversion()
265: .getSqlValue(value));
266: }
267: }
268:
269: public Update fields(Object[] keyValues) {
270: if (null == keyValues)
271: throw new IllegalArgumentException(
272: "keyValues can't be null.");
273: if (0 == keyValues.length)
274: throw new IllegalArgumentException(
275: "keyValues can't be empty.");
276:
277: for (int i = 0; i < keyValues.length; i += 2) {
278: if (null != keyValues[i]) {
279: field(keyValues[i].toString(), keyValues[i + 1]);
280: }
281: }
282:
283: return this ;
284: }
285:
286: public Update fields(Object bean) throws DbQueryException {
287: return fieldsFiltered(bean, null, null);
288: }
289:
290: public Update fieldsIncluded(Object bean, String[] includedFields)
291: throws DbQueryException {
292: return fieldsFiltered(bean, includedFields, null);
293: }
294:
295: public Update fieldsExcluded(Object bean, String[] excludedFields)
296: throws DbQueryException {
297: return fieldsFiltered(bean, null, excludedFields);
298: }
299:
300: public Update fieldsFiltered(Object bean, String[] includedFields,
301: String[] excludedFields) throws DbQueryException {
302: if (null == bean)
303: throw new IllegalArgumentException("bean can't be null.");
304:
305: Constrained constrained = ConstrainedUtils
306: .makeConstrainedInstance(bean);
307: Map<String, String> property_values = QueryHelper
308: .getBeanPropertyValues(bean, includedFields,
309: excludedFields, getDatasource());
310:
311: for (String property_name : property_values.keySet()) {
312: if (!ConstrainedUtils.saveConstrainedProperty(constrained,
313: property_name, null)) {
314: continue;
315: }
316:
317: _field(property_name, property_values.get(property_name));
318: }
319:
320: return this ;
321: }
322:
323: public Update fieldsParameters(Class beanClass)
324: throws DbQueryException {
325: return fieldsParametersExcluded(beanClass, null);
326: }
327:
328: public Update fieldsParametersExcluded(Class beanClass,
329: String[] excludedFields) throws DbQueryException {
330: if (null == beanClass)
331: throw new IllegalArgumentException(
332: "beanClass can't be null.");
333:
334: clearGenerated();
335:
336: Constrained constrained = ConstrainedUtils
337: .getConstrainedInstance(beanClass);
338: Set<String> property_names = QueryHelper.getBeanPropertyNames(
339: beanClass, excludedFields);
340:
341: for (String property_name : property_names) {
342: if (!ConstrainedUtils.saveConstrainedProperty(constrained,
343: property_name, null)) {
344: continue;
345: }
346:
347: addFieldParameter(property_name);
348: _field(property_name, "?");
349: }
350:
351: return this ;
352: }
353:
354: public Update clone() {
355: Update new_instance = super .clone();
356: if (new_instance != null) {
357: if (mFields != null) {
358: new_instance.mFields = new LinkedHashMap<String, Object>();
359: new_instance.mFields.putAll(mFields);
360: }
361: }
362:
363: return new_instance;
364: }
365: }
|