View Javadoc
1   package org.dbunit.ext.postgresql;
2   
3   import static org.assertj.core.api.Assertions.assertThat;
4   
5   import java.io.StringReader;
6   import java.sql.Statement;
7   import java.util.Objects;
8   
9   import org.dbunit.DatabaseEnvironment;
10  import org.dbunit.database.DatabaseConfig;
11  import org.dbunit.database.IDatabaseConnection;
12  import org.dbunit.dataset.IDataSet;
13  import org.dbunit.dataset.ITable;
14  import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
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  import org.xml.sax.InputSource;
21  
22  /**
23   * Reproduces issue 656: PostgreSQL folds an unquoted schema name to lower case at creation
24   * time, so a {@code FlatXmlDataSet} row qualified with a differently-cased schema (e.g. the
25   * originally reported {@code CORE.USER}, matching a live {@code core} schema) must still be
26   * found once {@link DatabaseConfig#FEATURE_QUALIFIED_TABLE_NAMES} is enabled - even on the very
27   * first table access for that schema, before any other access has happened to prime the schema
28   * cache with a matching case.
29   *
30   * @author Jeff Jensen
31   */
32  @EnabledIfSystemProperty(named = "dbunit.profile", matches = "postgresql")
33  class PostgresqlUppercaseSchemaIT
34  {
35      private static final String SCHEMA = "core";
36      private static final String TABLE = "user_account";
37  
38      private IDatabaseConnection _connection;
39  
40      @BeforeEach
41      protected void setUp() throws Exception
42      {
43          _connection = DatabaseEnvironment.getInstance().getConnection();
44          final Statement statement = _connection.getConnection().createStatement();
45          statement.execute("DROP SCHEMA IF EXISTS " + SCHEMA + " CASCADE;");
46          statement.execute("CREATE SCHEMA " + SCHEMA + ";");
47          statement.execute("CREATE TABLE " + SCHEMA + "." + TABLE
48                  + "(id INTEGER NOT NULL, username VARCHAR(32));");
49          statement.close();
50          // Re-acquire the connection so the new schema is visible - mirrors the
51          // same re-connect PostgresqlUuidIT needs after DDL.
52          _connection.close();
53          _connection = DatabaseEnvironment.getInstance().getConnection();
54      }
55  
56      @AfterEach
57      protected void tearDown() throws Exception
58      {
59          if (!Objects.isNull(_connection))
60          {
61              final Statement statement = _connection.getConnection().createStatement();
62              statement.execute("DROP SCHEMA IF EXISTS " + SCHEMA + " CASCADE;");
63              statement.close();
64              _connection.close();
65              _connection = null;
66          }
67      }
68  
69      @Test
70      void testCleanInsert_withUppercaseSchemaAgainstLowercasePostgresSchema_insertsSuccessfully()
71              throws Exception
72      {
73          _connection.getConfig().setFeature(
74                  DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
75  
76          final String qualifiedTag =
77                  SCHEMA.toUpperCase() + "." + TABLE.toUpperCase();
78          final String xml = "<?xml version=\"1.0\"?><dataset>"
79                  + "<" + qualifiedTag + " ID=\"10\" USERNAME=\"john\"/>"
80                  + "<" + qualifiedTag + " ID=\"11\" USERNAME=\"josh\"/>"
81                  + "</dataset>";
82  
83          final IDataSet dataSet = new FlatXmlDataSetBuilder()
84                  .build(new InputSource(new StringReader(xml)));
85  
86          DatabaseOperation.CLEAN_INSERT.execute(_connection, dataSet);
87  
88          final ITable table =
89                  _connection.createDataSet().getTable(SCHEMA + "." + TABLE);
90          assertThat(table.getRowCount()).as("row count.").isEqualTo(2);
91          assertThat(table.getValue(0, "username")).as("row 0 username.")
92                  .isEqualTo("john");
93          assertThat(table.getValue(1, "username")).as("row 1 username.")
94                  .isEqualTo("josh");
95      }
96  }