Skip to content

Commit

Permalink
Merge pull request #126 from ushahidi/add-pdo-reader
Browse files Browse the repository at this point in the history
Add PdoReader
  • Loading branch information
ddeboer committed Jan 22, 2015
2 parents 6222a8f + 694cf21 commit c06703d
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 0 deletions.
126 changes: 126 additions & 0 deletions src/Ddeboer/DataImport/Reader/PdoReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php
namespace Ddeboer\DataImport\Reader;

/**
* Reads data through PDO
*/
class PdoReader implements ReaderInterface
{
/**
* @var \PDO
*/
protected $pdo;

/**
* @var string
*/
protected $tableName;

/**
* @var \PDOStatement
*/
protected $statement;

/**
* @var array
*/
private $data;

/**
* Constructor
*
* @param PDO $pdo Database connection
* @param string $sql SQL statement
* @param array $params SQL statement parameters
*/
public function __construct(\PDO $pdo, $sql, array $params = array())
{
$this->pdo = $pdo;
$this->statement = $this->pdo->prepare($sql);

foreach ($params as $key => $value) {
$this->statement->bindValue($key, $value);
}
}

/**
* {@inheritdoc}
*/
public function getFields()
{
if ($this->statement->execute()) {
// Statement executed successfully
// Grab the first row to find keys
$row = $this->statement->fetch(\PDO::FETCH_ASSOC);
// Return field keys, or empty array no rows remain
return array_keys($row ? $row : array());
} else {
// If the statement errors return empty
return array();
}
}

/**
* {@inheritdoc}
*/
public function current()
{
return current($this->data);
}

/**
* {@inheritdoc}
*/
public function next()
{
next($this->data);
}

/**
* {@inheritdoc}
*/
public function key()
{
return key($this->data);
}

/**
* {@inheritdoc}
*/
public function valid()
{
$key = key($this->data);

return ($key !== null && $key !== false);
}

/**
* {@inheritdoc}
*/
public function rewind()
{
$this->loadData();
reset($this->data);
}

/**
* {@inheritdoc}
*/
public function count()
{
$this->loadData();

return count($this->data);
}

/**
* Load data if it hasn't been loaded yet
*/
protected function loadData()
{
if (null === $this->data) {
$this->statement->execute();
$this->data = $this->statement->fetchAll(\PDO::FETCH_ASSOC);
}
}
}
91 changes: 91 additions & 0 deletions tests/Ddeboer/DataImport/Tests/Reader/PdoReaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace Ddeboer\DataImport\Tests\Reader;

use Ddeboer\DataImport\Reader\PdoReader;
// use Doctrine\DBAL\Configuration;
// use Doctrine\DBAL\DriverManager;
// use Doctrine\DBAL\Platforms\SqlitePlatform;

class PdoReaderTest extends \PHPUnit_Framework_TestCase
{
public function testGetFields()
{
$fields = $this->getReader()->getFields();
$this->assertInternalType('array', $fields);
$this->assertEquals(array('id', 'username', 'name'), $fields);
}

public function testCount()
{
$this->assertEquals(100, $this->getReader()->count());
}

public function testIterate()
{
$i=1;
foreach ($this->getReader() as $row) {
$this->assertInternalType('array', $row);
$this->assertEquals('user-'.$i, $row['username']);
$i++;
}
}

public function testReaderRewindWorksCorrectly()
{
$reader = $this->getReader();
foreach ($reader as $row) {
}

foreach ($reader as $row) {
}
}

public function getConnection()
{
$connection = new \PDO('sqlite::memory:');
// Set error mode = exception for easy debugging
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

// Build schema
$connection->query('CREATE TABLE pdo_group (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(45)
)');

$connection->query('CREATE TABLE pdo_user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(32),
group_id INTEGER,
FOREIGN KEY(group_id) REFERENCES pdo_group(id)
)');
$connection->query('CREATE UNIQUE INDEX user_username ON pdo_user(username)');

return $connection;
}

protected function getReader()
{
$connection = $this->getConnection();

$group_insert = $connection->prepare('INSERT INTO pdo_group (name) VALUES (:name)');
$user_insert = $connection->prepare('INSERT INTO pdo_user (username, group_id) VALUES (:username, :group)');

$counter = 1;
for ($i = 1; $i <= 10; $i++) {
$group_insert->execute(array(':name' => "name {$i}"));
$id = $connection->lastInsertId();

for ($j = 1; $j <= 10; $j++) {
$user_insert->execute(array(
':username' => "user-{$counter}",
':group' => $id
));

$counter++;
}
}

return new PdoReader($connection, 'SELECT u.id, u.username, g.name FROM `pdo_user` u INNER JOIN `pdo_group` g ON u.group_id = g.id');
}
}

0 comments on commit c06703d

Please sign in to comment.