Skip to content

Commit

Permalink
Merge pull request #10484 from creative-commoners/pulls/5/rescue-mast…
Browse files Browse the repository at this point in the history
…er-orm-generators

API rescue master-branch PR: Use Generators for ORM
  • Loading branch information
emteknetnz authored Sep 15, 2022
2 parents 03b929d + e140c37 commit 71dca01
Show file tree
Hide file tree
Showing 17 changed files with 300 additions and 487 deletions.
4 changes: 0 additions & 4 deletions src/Forms/GridField/GridFieldExportButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,6 @@ public function generateExportFileData($gridField)

// Remove limit as the list may be paginated, we want the full list for the export
$items = $items->limit(null);
// Use Generator in applicable cases to reduce memory consumption
$items = $items instanceof DataList
? $items->getGenerator()
: $items;

/** @var DataObject $item */
foreach ($items as $item) {
Expand Down
14 changes: 7 additions & 7 deletions src/ORM/ArrayList.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ public function exists()
#[\ReturnTypeWillChange]
public function getIterator()
{
$items = array_map(
function ($item) {
return is_array($item) ? new ArrayData($item) : $item;
},
$this->items ?? []
);
return new ArrayIterator($items);
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 @@ -378,7 +378,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
50 changes: 22 additions & 28 deletions src/ORM/Connect/MySQLQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,44 +45,38 @@ public function __destruct()
}
}

public function seek($row)
#[\ReturnTypeWillChange]
public function getIterator()
{
$floatTypes = [MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE, MYSQLI_TYPE_DECIMAL, MYSQLI_TYPE_NEWDECIMAL];
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 ($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;
}
yield $data;
}
// Check for the method first since $this->handle is a mixed type
if (method_exists($this->handle, 'data_seek')) {
// Reset so the query can be iterated over again
$this->handle->data_seek(0);
}
}
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;
}
}
81 changes: 34 additions & 47 deletions src/ORM/Connect/MySQLStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,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 +102,25 @@ 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()
#[\ReturnTypeWillChange]
public function getIterator()
{
$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) {
$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;
}
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;
}
}
Loading

0 comments on commit 71dca01

Please sign in to comment.