Skip to content

Commit

Permalink
Merge pull request #6518 from sminnee/generators
Browse files Browse the repository at this point in the history
Use Generators for ORM Query, Map, ArrayList
  • Loading branch information
dhensby authored and GuySartorelli committed Aug 11, 2022
1 parent 2ae5212 commit 3b10a68
Show file tree
Hide file tree
Showing 19 changed files with 253 additions and 543 deletions.
23 changes: 10 additions & 13 deletions src/ORM/ArrayList.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace SilverStripe\ORM;

use ArrayIterator;
use InvalidArgumentException;
use Iterator;
use LogicException;
use SilverStripe\Dev\Debug;
use SilverStripe\Dev\Deprecation;
Expand Down Expand Up @@ -103,19 +103,16 @@ public function exists()
/**
* Returns an Iterator for this ArrayList.
* This function allows you to use ArrayList in foreach loops
*
* @return ArrayIterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
$items = array_map(
function ($item) {
return is_array($item) ? new ArrayData($item) : $item;
},
$this->items ?? []
);
return new ArrayIterator($items);
public function getIterator(): Iterator
{
foreach ($this->items as $i => $item) {
if (is_array($item)) {
yield new ArrayData($item);
} else {
yield $item;
}
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/ORM/Connect/DBSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ public function requireTable(
if ($dbID && isset($options[$dbID])) {
if (preg_match('/ENGINE=([^\s]*)/', $options[$dbID] ?? '', $alteredEngineMatches)) {
$alteredEngine = $alteredEngineMatches[1];
$tableStatus = $this->query(sprintf('SHOW TABLE STATUS LIKE \'%s\'', $table))->first();
$tableStatus = $this->query(sprintf('SHOW TABLE STATUS LIKE \'%s\'', $table))->record();
$tableOptionsChanged = ($tableStatus['Engine'] != $alteredEngine);
}
}
Expand Down
35 changes: 7 additions & 28 deletions src/ORM/Connect/MySQLQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace SilverStripe\ORM\Connect;

use Iterator;

/**
* A result-set from a MySQL database (using MySQLiConnector)
* Note that this class is only used for the results of non-prepared statements
Expand Down Expand Up @@ -45,44 +47,21 @@ public function __destruct()
}
}

public function seek($row)
public function getIterator(): Iterator
{
if (is_object($this->handle)) {
// Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API
$this->handle->data_seek($row);
$result = $this->nextRecord();
$this->handle->data_seek($row);
return $result;
while ($data = $this->handle->fetch_assoc()) {
yield $data;
}
}
return null;
}

public function numRecords()
{
if (is_object($this->handle)) {
return $this->handle->num_rows;
}
return null;
}

public function nextRecord()
{
$floatTypes = [MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE, MYSQLI_TYPE_DECIMAL, MYSQLI_TYPE_NEWDECIMAL];

if (is_object($this->handle) && ($row = $this->handle->fetch_array(MYSQLI_NUM))) {
$data = [];
foreach ($row as $i => $value) {
if (!isset($this->columns[$i])) {
throw new DatabaseException("Can't get metadata for column $i");
}
if (in_array($this->columns[$i]->type, $floatTypes ?? [])) {
$value = (float)$value;
}
$data[$this->columns[$i]->name] = $value;
}
return $data;
} else {
return false;
}
return null;
}
}
77 changes: 30 additions & 47 deletions src/ORM/Connect/MySQLStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SilverStripe\ORM\Connect;

use Iterator;
use mysqli_result;
use mysqli_stmt;

Expand Down Expand Up @@ -56,6 +57,26 @@ class MySQLStatement extends Query
*/
protected $boundValues = [];

/**
* Hook the result-set given into a Query class, suitable for use by SilverStripe.
* @param mysqli_stmt $statement The related statement, if present
* @param mysqli_result $metadata The metadata for this statement
*/
public function __construct($statement, $metadata)
{
$this->statement = $statement;
$this->metadata = $metadata;

// Immediately bind and buffer
$this->bind();
}

public function __destruct()
{
$this->statement->close();
$this->currentRecord = false;
}

/**
* Binds this statement to the variables
*/
Expand All @@ -82,58 +103,20 @@ protected function bind()
call_user_func_array([$this->statement, 'bind_result'], $variables ?? []);
}

/**
* Hook the result-set given into a Query class, suitable for use by SilverStripe.
* @param mysqli_stmt $statement The related statement, if present
* @param mysqli_result $metadata The metadata for this statement
*/
public function __construct($statement, $metadata)
{
$this->statement = $statement;
$this->metadata = $metadata;

// Immediately bind and buffer
$this->bind();
}

public function __destruct()
public function getIterator(): Iterator
{
$this->statement->close();
$this->currentRecord = false;
}

public function seek($row)
{
$this->rowNum = $row - 1;

// Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API
$this->statement->data_seek($row);
$result = $this->next();
$this->statement->data_seek($row);
return $result;
while ($this->statement->fetch()) {
// Dereferenced row
$row = [];
foreach ($this->boundValues as $key => $value) {
$row[$key] = $value;
}
yield $row;
}
}

public function numRecords()
{
return $this->statement->num_rows();
}

public function nextRecord()
{
// Skip data if out of data
if (!$this->statement->fetch()) {
return false;
}

// Dereferenced row
$row = [];
foreach ($this->boundValues as $key => $value) {
$floatTypes = [MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE, MYSQLI_TYPE_DECIMAL, MYSQLI_TYPE_NEWDECIMAL];
if (in_array($this->types[$key], $floatTypes ?? [])) {
$value = (float)$value;
}
$row[$key] = $value;
}
return $row;
}
}
23 changes: 7 additions & 16 deletions src/ORM/Connect/PDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace SilverStripe\ORM\Connect;

use ArrayIterator;
use Iterator;

/**
* A result-set from a PDO database.
*/
Expand All @@ -14,7 +17,7 @@ class PDOQuery extends Query

/**
* Hook the result-set given into a Query class, suitable for use by SilverStripe.
* @param PDOStatement $statement The internal PDOStatement containing the results
* @param PDOStatementHandle $statement The internal PDOStatement containing the results
*/
public function __construct(PDOStatementHandle $statement)
{
Expand All @@ -26,25 +29,13 @@ public function __construct(PDOStatementHandle $statement)
$statement->closeCursor();
}

public function seek($row)
public function getIterator(): Iterator
{
$this->rowNum = $row - 1;
return $this->nextRecord();
return new ArrayIterator($this->results);
}

public function numRecords()
{
return count($this->results ?? []);
}

public function nextRecord()
{
$index = $this->rowNum + 1;

if (isset($this->results[$index])) {
return $this->results[$index];
} else {
return false;
}
return count($this->results);
}
}
Loading

0 comments on commit 3b10a68

Please sign in to comment.