DeleteTruncateTest.php 6.46 KB
Newer Older
1 2
<?php

3
namespace Drupal\KernelTests\Core\Database;
4 5

/**
6
 * Tests delete and truncate queries.
7 8 9 10 11 12 13 14
 *
 * The DELETE tests are not as extensive, as all of the interesting code for
 * DELETE queries is in the conditional which is identical to the UPDATE and
 * SELECT conditional handling.
 *
 * The TRUNCATE tests are not extensive either, because the behavior of
 * TRUNCATE queries is not consistent across database engines. We only test
 * that a TRUNCATE query actually deletes all rows from the target table.
15 16
 *
 * @group Database
17 18 19 20
 */
class DeleteTruncateTest extends DatabaseTestBase {

  /**
21
   * Confirms that we can use a subselect in a delete successfully.
22
   */
23
  public function testSubselectDelete() {
24
    $num_records_before = $this->connection->query('SELECT COUNT(*) FROM {test_task}')->fetchField();
25
    $pid_to_delete = $this->connection->query("SELECT * FROM {test_task} WHERE [task] = 'sleep' ORDER BY [tid]")->fetchField();
26

27
    $subquery = $this->connection->select('test', 't')
28 29
      ->fields('t', ['id'])
      ->condition('t.id', [$pid_to_delete], 'IN');
30
    $delete = $this->connection->delete('test_task')
31 32 33 34
      ->condition('task', 'sleep')
      ->condition('pid', $subquery, 'IN');

    $num_deleted = $delete->execute();
35
    $this->assertEqual($num_deleted, 1, 'Deleted 1 record.');
36

37
    $num_records_after = $this->connection->query('SELECT COUNT(*) FROM {test_task}')->fetchField();
38
    $this->assertEqual($num_records_before, $num_records_after + $num_deleted, 'Deletion adds up.');
39 40 41
  }

  /**
42
   * Confirms that we can delete a single record successfully.
43
   */
44
  public function testSimpleDelete() {
45
    $num_records_before = $this->connection->query('SELECT COUNT(*) FROM {test}')->fetchField();
46

47
    $num_deleted = $this->connection->delete('test')
48 49
      ->condition('id', 1)
      ->execute();
50
    $this->assertIdentical($num_deleted, 1, 'Deleted 1 record.');
51

52
    $num_records_after = $this->connection->query('SELECT COUNT(*) FROM {test}')->fetchField();
53
    $this->assertEqual($num_records_before, $num_records_after + $num_deleted, 'Deletion adds up.');
54 55 56
  }

  /**
57
   * Confirms that we can truncate a whole table successfully.
58
   */
59
  public function testTruncate() {
60
    $num_records_before = $this->connection->query("SELECT COUNT(*) FROM {test}")->fetchField();
61
    $this->assertTrue($num_records_before > 0, 'The table is not empty.');
62

63
    $this->connection->truncate('test')->execute();
64

65
    $num_records_after = $this->connection->query("SELECT COUNT(*) FROM {test}")->fetchField();
66
    $this->assertEqual(0, $num_records_after, 'Truncate really deletes everything.');
67
  }
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
  /**
   * Confirms that we can truncate a whole table while in transaction.
   */
  public function testTruncateInTransaction() {
    // This test won't work right if transactions are not supported.
    if (!$this->connection->supportsTransactions()) {
      $this->markTestSkipped('The database driver does not support transactions.');
    }

    $num_records_before = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertGreaterThan(0, $num_records_before, 'The table is not empty.');

    $transaction = $this->connection->startTransaction('test_truncate_in_transaction');
    $this->connection->insert('test')
      ->fields([
        'name' => 'Freddie',
        'age' => 45,
        'job' => 'Great singer',
      ])
      ->execute();
    $num_records_after_insert = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals($num_records_before + 1, $num_records_after_insert);

    $this->connection->truncate('test')->execute();

    // Checks that there are no records left in the table, and transaction is
    // still active.
    $this->assertTrue($this->connection->inTransaction());
    $num_records_after = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals(0, $num_records_after);

    // Close the transaction, and check that there are still no records in the
    // table.
    $transaction = NULL;
    $this->assertFalse($this->connection->inTransaction());
    $num_records_after = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals(0, $num_records_after);
  }

  /**
   * Confirms that transaction rollback voids a truncate operation.
   */
  public function testTruncateTransactionRollback() {
    // This test won't work right if transactions are not supported.
    if (!$this->connection->supportsTransactions()) {
      $this->markTestSkipped('The database driver does not support transactions.');
    }

    $num_records_before = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertGreaterThan(0, $num_records_before, 'The table is not empty.');

    $transaction = $this->connection->startTransaction('test_truncate_in_transaction');
    $this->connection->insert('test')
      ->fields([
        'name' => 'Freddie',
        'age' => 45,
        'job' => 'Great singer',
      ])
      ->execute();
    $num_records_after_insert = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals($num_records_before + 1, $num_records_after_insert);

    $this->connection->truncate('test')->execute();

    // Checks that there are no records left in the table, and transaction is
    // still active.
    $this->assertTrue($this->connection->inTransaction());
    $num_records_after = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals(0, $num_records_after);

    // Roll back the transaction, and check that we are back to status before
    // insert and truncate.
    $this->connection->rollBack();
    $this->assertFalse($this->connection->inTransaction());
    $num_records_after = $this->connection->select('test')->countQuery()->execute()->fetchField();
    $this->assertEquals($num_records_before, $num_records_after);
  }

147 148 149
  /**
   * Confirms that we can delete a single special column name record successfully.
   */
150
  public function testSpecialColumnDelete() {
151
    $num_records_before = $this->connection->query('SELECT COUNT(*) FROM {select}')->fetchField();
152

153 154
    $num_deleted = $this->connection->delete('select')
      ->condition('update', 'Update value 1')
155
      ->execute();
156
    $this->assertEquals(1, $num_deleted, 'Deleted 1 special column record.');
157

158 159
    $num_records_after = $this->connection->query('SELECT COUNT(*) FROM {select}')->fetchField();
    $this->assertEquals($num_records_before, $num_records_after + $num_deleted, 'Deletion adds up.');
160
  }
161

162
}