You are here

public function SqlsrvTest::testTemporaryTables in Drupal driver for SQL Server and SQL Azure 8.2

Same name and namespace in other branches
  1. 4.2.x tests/src/Kernel/SqlsrvTest.php \Drupal\Tests\sqlsrv\Kernel\SqlsrvTest::testTemporaryTables()
  2. 3.0.x tests/src/Kernel/SqlsrvTest.php \Drupal\Tests\sqlsrv\Kernel\SqlsrvTest::testTemporaryTables()
  3. 3.1.x tests/src/Kernel/SqlsrvTest.php \Drupal\Tests\sqlsrv\Kernel\SqlsrvTest::testTemporaryTables()
  4. 4.0.x tests/src/Kernel/SqlsrvTest.php \Drupal\Tests\sqlsrv\Kernel\SqlsrvTest::testTemporaryTables()
  5. 4.1.x tests/src/Kernel/SqlsrvTest.php \Drupal\Tests\sqlsrv\Kernel\SqlsrvTest::testTemporaryTables()

Test the temporary table functionality.

@dataProvider dataProviderForTestTemporaryTables

File

tests/src/Kernel/SqlsrvTest.php, line 69

Class

SqlsrvTest
Test behavior that is unique to the Sql Server Driver.

Namespace

Drupal\Tests\sqlsrv\Kernel

Code

public function testTemporaryTables($temp_prefix, $leak_table) {

  // Set the temp table prefix on the Connection.
  $reflectionClass = new \ReflectionClass(Connection::class);
  $reflectionProperty = $reflectionClass
    ->getProperty('tempTablePrefix');
  $reflectionProperty
    ->setAccessible(TRUE);
  $reflectionProperty
    ->setValue($this->connection, $temp_prefix);
  $reflectionMethod = $reflectionClass
    ->getMethod('setPrefix');
  $reflectionMethod
    ->setAccessible(TRUE);
  $prefixProperty = $reflectionClass
    ->getProperty('prefixes');
  $prefixProperty
    ->setAccessible(TRUE);
  $prefixes = $prefixProperty
    ->getValue($this->connection);
  $reflectionMethod
    ->invoke($this->connection, $prefixes);
  $query = $this->connection
    ->select('test_task', 't');
  $query
    ->fields('t');
  $table = $this->connection
    ->queryTemporary((string) $query);

  // First assert that the table exists.
  $this
    ->assertTRUE($this->connection
    ->schema()
    ->tableExists($table), 'The temporary table exists.');
  $query2 = $this->connection
    ->select($table, 't');
  $query2
    ->fields('t');

  // Now make sure that both tables are exactly the same.
  $data1 = $query
    ->execute()
    ->fetchAllAssoc('tid');
  $data2 = $query2
    ->execute()
    ->fetchAllAssoc('tid');

  // User ID's are negative, so this should return 0 matches.
  $this
    ->assertEqual(count($data1), count($data2), 'Temporary table has the same number of rows.');

  // Drop the table.
  $this->connection
    ->schema()
    ->dropTable($table);

  // The table should not exist now.
  $this
    ->assertFALSE($this->connection
    ->schema()
    ->tableExists($table), 'The temporary table does not exist');
  $schema = [
    'description' => 'Basic test table for the database unit tests.',
    'fields' => [
      'id' => [
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ],
    ],
  ];

  // Create a second independant connection.
  $connection_info = $this
    ->getDatabaseConnectionInfo()['default'];
  Database::addConnectionInfo('second', 'second', $connection_info);
  Database::addConnectionInfo('third', 'third', $connection_info);
  $second_connection = Database::getConnection('second', 'second');
  $reflectionProperty
    ->setValue($second_connection, $temp_prefix);
  $prefixes = $prefixProperty
    ->getValue($second_connection);
  $reflectionMethod
    ->invoke($second_connection, $prefixes);
  $third_connection = Database::getConnection('third', 'third');
  $reflectionProperty
    ->setValue($third_connection, $temp_prefix);
  $prefixes = $prefixProperty
    ->getValue($third_connection);
  $reflectionMethod
    ->invoke($third_connection, $prefixes);

  // Ensure connections are unique.
  $connection_id1 = $this->connection
    ->query('SELECT @@SPID AS [ID]')
    ->fetchField();
  $connection_id2 = $second_connection
    ->query('SELECT @@SPID AS [ID]')
    ->fetchField();
  $connection_id3 = $third_connection
    ->query('SELECT @@SPID AS [ID]')
    ->fetchField();
  $this
    ->assertNotEquals($connection_id2, $connection_id3, 'Connections 2 & 3 have different IDs.');
  $this
    ->assertNotEquals($connection_id1, $connection_id3, 'Connections 1 & 3 have different IDs.');
  $this
    ->assertNotEquals($connection_id2, $connection_id1, 'Connections 1 & 2 have different IDs.');

  // Create a temporary table in this connection.
  $table = $second_connection
    ->queryTemporary((string) $query);

  // Is the temp table visible on the originating connection?
  $this
    ->assertTrue($second_connection
    ->schema()
    ->tableExists($table), 'Temporary table exists.');

  // Create a normal table.
  $second_connection
    ->schema()
    ->createTable('real_table_for_temp_test', $schema);

  // Is the real table visible on the other connection?
  $this
    ->assertTrue($third_connection
    ->schema()
    ->tableExists('real_table_for_temp_test'), 'Real table found across connections.');

  // Is the temp table visible on the other connection?
  $this
    ->assertEquals($leak_table, $third_connection
    ->schema()
    ->tableExists($table), 'Temporary table leaking appropriately.');

  // Is the temp table still visible on the originating connection?
  $this
    ->assertTrue($second_connection
    ->schema()
    ->tableExists($table), 'Temporary table still exists.');

  // Close the Connection that created the table and ensure that
  // it is removed.
  unset($second_connection);
  Database::removeConnection('second');

  // Next assertion has intermittent failures. Add a wait?
  sleep(2);
  $this
    ->assertFalse($third_connection
    ->schema()
    ->tableExists($table), 'Temporary table removed when creation connection closes.');
}