diff --git a/docs/en/seeding.rst b/docs/en/seeding.rst index 9569b9cc6..f90374aea 100644 --- a/docs/en/seeding.rst +++ b/docs/en/seeding.rst @@ -138,7 +138,7 @@ within your seed class and then use the `insert()` method to insert data: ],[ 'body' => 'bar', 'created' => date('Y-m-d H:i:s'), - ] + ], ]; $posts = $this->table('posts'); @@ -193,6 +193,21 @@ Then use it in your seed classes: } } +Executing seeds only once +------------------------- + +If you want to make sure your seed data doesn't get added multiple times, a +basic check on if the table is empty or contains already some data can help. + +.. code-block:: php + public function run() + { + if ($this->hasData('posts')) { + return; + } + ... + } + Truncating Tables ----------------- diff --git a/src/Phinx/Seed/AbstractSeed.php b/src/Phinx/Seed/AbstractSeed.php index ee259f4c0..867925fde 100644 --- a/src/Phinx/Seed/AbstractSeed.php +++ b/src/Phinx/Seed/AbstractSeed.php @@ -162,11 +162,21 @@ public function fetchAll($sql) */ public function insert($table, $data) { - // convert to table object - if (is_string($table)) { - $table = new Table($table, [], $this->getAdapter()); - } - $table->insert($data)->save(); + $tableInstance = new Table($table, [], $this->getAdapter()); + $tableInstance->insert($data)->save(); + } + + /** + * @param string $tableName + * + * @return bool + */ + public function hasData(string $tableName): bool + { + $countQuery = $this->getAdapter()->query('SELECT COUNT(*) FROM ' . $tableName); + $res = $countQuery->fetchAll(); + + return $res[0]['count'] > 0; } /** diff --git a/tests/Phinx/Seed/SeedTest.php b/tests/Phinx/Seed/SeedTest.php new file mode 100644 index 000000000..7288819c1 --- /dev/null +++ b/tests/Phinx/Seed/SeedTest.php @@ -0,0 +1,59 @@ +getMockBuilder(PDOStatement::class)->disableOriginalConstructor()->getMock(); + $queryStub->expects($this->once()) + ->method('fetchAll') + ->will($this->returnValue([0 => ['count' => 0]])); + + $adapterStub = $this->getMockBuilder(PdoAdapter::class) + ->setConstructorArgs([[]]) + ->getMock(); + $adapterStub->expects($this->once()) + ->method('query') + ->will($this->returnValue($queryStub)); + + $stub = $this->getMockForAbstractClass(AbstractSeed::class); + $stub->setAdapter($adapterStub); + $result = $stub->hasData('foo'); + + $this->assertFalse($result); + } + + /** + * @return void + */ + public function testHasDataTrue(): void + { + $queryStub = $this->getMockBuilder(PDOStatement::class)->disableOriginalConstructor()->getMock(); + $queryStub->expects($this->once()) + ->method('fetchAll') + ->will($this->returnValue([0 => ['count' => 1]])); + + $adapterStub = $this->getMockBuilder(PdoAdapter::class) + ->setConstructorArgs([[]]) + ->getMock(); + $adapterStub->expects($this->once()) + ->method('query') + ->will($this->returnValue($queryStub)); + + $stub = $this->getMockForAbstractClass(AbstractSeed::class); + $stub->setAdapter($adapterStub); + $result = $stub->hasData('foo'); + + $this->assertTrue($result); + } +}