001: package com.mockrunner.jdbc;
002:
003: import java.sql.SQLException;
004: import java.util.ArrayList;
005: import java.util.Arrays;
006: import java.util.Collections;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Map;
011: import java.util.TreeMap;
012:
013: import com.mockrunner.mock.jdbc.MockResultSet;
014: import com.mockrunner.util.common.ArrayUtil;
015:
016: /**
017: * Abstract base class for all statement types
018: * that support parameters, i.e. <code>PreparedStatement</code>
019: * and <code>CallableStatement</code>.
020: */
021: public abstract class AbstractParameterResultSetHandler extends
022: AbstractResultSetHandler {
023: private boolean exactMatchParameter = false;
024: private Map resultSetsForStatement = new TreeMap();
025: private Map updateCountForStatement = new TreeMap();
026: private Map throwsSQLException = new TreeMap();
027: private Map generatedKeysForStatement = new TreeMap();
028: private Map executedStatementParameters = new TreeMap();
029:
030: /**
031: * Collects all SQL strings that were executed.
032: * @param sql the SQL string
033: * @param parameters a copy of the corresponding parameter map
034: */
035: public void addParameterMapForExecutedStatement(String sql,
036: Map parameters) {
037: if (null != parameters) {
038: if (null == executedStatementParameters.get(sql)) {
039: executedStatementParameters.put(sql, new ParameterSets(
040: sql));
041: }
042: ParameterSets sets = (ParameterSets) executedStatementParameters
043: .get(sql);
044: sets.addParameterSet(parameters);
045: }
046: }
047:
048: /**
049: * Returns the <code>ParameterSets</code> for a specified
050: * SQL string.
051: * @param sql the SQL string
052: * @return the <code>Map</code> of parameters
053: */
054: public ParameterSets getParametersForExecutedStatement(String sql) {
055: return (ParameterSets) executedStatementParameters.get(sql);
056: }
057:
058: /**
059: * Returns the <code>Map</code> of executed SQL strings.
060: * Each string maps to the corresponding {@link ParameterSets}
061: * object.
062: * @return the <code>Map</code> of parameters
063: */
064: public Map getExecutedStatementParameterMap() {
065: return Collections.unmodifiableMap(executedStatementParameters);
066: }
067:
068: /**
069: * @deprecated use {@link #getExecutedStatementParameterMap}
070: */
071: public Map getExecutedStatementParameter() {
072: return getExecutedStatementParameterMap();
073: }
074:
075: /**
076: * Sets if the specified parameters must match exactly
077: * in order and number.
078: * Defaults to <code>false</code>, i.e. the specified
079: * parameters must be present in the actual parameter
080: * list of the prepared statement with the correct index
081: * but it's ok if there are more actual parameters.
082: * @param exactMatchParameter must parameters match exactly
083: */
084: public void setExactMatchParameter(boolean exactMatchParameter) {
085: this .exactMatchParameter = exactMatchParameter;
086: }
087:
088: /**
089: * Returns the first update count that matches the
090: * specified SQL string and the specified parameters.
091: * If the specified SQL string was prepared to return multiple update
092: * counts, the first one will be returned.
093: * Please note that you can modify the match parameters with
094: * {@link #setCaseSensitive}, {@link #setExactMatch} and
095: * {@link #setUseRegularExpressions} and the match parameters for the
096: * specified parameter list with {@link #setExactMatchParameter}.
097: * @param sql the SQL string
098: * @param parameters the parameters
099: * @return the corresponding update count
100: */
101: public Integer getUpdateCount(String sql, Map parameters) {
102: Integer[] updateCounts = getUpdateCounts(sql, parameters);
103: if (null != updateCounts && updateCounts.length > 0) {
104: return updateCounts[0];
105: }
106: return null;
107: }
108:
109: /**
110: * Returns the first update count array that matches the
111: * specified SQL string and the specified parameters.
112: * If the specified SQL string was prepared to return one update count,
113: * this value will be wrapped in an array with one element.
114: * Please note that you can modify the match parameters with
115: * {@link #setCaseSensitive}, {@link #setExactMatch} and
116: * {@link #setUseRegularExpressions} and the match parameters for the
117: * specified parameter list with {@link #setExactMatchParameter}.
118: * @param sql the SQL string
119: * @param parameters the parameters
120: * @return the corresponding update count
121: */
122: public Integer[] getUpdateCounts(String sql, Map parameters) {
123: ParameterWrapper wrapper = (ParameterWrapper) getMatchingParameterWrapper(
124: sql, parameters, updateCountForStatement);
125: if (null != wrapper) {
126: if (wrapper instanceof MockUpdateCountWrapper) {
127: return new Integer[] { ((MockUpdateCountWrapper) wrapper)
128: .getUpdateCount() };
129: } else if (wrapper instanceof MockUpdateCountArrayWrapper) {
130: return ((MockUpdateCountArrayWrapper) wrapper)
131: .getUpdateCount();
132: }
133: }
134: return null;
135: }
136:
137: /**
138: * Returns the if the specified SQL string with the specified parameters
139: * returns multiple update counts.
140: * Please note that you can modify the match parameters with {@link #setCaseSensitive},
141: * {@link #setExactMatch} and {@link #setUseRegularExpressions}.
142: * @param sql the SQL string
143: * @return <code>true</code> if the SQL string returns multiple update counts,
144: * <code>false</code> otherwise
145: */
146: public boolean hasMultipleUpdateCounts(String sql, Map parameters) {
147: ParameterWrapper wrapper = (ParameterWrapper) getMatchingParameterWrapper(
148: sql, parameters, updateCountForStatement);
149: return (wrapper instanceof MockUpdateCountArrayWrapper);
150: }
151:
152: /**
153: * Returns the first <code>ResultSet</code> that matches the
154: * specified SQL string and the specified parameters.
155: * If the specified SQL string was prepared to return multiple result
156: * sets, the first one will be returned.
157: * Please note that you can modify the match parameters with
158: * {@link #setCaseSensitive}, {@link #setExactMatch} and
159: * {@link #setUseRegularExpressions} and the match parameters for the
160: * specified parameter list with {@link #setExactMatchParameter}.
161: * @param sql the SQL string
162: * @param parameters the parameters
163: * @return the corresponding {@link MockResultSet}
164: */
165: public MockResultSet getResultSet(String sql, Map parameters) {
166: MockResultSet[] resultSets = getResultSets(sql, parameters);
167: if (null != resultSets && resultSets.length > 0) {
168: return resultSets[0];
169: }
170: return null;
171: }
172:
173: /**
174: * Returns the first <code>ResultSet[]</code> that matches the
175: * specified SQL string and the specified parameters.
176: * If the specified SQL string was prepared to return one single
177: * <code>ResultSet</code>, this <code>ResultSet</code> will be wrapped
178: * in an array with one element.
179: * Please note that you can modify the match parameters with
180: * {@link #setCaseSensitive}, {@link #setExactMatch} and
181: * {@link #setUseRegularExpressions} and the match parameters for the
182: * specified parameter list with {@link #setExactMatchParameter}.
183: * @param sql the SQL string
184: * @param parameters the parameters
185: * @return the corresponding update count
186: */
187: public MockResultSet[] getResultSets(String sql, Map parameters) {
188: ParameterWrapper wrapper = (ParameterWrapper) getMatchingParameterWrapper(
189: sql, parameters, resultSetsForStatement);
190: if (null != wrapper) {
191: if (wrapper instanceof MockResultSetWrapper) {
192: return new MockResultSet[] { ((MockResultSetWrapper) wrapper)
193: .getResultSet() };
194: } else if (wrapper instanceof MockResultSetArrayWrapper) {
195: return ((MockResultSetArrayWrapper) wrapper)
196: .getResultSets();
197: }
198: }
199: return null;
200: }
201:
202: /**
203: * Returns the if the specified SQL string with the specified parameters
204: * returns multiple result sets.
205: * Please note that you can modify the match parameters with {@link #setCaseSensitive},
206: * {@link #setExactMatch} and {@link #setUseRegularExpressions}.
207: * @param sql the SQL string
208: * @return <code>true</code> if the SQL string returns multiple update counts,
209: * <code>false</code> otherwise
210: */
211: public boolean hasMultipleResultSets(String sql, Map parameters) {
212: ParameterWrapper wrapper = (ParameterWrapper) getMatchingParameterWrapper(
213: sql, parameters, resultSetsForStatement);
214: return (wrapper instanceof MockResultSetArrayWrapper);
215: }
216:
217: /**
218: * Returns if the specified SQL string with the specified parameters
219: * should raise an exception.
220: * This can be used to simulate database exceptions.
221: * Please note that you can modify the match parameters with
222: * {@link #setCaseSensitive}, {@link #setExactMatch} and
223: * {@link #setUseRegularExpressions} and the match parameters for the
224: * specified parameter list with {@link #setExactMatchParameter}.
225: * @param sql the SQL string
226: * @param parameters the parameters
227: * @return <code>true</code> if the specified SQL string should raise an exception,
228: * <code>false</code> otherwise
229: */
230: public boolean getThrowsSQLException(String sql, Map parameters) {
231: return (getSQLException(sql, parameters) != null);
232: }
233:
234: /**
235: * Returns the <code>SQLException</code> the specified SQL string
236: * should throw. Returns <code>null</code> if the specified SQL string
237: * should not throw an exception.
238: * This can be used to simulate database exceptions.
239: * Please note that you can modify the match parameters with
240: * {@link #setCaseSensitive}, {@link #setExactMatch} and
241: * {@link #setUseRegularExpressions} and the match parameters for the
242: * specified parameter list with {@link #setExactMatchParameter}.
243: * @param sql the SQL string
244: * @param parameters the parameters
245: * @return the <code>SQLException</code> or <code>null</code>
246: */
247: public SQLException getSQLException(String sql, Map parameters) {
248: MockSQLExceptionWrapper wrapper = (MockSQLExceptionWrapper) getMatchingParameterWrapper(
249: sql, parameters, throwsSQLException);
250: if (null != wrapper) {
251: return wrapper.getException();
252: }
253: return null;
254: }
255:
256: /**
257: * Returns the first generated keys <code>ResultSet</code> that
258: * matches the specified SQL string.
259: * Please note that you can modify the match parameters with
260: * {@link #setCaseSensitive}, {@link #setExactMatch} and
261: * {@link #setUseRegularExpressions} and the match parameters for the
262: * specified parameter list with {@link #setExactMatchParameter}.
263: * @param sql the SQL string
264: * @param parameters the parameters
265: * @return the corresponding generated keys {@link MockResultSet}
266: */
267: public MockResultSet getGeneratedKeys(String sql, Map parameters) {
268: MockResultSetWrapper wrapper = (MockResultSetWrapper) getMatchingParameterWrapper(
269: sql, parameters, generatedKeysForStatement);
270: if (null != wrapper) {
271: return wrapper.getResultSet();
272: }
273: return null;
274: }
275:
276: protected ParameterWrapper getMatchingParameterWrapper(String sql,
277: Map parameters, Map statementMap) {
278: SQLStatementMatcher matcher = new SQLStatementMatcher(
279: getCaseSensitive(), getExactMatch(),
280: getUseRegularExpressions());
281: List list = matcher.getMatchingObjects(statementMap, sql, true,
282: true);
283: for (int ii = 0; ii < list.size(); ii++) {
284: ParameterWrapper wrapper = (ParameterWrapper) list.get(ii);
285: if (doParameterMatch(wrapper.getParamters(), parameters)) {
286: return wrapper;
287: }
288: }
289: return null;
290: }
291:
292: private boolean doParameterMatch(Map expectedParameters,
293: Map actualParameters) {
294: if (exactMatchParameter) {
295: if (actualParameters.size() != expectedParameters.size())
296: return false;
297: Iterator iterator = actualParameters.keySet().iterator();
298: while (iterator.hasNext()) {
299: Object currentKey = iterator.next();
300: if (!actualParameters.containsKey(currentKey))
301: return false;
302: Object expectedObject = expectedParameters
303: .get(currentKey);
304: if (!ParameterUtil.compareParameter(actualParameters
305: .get(currentKey), expectedObject)) {
306: return false;
307: }
308: }
309: return true;
310: } else {
311: Iterator iterator = expectedParameters.keySet().iterator();
312: while (iterator.hasNext()) {
313: Object currentKey = iterator.next();
314: if (!actualParameters.containsKey(currentKey))
315: return false;
316: Object actualObject = actualParameters.get(currentKey);
317: if (!ParameterUtil.compareParameter(actualObject,
318: expectedParameters.get(currentKey))) {
319: return false;
320: }
321: }
322: return true;
323: }
324: }
325:
326: /**
327: * Clears the <code>ResultSet</code> objects.
328: */
329: public void clearResultSets() {
330: super .clearResultSets();
331: resultSetsForStatement.clear();
332: }
333:
334: /**
335: * Clears the update counts.
336: */
337: public void clearUpdateCounts() {
338: super .clearUpdateCounts();
339: updateCountForStatement.clear();
340: }
341:
342: /**
343: * Clears the list of statements that should throw an exception
344: */
345: public void clearThrowsSQLException() {
346: super .clearThrowsSQLException();
347: throwsSQLException.clear();
348: }
349:
350: /**
351: * Clears the list of statements that return generated keys.
352: */
353: public void clearGeneratedKeys() {
354: super .clearGeneratedKeys();
355: generatedKeysForStatement.clear();
356: }
357:
358: /**
359: * Prepare a <code>ResultSet</code> for a specified SQL string and
360: * the specified parameters. The specified parameters array
361: * must contain the parameters in the correct order starting with index 0 for
362: * the first parameter. Please keep in mind that parameters in
363: * <code>PreparedStatement</code> objects start with 1 as the first
364: * parameter. So <code>parameters[0]</code> maps to the
365: * parameter with index 1.
366: * Please note that you can modify the match parameters with
367: * {@link #setCaseSensitive}, {@link #setExactMatch} and
368: * {@link #setUseRegularExpressions} and the match parameters for the
369: * specified parameter list with {@link #setExactMatchParameter}.
370: * @param sql the SQL string
371: * @param resultSet the corresponding {@link MockResultSet}
372: * @param parameters the parameters
373: */
374: public void prepareResultSet(String sql, MockResultSet resultSet,
375: Object[] parameters) {
376: prepareResultSet(sql, resultSet, Arrays.asList(parameters));
377: }
378:
379: /**
380: * Prepare an array of <code>ResultSet</code> objects for a specified SQL string and
381: * the specified parameters. This method can be used for queries that return
382: * multiple result sets. The specified parameters array
383: * must contain the parameters in the correct order starting with index 0 for
384: * the first parameter. Please keep in mind that parameters in
385: * <code>PreparedStatement</code> objects start with 1 as the first
386: * parameter. So <code>parameters[0]</code> maps to the
387: * parameter with index 1.
388: * Please note that you can modify the match parameters with
389: * {@link #setCaseSensitive}, {@link #setExactMatch} and
390: * {@link #setUseRegularExpressions} and the match parameters for the
391: * specified parameter list with {@link #setExactMatchParameter}.
392: * @param sql the SQL string
393: * @param resultSets the corresponding <code>MockResultSet[]</code>
394: * @param parameters the parameters
395: */
396: public void prepareResultSets(String sql,
397: MockResultSet[] resultSets, Object[] parameters) {
398: prepareResultSets(sql, resultSets, Arrays.asList(parameters));
399: }
400:
401: /**
402: * Prepare a <code>ResultSet</code> for a specified SQL string and
403: * the specified parameters. The specified parameters <code>List</code>
404: * must contain the parameters in the correct order starting with index 0 for
405: * the first parameter. Please keep in mind that parameters in
406: * <code>PreparedStatement</code> objects start with 1 as the first
407: * parameter. So <code>parameters.get(0)</code> maps to the
408: * parameter with index 1.
409: * Please note that you can modify the match parameters with
410: * {@link #setCaseSensitive}, {@link #setExactMatch} and
411: * {@link #setUseRegularExpressions} and the match parameters for the
412: * specified parameter list with {@link #setExactMatchParameter}.
413: * @param sql the SQL string
414: * @param resultSet the corresponding {@link MockResultSet}
415: * @param parameters the parameters
416: */
417: public void prepareResultSet(String sql, MockResultSet resultSet,
418: List parameters) {
419: Map params = createParameterMap(parameters);
420: prepareResultSet(sql, resultSet, params);
421: }
422:
423: /**
424: * Prepare an array of <code>ResultSet</code> objects for a specified SQL string and
425: * the specified parameters. This method can be used for queries that return
426: * multiple result sets. The specified parameters <code>List</code>
427: * must contain the parameters in the correct order starting with index 0 for
428: * the first parameter. Please keep in mind that parameters in
429: * <code>PreparedStatement</code> objects start with 1 as the first
430: * parameter. So <code>parameters.get(0)</code> maps to the
431: * parameter with index 1.
432: * Please note that you can modify the match parameters with
433: * {@link #setCaseSensitive}, {@link #setExactMatch} and
434: * {@link #setUseRegularExpressions} and the match parameters for the
435: * specified parameter list with {@link #setExactMatchParameter}.
436: * @param sql the SQL string
437: * @param resultSets the corresponding <code>MockResultSet[]</code>
438: * @param parameters the parameters
439: */
440: public void prepareResultSets(String sql,
441: MockResultSet[] resultSets, List parameters) {
442: Map params = createParameterMap(parameters);
443: prepareResultSets(sql, resultSets, params);
444: }
445:
446: /**
447: * Prepare a <code>ResultSet</code> for a specified SQL string and
448: * the specified parameters. The specified parameters <code>Map</code>
449: * must contain the parameters by mapping <code>Integer</code> objects
450: * to the corresponding parameter. The <code>Integer</code> object
451: * is the index of the parameter. In the case of a <code>CallableStatement</code>,
452: * <code>String</code> keys for named parameters are also allowed.
453: * Please note that you can modify the match parameters with
454: * {@link #setCaseSensitive}, {@link #setExactMatch} and
455: * {@link #setUseRegularExpressions} and the match parameters for the
456: * specified parameter list with {@link #setExactMatchParameter}.
457: * @param sql the SQL string
458: * @param resultSet the corresponding {@link MockResultSet}
459: * @param parameters the parameters
460: */
461: public void prepareResultSet(String sql, MockResultSet resultSet,
462: Map parameters) {
463: List list = getListFromMapForSQLStatement(sql,
464: resultSetsForStatement);
465: list.add(new MockResultSetWrapper(resultSet, new HashMap(
466: parameters)));
467: }
468:
469: /**
470: * Prepare an array of <code>ResultSet</code> objects for a specified SQL string and
471: * the specified parameters. This method can be used for queries that return
472: * multiple result sets. The specified parameters <code>Map</code>
473: * must contain the parameters by mapping <code>Integer</code> objects
474: * to the corresponding parameter. The <code>Integer</code> object
475: * is the index of the parameter. In the case of a <code>CallableStatement</code>,
476: * <code>String</code> keys for named parameters are also allowed.
477: * Please note that you can modify the match parameters with
478: * {@link #setCaseSensitive}, {@link #setExactMatch} and
479: * {@link #setUseRegularExpressions} and the match parameters for the
480: * specified parameter list with {@link #setExactMatchParameter}.
481: * @param sql the SQL string
482: * @param resultSets the corresponding <code>MockResultSet[]</code>
483: * @param parameters the parameters
484: */
485: public void prepareResultSets(String sql,
486: MockResultSet[] resultSets, Map parameters) {
487: List list = getListFromMapForSQLStatement(sql,
488: resultSetsForStatement);
489: list.add(new MockResultSetArrayWrapper(
490: (MockResultSet[]) resultSets.clone(), new HashMap(
491: parameters)));
492: }
493:
494: /**
495: * Prepare that the specified SQL string with the specified parameters
496: * should raise an exception.
497: * This can be used to simulate database exceptions.
498: * This method creates an <code>SQLException</code> and will throw this
499: * exception. With {@link #prepareThrowsSQLException(String, SQLException, Object[])}
500: * you can specify the exception.
501: * The specified parameters array must contain the parameters in
502: * the correct order starting with index 0 for the first parameter.
503: * Please keep in mind that parameters in <code>PreparedStatement</code>
504: * objects start with 1 as the first parameter. So <code>parameters[0]</code>
505: * maps to the parameter with index 1.
506: * Please note that you can modify the match parameters with
507: * {@link #setCaseSensitive}, {@link #setExactMatch} and
508: * {@link #setUseRegularExpressions} and the match parameters for the
509: * specified parameter list with {@link #setExactMatchParameter}.
510: * @param sql the SQL string
511: * @param parameters the parameters
512: */
513: public void prepareThrowsSQLException(String sql,
514: Object[] parameters) {
515: SQLException exc = new SQLException("Statement " + sql
516: + " was specified to throw an exception");
517: prepareThrowsSQLException(sql, exc, parameters);
518: }
519:
520: /**
521: * Prepare that the specified SQL string with the specified parameters
522: * should raise an exception.
523: * This can be used to simulate database exceptions.
524: * This method creates an <code>SQLException</code> and will throw this
525: * exception. With {@link #prepareThrowsSQLException(String, SQLException, List)}
526: * you can specify the exception.
527: * The specified parameters <code>List</code> must contain the
528: * parameters in the correct order starting with index 0 for the first
529: * parameter. Please keep in mind that parameters in
530: * <code>PreparedStatement</code> objects start with 1 as the first
531: * parameter. So <code>parameters.get(0)</code> maps to the parameter
532: * with index 1.
533: * Please note that you can modify the match parameters with
534: * {@link #setCaseSensitive}, {@link #setExactMatch} and
535: * {@link #setUseRegularExpressions} and the match parameters for the
536: * specified parameter list with {@link #setExactMatchParameter}.
537: * @param sql the SQL string
538: * @param parameters the parameters
539: */
540: public void prepareThrowsSQLException(String sql, List parameters) {
541: SQLException exc = new SQLException("Statement " + sql
542: + " was specified to throw an exception");
543: prepareThrowsSQLException(sql, exc, parameters);
544: }
545:
546: /**
547: * Prepare that the specified SQL string with the specified parameters
548: * should raise an exception.
549: * This can be used to simulate database exceptions.
550: * This method creates an <code>SQLException</code> and will throw this
551: * exception. With {@link #prepareThrowsSQLException(String, SQLException, Map)}
552: * you can specify the exception.
553: * The specified parameters <code>Map</code> must contain the parameters by
554: * mapping <code>Integer</code> objects to the corresponding parameter.
555: * The <code>Integer</code> object is the index of the parameter. In the case
556: * of a <code>CallableStatement</code>,
557: * <code>String</code> keys for named parameters are also allowed.
558: * Please note that you can modify the match parameters with
559: * {@link #setCaseSensitive}, {@link #setExactMatch} and
560: * {@link #setUseRegularExpressions} and the match parameters for the
561: * specified parameter list with {@link #setExactMatchParameter}.
562: * @param sql the SQL string
563: * @param parameters the parameters
564: */
565: public void prepareThrowsSQLException(String sql, Map parameters) {
566: SQLException exc = new SQLException("Statement " + sql
567: + " was specified to throw an exception");
568: prepareThrowsSQLException(sql, exc, parameters);
569: }
570:
571: /**
572: * Prepare that the specified SQL string with the specified parameters
573: * should raise an exception.
574: * This can be used to simulate database exceptions.
575: * This method takes an exception object that will be thrown.
576: * The specified parameters array must contain the parameters in
577: * the correct order starting with index 0 for the first parameter.
578: * Please keep in mind that parameters in <code>PreparedStatement</code>
579: * objects start with 1 as the first parameter. So <code>parameters[0]</code>
580: * maps to the parameter with index 1.
581: * Please note that you can modify the match parameters with
582: * {@link #setCaseSensitive}, {@link #setExactMatch} and
583: * {@link #setUseRegularExpressions} and the match parameters for the
584: * specified parameter list with {@link #setExactMatchParameter}.
585: * @param sql the SQL string
586: * @param exc the <code>SQLException</code> that should be thrown
587: * @param parameters the parameters
588: */
589: public void prepareThrowsSQLException(String sql, SQLException exc,
590: Object[] parameters) {
591: prepareThrowsSQLException(sql, exc, Arrays.asList(parameters));
592: }
593:
594: /**
595: * Prepare that the specified SQL string with the specified parameters
596: * should raise an exception.
597: * This can be used to simulate database exceptions.
598: * This method takes an exception object that will be thrown.
599: * The specified parameters <code>List</code> must contain the
600: * parameters in the correct order starting with index 0 for the first
601: * parameter. Please keep in mind that parameters in
602: * <code>PreparedStatement</code> objects start with 1 as the first
603: * parameter. So <code>parameters.get(0)</code> maps to the parameter
604: * with index 1.
605: * Please note that you can modify the match parameters with
606: * {@link #setCaseSensitive}, {@link #setExactMatch} and
607: * {@link #setUseRegularExpressions} and the match parameters for the
608: * specified parameter list with {@link #setExactMatchParameter}.
609: * @param sql the SQL string
610: * @param exc the <code>SQLException</code> that should be thrown
611: * @param parameters the parameters
612: */
613: public void prepareThrowsSQLException(String sql, SQLException exc,
614: List parameters) {
615: Map params = createParameterMap(parameters);
616: prepareThrowsSQLException(sql, exc, params);
617: }
618:
619: /**
620: * Prepare that the specified SQL string with the specified parameters
621: * should raise an exception.
622: * This can be used to simulate database exceptions.
623: * This method takes an exception object that will be thrown.
624: * The specified parameters <code>Map</code> must contain the parameters by
625: * mapping <code>Integer</code> objects to the corresponding parameter.
626: * The <code>Integer</code> object is the index of the parameter. In the case
627: * of a <code>CallableStatement</code>,
628: * <code>String</code> keys for named parameters are also allowed.
629: * Please note that you can modify the match parameters with
630: * {@link #setCaseSensitive}, {@link #setExactMatch} and
631: * {@link #setUseRegularExpressions} and the match parameters for the
632: * specified parameter list with {@link #setExactMatchParameter}.
633: * @param sql the SQL string
634: * @param exc the <code>SQLException</code> that should be thrown
635: * @param parameters the parameters
636: */
637: public void prepareThrowsSQLException(String sql, SQLException exc,
638: Map parameters) {
639: List list = getListFromMapForSQLStatement(sql,
640: throwsSQLException);
641: list.add(new MockSQLExceptionWrapper(exc, new HashMap(
642: parameters)));
643: }
644:
645: /**
646: * Prepare the update count for execute update calls for a specified SQL string
647: * and the specified parameters. The specified parameters array
648: * must contain the parameters in the correct order starting with index 0 for
649: * the first parameter. Please keep in mind that parameters in
650: * <code>PreparedStatement</code> objects start with 1 as the first
651: * parameter. So <code>parameters[0]</code> maps to the
652: * parameter with index 1.
653: * Please note that you can modify the match parameters with
654: * {@link #setCaseSensitive}, {@link #setExactMatch} and
655: * {@link #setUseRegularExpressions} and the match parameters for the
656: * specified parameter list with {@link #setExactMatchParameter}.
657: * @param sql the SQL string
658: * @param updateCount the update count
659: * @param parameters the parameters
660: */
661: public void prepareUpdateCount(String sql, int updateCount,
662: Object[] parameters) {
663: prepareUpdateCount(sql, updateCount, Arrays.asList(parameters));
664: }
665:
666: /**
667: * Prepare an array update count values for execute update calls for a specified SQL string
668: * and the specified parameters. This method can be used if multiple update counts
669: * are returned. The specified parameters array
670: * must contain the parameters in the correct order starting with index 0 for
671: * the first parameter. Please keep in mind that parameters in
672: * <code>PreparedStatement</code> objects start with 1 as the first
673: * parameter. So <code>parameters[0]</code> maps to the
674: * parameter with index 1.
675: * Please note that you can modify the match parameters with
676: * {@link #setCaseSensitive}, {@link #setExactMatch} and
677: * {@link #setUseRegularExpressions} and the match parameters for the
678: * specified parameter list with {@link #setExactMatchParameter}.
679: * @param sql the SQL string
680: * @param updateCounts the update count array
681: * @param parameters the parameters
682: */
683: public void prepareUpdateCounts(String sql, int[] updateCounts,
684: Object[] parameters) {
685: prepareUpdateCounts(sql, updateCounts, Arrays
686: .asList(parameters));
687: }
688:
689: /**
690: * Prepare the update count for execute update calls for a specified SQL string
691: * and the specified parameters. The specified parameters <code>List</code>
692: * must contain the parameters in the correct order starting with index 0 for
693: * the first parameter. Please keep in mind that parameters in
694: * <code>PreparedStatement</code> objects start with 1 as the first
695: * parameter. So <code>parameters.get(0)</code> maps to the
696: * parameter with index 1.
697: * Please note that you can modify the match parameters with
698: * {@link #setCaseSensitive}, {@link #setExactMatch} and
699: * {@link #setUseRegularExpressions} and the match parameters for the
700: * specified parameter list with {@link #setExactMatchParameter}.
701: * @param sql the SQL string
702: * @param updateCount the update count
703: * @param parameters the parameters
704: */
705: public void prepareUpdateCount(String sql, int updateCount,
706: List parameters) {
707: Map params = createParameterMap(parameters);
708: prepareUpdateCount(sql, updateCount, params);
709: }
710:
711: /**
712: * Prepare an array update count values for execute update calls for a specified SQL string
713: * and the specified parameters. This method can be used if multiple update counts
714: * are returned. The specified parameters <code>List</code>
715: * must contain the parameters in the correct order starting with index 0 for
716: * the first parameter. Please keep in mind that parameters in
717: * <code>PreparedStatement</code> objects start with 1 as the first
718: * parameter. So <code>parameters.get(0)</code> maps to the
719: * parameter with index 1.
720: * Please note that you can modify the match parameters with
721: * {@link #setCaseSensitive}, {@link #setExactMatch} and
722: * {@link #setUseRegularExpressions} and the match parameters for the
723: * specified parameter list with {@link #setExactMatchParameter}.
724: * @param sql the SQL string
725: * @param updateCounts the update count array
726: * @param parameters the parameters
727: */
728: public void prepareUpdateCounts(String sql, int[] updateCounts,
729: List parameters) {
730: Map params = createParameterMap(parameters);
731: prepareUpdateCounts(sql, updateCounts, params);
732: }
733:
734: /**
735: * Prepare the update count for execute update calls for a specified SQL string
736: * and the specified parameters. The specified parameters <code>Map</code>
737: * must contain the parameters by mapping <code>Integer</code> objects
738: * to the corresponding parameter. The <code>Integer</code> object
739: * is the index of the parameter. In the case of a <code>CallableStatement</code>,
740: * <code>String</code> keys for named parameters are also allowed.
741: * Please note that you can modify the match parameters with
742: * {@link #setCaseSensitive}, {@link #setExactMatch} and
743: * {@link #setUseRegularExpressions} and the match parameters for the
744: * specified parameter list with {@link #setExactMatchParameter}.
745: * @param sql the SQL string
746: * @param updateCount the update count
747: * @param parameters the parameters
748: */
749: public void prepareUpdateCount(String sql, int updateCount,
750: Map parameters) {
751: List list = getListFromMapForSQLStatement(sql,
752: updateCountForStatement);
753: list.add(new MockUpdateCountWrapper(updateCount, new HashMap(
754: parameters)));
755: }
756:
757: /**
758: * Prepare an array update count values for execute update calls for a specified SQL string
759: * and the specified parameters. This method can be used if multiple update counts
760: * are returned. The specified parameters <code>Map</code>
761: * must contain the parameters by mapping <code>Integer</code> objects
762: * to the corresponding parameter. The <code>Integer</code> object
763: * is the index of the parameter. In the case of a <code>CallableStatement</code>,
764: * <code>String</code> keys for named parameters are also allowed.
765: * Please note that you can modify the match parameters with
766: * {@link #setCaseSensitive}, {@link #setExactMatch} and
767: * {@link #setUseRegularExpressions} and the match parameters for the
768: * specified parameter list with {@link #setExactMatchParameter}.
769: * @param sql the SQL string
770: * @param updateCounts the update count array
771: * @param parameters the parameters
772: */
773: public void prepareUpdateCounts(String sql, int[] updateCounts,
774: Map parameters) {
775: List list = getListFromMapForSQLStatement(sql,
776: updateCountForStatement);
777: list.add(new MockUpdateCountArrayWrapper((int[]) updateCounts
778: .clone(), new HashMap(parameters)));
779: }
780:
781: /**
782: * Prepare the generated keys <code>ResultSet</code>
783: * for a specified SQL string.
784: * The specified parameters array must contain the parameters in
785: * the correct order starting with index 0 for the first parameter.
786: * Please keep in mind that parameters in <code>PreparedStatement</code>
787: * objects start with 1 as the first parameter. So <code>parameters[0]</code>
788: * maps to the parameter with index 1.
789: * Please note that you can modify the match parameters with
790: * {@link #setCaseSensitive}, {@link #setExactMatch} and
791: * {@link #setUseRegularExpressions} and the match parameters for the
792: * specified parameter list with {@link #setExactMatchParameter}.
793: * @param sql the SQL string
794: * @param generatedKeysResult the generated keys {@link MockResultSet}
795: * @param parameters the parameters
796: */
797: public void prepareGeneratedKeys(String sql,
798: MockResultSet generatedKeysResult, Object[] parameters) {
799: prepareGeneratedKeys(sql, generatedKeysResult, Arrays
800: .asList(parameters));
801: }
802:
803: /**
804: * Prepare the generated keys <code>ResultSet</code>
805: * for a specified SQL string.
806: * The specified parameters <code>List</code> must contain the
807: * parameters in the correct order starting with index 0 for the first
808: * parameter. Please keep in mind that parameters in
809: * <code>PreparedStatement</code> objects start with 1 as the first
810: * parameter. So <code>parameters.get(0)</code> maps to the parameter
811: * with index 1.
812: * Please note that you can modify the match parameters with
813: * {@link #setCaseSensitive}, {@link #setExactMatch} and
814: * {@link #setUseRegularExpressions} and the match parameters for the
815: * specified parameter list with {@link #setExactMatchParameter}.
816: * @param sql the SQL string
817: * @param generatedKeysResult the generated keys {@link MockResultSet}
818: * @param parameters the parameters
819: */
820: public void prepareGeneratedKeys(String sql,
821: MockResultSet generatedKeysResult, List parameters) {
822: Map params = createParameterMap(parameters);
823: prepareGeneratedKeys(sql, generatedKeysResult, params);
824: }
825:
826: /**
827: * Prepare the generated keys <code>ResultSet</code>
828: * for a specified SQL string.
829: * The specified parameters <code>Map</code> must contain the parameters by
830: * mapping <code>Integer</code> objects to the corresponding parameter.
831: * The <code>Integer</code> object is the index of the parameter. In the case
832: * of a <code>CallableStatement</code>,
833: * <code>String</code> keys for named parameters are also allowed.
834: * Please note that you can modify the match parameters with
835: * {@link #setCaseSensitive}, {@link #setExactMatch} and
836: * {@link #setUseRegularExpressions} and the match parameters for the
837: * specified parameter list with {@link #setExactMatchParameter}.
838: * @param sql the SQL string
839: * @param generatedKeysResult the generated keys {@link MockResultSet}
840: * @param parameters the parameters
841: */
842: public void prepareGeneratedKeys(String sql,
843: MockResultSet generatedKeysResult, Map parameters) {
844: List list = getListFromMapForSQLStatement(sql,
845: generatedKeysForStatement);
846: list.add(new MockResultSetWrapper(generatedKeysResult,
847: new HashMap(parameters)));
848: }
849:
850: private List getListFromMapForSQLStatement(String sql, Map map) {
851: List list = (List) map.get(sql);
852: if (null == list) {
853: list = new ArrayList();
854: map.put(sql, list);
855: }
856: return list;
857: }
858:
859: private Map createParameterMap(List parameters) {
860: Map params = new HashMap();
861: for (int ii = 0; ii < parameters.size(); ii++) {
862: params.put(new Integer(ii + 1), parameters.get(ii));
863: }
864: return params;
865: }
866:
867: protected class ParameterWrapper {
868: private Map parameters;
869:
870: public ParameterWrapper(Map parameters) {
871: this .parameters = parameters;
872: }
873:
874: public Map getParamters() {
875: return parameters;
876: }
877: }
878:
879: private class MockSQLExceptionWrapper extends ParameterWrapper {
880: private SQLException exception;
881:
882: public MockSQLExceptionWrapper(SQLException exception,
883: Map parameters) {
884: super (parameters);
885: this .exception = exception;
886: }
887:
888: public SQLException getException() {
889: return exception;
890: }
891: }
892:
893: private class MockResultSetWrapper extends ParameterWrapper {
894: private MockResultSet resultSet;
895:
896: public MockResultSetWrapper(MockResultSet resultSet,
897: Map parameters) {
898: super (parameters);
899: this .resultSet = resultSet;
900: }
901:
902: public MockResultSet getResultSet() {
903: return resultSet;
904: }
905: }
906:
907: private class MockResultSetArrayWrapper extends ParameterWrapper {
908: private MockResultSet[] resultSets;
909:
910: public MockResultSetArrayWrapper(MockResultSet[] resultSets,
911: Map parameters) {
912: super (parameters);
913: this .resultSets = resultSets;
914: }
915:
916: public MockResultSet[] getResultSets() {
917: return resultSets;
918: }
919: }
920:
921: private class MockUpdateCountWrapper extends ParameterWrapper {
922: private Integer updateCount;
923:
924: public MockUpdateCountWrapper(int updateCount, Map parameters) {
925: super (parameters);
926: this .updateCount = new Integer(updateCount);
927: }
928:
929: public Integer getUpdateCount() {
930: return updateCount;
931: }
932: }
933:
934: private class MockUpdateCountArrayWrapper extends ParameterWrapper {
935: private Integer[] updateCounts;
936:
937: public MockUpdateCountArrayWrapper(int[] updateCounts,
938: Map parameters) {
939: super (parameters);
940: this .updateCounts = (Integer[]) ArrayUtil
941: .convertToObjectArray(updateCounts);
942: }
943:
944: public Integer[] getUpdateCount() {
945: return updateCounts;
946: }
947: }
948: }
|