diff --git a/model/SQLQuery.php b/model/SQLQuery.php index c419586cf..020473101 100644 --- a/model/SQLQuery.php +++ b/model/SQLQuery.php @@ -1080,7 +1080,10 @@ class SQLQuery { public function lastRow() { $query = clone $this; $offset = $this->limit ? $this->limit['start'] : 0; - $query->setLimit(1, $this->count() + $offset - 1); + + // Limit index to start in case of empty results + $index = max($this->count() + $offset - 1, 0); + $query->setLimit(1, $index); return $query; } diff --git a/tests/model/SQLQueryTest.php b/tests/model/SQLQueryTest.php index 892018c34..8e2b25984 100755 --- a/tests/model/SQLQueryTest.php +++ b/tests/model/SQLQueryTest.php @@ -2,7 +2,7 @@ class SQLQueryTest extends SapphireTest { - static $fixture_file = null; + public static $fixture_file = 'SQLQueryTest.yml'; protected $extraDataObjects = array( 'SQLQueryTest_DO', @@ -300,6 +300,72 @@ class SQLQueryTest extends SapphireTest { $query->setWhereAny(array("Monkey = 'Chimp'", "Color = 'Brown'")); $this->assertEquals("SELECT * FROM MyTable WHERE (Monkey = 'Chimp' OR Color = 'Brown')",$query->sql()); } + + public function testSelectFirst() { + + // Test first from sequence + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $result = $query->firstRow()->execute(); + + $this->assertCount(1, $result); + foreach($result as $row) { + $this->assertEquals('Object 1', $row['Name']); + } + + // Test first from empty sequence + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $query->setWhere(array("\"Name\" = 'Nonexistent Object'")); + $result = $query->firstRow()->execute(); + $this->assertCount(0, $result); + + // Test that given the last item, the 'first' in this list matches the last + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $query->setLimit(1, 1); + $result = $query->firstRow()->execute(); + $this->assertCount(1, $result); + foreach($result as $row) { + $this->assertEquals('Object 2', $row['Name']); + } + } + + public function testSelectLast() { + + // Test last in sequence + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $result = $query->lastRow()->execute(); + + $this->assertCount(1, $result); + foreach($result as $row) { + $this->assertEquals('Object 2', $row['Name']); + } + + // Test last from empty sequence + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $query->setWhere(array("\"Name\" = 'Nonexistent Object'")); + $result = $query->lastRow()->execute(); + $this->assertCount(0, $result); + + // Test that given the first item, the 'last' in this list matches the first + $query = new SQLQuery(); + $query->setFrom('"SQLQueryTest_DO"'); + $query->setOrderBy('"Name"'); + $query->setLimit(1); + $result = $query->lastRow()->execute(); + $this->assertCount(1, $result); + foreach($result as $row) { + $this->assertEquals('Object 1', $row['Name']); + } + } } diff --git a/tests/model/SQLQueryTest.yml b/tests/model/SQLQueryTest.yml new file mode 100644 index 000000000..725b7dee4 --- /dev/null +++ b/tests/model/SQLQueryTest.yml @@ -0,0 +1,7 @@ +SQLQueryTest_DO: + test1: + Name: 'Object 1' + Meta: 'Details 1' + test2: + Name: 'Object 2' + Meta: 'Details 2' \ No newline at end of file