1 21 22 package org.dbunit.operation; 23 24 import org.dbunit.DatabaseUnitException; 25 import org.dbunit.database.IDatabaseConnection; 26 import org.dbunit.database.statement.IPreparedBatchStatement; 27 import org.dbunit.database.statement.SimplePreparedStatement; 28 import org.dbunit.dataset.Column; 29 import org.dbunit.dataset.DataSetException; 30 import org.dbunit.dataset.IDataSet; 31 import org.dbunit.dataset.ITable; 32 import org.dbunit.dataset.ITableIterator; 33 import org.dbunit.dataset.ITableMetaData; 34 import org.dbunit.dataset.NoPrimaryKeyException; 35 import org.dbunit.dataset.RowOutOfBoundsException; 36 import org.dbunit.dataset.datatype.DataType; 37 38 import java.sql.PreparedStatement ; 39 import java.sql.ResultSet ; 40 import java.sql.SQLException ; 41 import java.util.BitSet ; 42 43 53 public class RefreshOperation extends AbstractOperation 54 { 55 private final InsertOperation _insertOperation; 56 private final UpdateOperation _updateOperation; 57 58 RefreshOperation() 59 { 60 _insertOperation = (InsertOperation)DatabaseOperation.INSERT; 61 _updateOperation = (UpdateOperation)DatabaseOperation.UPDATE; 62 } 63 64 private boolean isEmpty(ITable table) throws DataSetException 65 { 66 return AbstractBatchOperation.isEmpty(table); 67 } 68 69 72 public void execute(IDatabaseConnection connection, IDataSet dataSet) 73 throws DatabaseUnitException, SQLException 74 { 75 76 ITableIterator iterator = dataSet.iterator(); 78 while (iterator.next()) 79 { 80 ITable table = iterator.getTable(); 81 82 if (isEmpty(table)) 84 { 85 continue; 86 } 87 88 ITableMetaData metaData = getOperationMetaData(connection, 89 table.getTableMetaData()); 90 RowOperation updateRowOperation = createUpdateOperation(connection, 91 metaData); 92 RowOperation insertRowOperation = new InsertRowOperation(connection, 93 metaData); 94 95 try 96 { 97 for (int i = 0; ; i++) 99 { 100 if (!updateRowOperation.execute(table, i)) 101 { 102 insertRowOperation.execute(table, i); 103 } 104 } 105 } 106 catch (RowOutOfBoundsException e) 107 { 108 } 110 finally 111 { 112 updateRowOperation.close(); 114 insertRowOperation.close(); 115 } 116 } 117 118 } 119 120 private RowOperation createUpdateOperation(IDatabaseConnection connection, 121 ITableMetaData metaData) 122 throws DataSetException, SQLException 123 { 124 if (metaData.getColumns().length > metaData.getPrimaryKeys().length) 126 { 127 return new UpdateRowOperation(connection, metaData); 128 } 129 130 return new RowExistOperation(connection, metaData); 132 } 133 134 137 class RowOperation 138 { 139 protected IPreparedBatchStatement _statement; 140 protected OperationData _operationData; 141 protected BitSet _ignoreMapping; 142 143 147 public boolean execute(ITable table, int row) 148 throws DataSetException, SQLException 149 { 150 Column[] columns = _operationData.getColumns(); 151 for (int i = 0; i < columns.length; i++) 152 { 153 if (_ignoreMapping == null || !_ignoreMapping.get(i)) 155 { 156 Object value = table.getValue(row, columns[i].getColumnName()); 157 _statement.addValue(value, columns[i].getDataType()); 158 } 159 } 160 _statement.addBatch(); 161 int result = _statement.executeBatch(); 162 _statement.clearBatch(); 163 164 return result == 1; 165 } 166 167 170 public void close() throws SQLException 171 { 172 if (_statement != null) 173 { 174 _statement.close(); 175 } 176 } 177 } 178 179 182 private class InsertRowOperation extends RowOperation 183 { 184 private IDatabaseConnection _connection; 185 private ITableMetaData _metaData; 186 187 public InsertRowOperation(IDatabaseConnection connection, 188 ITableMetaData metaData) 189 throws DataSetException, SQLException 190 { 191 _connection = connection; 192 _metaData = metaData; 193 } 194 195 public boolean execute(ITable table, int row) 196 throws DataSetException, SQLException 197 { 198 if (_ignoreMapping == null || 201 !_insertOperation.equalsIgnoreMapping(_ignoreMapping, table, row)) 202 { 203 if (_statement != null) 205 { 206 _statement.close(); 207 } 208 209 _ignoreMapping = _insertOperation.getIgnoreMapping(table, row); 210 _operationData = _insertOperation.getOperationData(_metaData, 211 _ignoreMapping, _connection); 212 _statement = new SimplePreparedStatement(_operationData.getSql(), 213 _connection.getConnection()); 214 } 215 216 return super.execute(table, row); 217 } 218 219 } 220 221 224 private class UpdateRowOperation extends RowOperation 225 { 226 PreparedStatement _countStatement; 227 228 public UpdateRowOperation(IDatabaseConnection connection, 229 ITableMetaData metaData) 230 throws DataSetException, SQLException 231 { 232 _operationData = _updateOperation.getOperationData( 234 metaData, null, connection); 235 _statement = new SimplePreparedStatement(_operationData.getSql(), 236 connection.getConnection()); 237 } 238 } 239 240 243 private class RowExistOperation extends RowOperation 244 { 245 PreparedStatement _countStatement; 246 247 public RowExistOperation(IDatabaseConnection connection, 248 ITableMetaData metaData) 249 throws DataSetException, SQLException 250 { 251 _operationData = getSelectCountData(metaData, connection); 253 _countStatement = connection.getConnection().prepareStatement( 254 _operationData.getSql()); 255 } 256 257 private OperationData getSelectCountData( 258 ITableMetaData metaData, IDatabaseConnection connection) throws DataSetException 259 { 260 Column[] primaryKeys = metaData.getPrimaryKeys(); 261 262 if (primaryKeys.length == 0) 264 { 265 throw new NoPrimaryKeyException(metaData.getTableName()); 266 } 267 268 StringBuffer sqlBuffer = new StringBuffer (128); 270 sqlBuffer.append("select COUNT(*) from "); 271 sqlBuffer.append(getQualifiedName(connection.getSchema(), 272 metaData.getTableName(), connection)); 273 274 sqlBuffer.append(" where "); 276 for (int i = 0; i < primaryKeys.length; i++) 277 { 278 Column column = primaryKeys[i]; 279 280 if (i > 0) 281 { 282 sqlBuffer.append(" and "); 283 } 284 sqlBuffer.append(column.getColumnName()); 285 sqlBuffer.append(" = ?"); 286 } 287 288 return new OperationData(sqlBuffer.toString(), primaryKeys); 289 } 290 291 294 298 public boolean execute(ITable table, int row) 299 throws DataSetException, SQLException 300 { 301 Column[] columns = _operationData.getColumns(); 302 for (int i = 0; i < columns.length; i++) 303 { 304 Object value = table.getValue(row, columns[i].getColumnName()); 305 DataType dataType = columns[i].getDataType(); 306 dataType.setSqlValue(value, i + 1, _countStatement); 307 } 308 309 ResultSet resultSet = _countStatement.executeQuery(); 310 try 311 { 312 resultSet.next(); 313 return resultSet.getInt(1) > 0; 314 } 315 finally 316 { 317 resultSet.close(); 318 } 319 } 320 321 public void close() throws SQLException 322 { 323 _countStatement.close(); 324 } 325 } 326 327 } 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | Popular Tags |