diff --git a/src/PostgresDriver/CursorDriver.php b/src/PostgresDriver/CursorDriver.php index b9fd8b302f720f4ebd8e73e52430a741079485cd..1a3d78105553360acb519c37934b0308a67ad913 100644 --- a/src/PostgresDriver/CursorDriver.php +++ b/src/PostgresDriver/CursorDriver.php @@ -11,28 +11,36 @@ use Dibi\Connection; * PostgreSQL cursor driver * * Basic envelope over PostgreSQL's cursor. This cursor envelope does not know - * cursor position, thus cannot do boundary checks. If you reach end, you simply - * get no more values. You can check if you reached the end by `isHeadOnRecord()`. + * cursor position, thus cannot do boundary checks. If you reach end, you + * simply + * get no more values. You can check if you reached the end by + * `isHeadOnRecord()`. * * @package Grifart\Mappi\Store\PostgresDriver */ -class CursorDriver implements ICursorDriver +final class CursorDriver implements ICursorDriver { - /** @var Connection */ private $connection; - /** @var string */ private $name; - /** @var bool */ private $headOnRecord = false; + /** + * Warning: this class itself does not check if cursor is really valid in + * constructor. + * + * @param Connection $connection Connection with defined cursor with + * name given in next parameter + * @param string $name Name of cursor defined in + * transaction (if not valid all later + * call wil fail) + */ public function __construct(Connection $connection, string $name) { $this->connection = $connection; $this->name = $name; - // todo: does cursor really exits? // todo: close; for now automatically closed on transaction end } @@ -53,10 +61,10 @@ class CursorDriver implements ICursorDriver public function moveTo(int $index) { - if($index < 0) { + if ($index < 0) { throw new \InvalidArgumentException("Negative index not supported. Use moveFromEndTo() instead."); } - $this->headOnRecord = !! $this->getConnection()->query( + $this->headOnRecord = !!$this->getConnection()->query( "MOVE ABSOLUTE %i IN %n", $index, $this->getName() @@ -65,11 +73,11 @@ class CursorDriver implements ICursorDriver public function moveFromEndTo(int $index) { - if($index < 0) { + if ($index < 0) { throw new \InvalidArgumentException("Negative index not supported. Use moveTo() instead."); } - if($index === 0) { // END position - $this->headOnRecord = !! $this->getConnection()->query( + if ($index === 0) { // END position + $this->headOnRecord = !!$this->getConnection()->query( "MOVE ABSOLUTE -1 IN %n; MOVE NEXT IN %n;", $this->getName(), $this->getName() @@ -78,7 +86,7 @@ class CursorDriver implements ICursorDriver } $negativeIndex = -$index; - $this->headOnRecord = !! $this->getConnection()->query( + $this->headOnRecord = !!$this->getConnection()->query( "MOVE ABSOLUTE %i IN %n", $negativeIndex, $this->getName() @@ -87,7 +95,7 @@ class CursorDriver implements ICursorDriver public function moveBy(int $rows) { - $this->headOnRecord = !! $this->getConnection()->query( + $this->headOnRecord = !!$this->getConnection()->query( "MOVE RELATIVE %i IN %n", $rows, $this->getName() @@ -100,7 +108,7 @@ class CursorDriver implements ICursorDriver { $forward = $rows >= 0; $numberOfRowsSQLClause = ($rows === self::FETCH_FOREGOING || $rows === self::FETCH_REMAINING) ? - "ALL" : abs($rows); + "ALL" : abs($rows); $recs = $this->connection->query( $forward ? "FETCH FORWARD %sql FROM %n" : "FETCH BACKWARD %sql FROM %n", @@ -108,9 +116,10 @@ class CursorDriver implements ICursorDriver $this->getName() )->fetchAll(); - if($rows === 0) { + if ($rows === 0) { $this->headOnRecord = count($recs) === 1; - } else { + } + else { // todo: test this properly!! $this->headOnRecord = count($recs) === abs($rows); } @@ -125,8 +134,10 @@ class CursorDriver implements ICursorDriver $index, $this->getName() )->fetch(); - $this->headOnRecord = $record !== FALSE; - if($record === FALSE) return NULL; + $this->headOnRecord = $record !== false; + if ($record === false) { + return null; + } return $record->toArray(); } @@ -137,9 +148,10 @@ class CursorDriver implements ICursorDriver $rows, $this->getName() )->fetch(); - $this->headOnRecord = $record !== FALSE; - if($record === FALSE) return NULL; + $this->headOnRecord = $record !== false; + if ($record === false) { + return null; + } return $record->toArray(); } - } \ No newline at end of file diff --git a/src/PostgresDriver/CursorDriverFactory.php b/src/PostgresDriver/CursorDriverFactory.php index fd8bc6306b3cece470eefd442645f7fc4e9ed286..8164b1befb8a24358d0bbac951e258e5918bc1e3 100644 --- a/src/PostgresDriver/CursorDriverFactory.php +++ b/src/PostgresDriver/CursorDriverFactory.php @@ -7,7 +7,7 @@ namespace Grifart\Mappi\Store\PostgresDriver; use Dibi\Connection; -class CursorDriverFactory +final class CursorDriverFactory { /** @var Connection */ private $connection; diff --git a/src/PostgresDriver/ICursor.php b/src/PostgresDriver/ICursor.php index 3f3d31eedbc77252fac8cb6a983286ed0e028e90..623fc25a3d18cb63276e423af0e82928314cf4d7 100644 --- a/src/PostgresDriver/ICursor.php +++ b/src/PostgresDriver/ICursor.php @@ -14,12 +14,10 @@ use Dibi\Connection; */ interface ICursor { + // ---- shared with ICursorDriver ---- public function getName() : string; - /** - * @internal - */ - public function getConnection() : Connection; + public function isOnRecord() : bool; /** * @param int $rows @@ -33,6 +31,35 @@ interface ICursor */ public function moveTo(int $index); + /** + * @param int $index + * @return mixed + */ + public function moveFromEndTo(int $index); + + /** + * Fetch the next/previous count rows. FORWARD 0 re-fetches the current row. + * @param int $rows + * @return array + */ + public function fetchRange(int $rows) : array; + + /** + * Fetch the count'th row of the query, or the abs(count)'th row from the end if count is negative. Position before first row or after last row if count is out of range; in particular, ABSOLUTE 0 positions before the first row. + * @param int $index + * @return array + */ + public function fetchOneAt(int $index) : array; + + /** + * Fetch the count'th succeeding row, or the abs(count)'th prior row if count is negative. RELATIVE 0 re-fetches the current row, if any. + * @param int $rows + * @return array + */ + public function fetchOneBy(int $rows) : array; + + + // ---- The UX part: ---- /** * Move cursor on the last row * @see fetchCurrent() @@ -62,49 +89,20 @@ interface ICursor * @return void */ public function moveToEnd(); - - /** - * Fetch the next/previous count rows. FORWARD 0 re-fetches the current row. - * @param int $rows - * @return array - */ - public function fetch(int $rows); /** - * @return array the row + * Moves cursor to the next position, then returns rows. + * @return mixed */ public function fetchNext(); - public function fetchCurrent(); - - /** - * @return mixed the value in first column - */ public function fetchNextSingle(); - public function fetchCurrentSingle(); - /** - * Fetch the count'th row of the query, or the abs(count)'th row from the end if count is negative. Position before first row or after last row if count is out of range; in particular, ABSOLUTE 0 positions before the first row. - * @param int $index - * @return array - */ - public function fetchOneAt(int $index); + public function fetchCurrent(); + public function fetchCurrentSingle(); - /** - * Fetch the count'th succeeding row, or the abs(count)'th prior row if count is negative. RELATIVE 0 re-fetches the current row, if any. - * @param int $rows - * @return array - */ - public function fetchOneBy(int $rows); + public function fetchPrevious(); + public function fetchPreviousSingle(); - /** - * Fetch all remaining rows. - * @return array of remaining rows - */ public function fetchRemaining(); - - /** - * Fetch all prior rows (scanning backwards). - * @return array of foregoing rows - */ public function fetchForegoing(); } \ No newline at end of file diff --git a/src/PostgresDriver/ICursorDriver.php b/src/PostgresDriver/ICursorDriver.php index 5948303360616e73f276275139a73022467189de..c4914ad09efbb676a14848a204af73ad02f426b3 100644 --- a/src/PostgresDriver/ICursorDriver.php +++ b/src/PostgresDriver/ICursorDriver.php @@ -21,8 +21,6 @@ interface ICursorDriver public function isOnRecord() : bool; - // ----- move ---- - /** * @param int $rows * @return void @@ -41,36 +39,6 @@ interface ICursorDriver */ public function moveFromEndTo(int $index); -// /** -// * Move cursor on the first row (index=1) -// * @see fetchCurrent() -// * @see fetchCurrentSingle() -// * @return void -// */ -// public function moveToFirst(); -// -// /** -// * Move cursor on the last row -// * @see fetchCurrent() -// * @see fetchCurrentSingle() -// * @return void -// */ -// public function moveToLast(); -// -// /** -// * Moves cursor to position BEFORE first row (index=0) -// * @see fetchNext() -// * @see fetchNextSingle() -// * @return void -// */ -// public function moveToBeginning(); -// -// /** -// * Moves cursor to position AFTER last row -// * @return void -// */ -// public function moveToEnd(); - /** * Fetch the next/previous count rows. FORWARD 0 re-fetches the current row. * @param int $rows @@ -92,15 +60,4 @@ interface ICursorDriver */ public function fetchOneBy(int $rows) : array; -// /** -// * Fetch all remaining rows. -// * @return array of remaining rows -// */ -// public function fetchRemaining() : array; -// -// /** -// * Fetch all prior rows (scanning backwards). -// * @return array of foregoing rows -// */ -// public function fetchForegoing() : array; } \ No newline at end of file diff --git a/tests/Store/PostgresDriver/CursorTest.phpt b/tests/Store/PostgresDriver/CursorTest.phpt index 342d2a8eb56d48d7e5f9ea5c41d841bbbbb9c711..20bd98c3dc782c4a458678d57b0e2b25a332b159 100644 --- a/tests/Store/PostgresDriver/CursorTest.phpt +++ b/tests/Store/PostgresDriver/CursorTest.phpt @@ -6,7 +6,7 @@ namespace Grifart\Mappi\Tests\Store\Store\PostgresDriver; use Grifart\Mappi\Store\PostgresDriver\CursorException; -use Grifart\Mappi\Store\PostgresDriver\Cursor; +use Grifart\Mappi\Store\PostgresDriver\CursorDriver; use Grifart\Mappi\Store\PostgresDriver\CursorFactory; use Tester\Assert;