Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions migrations/m250707_103609_tree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

use yii\db\Migration;

class m250707_103609_tree extends Migration
{
public function safeUp()
{
$rawPrimaryKey = 'NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY';

$this->createTable(
'{{%tree}}',
[
'id' => $this->db->driverName !== 'oci' ? $this->primaryKey()->notNull() : $rawPrimaryKey,
'name' => $this->db->driverName === 'oci' ? $this->string()->notNull() : $this->text()->notNull(),
'lft' => $this->integer()->notNull(),
'rgt' => $this->integer()->notNull(),
'depth' => $this->integer()->notNull(),
],
);

$this->createIndex('idx_tree_lft', '{{%tree}}', 'lft');
$this->createIndex('idx_tree_rgt', '{{%tree}}', 'rgt');
$this->createIndex('idx_tree_depth', '{{%tree}}', 'depth');
$this->createIndex('idx_tree_lft_rgt', '{{%tree}}', ['lft', 'rgt']);

if ($this->db->driverName !== 'sqlite') {
$this->addCommentOnTable('{{%tree}}', 'Nested sets tree structure for hierarchical data');
$this->addCommentOnColumn('{{%tree}}', 'id', 'Primary key of the tree node');
$this->addCommentOnColumn('{{%tree}}', 'name', 'Name of the tree node');
$this->addCommentOnColumn('{{%tree}}', 'lft', 'Left boundary of nested set');
$this->addCommentOnColumn('{{%tree}}', 'rgt', 'Right boundary of nested set');
$this->addCommentOnColumn('{{%tree}}', 'depth', 'Node depth in the tree hierarchy');
}
}

public function safeDown()
{
$this->dropTable('{{%tree}}');
}
}
44 changes: 44 additions & 0 deletions migrations/m250707_104009_multiple_tree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

use yii\db\Migration;

class m250707_104009_multiple_tree extends Migration
{
public function safeUp()
{
$rawPrimaryKey = 'NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY';

$this->createTable(
'{{%multiple_tree}}',
[
'id' => $this->db->driverName !== 'oci' ? $this->primaryKey()->notNull() : $rawPrimaryKey,
'tree' => $this->integer()->null(),
'name' => $this->db->driverName === 'oci' ? $this->string()->notNull() : $this->text()->notNull(),
'lft' => $this->integer()->notNull(),
'rgt' => $this->integer()->notNull(),
'depth' => $this->integer()->notNull(),
],
);

$this->createIndex('idx_multiple_tree_tree', '{{%multiple_tree}}', 'tree');
$this->createIndex('idx_multiple_tree_lft', '{{%multiple_tree}}', 'lft');
$this->createIndex('idx_multiple_tree_rgt', '{{%multiple_tree}}', 'rgt');
$this->createIndex('idx_multiple_tree_depth', '{{%multiple_tree}}', 'depth');
$this->createIndex('idx_multiple_tree_tree_lft_rgt', '{{%multiple_tree}}', ['tree', 'lft', 'rgt']);

if ($this->db->driverName !== 'sqlite') {
$this->addCommentOnTable('{{%multiple_tree}}', 'Multiple nested sets tree structure for hierarchical data');
$this->addCommentOnColumn('{{%multiple_tree}}', 'tree', 'Tree identifier for multiple trees support');
$this->addCommentOnColumn('{{%multiple_tree}}', 'lft', 'Left boundary of nested set');
$this->addCommentOnColumn('{{%multiple_tree}}', 'rgt', 'Right boundary of nested set');
$this->addCommentOnColumn('{{%multiple_tree}}', 'depth', 'Node depth in the tree hierarchy');
}
}

public function safeDown()
{
$this->dropTable('{{%multiple_tree}}');
}
}
77 changes: 43 additions & 34 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
use Yii;
use yii\base\InvalidArgumentException;
use yii\console\Application;
use yii\db\{ActiveQuery, ActiveRecord, Connection, SchemaBuilderTrait};
use yii\db\{ActiveQuery, ActiveRecord, Connection, Query, SchemaBuilderTrait};
use yii2\extensions\nestedsets\tests\support\model\{MultipleTree, Tree};
use yii2\extensions\nestedsets\tests\support\stub\EchoMigrateController;

use function array_merge;
use function array_values;
Expand Down Expand Up @@ -169,44 +170,24 @@ protected function buildFlatXMLDataSet(array $dataSet): string
protected function createDatabase(): void
{
$command = $this->getDb()->createCommand();
$dropTables = [
'migration',
'multiple_tree',
'tree',
];

if ($this->getDb()->getTableSchema('tree', true) !== null) {
$command->dropTable('tree')->execute();
try {
$this->runMigrate('down', ['all']);
} catch (RuntimeException) {
}

if ($this->getDb()->getTableSchema('multiple_tree', true) !== null) {
$command->dropTable('multiple_tree')->execute();
foreach ($dropTables as $table) {
if ($this->getDb()->getTableSchema($table, true) !== null) {
$command->dropTable($table)->execute();
}
}

$primaryKey = $this->driverName === 'oci'
? 'NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'
: $this->primaryKey()->notNull();
$name = $this->driverName === 'oci'
? $this->string()->notNull()
: $this->text()->notNull();

$command->createTable(
'tree',
[
'id' => $primaryKey,
'name' => $name,
'lft' => $this->integer()->notNull(),
'rgt' => $this->integer()->notNull(),
'depth' => $this->integer()->notNull(),
],
)->execute();

$command->createTable(
'multiple_tree',
[
'id' => $primaryKey,
'tree' => $this->integer(),
'name' => $name,
'lft' => $this->integer()->notNull(),
'rgt' => $this->integer()->notNull(),
'depth' => $this->integer()->notNull(),
],
)->execute();
$this->runMigrate('up');
}

/**
Expand Down Expand Up @@ -405,6 +386,34 @@ protected function replaceQuotes(string $sql): string
};
}

/**
* @phpstan-param array<array-key, mixed> $params
*/
protected function runMigrate(string $action, array $params = []): mixed
{
$migrate = new EchoMigrateController(
'migrate',
Yii::$app,
[
'migrationPath' => dirname(__DIR__) . '/migrations',
'interactive' => false,
],
);

ob_start();
ob_implicit_flush(false);

$result = $migrate->run($action, $params);

$capture = ob_get_clean();

if (is_int($result) && $result !== 0) {
throw new RuntimeException("Migration '{$action}' failed with code {$result}.\nOutput: {$capture}");
}

return $result;
}

/**
* Applies database updates to tree nodes.
*
Expand Down
17 changes: 17 additions & 0 deletions tests/support/stub/EchoMigrateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace yii2\extensions\nestedsets\tests\support\stub;

use yii\console\controllers\MigrateController;

final class EchoMigrateController extends MigrateController
{
public function stdout($string)
{
echo $string;

return true;
}
}