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.ext.mssql;
23  
24  import static org.assertj.core.api.Assertions.assertThat;
25  
26  import java.io.Reader;
27  
28  import org.dbunit.AbstractDatabaseIT;
29  import org.dbunit.Assertion;
30  import org.dbunit.database.DatabaseConfig;
31  import org.dbunit.dataset.Column;
32  import org.dbunit.dataset.DataSetUtils;
33  import org.dbunit.dataset.ForwardOnlyDataSet;
34  import org.dbunit.dataset.IDataSet;
35  import org.dbunit.dataset.ITable;
36  import org.dbunit.dataset.LowerCaseDataSet;
37  import org.dbunit.dataset.filter.IColumnFilter;
38  import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
39  import org.dbunit.dataset.xml.XmlDataSet;
40  import org.dbunit.operation.DatabaseOperation;
41  import org.dbunit.testutil.TestUtils;
42  import org.junit.jupiter.api.Test;
43  import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
44  
45  /**
46   * @author Manuel Laflamme
47   * @author Eric Pugh
48   * @version $Revision$
49   * @since Feb 19, 2002
50   */
51  @EnabledIfSystemProperty(named = "dbunit.profile", matches = "mssql")
52  class InsertIdentityOperationIT extends AbstractDatabaseIT
53  {
54      @Test
55      void testExecuteXML_withXmlDataSet_insertsIdentityRows() throws Exception
56      {
57          final Reader in =
58                  TestUtils.getFileReader("xml/insertIdentityOperationTest.xml");
59          final IDataSet dataSet = new XmlDataSet(in);
60  
61          testExecute(dataSet);
62      }
63  
64      @Test
65      void testExecute_withFlatXmlDataSet_insertsIdentityRows() throws Exception
66      {
67          final Reader in = TestUtils
68                  .getFileReader("xml/insertIdentityOperationTestFlat.xml");
69          final IDataSet dataSet = new FlatXmlDataSetBuilder().build(in);
70  
71          testExecute(dataSet);
72      }
73  
74      @Test
75      void testExecute_withLowerCaseDataSet_insertsIdentityRows() throws Exception
76      {
77          final Reader in = TestUtils
78                  .getFileReader("xml/insertIdentityOperationTestFlat.xml");
79          final IDataSet dataSet =
80                  new LowerCaseDataSet(new FlatXmlDataSetBuilder().build(in));
81  
82          testExecute(dataSet);
83      }
84  
85      @Test
86      void testExecute_withForwardOnlyDataSet_insertsIdentityRows() throws Exception
87      {
88          final Reader in = TestUtils
89                  .getFileReader("xml/insertIdentityOperationTestFlat.xml");
90          final IDataSet dataSet =
91                  new ForwardOnlyDataSet(new FlatXmlDataSetBuilder().build(in));
92  
93          testExecute(dataSet);
94      }
95  
96      private void testExecute(final IDataSet dataSet) throws Exception
97      {
98          final ITable[] tablesBefore =
99                  DataSetUtils.getTables(_connection.createDataSet());
100         // InsertIdentityOperation.CLEAN_INSERT.execute(_connection, dataSet);
101         InsertIdentityOperation.INSERT.execute(_connection, dataSet);
102         final ITable[] tablesAfter =
103                 DataSetUtils.getTables(_connection.createDataSet());
104 
105         assertThat(tablesAfter).as("table count").hasSameSizeAs(tablesBefore);
106 
107         // Verify tables after
108         for (int i = 0; i < tablesAfter.length; i++)
109         {
110             final ITable tableBefore = tablesBefore[i];
111             final ITable tableAfter = tablesAfter[i];
112 
113             final String name = tableAfter.getTableMetaData().getTableName();
114             if (name.startsWith("IDENTITY"))
115             {
116                 assertThat(tableBefore.getRowCount())
117                         .as("row count before: " + name).isZero();
118                 if (dataSet instanceof ForwardOnlyDataSet)
119                 {
120                     assertThat(tableAfter.getRowCount()).as(name).isPositive();
121                 } else
122                 {
123                     Assertion.assertEquals(dataSet.getTable(name), tableAfter);
124                 }
125             } else
126             {
127                 // Other tables should have not been affected
128                 Assertion.assertEquals(tableBefore, tableAfter);
129             }
130         }
131     }
132 
133     /*
134      * test case was added to validate the bug that tables with Identity columns
135      * that are not one of the primary keys are able to figure out if an
136      * IDENTITY_INSERT is needed. Thanks to Gaetano Di Gregorio for finding the
137      * bug.
138      */
139     @Test
140     void testIdentityInsertNoPK() throws Exception
141     {
142         final Reader in = TestUtils
143                 .getFileReader("xml/insertIdentityOperationTestNoPK.xml");
144         final IDataSet xmlDataSet = new FlatXmlDataSetBuilder().build(in);
145 
146         final ITable[] tablesBefore =
147                 DataSetUtils.getTables(_connection.createDataSet());
148         InsertIdentityOperation.CLEAN_INSERT.execute(_connection, xmlDataSet);
149         final ITable[] tablesAfter =
150                 DataSetUtils.getTables(_connection.createDataSet());
151 
152         // Verify tables after
153         for (int i = 0; i < tablesAfter.length; i++)
154         {
155             final ITable tableBefore = tablesBefore[i];
156             final ITable tableAfter = tablesAfter[i];
157 
158             final String name = tableAfter.getTableMetaData().getTableName();
159             if (name.equals("TEST_IDENTITY_NOT_PK"))
160             {
161                 assertThat(tableBefore.getRowCount())
162                         .as("row count before: " + name).isZero();
163                 Assertion.assertEquals(xmlDataSet.getTable(name), tableAfter);
164             } else
165             {
166                 // Other tables should have not been affected
167                 Assertion.assertEquals(tableBefore, tableAfter);
168             }
169         }
170     }
171 
172     @Test
173     void testSetCustomIdentityColumnFilter() throws Exception
174     {
175         _connection.getConfig().setProperty(
176                 DatabaseConfig.PROPERTY_IDENTITY_COLUMN_FILTER,
177                 IDENTITY_FILTER_INVALID);
178         try
179         {
180             final IDataSet dataSet = _connection.createDataSet();
181             final ITable table = dataSet.getTable("IDENTITY_TABLE");
182 
183             InsertIdentityOperation op =
184                     new InsertIdentityOperation(DatabaseOperation.INSERT);
185             boolean hasIdentityColumn =
186                     op.hasIdentityColumn(table.getTableMetaData(), _connection);
187             assertThat(hasIdentityColumn).as("Identity column recognized")
188                     .isFalse();
189 
190             // Verify that identity column is still correctly recognized with
191             // default identityColumnFilter
192             _connection.getConfig().setProperty(
193                     DatabaseConfig.PROPERTY_IDENTITY_COLUMN_FILTER, null);
194             op = new InsertIdentityOperation(DatabaseOperation.INSERT);
195             hasIdentityColumn =
196                     op.hasIdentityColumn(table.getTableMetaData(), _connection);
197             assertThat(hasIdentityColumn).as("Identity column not recognized")
198                     .isTrue();
199         } finally
200         {
201             // Reset property
202             _connection.getConfig().setProperty(
203                     DatabaseConfig.PROPERTY_IDENTITY_COLUMN_FILTER, null);
204         }
205     }
206 
207     private static final IColumnFilter IDENTITY_FILTER_INVALID =
208             new IColumnFilter()
209             {
210                 @Override
211                 public boolean accept(final String tableName,
212                         final Column column)
213                 {
214                     return column.getSqlTypeName().endsWith("invalid");
215                 }
216             };
217 }