diff --git a/library/Icinga/Data/DataArray/ArrayDatasource.php b/library/Icinga/Data/DataArray/ArrayDatasource.php index 09b731691..e30061634 100644 --- a/library/Icinga/Data/DataArray/ArrayDatasource.php +++ b/library/Icinga/Data/DataArray/ArrayDatasource.php @@ -196,11 +196,16 @@ class ArrayDatasource implements Selectable $filter = $query->getFilter(); $offset = $query->hasOffset() ? $query->getOffset() : 0; $limit = $query->hasLimit() ? $query->getLimit() : 0; + $data = $this->data; + + if ($query->hasOrder()) { + uasort($data, [$query, 'compare']); + } $foundStringKey = false; - $result = array(); + $result = []; $skipped = 0; - foreach ($this->data as $key => $row) { + foreach ($data as $key => $row) { if ($this->keyColumn !== null && !isset($row->{$this->keyColumn})) { $row = clone $row; // Make sure that this won't affect the actual data $row->{$this->keyColumn} = $key; @@ -239,14 +244,7 @@ class ArrayDatasource implements Selectable } } - // Sort the result - if ($query->hasOrder()) { - if ($foundStringKey) { - uasort($result, array($query, 'compare')); - } else { - usort($result, array($query, 'compare')); - } - } elseif (! $foundStringKey) { + if (! $foundStringKey) { $result = array_values($result); } diff --git a/test/php/library/Icinga/Data/DataArray/ArrayDatasourceTest.php b/test/php/library/Icinga/Data/DataArray/ArrayDatasourceTest.php index 7e715cac2..a40ad30d1 100644 --- a/test/php/library/Icinga/Data/DataArray/ArrayDatasourceTest.php +++ b/test/php/library/Icinga/Data/DataArray/ArrayDatasourceTest.php @@ -8,40 +8,128 @@ use Icinga\Data\DataArray\ArrayDatasource; class ArrayDatasourceTest extends BaseTestCase { - private $sampleData; + private $query; public function setUp(): void { parent::setUp(); - $this->sampleData = array( - (object) array( - 'host' => 'localhost', + $this->query = (new ArrayDatasource([ + (object) [ + 'host' => 'a host', 'problem' => '1', - 'service' => 'ping', 'state' => '2', 'handled' => '1' - ), - (object) array( - 'host' => 'localhost', + ], + (object) [ + 'host' => 'b host', 'problem' => '1', - 'service' => 'www.icinga.com', 'state' => '0', 'handled' => '0' - ), - (object) array( - 'host' => 'localhost', + ], + (object) [ + 'host' => 'c host', 'problem' => '1', - 'service' => 'www.icinga.com', 'state' => '1', 'handled' => '0' - ) - ); + ] + ]))->select(); } public function testSelectFactory() { - $ds = new ArrayDatasource($this->sampleData); - $query = $ds->select(); - $this->assertInstanceOf('Icinga\\Data\\SimpleQuery', $query); + $this->assertInstanceOf('Icinga\\Data\\SimpleQuery', $this->query); + } + + public function testOrderWithOneRuleIsCorrect() + { + $result = $this->query + ->order('host', 'desc') + ->fetchAll(); + + $this->assertEquals( + [ + (object) [ + 'host' => 'c host', + 'problem' => '1', + 'state' => '1', + 'handled' => '0' + ], + (object) [ + 'host' => 'b host', + 'problem' => '1', + 'state' => '0', + 'handled' => '0' + ], + (object) [ + 'host' => 'a host', + 'problem' => '1', + 'state' => '2', + 'handled' => '1' + ] + ], + $result, + 'ArrayDatasource does not sort queries correctly' + ); + } + + public function testOrderWithTwoRulesIsCorrect() + { + $result = $this->query + ->order('handled', 'asc') + ->order('host', 'asc') + ->fetchAll(); + + $this->assertEquals( + [ + (object) [ + 'host' => 'b host', + 'problem' => '1', + 'state' => '0', + 'handled' => '0' + ], + (object) [ + 'host' => 'c host', + 'problem' => '1', + 'state' => '1', + 'handled' => '0' + ], + (object) [ + 'host' => 'a host', + 'problem' => '1', + 'state' => '2', + 'handled' => '1' + ] + ], + $result, + 'ArrayDatasource does not sort queries correctly' + ); + } + + public function testOrderIsCorrectWithLimitAndOffset() + { + $result = $this->query + ->order('handled', 'asc') + ->order('host', 'asc') + ->limit(2) + ->fetchAll(); + + $this->assertEquals( + [ + (object) [ + 'host' => 'b host', + 'problem' => '1', + 'state' => '0', + 'handled' => '0' + ], + (object) [ + 'host' => 'c host', + 'problem' => '1', + 'state' => '1', + 'handled' => '0' + ] + ], + $result, + 'ArrayDatasource does not sort limited queries correctly' + ); } }