Skip to content

Commit

Permalink
Merge pull request #168 from PhpGt/162-type-safe-get
Browse files Browse the repository at this point in the history
Type safe Row getters
  • Loading branch information
g105b authored Aug 21, 2019
2 parents 30b7531 + 44c9843 commit c068767
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/Result/BadlyFormedDataException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace Gt\Database\Result;

use Gt\Database\DatabaseException;

class BadlyFormedDataException extends DatabaseException {}
80 changes: 62 additions & 18 deletions src/Result/Row.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace Gt\Database\Result;

use DateTime;
use Iterator;

class Row implements Iterator {
Expand All @@ -11,55 +12,98 @@ class Row implements Iterator {

public function __construct(array $data = []) {
$this->data = $data;
$this->setProperties($data);
}

public function toArray():array {
return $this->data;
public function get(string $columnName):?string {
return $this->getString($columnName);
}

public function getString(string $columnName):string {
$this->checkColumn($columnName);
return $this->data[$columnName];
}

public function getInt(string $columnName):int {
$this->checkColumn($columnName);
return (int)$this->data[$columnName];
}

public function getFloat(string $columnName):float {
$this->checkColumn($columnName);
return (float)$this->data[$columnName];
}

public function getBool(string $columnName):bool {
$this->checkColumn($columnName);
return (bool)$this->data[$columnName];
}

public function __get($name) {
if(!isset($this->$name)) {
throw new NoSuchColumnException($name);
public function getDateTime(string $columnName):DateTime {
$this->checkColumn($columnName);
$dateString = $this->data[$columnName];
if(is_null($dateString)) {
return null;
}

if(is_numeric($dateString)) {
$dateTime = new DateTime();
$dateTime->setTimestamp($dateString);
return $dateTime;
}

$dateTime = new DateTime($dateString);
if(!$dateTime) {
throw new BadlyFormedDataException($columnName);
}

return $this->data[$name];
return $dateTime;
}

public function __isset($name) {
public function toArray():array {
return $this->data;
}

public function __get(string $name):string {
return $this->getString($name);
}

public function __isset(string $name):bool {
return array_key_exists($name, $this->data);
}

public function contains(string $name):bool {
return $this->__isset($name);
}

protected function setProperties(array $data) {
foreach($data as $key => $value) {
$this->$key = $value;
}
}

public function rewind():void {
$this->iterator_index = 0;
$this->iterator_data_key_list = array_keys($this->data);
}

public function current() {
public function current():?string {
$key = $this->key();

return $this->$key;
}

public function key():?string {
return $this->iterator_data_key_list[$this->iterator_index] ?? null;
return $this->iterator_data_key_list[
$this->iterator_index
] ?? null;
}

public function next():void {
$this->iterator_index++;
}

public function valid():bool {
return isset($this->iterator_data_key_list[$this->iterator_index]);
return isset($this->iterator_data_key_list[
$this->iterator_index
]);
}

protected function checkColumn(string $columnName):void {
if(!isset($this->data[$columnName])) {
throw new NoSuchColumnException($columnName);
}
}
}
103 changes: 97 additions & 6 deletions test/unit/Result/RowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace unit\Result;

use DateTime;
use Gt\Database\Result\NoSuchColumnException;
use Gt\Database\Result\Row;
use PHPUnit\Framework\TestCase;
Expand All @@ -12,7 +13,12 @@ public function testFieldAccess(array $data) {
$row = new Row($data);

foreach($data as $key => $value) {
self::assertEquals($data[$key], $row->$key);
if(is_float($data[$key])) {
self::assertEqualsWithDelta($data[$key], $value, 0.0001);
}
else {
self::assertEquals($data[$key], $value);
}
}
}

Expand Down Expand Up @@ -57,14 +63,99 @@ public function testIteration(array $data) {
$row = new Row($data);

foreach($row as $colName => $value) {
self::assertEquals($data[$colName], $value);
if(is_float($data[$colName])) {
self::assertEqualsWithDelta($data[$colName], $value, 0.0001);
}
else {
self::assertEquals($data[$colName], $value);
}
}
}

/** @dataProvider data_getTestRow */
public function testGetString(array $data) {
$row = new Row($data);
foreach($data as $key => $expected) {
$actual = $row->getString($key);
self::assertIsString($actual);
self::assertSame((string)$expected, $actual);
}
}

/** @dataProvider data_getTestRow */
public function testGetInt(array $data) {
$row = new Row($data);
$id = $row->getInt("id");
self::assertIsInt($id);
self::assertSame((int)$data["id"], $id);
}

/** @dataProvider data_getTestRow */
public function testGetFloat(array $data) {
$row = new Row($data);
$float = $row->getFloat("exampleFloat");
self::assertIsFloat($float);
self::assertSame((float)$data["exampleFloat"], $float);
}

/** @dataProvider data_getTestRow */
public function testGetBool(array $data) {
$row = new Row($data);
$bool = $row->getBool("exampleBool");
self::assertIsBool($bool);
self::assertSame((bool)$data["exampleBool"], $bool);
}

/** @dataProvider data_getTestRow */
public function testGetDateTime(array $data) {
$row = new Row($data);
$dateTime = $row->getDateTime("exampleDateTime");
self::assertInstanceOf(DateTime::class, $dateTime);
self::assertEquals(
$dateTime->format("Y-m-d H:i:s"),
$data["exampleDateTime"]
);
}

public function data_getTestRow():array {
return [
[["id" => 1, "name" => "Alice"]],
[["col1" => "binky", "col2" => "boo", "col3", "dah"]],
];
$data = [];

$columns = ["id", "name", "example", "exampleFloat", "exampleDateTime", "exampleBool"];
$rows = [];
$rowNum = rand(2, 50);
for($i = 0; $i < $rowNum; $i++) {
$row = [];
foreach($columns as $columnIndex => $columnName) {
switch($columnName) {
case "id":
$value = $columnIndex;
break;

case "exampleFloat":
$value = rand(100, 1000000) / 3.141;
break;

case "exampleDateTime":
$timestamp = rand(0, 4260560700);
$dateTime = new DateTime();
$dateTime->setTimestamp($timestamp);
$value = $dateTime->format("Y-m-d H:i:s");
break;

case "exampleBool":
$value = rand(0, 1);
break;

default:
$value = uniqid();
}

$row[$columnName] = $value;
}

$data []= [$row];
}

return $data;
}
}

0 comments on commit c068767

Please sign in to comment.