FetchTest.php 6.64 KB
Newer Older
1 2
<?php

3
namespace Drupal\KernelTests\Core\Database;
4

5
use Drupal\Core\Database\RowCountException;
6
use Drupal\Core\Database\StatementInterface;
7
use Drupal\Tests\system\Functional\Database\FakeRecord;
8 9

/**
10
 * Tests the Database system's various fetch capabilities.
11 12
 *
 * We get timeout errors if we try to run too many tests at once.
13 14
 *
 * @group Database
15 16 17 18
 */
class FetchTest extends DatabaseTestBase {

  /**
19
   * Confirms that we can fetch a record properly in default object mode.
20
   */
21
  public function testQueryFetchDefault() {
22
    $records = [];
23
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]);
24
    $this->assertInstanceOf(StatementInterface::class, $result);
25 26
    foreach ($result as $record) {
      $records[] = $record;
27 28
      $this->assertIsObject($record);
      $this->assertSame('John', $record->name);
29 30
    }

31
    $this->assertCount(1, $records, 'There is only one record.');
32 33 34
  }

  /**
35
   * Confirms that we can fetch a record to an object explicitly.
36
   */
37
  public function testQueryFetchObject() {
38
    $records = [];
39
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => \PDO::FETCH_OBJ]);
40 41
    foreach ($result as $record) {
      $records[] = $record;
42 43
      $this->assertIsObject($record);
      $this->assertSame('John', $record->name);
44 45
    }

46
    $this->assertCount(1, $records, 'There is only one record.');
47 48 49
  }

  /**
50
   * Confirms that we can fetch a record to an associative array explicitly.
51
   */
52
  public function testQueryFetchArray() {
53
    $records = [];
54
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => \PDO::FETCH_ASSOC]);
55 56
    foreach ($result as $record) {
      $records[] = $record;
57 58 59
      $this->assertIsArray($record);
      $this->assertArrayHasKey('name', $record);
      $this->assertSame('John', $record['name']);
60 61
    }

62
    $this->assertCount(1, $records, 'There is only one record.');
63 64 65
  }

  /**
66
   * Confirms that we can fetch a record into a new instance of a custom class.
67
   *
68
   * @see \Drupal\system\Tests\Database\FakeRecord
69
   */
70
  public function testQueryFetchClass() {
71
    $records = [];
72
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => FakeRecord::class]);
73 74
    foreach ($result as $record) {
      $records[] = $record;
75 76
      $this->assertInstanceOf(FakeRecord::class, $record);
      $this->assertSame('John', $record->name);
77 78
    }

79
    $this->assertCount(1, $records, 'There is only one record.');
80 81
  }

82 83 84 85 86 87 88 89
  /**
   * Confirms that we can fetch a record into a class using fetchObject.
   *
   * @see \Drupal\system\Tests\Database\FakeRecord
   * @see \Drupal\Core\Database\StatementPrefech::fetchObject
   */
  public function testQueryFetchObjectClass() {
    $records = 0;
90
    $query = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]);
91 92 93 94 95 96 97 98
    while ($result = $query->fetchObject(FakeRecord::class)) {
      $records += 1;
      $this->assertInstanceOf(FakeRecord::class, $result);
      $this->assertSame('John', $result->name, '25 year old is John.');
    }
    $this->assertSame(1, $records, 'There is only one record.');
  }

99 100 101 102 103 104 105 106
  /**
   * Confirms that we can fetch a record into a new instance of a custom class.
   * The name of the class is determined from a value of the first column.
   *
   * @see \Drupal\Tests\system\Functional\Database\FakeRecord
   */
  public function testQueryFetchClasstype() {
    $records = [];
107
    $result = $this->connection->query('SELECT [classname], [name], [job] FROM {test_classtype} WHERE [age] = :age', [':age' => 26], ['fetch' => \PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE]);
108 109
    foreach ($result as $record) {
      $records[] = $record;
110 111 112
      $this->assertInstanceOf(FakeRecord::class, $record);
      $this->assertSame('Kay', $record->name);
      $this->assertSame('Web Developer', $record->job);
113 114 115 116 117 118
      $this->assertFalse(isset($record->classname), 'Classname field not found, as intended.');
    }

    $this->assertCount(1, $records, 'There is only one record.');
  }

119 120 121
  /**
   * Confirms that we can fetch a record into an indexed array explicitly.
   */
122
  public function testQueryFetchNum() {
123
    $records = [];
124
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => \PDO::FETCH_NUM]);
125 126
    foreach ($result as $record) {
      $records[] = $record;
127 128 129
      $this->assertIsArray($record);
      $this->assertArrayHasKey(0, $record);
      $this->assertSame('John', $record[0]);
130 131
    }

132
    $this->assertCount(1, $records, 'There is only one record');
133 134 135
  }

  /**
136
   * Confirms that we can fetch a record into a doubly-keyed array explicitly.
137
   */
138
  public function testQueryFetchBoth() {
139
    $records = [];
140
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => \PDO::FETCH_BOTH]);
141 142
    foreach ($result as $record) {
      $records[] = $record;
143 144 145 146 147
      $this->assertIsArray($record);
      $this->assertArrayHasKey(0, $record);
      $this->assertSame('John', $record[0]);
      $this->assertArrayHasKey('name', $record);
      $this->assertSame('John', $record['name']);
148 149
    }

150
    $this->assertCount(1, $records, 'There is only one record.');
151 152
  }

153 154 155 156
  /**
   * Confirms that we can fetch all records into an array explicitly.
   */
  public function testQueryFetchAllColumn() {
157
    $query = $this->connection->select('test');
158 159 160 161 162 163 164 165
    $query->addField('test', 'name');
    $query->orderBy('name');
    $query_result = $query->execute()->fetchAll(\PDO::FETCH_COLUMN);

    $expected_result = ['George', 'John', 'Paul', 'Ringo'];
    $this->assertEqual($query_result, $expected_result, 'Returned the correct result.');
  }

166
  /**
167
   * Confirms that we can fetch an entire column of a result set at once.
168
   */
169
  public function testQueryFetchCol() {
170
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] > :age', [':age' => 25]);
171
    $column = $result->fetchCol();
172
    $this->assertCount(3, $column, 'fetchCol() returns the right number of records.');
173

174
    $result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] > :age', [':age' => 25]);
175 176
    $i = 0;
    foreach ($result as $record) {
177
      $this->assertIdentical($record->name, $column[$i++], 'Column matches direct access.');
178 179
    }
  }
180 181 182 183 184

  /**
   * Tests that rowCount() throws exception on SELECT query.
   */
  public function testRowCount() {
185
    $result = $this->connection->query('SELECT [name] FROM {test}');
186 187 188 189 190 191 192 193 194 195
    try {
      $result->rowCount();
      $exception = FALSE;
    }
    catch (RowCountException $e) {
      $exception = TRUE;
    }
    $this->assertTrue($exception, 'Exception was thrown');
  }

196
}