View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  
22  package org.dbunit.ant;
23  
24  import org.apache.tools.ant.DirectoryScanner;
25  import org.apache.tools.ant.types.FileSet;
26  import org.dbunit.DatabaseUnitException;
27  import org.dbunit.database.IDatabaseConnection;
28  import org.dbunit.database.DatabaseSequenceFilter;
29  import org.dbunit.dataset.CompositeDataSet;
30  import org.dbunit.dataset.IDataSet;
31  import org.dbunit.dataset.ReplacementDataSet;
32  import org.dbunit.dataset.FilteredDataSet;
33  import org.dbunit.ext.mssql.InsertIdentityOperation;
34  import org.dbunit.operation.DatabaseOperation;
35  import org.dbunit.operation.TransactionOperation;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  import java.io.File;
40  import java.sql.SQLException;
41  import java.util.ArrayList;
42  import java.util.Arrays;
43  import java.util.List;
44  
45  /**
46   * The <code>Operation</code> class is the step that defines which
47   * operation will be performed in the execution of the <code>DbUnitTask</code>
48   * task.
49   *
50   * @author Timothy Ruppert
51   * @author Ben Cox
52   * @version $Revision$
53   * @since Jun 10, 2002
54   */
55  public class Operation extends AbstractStep
56  {
57  
58      /**
59       * Logger for this class
60       */
61      private static final Logger logger = LoggerFactory.getLogger(Operation.class);
62  
63      private static final String DEFAULT_FORMAT = FORMAT_FLAT;
64  
65      protected String _type = "CLEAN_INSERT";
66      private String _format;
67      private List<File> _sources = new ArrayList<>();
68      private boolean _combine = false;
69      private boolean _transaction = false;
70      private DatabaseOperation _operation;
71      private boolean _forwardOperation = true;
72      private String _nullToken;
73  
74      public File[] getSrc()
75      {
76          return _sources.toArray(new File[_sources.size()]);
77      }
78  
79      public void setSrc(File[] sources)
80      {
81          _sources.clear();
82          _sources.addAll(Arrays.asList(sources));
83      }
84  
85      public void setSrc(File src)
86      {
87          _sources.clear();
88          _sources.add(src);
89      }
90  
91      public void addConfiguredFileset(FileSet fileSet)
92      {
93          DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
94          for (String file : scanner.getIncludedFiles()) {
95              _sources.add(new File(scanner.getBasedir(), file));
96          }
97      }
98  
99      public String getFormat()
100     {
101         return _format != null ? _format : DEFAULT_FORMAT;
102     }
103 
104     public void setFormat(String format)
105     {
106         logger.debug("setFormat(format={}) - start", format);
107 
108         // Check if the given format is accepted
109         checkDataFormat(format);
110         // If we get here the given format is a valid data format
111         _format = format;
112     }
113 
114     public boolean isCombine()
115     {
116         return _combine;
117     }
118 
119     public void setCombine(boolean combine)
120     {
121         _combine = combine;
122     }
123 
124     public boolean isTransaction()
125     {
126         return _transaction;
127     }
128 
129     public void setTransaction(boolean transaction)
130     {
131         _transaction = transaction;
132     }
133 
134     public String getNullToken() 
135     {
136         return _nullToken;
137     }
138 
139     public void setNullToken(final String nullToken) 
140     {
141         this._nullToken = nullToken;
142     }
143 
144     public DatabaseOperation getDbOperation()
145     {
146         return _operation;
147     }
148 
149     public String getType()
150     {
151         return _type;
152     }
153 
154     public void setType(String type) 
155     {
156         logger.debug("setType(type={}) - start", type);
157 
158         if ("UPDATE".equals(type)) {
159             _operation = DatabaseOperation.UPDATE;
160             _forwardOperation = true;
161         } else if ("INSERT".equals(type)) {
162             _operation = DatabaseOperation.INSERT;
163             _forwardOperation = true;
164         } else if ("REFRESH".equals(type)) {
165             _operation = DatabaseOperation.REFRESH;
166             _forwardOperation = true;
167         } else if ("DELETE".equals(type)) {
168             _operation = DatabaseOperation.DELETE;
169             _forwardOperation = false;
170         } else if ("DELETE_ALL".equals(type)) {
171             _operation = DatabaseOperation.DELETE_ALL;
172             _forwardOperation = false;
173         } else if ("CLEAN_INSERT".equals(type)) {
174             _operation = DatabaseOperation.CLEAN_INSERT;
175             _forwardOperation = false;
176         } else if ("NONE".equals(type)) {
177             _operation = DatabaseOperation.NONE;
178             _forwardOperation = true;
179         } else if ("MSSQL_CLEAN_INSERT".equals(type)) {
180             _operation = InsertIdentityOperation.CLEAN_INSERT;
181             _forwardOperation = false;
182         } else if ("MSSQL_INSERT".equals(type)) {
183             _operation = InsertIdentityOperation.INSERT;
184             _forwardOperation = true;
185         } else if ("MSSQL_REFRESH".equals(type)) {
186             _operation = InsertIdentityOperation.REFRESH;
187             _forwardOperation = true;
188         } else {
189             throw new IllegalArgumentException("Type must be one of: UPDATE, INSERT,"
190                     + " REFRESH, DELETE, DELETE_ALL, CLEAN_INSERT, MSSQL_INSERT, "
191                     + " or MSSQL_REFRESH but was: " + type);
192         }
193         _type = type;
194     }
195 
196     public void execute(IDatabaseConnection connection) throws DatabaseUnitException
197     {
198         logger.debug("execute(connection={}) - start", connection);
199         if (_operation == null)
200         {
201             throw new DatabaseUnitException("Operation.execute(): setType(String) must be called before execute()!");
202         }
203 
204         if (_operation == DatabaseOperation.NONE)
205         {
206             return;
207         }
208 
209         if (_sources.size() == 0)
210         {
211             throw new DatabaseUnitException("Operation.execute(): must call setSrc(File), addSrc(File), or setSources(File[]) before execute()!");
212         }
213 
214         try {
215             DatabaseOperation operation = (_transaction ? new TransactionOperation(_operation) : _operation);
216             // TODO This is not very nice and the design should be reviewed but it works for now (gommma)
217             boolean useForwardOnly = _forwardOperation && ! isOrdered();
218             IDataSet dataset;
219             if (_sources.size() > 1) {
220                 IDataSet[] datasets = new IDataSet[_sources.size()];
221                 for (int i = 0; i < _sources.size(); i++) {
222                     datasets[i] = getSrcDataSet(_sources.get(i), getFormat(), useForwardOnly);
223                 }
224                 dataset = new CompositeDataSet(datasets, _combine);
225             } else {
226                 dataset = getSrcDataSet(_sources.get(0), getFormat(), useForwardOnly);
227             }
228             if (_nullToken != null) {
229                 dataset = new ReplacementDataSet(dataset);
230                 ((ReplacementDataSet)dataset).addReplacementObject(_nullToken, null);
231             }
232             if(isOrdered()) 
233             {
234                 DatabaseSequenceFilter databaseSequenceFilter = new DatabaseSequenceFilter(connection);
235                 dataset = new FilteredDataSet(databaseSequenceFilter, dataset);
236             }
237             operation.execute(connection, dataset);
238         }
239         catch (SQLException e)
240         {
241             throw new DatabaseUnitException(e);
242         }
243     }
244 
245     public String getLogMessage()
246     {
247         final StringBuilder result = new StringBuilder();
248         result.append("Executing operation: " + _type);
249         result.append("\n          on   files: [ ");
250         for (File f : _sources) {
251             result.append(f.getAbsolutePath() + " ");
252         }
253         result.append("]");
254         result.append("\n          with format: " + _format);
255         return result.toString();
256     }
257 
258     public String toString()
259     {
260         final StringBuilder result = new StringBuilder();
261         result.append("Operation: ");
262         result.append(" type=").append(_type);
263         result.append(", format=").append(_format);
264         result.append(", sources=[ ");
265         for (File f : _sources) {
266             result.append(f.getAbsolutePath() + " ");
267         }
268         result.append("]");
269         result.append(", operation=").append(_operation);
270         result.append(", nullToken=").append(_nullToken);
271         result.append(", ordered=").append(super.isOrdered());
272         return result.toString();
273     }
274 }