001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.persistence.engines.jdbcengine.querygenerator;
051:
052: import java.util.*;
053: import org.jaffa.persistence.engines.jdbcengine.configservice.ClassMetaData;
054: import org.jaffa.persistence.engines.jdbcengine.configservice.ConfigurationService;
055: import org.jaffa.persistence.IPersistent;
056: import org.jaffa.persistence.engines.jdbcengine.util.MoldingService;
057: import org.jaffa.persistence.engines.jdbcengine.proxy.PersistentInstanceFactory;
058: import java.lang.reflect.InvocationTargetException;
059: import java.io.IOException;
060: import org.jaffa.persistence.engines.jdbcengine.variants.Variant;
061:
062: /** This class has functions to return SQL Strings used in Statements.
063: */
064: public class StatementHelper {
065:
066: // some constants used in the methods.
067: private static final String INSERT_INTO = "INSERT INTO";
068: private static final String VALUES = "VALUES";
069: private static final String UPDATE = "UPDATE";
070: private static final String SET = "SET";
071: private static final String WHERE = "WHERE";
072: private static final String AND = "AND";
073: private static final String DELETE_FROM = "DELETE FROM";
074: private static final String SELECT_STAR_FROM = "SELECT * FROM";
075: private static final String IS_NULL = "IS NULL";
076:
077: /** Returns a SQL String for use in Statements for inserting records into the table corresponding to the input Persistent object.
078: * @param object The object to be inserted.
079: * @param engineType The engine type as defined in init.xml
080: * @throws IllegalAccessException if the accessor Method for an attribute enforces Java language access control and the underlying method is inaccessible.
081: * @throws InvocationTargetException if the accessor method for an attribute throws an exception.
082: * @throws IOException if any error occurs while extracting the value for an attribute.
083: * @return a SQL String for use in Statements for inserting records.
084: */
085: public static String getInsertStatementString(IPersistent object,
086: String engineType) throws IllegalAccessException,
087: InvocationTargetException, IOException {
088: ClassMetaData classMetaData = getClassMetaData(object);
089: StringBuffer buf1 = new StringBuffer();
090: buf1.append('('); // the fieldlist buffer
091: StringBuffer buf2 = new StringBuffer();
092: buf2.append('('); // the Values buffer
093: boolean first = true;
094: for (Iterator i = classMetaData.getNonAutoKeyFieldNames()
095: .keySet().iterator(); i.hasNext();) {
096: if (first) {
097: first = false;
098: } else {
099: buf1.append(',');
100: buf2.append(',');
101: }
102: String attributeName = (String) i.next();
103: Object value = MoldingService.getInstanceValue(object,
104: classMetaData, attributeName);
105: buf1.append(classMetaData.getSqlName(attributeName));
106: buf2.append(DataTranslator.getDml(value, classMetaData
107: .getSqlType(attributeName), engineType));
108: }
109: for (Iterator i = classMetaData.getAttributes().keySet()
110: .iterator(); i.hasNext();) {
111: if (first) {
112: first = false;
113: } else {
114: buf1.append(',');
115: buf2.append(',');
116: }
117: String attributeName = (String) i.next();
118: Object value = MoldingService.getInstanceValue(object,
119: classMetaData, attributeName);
120: buf1.append(classMetaData.getSqlName(attributeName));
121: buf2.append(DataTranslator.getDml(value, classMetaData
122: .getSqlType(attributeName), engineType));
123: }
124: buf1.append(')');
125: buf2.append(')');
126:
127: StringBuffer buf = new StringBuffer(INSERT_INTO);
128: buf.append(' ');
129: buf.append(classMetaData.getTable());
130: buf.append(buf1);
131: buf.append(' ');
132: buf.append(VALUES);
133: buf.append(buf2);
134: return buf.toString();
135: }
136:
137: /** Returns a SQL String for use in Statements for updating records in the table corresponding to the input Persistent object.
138: * @param object The object to be updated.
139: * @param engineType The engine type as defined in init.xml
140: * @throws IllegalAccessException if the accessor Method for an attribute enforces Java language access control and the underlying method is inaccessible.
141: * @throws InvocationTargetException if the accessor method for an attribute throws an exception.
142: * @throws IOException if any error occurs while extracting the value for an attribute.
143: * @return a SQL String for use in Statements for updating records.
144: */
145: public static String getUpdateStatementString(IPersistent object,
146: String engineType) throws IllegalAccessException,
147: InvocationTargetException, IOException {
148: ClassMetaData classMetaData = getClassMetaData(object);
149: StringBuffer buf = new StringBuffer(UPDATE);
150: buf.append(' ');
151: buf.append(classMetaData.getTable());
152: buf.append(' ');
153: buf.append(SET);
154: buf.append(' ');
155:
156: boolean first = true;
157: for (Iterator i = classMetaData.getAttributes().keySet()
158: .iterator(); i.hasNext();) {
159: if (first) {
160: first = false;
161: } else {
162: buf.append(',');
163: }
164: String attributeName = (String) i.next();
165: Object value = MoldingService.getInstanceValue(object,
166: classMetaData, attributeName);
167: buf.append(classMetaData.getSqlName(attributeName));
168: buf.append('=');
169: buf.append(DataTranslator.getDml(value, classMetaData
170: .getSqlType(attributeName), engineType));
171: }
172:
173: buf.append(' ');
174: buf.append(WHERE);
175: buf.append(' ');
176: first = true;
177: for (Iterator i = classMetaData.getAllKeyFieldNames().keySet()
178: .iterator(); i.hasNext();) {
179: if (first) {
180: first = false;
181: } else {
182: buf.append(' ');
183: buf.append(AND);
184: buf.append(' ');
185: }
186: String attributeName = (String) i.next();
187: Object value = MoldingService.getInstanceValue(object,
188: classMetaData, attributeName);
189: buf.append(classMetaData.getSqlName(attributeName));
190: if (value == null)
191: buf.append(' ').append(IS_NULL);
192: else
193: buf
194: .append('=')
195: .append(
196: DataTranslator
197: .getDml(
198: value,
199: classMetaData
200: .getSqlType(attributeName),
201: engineType));
202: }
203: return buf.toString();
204: }
205:
206: /** Returns a SQL String for use in Statements for deleting records from the table corresponding to the input Persistent object.
207: * @param object The object to be deleted.
208: * @param engineType The engine type as defined in init.xml
209: * @throws IllegalAccessException if the accessor Method for an attribute enforces Java language access control and the underlying method is inaccessible.
210: * @throws InvocationTargetException if the accessor method for an attribute throws an exception.
211: * @throws IOException if any error occurs while extracting the value for an attribute.
212: * @return a SQL String for use in Statements for deleting records.
213: */
214: public static String getDeleteStatementString(IPersistent object,
215: String engineType) throws IllegalAccessException,
216: InvocationTargetException, IOException {
217: ClassMetaData classMetaData = getClassMetaData(object);
218: StringBuffer buf = new StringBuffer(DELETE_FROM);
219: buf.append(' ');
220: buf.append(classMetaData.getTable());
221: buf.append(' ');
222: buf.append(WHERE);
223: buf.append(' ');
224: boolean first = true;
225: for (Iterator i = classMetaData.getAllKeyFieldNames().keySet()
226: .iterator(); i.hasNext();) {
227: if (first) {
228: first = false;
229: } else {
230: buf.append(' ');
231: buf.append(AND);
232: buf.append(' ');
233: }
234: String attributeName = (String) i.next();
235: Object value = MoldingService.getInstanceValue(object,
236: classMetaData, attributeName);
237: buf.append(classMetaData.getSqlName(attributeName));
238: if (value == null)
239: buf.append(' ').append(IS_NULL);
240: else
241: buf
242: .append('=')
243: .append(
244: DataTranslator
245: .getDml(
246: value,
247: classMetaData
248: .getSqlType(attributeName),
249: engineType));
250: }
251: return buf.toString();
252: }
253:
254: /** Returns a SQL String for use in Statements for locking records in the table corresponding to the input Persistent object.
255: * @param object The object to be locked.
256: * @param engineType The engine type as defined in init.xml
257: * @throws IllegalAccessException if the accessor Method for an attribute enforces Java language access control and the underlying method is inaccessible.
258: * @throws InvocationTargetException if the accessor method for an attribute throws an exception.
259: * @throws IOException if any error occurs while extracting the value for an attribute.
260: * @return a SQL String for use in Statements for locking records.
261: */
262: public static String getLockStatementString(IPersistent object,
263: String engineType) throws IllegalAccessException,
264: InvocationTargetException, IOException {
265: ClassMetaData classMetaData = getClassMetaData(object);
266: StringBuffer buf = new StringBuffer(SELECT_STAR_FROM);
267: buf.append(' ');
268: buf.append(classMetaData.getTable());
269: buf.append(' ');
270: // Added for supplying Locking 'Hints' used by SqlServer
271: buf.append(Variant.getProperty(engineType,
272: Variant.PROP_LOCK_CONSTRUCT_IN_FROM_SELECT_STATEMENT));
273: buf.append(' ');
274: buf.append(WHERE);
275: buf.append(' ');
276:
277: boolean first = true;
278: for (Iterator i = classMetaData.getAllKeyFieldNames().keySet()
279: .iterator(); i.hasNext();) {
280: if (first) {
281: first = false;
282: } else {
283: buf.append(AND);
284: buf.append(' ');
285: }
286: String attributeName = (String) i.next();
287: Object value = MoldingService.getInstanceValue(object,
288: classMetaData, attributeName);
289: buf.append(classMetaData.getSqlName(attributeName));
290: if (value == null)
291: buf.append(' ').append(IS_NULL);
292: else
293: buf
294: .append('=')
295: .append(
296: DataTranslator
297: .getDml(
298: value,
299: classMetaData
300: .getSqlType(attributeName),
301: engineType));
302: buf.append(' ');
303: }
304: buf.append(Variant.getProperty(engineType,
305: Variant.PROP_LOCK_CONSTRUCT_IN_SELECT_STATEMENT));
306: return buf.toString();
307: }
308:
309: private static ClassMetaData getClassMetaData(IPersistent object) {
310: return ConfigurationService.getInstance().getMetaData(
311: PersistentInstanceFactory.getActualPersistentClass(
312: object).getName());
313: }
314: }
|