From 74c8e52eb37d2a04b73b40d0e0cff86535b5f34d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kucha=C5=99?= <honza.kuchar@grifart.cz>
Date: Sat, 7 May 2016 12:01:16 +0200
Subject: [PATCH] added usage of cursor factory

---
 src/PostgresDriver/Cursor.php                 | 34 +++++-------
 src/PostgresDriver/CursorFactory.php          | 54 +++++++++++++++++++
 src/PostgresDriver/ICursorFactory.php         | 11 ++++
 tests/Store/PostgresDriver/CursorTest.phpt    |  4 +-
 .../PostgresDriver/TrackedCursorTest.phpt     |  7 ++-
 5 files changed, 86 insertions(+), 24 deletions(-)
 create mode 100644 src/PostgresDriver/CursorFactory.php
 create mode 100644 src/PostgresDriver/ICursorFactory.php

diff --git a/src/PostgresDriver/Cursor.php b/src/PostgresDriver/Cursor.php
index cc11e09..e3d8816 100644
--- a/src/PostgresDriver/Cursor.php
+++ b/src/PostgresDriver/Cursor.php
@@ -7,6 +7,13 @@ namespace Grifart\Mappi\Store\PostgresDriver;
 
 use Dibi\Connection;
 
+/**
+ * PostgreSQL cursor driver
+ *
+ * Basic envelope over postgres' cursor, without proper check for edge cases.
+ *
+ * @package Grifart\Mappi\Store\PostgresDriver
+ */
 class Cursor implements ICursor
 {
 
@@ -14,25 +21,14 @@ class Cursor implements ICursor
 	private $connection;
 
 	/** @var string */
-	private $cursorName;
-
-	/** @var string */
-	private $sql;
+	private $name;
 
-	// todo: require only connection and name
-	// todo: cursor declaration will be in competence of factory
-	// todo: close
-	public function __construct(Connection $connection, string $sql, bool $scroll = true)
+	public function __construct(Connection $connection, string $name)
 	{
 		$this->connection = $connection;
-
-		// declare cursor
-		$connection->query(
-			"DECLARE %n %SQL CURSOR FOR (%SQL)",
-			$this->cursorName = $this->generateCursorName(),
-			$scroll ? "SCROLL" : "NO SCROLL",
-			$this->sql = $sql
-		);
+		$this->name = $name;
+		// todo: does cursor really exits?
+		// todo: close; for now automatically closed on transaction end
 	}
 
 	public function getConnection() : Connection
@@ -42,13 +38,9 @@ class Cursor implements ICursor
 
 	public function getName() : string
 	{
-		return $this->cursorName;
+		return $this->name;
 	}
 
-	private function generateCursorName() : string
-	{
-		return uniqid();
-	}
 
 	public function moveTo(int $index)
 	{
diff --git a/src/PostgresDriver/CursorFactory.php b/src/PostgresDriver/CursorFactory.php
new file mode 100644
index 0000000..5fb5206
--- /dev/null
+++ b/src/PostgresDriver/CursorFactory.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types = 1);
+/**
+ * This file is part of mappi/store.
+ */
+
+namespace Grifart\Mappi\Store\PostgresDriver;
+
+use Dibi\Connection;
+
+class CursorFactory implements ICursorFactory
+{
+	/** @var Connection */
+	private $connection;
+
+	/**
+	 * CursorFactory constructor.
+	 * @param Connection $connection
+	 */
+	public function __construct(Connection $connection)
+	{
+		$this->connection = $connection;
+	}
+
+	/**
+	 * Creates new instance of Cursor
+	 *
+	 * Warning: creating cursor requires to be IN transaction block.
+	 * Please enter transaction before calling create()
+	 *
+	 * @param string $sql
+	 * @param bool $scroll
+	 * @return ICursor
+	 */
+	public function create(string $sql, bool $scroll) : ICursor
+	{
+		$this->connection->query(
+			"DECLARE %n %SQL CURSOR FOR (%SQL)",
+			$name = $this->generateCursorName(),
+			$scroll ? "SCROLL" : "NO SCROLL",
+			$sql
+		);
+		
+		return new Cursor(
+			$this->connection,
+			$name
+		);
+	}
+
+	private function generateCursorName() : string
+	{
+		return uniqid();
+	}
+
+}
\ No newline at end of file
diff --git a/src/PostgresDriver/ICursorFactory.php b/src/PostgresDriver/ICursorFactory.php
new file mode 100644
index 0000000..d4f7276
--- /dev/null
+++ b/src/PostgresDriver/ICursorFactory.php
@@ -0,0 +1,11 @@
+<?php declare(strict_types = 1);
+/**
+ * This file is part of mappi/store.
+ */
+
+namespace Grifart\Mappi\Store\PostgresDriver;
+
+interface ICursorFactory
+{
+	public function create(string $sql, bool $scroll) : ICursor;
+}
\ No newline at end of file
diff --git a/tests/Store/PostgresDriver/CursorTest.phpt b/tests/Store/PostgresDriver/CursorTest.phpt
index beef539..342d2a8 100644
--- a/tests/Store/PostgresDriver/CursorTest.phpt
+++ b/tests/Store/PostgresDriver/CursorTest.phpt
@@ -7,6 +7,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\CursorFactory;
 use Tester\Assert;
 
 require_once __DIR__ . "/../../bootstrap.php";
@@ -19,7 +20,8 @@ class CursorTest extends CursorInterfaceTest
 		global $connection, $SQL_thousandRowsAscending;
 		$connection->begin();
 
-		$this->uut = new Cursor($connection, $SQL_thousandRowsAscending, true);
+		$factory = new CursorFactory($connection);
+		$this->uut = $factory->create($SQL_thousandRowsAscending, true);
 		parent::setUp();
 	}
 
diff --git a/tests/Store/PostgresDriver/TrackedCursorTest.phpt b/tests/Store/PostgresDriver/TrackedCursorTest.phpt
index 7da5bf8..4505384 100644
--- a/tests/Store/PostgresDriver/TrackedCursorTest.phpt
+++ b/tests/Store/PostgresDriver/TrackedCursorTest.phpt
@@ -7,6 +7,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\CursorFactory;
 use Grifart\Mappi\Store\PostgresDriver\TrackedCursor;
 use Tester\Assert;
 
@@ -26,8 +27,10 @@ class TrackedCursorTest extends CursorInterfaceTest
 		global $connection, $SQL_thousandRowsAscending;
 		$connection->begin();
 
-		$fastCursor = new Cursor($connection, $SQL_thousandRowsAscending, true);
-		$this->uut = new TrackedCursor($fastCursor);
+		$factory = new CursorFactory($connection);
+		$this->uut = new TrackedCursor(
+			$factory->create($SQL_thousandRowsAscending, true)
+		);
 		parent::setUp();
 	}
 
-- 
GitLab