001 package com.mockrunner.jdbc;
002
003 import com.mockrunner.mock.jdbc.MockResultSet;
004
005 /**
006 * A <code>ResultSetFactory</code> implementation which will produce
007 * <code>MockResultSet</code> instances based on information given as
008 * <code>String</code> arrays.
009 *
010 * <p>
011 * <code>StringValuesTable</code> and <code>ArrayResultSetFactory</code> can
012 * provide easy set up of unit test fixtures and assertion of outcomes with the
013 * same data structures, without any need for external sources of test data:
014 * </p>
015 *
016 * <p>
017 * <pre>
018 * private static final String _SQL_SELECT_ALL_EMPLOYEES =
019 * "SELECT * FROM employee";
020 * private StringValuesTable <b>_employeeQueryResults</b>;
021 * ArrayResultSetFactory <b>_arrayResultSetFactory</b>;
022 * private Employee[] _employees;
023 *
024 * protected void setUp() throws Exception {
025 * super.setUp();
026 * <b>_employeeQueryResults</b> = new StringValuesTable(
027 * "employeeQueryResults",
028 * new String[] {
029 * "id", "lastname", "firstname",
030 * },
031 * new String[][] {
032 * new String[] {"1", "gibbons", "peter"},
033 * new String[] {"2", "lumbergh", "bill"},
034 * new String[] {"3", "waddams", "milton"},
035 * }
036 * );
037 * _employees = new Employee[3] {
038 * new Employee(
039 * <b>_employeeQueryResults.getItem(1, "id")</b>,
040 * <b>_employeeQueryResults.getItem(1, "lastname")</b>,
041 * <b>_employeeQueryResults.getItem(1, "firstname")</b>,
042 * ),
043 * ...
044 * };
045 * ...
046 * }
047 *
048 * public void testGetEmployees() throws Exception {
049 * PreparedStatementResultSetHandler preparedStatementResultSetHandler =
050 * getPreparedStatementResultSetHandler();
051 * <b>_arrayResultSetFactory</b> =
052 * new ArrayResultSetFactory(<b>_employeeQueryResults</b>);
053 * MockResultSet resultSet =
054 * preparedStatementResultSetHandler.createResultSet(
055 * <b>_employeeQueryResults.getName()</b>,
056 * <b>arrayResultSetFactory</b>);
057 * preparedStatementResultSetHandler.prepareResultSet(
058 * _SQL_SELECT_ALL_EMPLOYEES, resultSet);
059 *
060 * // execute query, perhaps calling method on an EmployeeDAO...
061 *
062 * assertEquals(
063 * <b>_employeeQueryResults.getNumberOfRows()</b>,
064 * resultsList.size());
065 * for (int i = 0; i < _employees.length; i++) {
066 * assertTrue(resultsList.contains(_employees[i]));
067 * }
068 * MockResultSet mockResultSet =
069 * preparedStatementResultSetHandler.getResultSet(
070 * SQL_SELECT_ALL_EMPLOYEES);
071 * int rows = mockResultSet.getRowCount();
072 * for (int row = 1; row <= rows; row++) {
073 * verifyResultSetRow(
074 * <b>_employeeQueryResults.getName()</b>,
075 * row, <b>_employeeQueryResults.getRow(row)</b>);
076 * }
077 * verifySQLStatementExecuted(_SQL_SELECT_ALL_EMPLOYEES);
078 * verifyAllResultSetsClosed();
079 * verifyAllStatementsClosed();
080 * verifyConnectionClosed();
081 * }
082 * </pre>
083 * </p>
084 *
085 * @author Erick G. Reid
086 */
087 public class ArrayResultSetFactory implements ResultSetFactory
088 {
089 private String[] columnNames = new String[0];
090 private String[][] stringMatrix = new String[0][0];
091
092 /**
093 * Creates a new <code>ArrayResultSetFactory</code> that will produce
094 * result sets based on information in the given
095 * <code>StringValuesTable</code>.
096 *
097 * @param stringValuesTable the <code>StringValuesTable</code> to use. This argument
098 * cannot be <code>null</code>.
099 */
100 public ArrayResultSetFactory(StringValuesTable stringValuesTable)
101 {
102 if (stringValuesTable != null)
103 {
104 this.stringMatrix = stringValuesTable.getStringMatrix();
105 this.columnNames = stringValuesTable.getColumnNames();
106 return;
107 }
108 throw new IllegalArgumentException("the string table cannot be null");
109 }
110
111 /**
112 * Creates a new <code>ArrayResultSetFactory</code> with the given matrix
113 * for data representation.
114 *
115 * @param stringMatrix the data representation for the result sets this factory will
116 * produce. This argument cannot be <code>null</code>, must
117 * not contain any null values, and each array in the matrix must
118 * contain the same number of elements as the first (<code>stringMatrix[0].length == stringMatrix[n].length</code>
119 * for any given valid row number, <code>n</code>). Further,
120 * this matrix must, at a minimum represent <code>1</code> row
121 * and <code>1</code> column of items (<code>stringMatrix.length >= 1</code>,
122 * and <code>stringMatrix[0].length >= 1</code>).
123 */
124 public ArrayResultSetFactory(String[][] stringMatrix)
125 {
126 this.stringMatrix = StringValuesTable.verifyStringMatrix(stringMatrix);
127 }
128
129 /**
130 * Creates a new <code>ArrayResultSetFactory</code> with the given set of
131 * column names and the given matrix for data representation.
132 *
133 * @param columnNames the column names for the result sets this factory will
134 * produce. This argument may be <code>null</code> if no column
135 * names are desired, but if a non-<code>null</code> array
136 * reference is given, the array cannot contain any
137 * <code>null</code> nor duplicate elements, and must have the
138 * same number of elements as there are columns in the given
139 * string matrix (<code>stringMatrix[n]</code> for any given
140 * valid row number, <code>n</code>).
141 * @param stringMatrix the data representation for the result sets this factory will
142 * produce. This argument cannot be <code>null</code>, must
143 * not contain any null values, and each array in the matrix must
144 * contain the same number of elements as the first (<code>stringMatrix[0].length == stringMatrix[n].length</code>
145 * for any given valid row number, <code>n</code>). Further,
146 * this matrix must, at a minimum represent <code>1</code> row
147 * and <code>1</code> column of items (<code>stringMatrix.length >= 1</code>,
148 * and <code>stringMatrix[0].length >= 1</code>).
149 */
150 public ArrayResultSetFactory(String[] columnNames, String[][] stringMatrix)
151 {
152 this.stringMatrix = StringValuesTable.verifyStringMatrix(stringMatrix);
153 if (columnNames != null)
154 {
155 this.columnNames = StringValuesTable.verifyColumnNames(columnNames, stringMatrix);
156 }
157 }
158
159 /**
160 * Returns a <code>MockResultSet</code> with the given ID, containing
161 * values based on the elements given at construction.
162 *
163 * @param id the ID for the result set. This argument cannot be
164 * <code>null</code>.
165 */
166 public MockResultSet create(String id)
167 {
168 if (id != null)
169 {
170 MockResultSet resultSet = new MockResultSet(id);
171 if (columnNames != null)
172 {
173 for (int ii = 0; ii < columnNames.length; ii++)
174 {
175 resultSet.addColumn(columnNames[ii]);
176 }
177 }
178 for (int jj = 0; jj < stringMatrix.length; jj++)
179 {
180 resultSet.addRow(stringMatrix[jj]);
181 }
182 return resultSet;
183 }
184 throw new IllegalArgumentException("the result set ID cannot be null");
185 }
186 }