From 1a67776e1da77540b11d8523d61a700f8aa5bfdb Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 29 Oct 2011 22:56:44 +0200 Subject: [PATCH] Add Doctrine ORM Faker --- src/Faker/ORM/Doctrine/ColumnTypeGuesser.php | 48 +++++++++ src/Faker/ORM/Doctrine/EntityPopulator.php | 103 +++++++++++++++++++ src/Faker/ORM/Doctrine/Populator.php | 68 ++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 src/Faker/ORM/Doctrine/ColumnTypeGuesser.php create mode 100644 src/Faker/ORM/Doctrine/EntityPopulator.php create mode 100644 src/Faker/ORM/Doctrine/Populator.php diff --git a/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php b/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php new file mode 100644 index 00000000..3f0f6f9f --- /dev/null +++ b/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php @@ -0,0 +1,48 @@ +generator = $generator; + } + + public function guessFormat($fieldName, ClassMetadata $class) + { + $generator = $this->generator; + $type = $class->getTypeOfField($fieldName); + switch ($type) { + case 'boolean': + return function() use ($generator) { return $generator->boolean; }; + case 'decimal': + $size = isset($class->fieldMappings[$fieldName]['precision']) ? $class->fieldMappings[$fieldName]['precision'] : 2; + return function() use ($generator, $size) { return $generator->randomNumber($size + 2) / 100; }; + case 'smallint': + return function() { return mt_rand(0,65535); }; + case 'integer': + return function() { return mt_rand(0,4294967295); }; + case 'bigint': + return function() { return mt_rand(0,18446744073709551615); }; + case 'float': + return function() { return mt_rand(0,4294967295)/mt_rand(1,4294967295); }; + case 'string': + $size = isset($class->fieldMappings[$fieldName]['length']) ? $class->fieldMappings[$fieldName]['length'] : 255; + return function() use ($generator, $size) { return $generator->text($size); }; + case 'text': + return function() use ($generator) { return $generator->text; }; + case 'datetime': + case 'date': + case 'time': + return function() use ($generator) { return $generator->datetime; }; + default: + // no smart way to guess what the user expects here + return null; + } + } +} \ No newline at end of file diff --git a/src/Faker/ORM/Doctrine/EntityPopulator.php b/src/Faker/ORM/Doctrine/EntityPopulator.php new file mode 100644 index 00000000..adc06870 --- /dev/null +++ b/src/Faker/ORM/Doctrine/EntityPopulator.php @@ -0,0 +1,103 @@ +class = $class; + } + + /** + * @return string + */ + public function getClass() + { + return $this->class->getName(); + } + + public function setColumnFormatters($columnFormatters) + { + $this->columnFormatters = $columnFormatters; + } + + public function getColumnFormatters() + { + return $this->columnFormatters; + } + + public function mergeColumnFormattersWith($columnFormatters) + { + $this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters); + } + + public function guessColumnFormatters(\Faker\Generator $generator) + { + $formatters = array(); + $class = $this->class; + $nameGuesser = new \Faker\Guesser\Name($generator); + $columnTypeGuesser = new ColumnTypeGuesser($generator); + foreach ($this->class->getFieldNames() AS $fieldName) { + if ($this->class->isIdentifier($fieldName) || !$this->class->hasField($fieldName)) { + continue; + } + + if ($formatter = $nameGuesser->guessFormat($fieldName)) { + $formatters[$fieldName] = $formatter; + continue; + } + if ($formatter = $columnTypeGuesser->guessFormat($fieldName, $this->class)) { + $formatters[$fieldName] = $formatter; + continue; + } + } + + foreach ($this->class->getAssociationNames() AS $assocName) { + if (!$this->class->isIdentifier($assocName) || !$this->class->isCollectionValuedAssociation($assocName)) { + continue; + } + $relatedClass = $this->class->getAssociationTargetClass($fieldName); + $formatters[$assocName] = function($inserted) use($relatedClass) { return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null; }; + } + + return $formatters; + } + + /** + * Insert one new record using the Entity class. + */ + public function execute($con, $insertedEntities) + { + $obj = new $this->class->getName(); + foreach ($this->columnFormatters as $field => $format) { + if (null !== $field) { + $value = is_callable($format) ? $format($insertedEntities, $obj) : $format; + $this->class->reflFields[$field]->setValue($obj, $value); + } + } + $con->persist($obj); + + return $obj; + } + +} \ No newline at end of file diff --git a/src/Faker/ORM/Doctrine/Populator.php b/src/Faker/ORM/Doctrine/Populator.php new file mode 100644 index 00000000..af424abc --- /dev/null +++ b/src/Faker/ORM/Doctrine/Populator.php @@ -0,0 +1,68 @@ +generator = $generator; + $this->manager = $manager; + } + + /** + * Add an order for the generation of $number records for $entity. + * + * @param mixed $entity A Doctrine classname, or a \Faker\ORM\Doctrine\EntityPopulator instance + * @param int $number The number of entities to populate + */ + public function addEntity($entity, $number, $customColumnFormatters = array()) + { + if (!$entity instanceof \Faker\ORM\Doctrine\EntityPopulator) { + $entity = new \Faker\ORM\Doctrine\EntityPopulator($this->manager->getClassMetadata($entity)); + } + $entity->setColumnFormatters($entity->guessColumnFormatters($this->generator)); + if ($customColumnFormatters) { + $entity->mergeColumnFormattersWith($customColumnFormatters); + } + $class = $entity->getClass(); + $this->entities[$class] = $entity; + $this->quantities[$class] = $number; + } + + /** + * Populate the database using all the Entity classes previously added. + * + * @param EntityManager $entityManager A Propel connection object + * + * @return array A list of the inserted PKs + */ + public function execute($entityManager = null) + { + if (null !== $entityManager) { + $entityManager = $this->manager; + } + + $insertedEntities = array(); + foreach ($this->quantities as $class => $number) { + for ($i=0; $i < $number; $i++) { + $insertedEntities[$class][]= $this->entities[$class]->execute($entityManager, $insertedEntities); + } + } + $entityManager->flush(); + + return $insertedEntities; + } + +}