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.database;
23  
24  import static org.assertj.core.api.Assertions.assertThat;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  
27  import org.dbunit.DatabaseEnvironment;
28  import org.dbunit.dataset.AbstractDataSetTest;
29  import org.dbunit.dataset.Column;
30  import org.dbunit.dataset.DataSetException;
31  import org.dbunit.dataset.DefaultTableMetaData;
32  import org.dbunit.dataset.IDataSet;
33  import org.dbunit.dataset.ITable;
34  import org.dbunit.dataset.ITableMetaData;
35  import org.dbunit.dataset.NoSuchTableException;
36  import org.dbunit.dataset.datatype.DataType;
37  import org.dbunit.dataset.filter.DefaultColumnFilter;
38  import org.dbunit.dataset.filter.ITableFilterSimple;
39  import org.dbunit.ext.oracle.OracleBlobDataType;
40  import org.dbunit.ext.oracle.OracleClobDataType;
41  import org.dbunit.util.QualifiedTableName;
42  import org.junit.jupiter.api.AfterEach;
43  import org.junit.jupiter.api.BeforeEach;
44  import org.junit.jupiter.api.Test;
45  
46  /**
47   * @author Manuel Laflamme
48   * @version $Revision$
49   * @since Feb 18, 2002
50   */
51  class DatabaseDataSetIT extends AbstractDataSetTest
52  {
53      private IDatabaseConnection _connection;
54  
55      ////////////////////////////////////////////////////////////////////////////
56      // TestCase class
57  
58      @BeforeEach
59      protected void setUpConnection() throws Exception
60      {
61          _connection = DatabaseEnvironment.getInstance().getConnection();
62      }
63  
64      @AfterEach
65      protected void tearDown() throws Exception
66      {
67  
68          _connection = null;
69      }
70  
71      ////////////////////////////////////////////////////////////////////////////
72      // AbstractDataSetTest class
73  
74      @Override
75      protected String convertString(final String str) throws Exception
76      {
77          return DatabaseEnvironment.getInstance().convertString(str);
78      }
79  
80      @Override
81      protected IDataSet createDataSet() throws Exception
82      {
83          return _connection.createDataSet();
84      }
85  
86      @Override
87      protected String[] getExpectedNames() throws Exception
88      {
89          return _connection.createDataSet().getTableNames();
90      }
91  
92      @Override
93      protected IDataSet createDuplicateDataSet() throws Exception
94      {
95          throw new UnsupportedOperationException();
96      }
97  
98      @Override
99      protected IDataSet createMultipleCaseDuplicateDataSet() throws Exception
100     {
101         throw new UnsupportedOperationException();
102     }
103 
104     ////////////////////////////////////////////////////////////////////////////
105     // Test methods
106 
107     @Test
108     void testGetSelectStatement_withSchemaAndColumns_returnsCorrectSqlStatement() throws Exception
109     {
110         final String schemaName = "schema";
111         final String tableName = "table";
112         final Column[] columns =
113                 new Column[] {new Column("c1", DataType.UNKNOWN),
114                         new Column("c2", DataType.UNKNOWN),
115                         new Column("c3", DataType.UNKNOWN),};
116         final String expected = "select c1, c2, c3 from schema.table";
117 
118         final ITableMetaData metaData =
119                 new DefaultTableMetaData(tableName, columns);
120         final String sql =
121                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null);
122         assertThat(sql).as("select statement").isEqualTo(expected);
123     }
124 
125     @Test
126     void testGetSelectStatementWithEscapedNames_withEscapePattern_returnsEscapedSql() throws Exception
127     {
128         final String schemaName = "schema";
129         final String tableName = "table";
130         final Column[] columns =
131                 new Column[] {new Column("c1", DataType.UNKNOWN),
132                         new Column("c2", DataType.UNKNOWN),
133                         new Column("c3", DataType.UNKNOWN),};
134         final String expected = "select 'c1', 'c2', 'c3' from 'schema'.'table'";
135 
136         final ITableMetaData metaData =
137                 new DefaultTableMetaData(tableName, columns);
138         final String sql =
139                 DatabaseDataSet.getSelectStatement(schemaName, metaData, "'?'");
140         assertThat(sql).as("select statement").isEqualTo(expected);
141     }
142 
143     @Test
144     void testGetSelectStatementWithEscapedNamesAndOrderBy_withPrimaryKeys_includesOrderByClause() throws Exception
145     {
146         final String schemaName = "schema";
147         final String tableName = "table";
148         final Column[] columns =
149                 new Column[] {new Column("c1", DataType.UNKNOWN),
150                         new Column("c2", DataType.UNKNOWN),
151                         new Column("c3", DataType.UNKNOWN),};
152         final String expected =
153                 "select 'c1', 'c2', 'c3' from 'schema'.'table' order by 'c1', 'c2'";
154 
155         final String[] primaryKeys = {"c1", "c2"};
156 
157         final ITableMetaData metaData =
158                 new DefaultTableMetaData(tableName, columns, primaryKeys);
159         final String sql =
160                 DatabaseDataSet.getSelectStatement(schemaName, metaData, "'?'");
161         assertThat(sql).as("select statement").isEqualTo(expected);
162     }
163 
164     @Test
165     void testGetSelectStatementWithPrimaryKeys_withPrimaryKeyColumns_appendsOrderByClause() throws Exception
166     {
167         final String schemaName = "schema";
168         final String tableName = "table";
169         final Column[] columns =
170                 new Column[] {new Column("c1", DataType.UNKNOWN),
171                         new Column("c2", DataType.UNKNOWN),
172                         new Column("c3", DataType.UNKNOWN),};
173         final String expected =
174                 "select c1, c2, c3 from schema.table order by c1, c2, c3";
175 
176         final ITableMetaData metaData =
177                 new DefaultTableMetaData(tableName, columns, columns);
178         final String sql =
179                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null);
180         assertThat(sql).as("select statement").isEqualTo(expected);
181     }
182 
183     @Test
184     void testGetSelectStatement_withNoPrimaryKeyAndSortFeatureDisabled_omitsOrderByClause()
185             throws Exception
186     {
187         final String schemaName = "schema";
188         final String tableName = "table";
189         final Column[] columns = new Column[] {new Column("c1", DataType.UNKNOWN),
190                 new Column("c2", DataType.UNKNOWN),};
191         final String expected = "select c1, c2 from schema.table";
192 
193         final ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
194         final String sql =
195                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null, false);
196         assertThat(sql).as("select statement").isEqualTo(expected);
197     }
198 
199     @Test
200     void testGetSelectStatement_withNoPrimaryKeyAndSortFeatureEnabled_sortsByAllColumns()
201             throws Exception
202     {
203         final String schemaName = "schema";
204         final String tableName = "table";
205         final Column[] columns = new Column[] {new Column("c1", DataType.UNKNOWN),
206                 new Column("c2", DataType.UNKNOWN),};
207         final String expected = "select c1, c2 from schema.table order by c1, c2";
208 
209         final ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
210         final String sql =
211                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null, true);
212         assertThat(sql).as("select statement").isEqualTo(expected);
213     }
214 
215     @Test
216     void testGetSelectStatement_withNoPrimaryKeyLobColumnAndSortFeatureEnabled_excludesLobColumnsFromOrderBy()
217             throws Exception
218     {
219         final String schemaName = "schema";
220         final String tableName = "table";
221         final Column[] columns = new Column[] {new Column("c1", DataType.UNKNOWN),
222                 new Column("blob_col", DataType.BLOB),
223                 new Column("clob_col", DataType.CLOB),
224                 new Column("c2", DataType.UNKNOWN),};
225         final String expected =
226                 "select c1, blob_col, clob_col, c2 from schema.table order by c1, c2";
227 
228         final ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
229         final String sql =
230                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null, true);
231         assertThat(sql).as("select statement").isEqualTo(expected);
232     }
233 
234     @Test
235     void testGetSelectStatement_withNoPrimaryKeyVendorLobColumnAndSortFeatureEnabled_excludesLobColumnsFromOrderBy()
236             throws Exception
237     {
238         // OracleClobDataType/OracleBlobDataType are distinct DataType instances
239         // from the generic DataType.CLOB/DataType.BLOB singletons, so this
240         // guards against a reference-equality check missing vendor-specific
241         // LOB types.
242         final String schemaName = "schema";
243         final String tableName = "table";
244         final Column[] columns = new Column[] {new Column("c1", DataType.UNKNOWN),
245                 new Column("blob_col", new OracleBlobDataType()),
246                 new Column("clob_col", new OracleClobDataType()),
247                 new Column("c2", DataType.UNKNOWN),};
248         final String expected =
249                 "select c1, blob_col, clob_col, c2 from schema.table order by c1, c2";
250 
251         final ITableMetaData metaData = new DefaultTableMetaData(tableName, columns);
252         final String sql =
253                 DatabaseDataSet.getSelectStatement(schemaName, metaData, null, true);
254         assertThat(sql).as("select statement").isEqualTo(expected);
255     }
256 
257     @Test
258     void testGetTable_withNoPrimaryKeyTableAndSortFeatureEnabled_executesWithoutSqlError()
259             throws Exception
260     {
261         // TEST_TABLE has no primary key. Its row count is not asserted here
262         // since it depends on fixture state shared with other IT classes;
263         // this test only confirms the ORDER BY clause the enabled feature
264         // adds does not itself cause a SQLException.
265         final String tableName = "TEST_TABLE";
266         final IDatabaseConnection connection = new DatabaseConnection(
267                 _connection.getConnection(), _connection.getSchema());
268         connection.getConfig().setFeature(
269                 DatabaseConfig.FEATURE_SORT_ALL_COLUMNS_WHEN_NO_PRIMARY_KEY, true);
270 
271         final ITable table = connection.createDataSet().getTable(tableName);
272 
273         assertThat(table.getRowCount()).as("row count").isGreaterThanOrEqualTo(0);
274     }
275 
276     @Test
277     void testGetQualifiedTableNames_withQualifiedNamesEnabled_returnsPrefixedTableNames() throws Exception
278     {
279         final String[] expectedNames = getExpectedNames();
280 
281         final IDatabaseConnection connection = new DatabaseConnection(
282                 _connection.getConnection(), _connection.getSchema());
283         connection.getConfig()
284                 .setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
285 
286         final IDataSet dataSet = connection.createDataSet();
287         final String[] actualNames = dataSet.getTableNames();
288 
289         assertThat(actualNames).as("name count").hasSize(expectedNames.length);
290         for (int i = 0; i < actualNames.length; i++)
291         {
292             final String expected = new QualifiedTableName(expectedNames[i],
293                     _connection.getSchema()).getQualifiedName();
294             final String actual = actualNames[i];
295             assertThat(actual).as("name").isEqualTo(expected);
296         }
297     }
298 
299     @Test
300     void testGetColumnsAndQualifiedNamesEnabled_withQualifiedNamesEnabled_returnsCorrectColumns() throws Exception
301     {
302         final String tableName =
303                 new QualifiedTableName("TEST_TABLE", _connection.getSchema())
304                         .getQualifiedName();
305         final String[] expected = {"COLUMN0", "COLUMN1", "COLUMN2", "COLUMN3"};
306 
307         final IDatabaseConnection connection = new DatabaseConnection(
308                 _connection.getConnection(), _connection.getSchema());
309         connection.getConfig()
310                 .setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
311 
312         final ITableMetaData metaData =
313                 connection.createDataSet().getTableMetaData(tableName);
314         final Column[] columns = metaData.getColumns();
315         assertThat(columns).as("column count").hasSize(expected.length);
316         for (int i = 0; i < columns.length; i++)
317         {
318             assertThat(columns[i].getColumnName()).as("column name")
319                     .isEqualTo(convertString(expected[i]));
320         }
321     }
322 
323     @Test
324     void testGetPrimaryKeysAndQualifiedNamesEnabled_withQualifiedNamesEnabled_returnsCorrectPrimaryKeys() throws Exception
325     {
326         final String tableName =
327                 new QualifiedTableName("PK_TABLE", _connection.getSchema())
328                         .getQualifiedName();
329         final String[] expected = {"PK0", "PK1", "PK2"};
330 
331         final IDatabaseConnection connection = new DatabaseConnection(
332                 _connection.getConnection(), _connection.getSchema());
333         connection.getConfig()
334                 .setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
335 
336         final ITableMetaData metaData =
337                 connection.createDataSet().getTableMetaData(tableName);
338         final Column[] columns = metaData.getPrimaryKeys();
339 
340         assertThat(columns).as("column count").hasSize(expected.length);
341         for (int i = 0; i < columns.length; i++)
342         {
343             assertThat(columns[i].getColumnName()).as("column name")
344                     .isEqualTo(convertString(expected[i]));
345         }
346     }
347 
348     @Test
349     void testGetPrimaryKeysWithColumnFilters_withPrimaryKeyFilter_returnsOnlyIncludedKeys() throws Exception
350     {
351 
352         // TODO (felipeal): I don't know if PK_TABLE is a standard JDBC name or
353         // if
354         // it's HSQLDB specific. Anyway, now that HSQLDB's schema is set on
355         // property,
356         // we cannot add it as prefix here....
357         final String tableName = "PK_TABLE";
358         // String tableName = DataSetUtils.getQualifiedName(
359         // _connection.getSchema(), "PK_TABLE");
360 
361         final String[] expected = {"PK0", "PK2"};
362 
363         final DefaultColumnFilter filter = new DefaultColumnFilter();
364         filter.includeColumn("PK0");
365         filter.includeColumn("PK2");
366 
367         final IDatabaseConnection connection = new DatabaseConnection(
368                 _connection.getConnection(), _connection.getSchema());
369         connection.getConfig().setProperty(
370                 DatabaseConfig.PROPERTY_PRIMARY_KEY_FILTER, filter);
371 
372         final ITableMetaData metaData =
373                 connection.createDataSet().getTableMetaData(tableName);
374         final Column[] columns = metaData.getPrimaryKeys();
375 
376         assertThat(columns).as("column count").hasSize(expected.length);
377         for (int i = 0; i < columns.length; i++)
378         {
379             assertThat(columns[i].getColumnName()).as("column name")
380                     .isEqualTo(convertString(expected[i]));
381         }
382     }
383 
384     @Override
385     @Test
386     public void testCreateDuplicateDataSet_withDuplicateTableNames_throwsAmbiguousTableNameException() throws Exception
387     {
388         // Cannot test! Unsupported feature.
389     }
390 
391     @Override
392     @Test
393     public void testCreateMultipleCaseDuplicateDataSet_withDuplicateCaseVariantNames_throwsAmbiguousTableNameException() throws Exception
394     {
395         // Cannot test! Unsupported feature.
396     }
397 
398     @Test
399     void testGetTableMetaData_withLowerCasedTableName_returnsStoredTableName() throws Exception
400     {
401         final IDataSet dataSet = _connection.createDataSet();
402 
403         // Find the name exactly as the database stores it (adapts to any DB case convention)
404         String storedName = null;
405         for (final String name : dataSet.getTableNames())
406         {
407             if (name.equalsIgnoreCase("TEST_TABLE"))
408             {
409                 storedName = name;
410                 break;
411             }
412         }
413         assertThat(storedName).as("TEST_TABLE must exist in the database").isNotNull();
414 
415         // Lowercase input must not throw and must return the database-stored name
416         final ITableMetaData metaData = dataSet.getTableMetaData("test_table");
417         assertThat(metaData.getTableName()).as("table name in metadata").isEqualTo(storedName);
418     }
419 
420     @Test
421     void testGetTableThatIsFiltered_withFilteredTable_throwsNoSuchTableException() throws Exception
422     {
423         final String existingTableToFilter = convertString("TEST_TABLE");
424         final ITableFilterSimple tableFilter = new ITableFilterSimple()
425         {
426             @Override
427             public boolean accept(final String tableName)
428                     throws DataSetException
429             {
430                 if (tableName.equals(existingTableToFilter))
431                     return false;
432                 return true;
433             }
434         };
435         final IDataSet dataSet =
436                 new DatabaseDataSet(_connection, false, tableFilter);
437 
438         final NoSuchTableException expected = assertThrows(
439                 NoSuchTableException.class,
440                 () -> dataSet.getTable(existingTableToFilter),
441                 "Should not be able to retrieve table from dataset that has not been loaded - expected an exception");
442         assertThat(expected).hasMessage(existingTableToFilter);
443     }
444 
445 }