diff --git a/src/Position.php b/src/Position.php index ff4f2038ba95546ca86dc56747a6cdd3caecc35f..8a8e9ef19a087e8bd452952ec515ded5bd71d78f 100644 --- a/src/Position.php +++ b/src/Position.php @@ -5,10 +5,9 @@ namespace Grifart\Mappi\Cursor; -// todo: make this immutable as VOs should be - /** - * Value object for TrackedCursor position + * Value Object that holds position of cursor + * use by {@see TrackedCursor} * * @link https://github.com/nicolopignatelli/valueobjects (inspiration) * @package Grifart\Mappi\Cursor @@ -25,9 +24,13 @@ final class Position * @param PositionOrigin $origin from left or from right? * @param int $position which position */ - public function __construct(PositionOrigin $origin, int $position) + private function __construct(PositionOrigin $origin, int $position) { - $this->setPosition($origin, $position); + if($position < 0) { + throw CursorException::cursorPosition_invalidIndexValue($position); + } + $this->origin = $origin; + $this->position = $position; } public static function fromLeft(int $position) : self @@ -45,36 +48,15 @@ final class Position $position ); } - - public function setPositionFromLeft(int $position) - { - $this->setPosition(PositionOrigin::get(PositionOrigin::FROM_LEFT), $position); - } - - public function setPositionFromRight(int $position) - { - $this->setPosition(PositionOrigin::get(PositionOrigin::FROM_RIGHT), $position); - } - - private function setPosition(PositionOrigin $origin, int $position) - { - if($position < 0) { - throw CursorException::cursorPosition_invalidIndexValue($position); - } - $this->origin = $origin; - $this->position = $position; - } - - /** - * @param int $by negative = left; positive = right - */ - public function movePositionBy(int $by) + + public static function relativeTo(Position $position, int $offset) : self { - $modifier = 1; - if ($this->origin->is(PositionOrigin::FROM_RIGHT)) { - $modifier = -1; - } - $this->position += $modifier * $by; + $positionDelta = ($position->getOrigin() + ->is(PositionOrigin::FROM_LEFT) ? 1 : -1) * $offset; + return new self( + $position->getOrigin(), + $position->getPosition() + $positionDelta + ); } /** diff --git a/src/TrackedCursor.php b/src/TrackedCursor.php index 2d1ceb290b6fe9cac4e47779acdce74f26908cbe..cf92d013e5b24f808e10fe4cb883e359e5eebc04 100644 --- a/src/TrackedCursor.php +++ b/src/TrackedCursor.php @@ -47,18 +47,16 @@ class TrackedCursor implements ICursor { $this->cursor->moveTo($index); if ($this->cursor->isOnRecord()) { - $this->position->setPositionFromLeft( - $index - ); + $this->position = Position::fromLeft($index); return; } if ($index === 0) { - $this->position->setPositionFromLeft(0); // BEGINNING + $this->position = Position::fromLeft(0); // BEGINNING return; } if ($index > 0 ) { - $this->position->setPositionFromRight(0); // END + $this->position = Position::fromRight(0); // END return; } throw CursorException::cursorPosition_unknownError(); @@ -68,18 +66,16 @@ class TrackedCursor implements ICursor { $this->cursor->moveFromEndTo($index); if ($this->cursor->isOnRecord()) { - $this->position->setPositionFromRight( - $index - ); + $this->position = Position::fromRight($index); return; } if ($index === 0) { - $this->position->setPositionFromRight(0); // END + $this->position = Position::fromRight(0); // END return; } if ($index > 0) { - $this->position->setPositionFromLeft(0); // BEGINNING + $this->position = Position::fromLeft(0); // BEGINNING return; } throw CursorException::cursorPosition_unknownError(); @@ -90,15 +86,15 @@ class TrackedCursor implements ICursor // todo: use MOVE FORWARD n IN ... which returns number of rows read $this->cursor->moveBy($offset); if ($this->cursor->isOnRecord()) { - $this->position->movePositionBy($offset); + $this->position = Position::relativeTo($this->position, $offset); return; } if ($offset < 0) { - $this->position->setPositionFromLeft(0); // BEGINNING + $this->position = Position::fromLeft(0); // BEGINNING return; } if ($offset > 0) { - $this->position->setPositionFromRight(0); // END + $this->position = Position::fromRight(0); // END return; } if ($offset === 0) { @@ -118,17 +114,18 @@ class TrackedCursor implements ICursor $count = count($result); $reachedEnd = $count < abs($offset); if(!$reachedEnd) { - $this->position->movePositionBy( + $this->position = Position::relativeTo( + $this->position, $count * ($forward ? 1 : -1) ); return $result; } if($forward) { - $this->position->setPositionFromRight(0); // right END + $this->position = Position::fromRight(0); // right END return $result; } else { - $this->position->setPositionFromLeft(0); // left END + $this->position = Position::fromLeft(0); // left END return $result; } } @@ -138,24 +135,24 @@ class TrackedCursor implements ICursor $row = $this->cursor->fetchOneAt($index); if ($row !== NULL) { if($index < 0) { - $this->position->setPositionFromRight(abs($index)); + $this->position = Position::fromRight(abs($index)); } else /* >= 0 */ { - $this->position->setPositionFromLeft($index); + $this->position = Position::fromLeft(abs($index)); } return $row; } if ($index === 0) { - $this->position->setPositionFromLeft(0); // BEGINNING + $this->position = Position::fromLeft(0); // BEGINNING return NULL; } if ($index < 0) { // went from right to left -> hit beginning - $this->position->setPositionFromLeft(0); + $this->position = Position::fromLeft(0); return NULL; } if ($index > 0) { // went left->right -> hit end - $this->position->setPositionFromRight(0); + $this->position = Position::fromRight(0); return NULL; } @@ -166,16 +163,16 @@ class TrackedCursor implements ICursor { // todo: content tests $row = $this->cursor->fetchOneBy($offset); if ($row !== NULL) { - $this->position->movePositionBy($offset); + $this->position = $this->position = Position::relativeTo($this->position, $offset); return $row; } if ($offset < 0) { - $this->position->setPositionFromLeft(0); // BEGINNING + $this->position = Position::fromLeft(0); // BEGINNING return NULL; } if ($offset > 0) { - $this->position->setPositionFromRight(0); // END + $this->position = Position::fromRight(0); // END return NULL; } if ($offset === 0) {