3 namespace Drupal\Core\Database;
6 * Default implementation of StatementInterface.
8 * \PDO allows us to extend the \PDOStatement class to provide additional
9 * functionality beyond that offered by default. We do need extra
10 * functionality. By default, this class is not driver-specific. If a given
11 * driver needs to set a custom statement class, it may do so in its
14 * @see http://php.net/pdostatement
16 class Statement extends \PDOStatement implements StatementInterface {
19 * Reference to the database connection object for this statement.
21 * The name $dbh is inherited from \PDOStatement.
23 * @var \Drupal\Core\Database\Connection
28 * Is rowCount() execution allowed.
32 public $allowRowCount = FALSE;
34 protected function __construct(Connection $dbh) {
36 $this->setFetchMode(\PDO::FETCH_OBJ);
42 public function execute($args = [], $options = []) {
43 if (isset($options['fetch'])) {
44 if (is_string($options['fetch'])) {
45 // \PDO::FETCH_PROPS_LATE tells __construct() to run before properties
46 // are added to the object.
47 $this->setFetchMode(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, $options['fetch']);
50 $this->setFetchMode($options['fetch']);
54 $logger = $this->dbh->getLogger();
55 if (!empty($logger)) {
56 $query_start = microtime(TRUE);
59 $return = parent::execute($args);
61 if (!empty($logger)) {
62 $query_end = microtime(TRUE);
63 $logger->log($this, $args, $query_end - $query_start);
72 public function getQueryString() {
73 return $this->queryString;
79 public function fetchCol($index = 0) {
80 return $this->fetchAll(\PDO::FETCH_COLUMN, $index);
86 public function fetchAllAssoc($key, $fetch = NULL) {
89 if (is_string($fetch)) {
90 $this->setFetchMode(\PDO::FETCH_CLASS, $fetch);
93 $this->setFetchMode($fetch);
97 foreach ($this as $record) {
98 $record_key = is_object($record) ? $record->$key : $record[$key];
99 $return[$record_key] = $record;
108 public function fetchAllKeyed($key_index = 0, $value_index = 1) {
110 $this->setFetchMode(\PDO::FETCH_NUM);
111 foreach ($this as $record) {
112 $return[$record[$key_index]] = $record[$value_index];
120 public function fetchField($index = 0) {
121 // Call \PDOStatement::fetchColumn to fetch the field.
122 return $this->fetchColumn($index);
128 public function fetchAssoc() {
129 // Call \PDOStatement::fetch to fetch the row.
130 return $this->fetch(\PDO::FETCH_ASSOC);
136 public function rowCount() {
137 // SELECT query should not use the method.
138 if ($this->allowRowCount) {
139 return parent::rowCount();
142 throw new RowCountException();
149 public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
150 // Call \PDOStatement::setFetchMode to set fetch mode.
151 // \PDOStatement is picky about the number of arguments in some cases so we
152 // need to be pass the exact number of arguments we where given.
153 switch (func_num_args()) {
155 return parent::setFetchMode($mode);
157 return parent::setFetchMode($mode, $a1);
160 return parent::setFetchMode($mode, $a1, $a2);
167 public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
168 // Call \PDOStatement::fetchAll to fetch all rows.
169 // \PDOStatement is picky about the number of arguments in some cases so we
170 // need to be pass the exact number of arguments we where given.
171 switch (func_num_args()) {
173 return parent::fetchAll();
175 return parent::fetchAll($mode);
177 return parent::fetchAll($mode, $column_index);
180 return parent::fetchAll($mode, $column_index, $constructor_arguments);