mirror of
https://github.com/fzaninotto/Faker.git
synced 2025-03-20 23:39:51 +01:00
Refactor Propel ORM populator
This commit is contained in:
parent
844c782436
commit
ec5d905c48
@ -1,83 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Faker\ORM;
|
||||
|
||||
include __DIR__ . '/../Guesser/Name.php';
|
||||
|
||||
class Propel
|
||||
{
|
||||
protected $class;
|
||||
protected $columnFormatters = array();
|
||||
|
||||
public static function populateClasses($generator, $classes)
|
||||
{
|
||||
$entities = array();
|
||||
foreach ($classes as $class => $number) {
|
||||
$populator = new self($class);
|
||||
$populator->setColumnFormatters($populator->guessColumnFormatters($generator));
|
||||
$populator->populate($number, $entities);
|
||||
}
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
public function __construct($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function setColumnFormatters($columnFormatters)
|
||||
{
|
||||
$this->columnFormatters = array_merge($columnFormatters, $this->columnFormatters);
|
||||
}
|
||||
|
||||
public function guessColumnFormatters(\Faker\Generator $generator)
|
||||
{
|
||||
$formatters = array();
|
||||
$class = $this->class;
|
||||
$peerClass = $class::PEER;
|
||||
$tableMap = $peerClass::getTableMap();
|
||||
$nameGuesser = new \Faker\Guesser\Name($generator);
|
||||
foreach ($tableMap->getColumns() as $columnMap) {
|
||||
if ($columnMap->isForeignKey()) {
|
||||
$relatedClass = $columnMap->getRelation()->getForeignTable()->getPhpName();
|
||||
$formatters[$columnMap->getPhpName()] = function($inserted) use($relatedClass) { return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null; };
|
||||
continue;
|
||||
}
|
||||
if ($columnMap->isPrimaryKey()) {
|
||||
continue;
|
||||
}
|
||||
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName())) {
|
||||
$formatters[$columnMap->getPhpName()] = $formatter;
|
||||
continue;
|
||||
}
|
||||
// TODO: PropelColumnTypeGuesser
|
||||
}
|
||||
return $formatters;
|
||||
}
|
||||
|
||||
public function populate($nb = 100, &$insertedEntities = array())
|
||||
{
|
||||
$pks = array();
|
||||
$class = $this->class;
|
||||
$peer = $class::PEER;
|
||||
$con = \Propel::getConnection($peer::DATABASE_NAME, \Propel::CONNECTION_WRITE);
|
||||
$con->beginTransaction();
|
||||
for ($i=0; $i < $nb; $i++) {
|
||||
$insertedEntities[$this->class][]= $this->populateOne($con, $insertedEntities);
|
||||
}
|
||||
$con->commit();
|
||||
}
|
||||
|
||||
public function populateOne($con, $insertedEntities)
|
||||
{
|
||||
$obj = new $this->class();
|
||||
foreach ($this->columnFormatters as $column => $format) {
|
||||
if (null !== $column) {
|
||||
$obj->setByName($column, is_callable($format) ? $format($insertedEntities) : $format);
|
||||
}
|
||||
}
|
||||
$obj->save($con);
|
||||
return $obj->getPrimaryKey();
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Faker\ORM\Propel;
|
||||
|
||||
include __DIR__ . '/../../Guesser/Name.php';
|
||||
|
||||
/**
|
||||
* Service class for populating a table through a Propel ActiveRecord class.
|
||||
*/
|
||||
class EntityPopulator
|
||||
{
|
||||
protected $class;
|
||||
protected $columnFormatters = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $class A Propel ActiveRecord classname
|
||||
*/
|
||||
public function __construct($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function setColumnFormatters($columnFormatters)
|
||||
{
|
||||
$this->columnFormatters = array_merge($columnFormatters, $this->columnFormatters);
|
||||
}
|
||||
|
||||
public function getColumnFormatters()
|
||||
{
|
||||
return $this->columnFormatters;
|
||||
}
|
||||
|
||||
public function guessColumnFormatters(\Faker\Generator $generator)
|
||||
{
|
||||
$formatters = array();
|
||||
$class = $this->class;
|
||||
$peerClass = $class::PEER;
|
||||
$tableMap = $peerClass::getTableMap();
|
||||
$nameGuesser = new \Faker\Guesser\Name($generator);
|
||||
foreach ($tableMap->getColumns() as $columnMap) {
|
||||
if ($columnMap->isForeignKey()) {
|
||||
$relatedClass = $columnMap->getRelation()->getForeignTable()->getPhpName();
|
||||
$formatters[$columnMap->getPhpName()] = function($inserted) use($relatedClass) { return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null; };
|
||||
continue;
|
||||
}
|
||||
if ($columnMap->isPrimaryKey()) {
|
||||
continue;
|
||||
}
|
||||
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName())) {
|
||||
$formatters[$columnMap->getPhpName()] = $formatter;
|
||||
continue;
|
||||
}
|
||||
// TODO: PropelColumnTypeGuesser
|
||||
}
|
||||
return $formatters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert one new record using the Entity class.
|
||||
*/
|
||||
public function execute($con, $insertedEntities)
|
||||
{
|
||||
$obj = new $this->class();
|
||||
foreach ($this->columnFormatters as $column => $format) {
|
||||
if (null !== $column) {
|
||||
$obj->setByName($column, is_callable($format) ? $format($insertedEntities) : $format);
|
||||
}
|
||||
}
|
||||
$obj->save($con);
|
||||
|
||||
return $obj->getPrimaryKey();
|
||||
}
|
||||
|
||||
}
|
71
src/Faker/ORM/Propel/Populator.php
Normal file
71
src/Faker/ORM/Propel/Populator.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Faker\ORM\Propel;
|
||||
|
||||
require_once __DIR__ . '/EntityPopulator.php';
|
||||
|
||||
/**
|
||||
* Service class for populating a database using the Propel ORM.
|
||||
* A Populator can populate several tables using ActiveRecord classes.
|
||||
*/
|
||||
class Populator
|
||||
{
|
||||
protected $generator;
|
||||
protected $entities;
|
||||
protected $quantities;
|
||||
|
||||
public function __construct(\Faker\Generator $generator)
|
||||
{
|
||||
$this->generator = $generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an order for the generation of $number records for $entity.
|
||||
*
|
||||
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance
|
||||
* @param int $number The number of entities to populate
|
||||
*/
|
||||
public function addEntity($entity, $number)
|
||||
{
|
||||
if (!$entity instanceof \Faker\ORM\Propel\EntityPopulator) {
|
||||
$entity = new \Faker\ORM\Propel\EntityPopulator($entity);
|
||||
}
|
||||
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
|
||||
$class = $entity->getClass();
|
||||
$this->entities[$class] = $entity;
|
||||
$this->quantities[$class] = $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the database using all the Entity classes previously added.
|
||||
*
|
||||
* @param PropelPDO $con A Propel connection object
|
||||
*
|
||||
* @return array A list of the inserted PKs
|
||||
*/
|
||||
public function execute($con = null)
|
||||
{
|
||||
if (null === $con) {
|
||||
$con = $this->getConnection();
|
||||
}
|
||||
$insertedEntities = array();
|
||||
$con->beginTransaction();
|
||||
foreach ($this->quantities as $class => $number) {
|
||||
for ($i=0; $i < $number; $i++) {
|
||||
$insertedEntities[$class][]= $this->entities[$class]->execute($con, $insertedEntities);
|
||||
}
|
||||
}
|
||||
$con->commit();
|
||||
|
||||
return $insertedEntities;
|
||||
}
|
||||
|
||||
protected function getConnection()
|
||||
{
|
||||
// use the first connection available
|
||||
$class = key($this->entities);
|
||||
$peer = $class::PEER;
|
||||
return \Propel::getConnection($peer::DATABASE_NAME, \Propel::CONNECTION_WRITE);
|
||||
}
|
||||
|
||||
}
|
@ -4,15 +4,15 @@ require_once dirname(__FILE__) . '/../../Propel/runtime/lib/Propel.php';
|
||||
set_include_path(dirname(__FILE__) . '/../../Propel/test/fixtures/bookstore/build/classes' . PATH_SEPARATOR . get_include_path());
|
||||
Propel::init(dirname(__FILE__) . '/../../Propel/test/fixtures/bookstore/build/conf/bookstore-conf.php');
|
||||
|
||||
require_once '../src/Faker/ORM/Propel.php';
|
||||
require_once '../src/Faker/ORM/Propel/Populator.php';
|
||||
require_once '../src/Faker/Factory.php';
|
||||
|
||||
BookQuery::create()->deleteAll();
|
||||
AuthorQuery::create()->deleteAll();
|
||||
|
||||
$inserted = Faker\ORM\Propel::populateClasses(Faker\Factory::create(), array(
|
||||
'Author' => 5,
|
||||
'Book' => 10
|
||||
));
|
||||
$generator = \Faker\Factory::create();
|
||||
$populator = new Faker\ORM\Propel\Populator($generator);
|
||||
$populator->addEntity('Author', 5);
|
||||
$populator->addEntity('Book', 10);
|
||||
$insertec = $populator->execute();
|
||||
|
||||
echo BookQuery::create()->joinWith('Book.Author')->find();
|
Loading…
x
Reference in New Issue
Block a user