1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.ext.mssql;
22
23 import java.sql.Connection;
24 import java.sql.SQLException;
25 import java.sql.Statement;
26
27 import org.dbunit.DatabaseUnitException;
28 import org.dbunit.database.DatabaseConfig;
29 import org.dbunit.database.IDatabaseConnection;
30 import org.dbunit.dataset.Column;
31 import org.dbunit.dataset.DataSetException;
32 import org.dbunit.dataset.DefaultDataSet;
33 import org.dbunit.dataset.IDataSet;
34 import org.dbunit.dataset.ITable;
35 import org.dbunit.dataset.ITableIterator;
36 import org.dbunit.dataset.ITableMetaData;
37 import org.dbunit.dataset.Column.AutoIncrement;
38 import org.dbunit.dataset.filter.IColumnFilter;
39 import org.dbunit.operation.AbstractOperation;
40 import org.dbunit.operation.CompositeOperation;
41 import org.dbunit.operation.DatabaseOperation;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class InsertIdentityOperation extends AbstractOperation
65 {
66
67
68
69
70 private static final Logger logger = LoggerFactory.getLogger(InsertIdentityOperation.class);
71
72 public static final String PROPERTY_IDENTITY_COLUMN_FILTER =
73 "http://www.dbunit.org/properties/mssql/identityColumnFilter";
74
75 public static final DatabaseOperation INSERT =
76 new InsertIdentityOperation(DatabaseOperation.INSERT);
77
78 public static final DatabaseOperation CLEAN_INSERT =
79 new CompositeOperation(DatabaseOperation.DELETE_ALL,
80 new InsertIdentityOperation(DatabaseOperation.INSERT));
81
82 public static final DatabaseOperation REFRESH =
83 new InsertIdentityOperation(DatabaseOperation.REFRESH);
84
85 private static final IColumnFilter DEFAULT_IDENTITY_FILTER = new IColumnFilter()
86 {
87 public boolean accept(String tableName, Column column)
88 {
89 return column.getSqlTypeName().endsWith("identity");
90 }
91 };
92
93
94
95
96
97
98
99
100
101
102
103 public static final IColumnFilter IDENTITY_FILTER_EXTENDED = new IColumnFilter() {
104
105 public boolean accept(String tableName, Column column)
106 {
107 String remarks = column.getRemarks();
108 boolean isIdentityCol = (remarks != null) && (
109 remarks.indexOf("GENERATED BY DEFAULT AS IDENTITY") > -1 ||
110 remarks.indexOf("GENERATED ALWAYS AS IDENTITY") > -1
111 );
112
113
114 if(!isIdentityCol)
115 {
116
117 isIdentityCol = (AutoIncrement.YES == column.getAutoIncrement());
118 }
119
120 return isIdentityCol;
121 }
122 };
123
124
125 private final DatabaseOperation _operation;
126
127
128
129
130
131 public InsertIdentityOperation(DatabaseOperation operation)
132 {
133 _operation = operation;
134 }
135
136 boolean hasIdentityColumn(ITableMetaData metaData, IDatabaseConnection connection)
137 throws DataSetException
138 {
139 logger.debug("hasIdentityColumn(metaData={}, connection={}) - start", metaData, connection);
140
141 DatabaseConfig config = connection.getConfig();
142 IColumnFilter identityFilter = (IColumnFilter)config.getProperty(
143 PROPERTY_IDENTITY_COLUMN_FILTER);
144 if (identityFilter == null)
145 {
146 identityFilter = DEFAULT_IDENTITY_FILTER;
147 }
148
149
150 Column[] columns = metaData.getColumns();
151 for (int i = 0; i < columns.length; i++)
152 {
153 if (identityFilter.accept(metaData.getTableName(), columns[i]))
154 {
155 return true;
156 }
157 }
158
159 return false;
160 }
161
162
163
164
165 public void execute(IDatabaseConnection connection, IDataSet dataSet)
166 throws DatabaseUnitException, SQLException
167 {
168 logger.debug("execute(connection={}, dataSet={}) - start", connection, dataSet);
169
170 Connection jdbcConnection = connection.getConnection();
171 Statement statement = jdbcConnection.createStatement();
172
173 boolean wasAutoCommit = false;
174 try
175 {
176 IDataSet databaseDataSet = connection.createDataSet();
177
178
179
180
181
182
183
184
185
186 if (jdbcConnection.getAutoCommit() == true)
187 {
188 wasAutoCommit = true;
189 jdbcConnection.setAutoCommit(false);
190 }
191
192
193 ITableIterator iterator = dataSet.iterator();
194 while(iterator.next())
195 {
196 ITable table = iterator.getTable();
197 String tableName = table.getTableMetaData().getTableName();
198
199 ITableMetaData metaData =
200 databaseDataSet.getTableMetaData(tableName);
201
202
203 boolean hasIdentityColumn = hasIdentityColumn(metaData, connection);
204
205 if (hasIdentityColumn)
206 {
207 StringBuffer sqlBuffer = new StringBuffer(128);
208 sqlBuffer.append("SET IDENTITY_INSERT ");
209 sqlBuffer.append(getQualifiedName(connection.getSchema(),
210 metaData.getTableName(), connection));
211 sqlBuffer.append(" ON");
212 statement.execute(sqlBuffer.toString());
213 }
214
215 try
216 {
217 _operation.execute(connection, new DefaultDataSet(table));
218 }
219 finally
220 {
221
222 if (hasIdentityColumn)
223 {
224 StringBuffer sqlBuffer = new StringBuffer(128);
225 sqlBuffer.append("SET IDENTITY_INSERT ");
226 sqlBuffer.append(getQualifiedName(connection.getSchema(),
227 metaData.getTableName(), connection));
228 sqlBuffer.append(" OFF");
229 statement.execute(sqlBuffer.toString());
230 }
231 jdbcConnection.commit();
232 }
233 }
234 }
235 finally
236 {
237 if(wasAutoCommit)
238 {
239
240 jdbcConnection.setAutoCommit(true);
241 }
242 statement.close();
243 }
244 }
245 }