Skip to content

Commit

Permalink
Make col optional when constructing a Prop with a getValue function
Browse files Browse the repository at this point in the history
This will simplify usage and improve efficiency for some computed properties.
  • Loading branch information
theodorejb committed Aug 1, 2023
1 parent 4c0cc89 commit dc944ec
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 25 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.6.0] - 2023-08-01
### Changed
- `col` is now optional when constructing `Prop` with a `getValue` function.

## [2.5.0] - 2023-03-05
### Changed
- Minor code cleanup and refactoring.
Expand Down Expand Up @@ -132,7 +136,8 @@ return early if passed an empty IDs array.
### Changed
- Initial stable release

[Unreleased]: https://github.com/theodorejb/phaster/compare/v2.5.0...HEAD
[Unreleased]: https://github.com/theodorejb/phaster/compare/v2.6.0...HEAD
[2.6.0]: https://github.com/theodorejb/phaster/compare/v2.5.0...v2.6.0
[2.5.0]: https://github.com/theodorejb/phaster/compare/v2.4.0...v2.5.0
[2.4.0]: https://github.com/theodorejb/phaster/compare/v2.3.0...v2.4.0
[2.3.0]: https://github.com/theodorejb/phaster/compare/v2.2.2...v2.3.0
Expand Down
26 changes: 14 additions & 12 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,20 @@ public static function mapRows(\Generator $rows, array $fieldProps): array
/** @var Prop[] $nullParents */
$nullParents = [];

/** @var mixed $value */
foreach ($row as $colName => $value) {
$prop = $aliasMap[$colName];
foreach ($aliasMap as $colName => $prop) {
if ($prop->getValue) {
/** @var mixed $value */
$value = ($prop->getValue)($row);
} else {
/** @var mixed $value */
$value = $row[$colName];

if ($prop->type) {
settype($value, $prop->type);
} elseif (is_string($value) && $prop->timeZone !== false) {
$value = (new \DateTimeImmutable($value, $prop->timeZone))->format(\DateTime::ATOM);
}
}

if ($prop->nullGroup && $value === null) {
// only add if there isn't a higher-level null parent
Expand All @@ -103,15 +114,6 @@ public static function mapRows(\Generator $rows, array $fieldProps): array
continue;
}

if ($prop->getValue) {
/** @var mixed $value */
$value = ($prop->getValue)($row);
} elseif ($prop->type) {
settype($value, $prop->type);
} elseif (is_string($value) && $prop->timeZone !== false) {
$value = (new \DateTimeImmutable($value, $prop->timeZone))->format(\DateTime::ATOM);
}

$key = $prop->map[0];
/** @psalm-suppress EmptyArrayAccess */
$_ref = &$entity[$key];
Expand Down
16 changes: 10 additions & 6 deletions src/Prop.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class Prop
*/
public function __construct(
string $name,
string $col,
string $col = '',
bool $nullGroup = false,
bool $isDefault = true,
string $alias = '',
Expand All @@ -86,7 +86,13 @@ public function __construct(
throw new \Exception("nullGroup cannot be set on top-level {$name} property");
}

if ($getValue !== null) {
if ($getValue === null) {
if ($col === '') {
throw new \Exception("col cannot be blank on {$name} property without getValue function");
} elseif (count($dependsOn) !== 0) {
throw new \Exception("dependsOn cannot be used on {$name} property without getValue function");
}
} else {
if ($type !== null) {
throw new \Exception("type cannot be set on {$name} property along with getValue");
} elseif ($timeZone !== false) {
Expand All @@ -106,10 +112,6 @@ public function __construct(
}
}

if (count($dependsOn) !== 0 && $getValue === null) {
throw new \Exception("dependsOn cannot be used on {$name} property without getValue function");
}

$this->name = $name;
$this->col = $col;
$this->alias = $alias;
Expand All @@ -125,6 +127,8 @@ public function getOutputCol(): string
{
if ($this->alias) {
return $this->alias;
} elseif ($this->col === '') {
return $this->name;
}

$col = explode('.', $this->col);
Expand Down
14 changes: 9 additions & 5 deletions src/QueryOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,22 @@ public function getFieldProps(): array

public function getColumns(): string
{
$columns = [];
$columns = '';

foreach ($this->fieldProps as $prop) {
$col = $prop->col;
if ($prop->col === '') {
continue;
}

$columns .= $prop->col;

if ($prop->alias) {
$col .= ' AS ' . $prop->alias;
$columns .= ' AS ' . $prop->alias;
}

$columns[] = $col;
$columns .= ', ';
}

return implode(', ', $columns);
return substr($columns, 0, -2);
}
}
4 changes: 3 additions & 1 deletion test/EntitiesDbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,14 @@ public function testModernUsers(Entities $entities, PeachySql $db): void
$ids = $entities->addEntities($users);
$db->insertRow('UserThings', ['user_id' => $ids[3]]);

$actual = $entities->getEntitiesByIds([$ids[2], $ids[3]], ['id', 'name', 'isDisabled', 'weight', 'thing.uid']);
$actual = $entities->getEntitiesByIds([$ids[2], $ids[3]], ['id', 'name', 'isDisabled', 'computed', 'weight', 'thing.uid']);

$expected = [
[
'id' => $ids[3],
'name' => 'Modern user 4',
'isDisabled' => false,
'computed' => $ids[3] - 1,
'weight' => 40.0,
'thing' => [
'uid' => $ids[3],
Expand All @@ -360,6 +361,7 @@ public function testModernUsers(Entities $entities, PeachySql $db): void
'id' => $ids[2],
'name' => 'Modern user 3 modified',
'isDisabled' => false,
'computed' => $ids[2] - 1,
'weight' => 30.0,
'thing' => null,
],
Expand Down
4 changes: 4 additions & 0 deletions test/HelpersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ public function testPropMapToAliasMap(): void
'username' => ['col' => 'a.UserName'],
'client.isDisabled' => ['col' => 'c.isDisabled', 'alias' => 'isClientDisabled', 'type' => 'bool'],
'dateCreated' => ['col' => 'DateCreatedUTC', 'timeZone' => $utc],
'computed' => ['getValue' => fn(array $_): bool => true],
'computed2' => ['alias' => 'aliased', 'getValue' => fn(array $_): bool => false],
];

$props = Helpers::rawPropMapToProps($rawPropMap);
Expand All @@ -272,6 +274,8 @@ public function testPropMapToAliasMap(): void
'UserName' => $propMap['username'],
'isClientDisabled' => $propMap['client.isDisabled'],
'DateCreatedUTC' => $propMap['dateCreated'],
'computed' => $propMap['computed'],
'aliased' => $propMap['computed2'],
];

$this->assertSame($expected, Helpers::propMapToAliasMap($propMap));
Expand Down
6 changes: 6 additions & 0 deletions test/src/ModernUsers.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,16 @@ protected function getMap(): array

protected function getSelectProps(): array
{
$getValue = function (array $row): int {
/** @var array{u_id: int} $row */
return $row['u_id'] - 1;
};

return [
new Prop('id', 'u.u_id'),
new Prop('name', 'name', false, true, 'username'),
new Prop('isDisabled', 'isDisabled', false, true, '', 'bool'),
new Prop('computed', '', false, true, '', null, false, $getValue),
new Prop('thing.id', 'ut.thing_id', true),
new Prop('thing.uid', 'ut.user_id', false, true, 'thing_user'),
];
Expand Down

0 comments on commit dc944ec

Please sign in to comment.