View Javadoc
1   package org.dbunit.ext.postgresql;
2   
3   import static org.assertj.core.api.Assertions.assertThat;
4   
5   import java.sql.ResultSet;
6   import java.sql.Statement;
7   
8   import org.dbunit.DatabaseEnvironment;
9   import org.dbunit.database.DatabaseConfig;
10  import org.dbunit.database.DatabaseConnection;
11  import org.dbunit.database.IDatabaseConnection;
12  import org.dbunit.dataset.DefaultDataSet;
13  import org.dbunit.dataset.DefaultTable;
14  import org.dbunit.dataset.IDataSet;
15  import org.dbunit.operation.DatabaseOperation;
16  import org.junit.jupiter.api.AfterEach;
17  import org.junit.jupiter.api.BeforeEach;
18  import org.junit.jupiter.api.Test;
19  import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
20  
21  /**
22   * Reproduces the second scenario of issue 397: an {@link IDatabaseConnection} configured with a
23   * non-default schema and given an <i>unqualified</i> table name, without
24   * {@link DatabaseConfig#FEATURE_QUALIFIED_TABLE_NAMES} enabled. The original report saw
25   * {@code DatabaseOperation.DELETE_ALL} generate {@code delete from app_role_all_children},
26   * missing the {@code bi} schema, failing with "relation ... does not exist" since the
27   * connection's own default schema was never applied to the generated SQL.
28   * <p>
29   * The report's other scenario - a schema-qualified table name failing to resolve - is a
30   * case-folding defect covered separately by {@link PostgresqlUppercaseSchemaIT} (issue 656).
31   *
32   * @author Jeff Jensen
33   */
34  @EnabledIfSystemProperty(named = "dbunit.profile", matches = "postgresql")
35  class PostgresqlNonPublicSchemaDeleteAllIT
36  {
37      private static final String SCHEMA = "bi";
38      private static final String TABLE = "app_role_all_children";
39  
40      private IDatabaseConnection _connection;
41  
42      @BeforeEach
43      protected void setUp() throws Exception
44      {
45          final IDatabaseConnection defaultConnection = DatabaseEnvironment.getInstance().getConnection();
46          try (Statement statement = defaultConnection.getConnection().createStatement())
47          {
48              statement.execute("DROP SCHEMA IF EXISTS " + SCHEMA + " CASCADE;");
49              statement.execute("CREATE SCHEMA " + SCHEMA + ";");
50              statement.execute("CREATE TABLE " + SCHEMA + "." + TABLE
51                      + "(id INTEGER NOT NULL, name VARCHAR(32));");
52              statement.execute("INSERT INTO " + SCHEMA + "." + TABLE
53                      + " (id, name) VALUES (1, 'root'), (2, 'child');");
54          }
55  
56          _connection = new DatabaseConnection(defaultConnection.getConnection(), SCHEMA);
57      }
58  
59      @AfterEach
60      protected void tearDown() throws Exception
61      {
62          if (_connection != null)
63          {
64              try (Statement statement = _connection.getConnection().createStatement())
65              {
66                  statement.execute("DROP SCHEMA IF EXISTS " + SCHEMA + " CASCADE;");
67              }
68              _connection.close();
69              _connection = null;
70          }
71      }
72  
73      @Test
74      void testDeleteAll_withUnqualifiedTableNameAndNonPublicConnectionSchema_deletesAllRows()
75              throws Exception
76      {
77          final IDataSet dataSet = new DefaultDataSet(new DefaultTable(TABLE));
78  
79          DatabaseOperation.DELETE_ALL.execute(_connection, dataSet);
80  
81          final int remainingRows;
82          try (Statement statement = _connection.getConnection().createStatement();
83                  ResultSet resultSet =
84                          statement.executeQuery("select count(*) from " + SCHEMA + "." + TABLE))
85          {
86              resultSet.next();
87              remainingRows = resultSet.getInt(1);
88          }
89  
90          assertThat(remainingRows).as("remaining row count.").isEqualTo(0);
91      }
92  }