Skip to content

Commit

Permalink
Merge branch 'master' into actualize_option_all
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov committed Oct 16, 2023
2 parents 4daf516 + 59f8546 commit 29e0e12
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 39 deletions.
8 changes: 8 additions & 0 deletions bin/MigrationContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Symfony\Component\Console\Application;
use Yiisoft\Db\Migration\Migrator;
use Yiisoft\Definitions\ReferencesArray;
use Yiisoft\Db\Migration\Informer\MigrationInformerInterface;
use Yiisoft\Db\Migration\Informer\NullMigrationInformer;
Expand Down Expand Up @@ -33,6 +34,13 @@ public static function definitions(): array
'updateNamespaces()' => [[]],
'updatePaths()' => [[]],
],
Migrator::class => [
'__constructor()' => [
'historyTable' => '{{%migration}}',
'migrationNameLimit' => 180,
'maxSqlOutputLength' => null,
],
],
MigrationInformerInterface::class => NullMigrationInformer::class,
];
}
Expand Down
39 changes: 19 additions & 20 deletions src/Command/CreateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
use Yiisoft\Db\Migration\Service\Generate\CreateService;
use Yiisoft\Db\Migration\Service\MigrationService;

use function file_exists;
use function file_put_contents;
use function implode;
use function in_array;
use function is_dir;
use function preg_match;
use function strlen;

Expand Down Expand Up @@ -63,6 +64,8 @@
#[AsCommand('migrate:create', 'Creates a new migration.')]
final class CreateCommand extends Command
{
private const AVAILABLE_COMMANDS = ['create', 'table', 'dropTable', 'addColumn', 'dropColumn', 'junction'];

public function __construct(
private CreateService $createService,
private MigrationService $migrationService,
Expand Down Expand Up @@ -109,15 +112,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var string $table */
$table = $input->getArgument('name');

/** @var string $command */
$command = $input->getOption('command');

$fields = $input->hasOption('fields') ? (string) $input->getOption('fields') : null;
$tableComment = $input->hasOption('table-comment') ? (string) $input->getOption('table-comment') : null;

/** @var string $and */
$and = $input->getOption('and');

if (!preg_match('/^[\w\\\\]+$/', $table)) {
$io->error(
'The migration name should contain letters, digits, underscore and/or backslash characters only.'
Expand All @@ -126,16 +120,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::INVALID;
}

$availableCommands = ['create', 'table', 'dropTable', 'addColumn', 'dropColumn', 'junction'];
/** @var string $command */
$command = $input->getOption('command');

if (!in_array($command, $availableCommands, true)) {
if (!in_array($command, self::AVAILABLE_COMMANDS, true)) {
$io->error(
"Command not found \"$command\". Available commands: " . implode(', ', $availableCommands) . '.'
"Command not found \"$command\". Available commands: " . implode(', ', self::AVAILABLE_COMMANDS) . '.'
);

return Command::INVALID;
}

/** @var string $and */
$and = $input->getOption('and');
$name = $this->generateName($command, $table, $and);

/**
Expand All @@ -154,24 +151,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$migrationPath = $this->migrationService->findMigrationPath($namespace);

$file = $migrationPath . DIRECTORY_SEPARATOR . $className . '.php';

/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');

if (!file_exists($migrationPath)) {
if (!is_dir($migrationPath)) {
$io->error("Invalid path directory $migrationPath");

return Command::INVALID;
}

/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');

$question = new ConfirmationQuestion(
"\n<fg=cyan>Create new migration y/n: </>",
false,
'/^(y)/i'
);

if ($helper->ask($input, $output, $question)) {
$fields = $input->hasOption('fields') ? (string) $input->getOption('fields') : null;
$tableComment = $input->hasOption('table-comment') ? (string) $input->getOption('table-comment') : null;

$content = $this->createService->run(
$command,
$table,
Expand All @@ -182,6 +179,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$tableComment,
);

$file = $migrationPath . DIRECTORY_SEPARATOR . $className . '.php';

file_put_contents($file, $content, LOCK_EX);

$output->writeln("\n\t<info>$className</info>");
Expand Down
8 changes: 5 additions & 3 deletions src/MigrationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
use Yiisoft\Db\Migration\Informer\MigrationInformerInterface;

use function implode;
use function ltrim;
use function microtime;
use function rtrim;
use function sprintf;
use function substr;

Expand All @@ -24,7 +26,7 @@ final class MigrationBuilder extends AbstractMigrationBuilder
public function __construct(
private ConnectionInterface $db,
private MigrationInformerInterface $informer,
private int $maxSqlOutputLength = 0
private ?int $maxSqlOutputLength = null,
) {
parent::__construct($this->db->getSchema());
}
Expand All @@ -51,8 +53,8 @@ public function getDb(): ConnectionInterface
public function execute(string $sql, array $params = []): void
{
$sqlOutput = $sql;
if (0 < $this->maxSqlOutputLength && $this->maxSqlOutputLength < strlen($sql)) {
$sqlOutput = substr($sql, 0, $this->maxSqlOutputLength) . ' [... hidden]';
if ($this->maxSqlOutputLength !== null && $this->maxSqlOutputLength < strlen($sql)) {
$sqlOutput = ltrim(rtrim(substr($sql, 0, $this->maxSqlOutputLength)) . ' [... hidden]');
}

$time = $this->beginCommand("Execute SQL: $sqlOutput");
Expand Down
4 changes: 3 additions & 1 deletion src/Migrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public function __construct(
private ConnectionInterface $db,
private MigrationInformerInterface $informer,
private string $historyTable = '{{%migration}}',
private ?int $migrationNameLimit = 180
private ?int $migrationNameLimit = 180,
private ?int $maxSqlOutputLength = null,
) {
}

Expand Down Expand Up @@ -157,6 +158,7 @@ private function createBuilder(?MigrationInformerInterface $informer = null): Mi
return new MigrationBuilder(
$this->db,
$informer ?? $this->informer,
$this->maxSqlOutputLength,
);
}
}
4 changes: 4 additions & 0 deletions src/Runner/DownRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Yiisoft\Db\Migration\Migrator;
use Yiisoft\Db\Migration\RevertibleMigrationInterface;

use function microtime;
use function sprintf;

final class DownRunner
{
private ?SymfonyStyle $io = null;
Expand Down Expand Up @@ -38,6 +41,7 @@ public function run(RevertibleMigrationInterface $migration): void
$this->migrator->down($migration);

$time = microtime(true) - $start;

$this->io->writeln(
"\n\t<info>>>> [OK] - Reverted $className (time: " . sprintf('%.3f', $time) . 's)</info>'
);
Expand Down
4 changes: 4 additions & 0 deletions src/Runner/UpdateRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Yiisoft\Db\Migration\MigrationInterface;
use Yiisoft\Db\Migration\Migrator;

use function microtime;
use function sprintf;

final class UpdateRunner
{
private ?SymfonyStyle $io = null;
Expand Down Expand Up @@ -38,6 +41,7 @@ public function run(MigrationInterface $migration): void
$this->migrator->up($migration);

$time = microtime(true) - $start;

$this->io->writeln(
"\n\t<info>>>> [OK] - Applied $className (time: " . sprintf('%.3f', $time) . 's)</info>'
);
Expand Down
38 changes: 24 additions & 14 deletions src/Service/MigrationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@
use Yiisoft\Db\Migration\Migrator;
use Yiisoft\Db\Migration\RevertibleMigrationInterface;

use function array_map;
use function array_values;
use function closedir;
use function dirname;
use function gmdate;
use function is_dir;
use function is_file;
use function ksort;
use function opendir;
use function preg_match;
use function preg_replace;
use function readdir;
use function str_contains;
use function str_replace;
use function trim;
use function ucwords;
Expand Down Expand Up @@ -117,27 +127,28 @@ public function getNewMigrations(): array

$migrations = [];
foreach ($migrationPaths as $item) {
[$updatePaths, $namespace] = $item;
$updatePaths = $this->aliases->get($updatePaths);
[$updatePath, $namespace] = $item;
$updatePath = $this->aliases->get($updatePath);

if (!file_exists($updatePaths)) {
if (!is_dir($updatePath)) {
continue;
}

$handle = opendir($updatePaths);
$handle = opendir($updatePath);
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}

$path = $updatePaths . DIRECTORY_SEPARATOR . $file;
$path = $updatePath . DIRECTORY_SEPARATOR . $file;

if (is_file($path) && preg_match('/^(M(\d{12}).*)\.php$/s', $file, $matches)) {
[, $class, $time] = $matches;

if (preg_match('/^(M(\d{12}).*)\.php$/s', $file, $matches) && is_file($path)) {
$class = $matches[1];
if (!empty($namespace)) {
$class = $namespace . '\\' . $class;
}
$time = $matches[2];

if (!isset($applied[$class])) {
$migrations[$time . '\\' . $class] = $class;
}
Expand Down Expand Up @@ -215,6 +226,7 @@ public function databaseConnection(): void
private function makeMigrationInstance(string $class): object
{
$class = trim($class, '\\');

if (!str_contains($class, '\\')) {
$isIncluded = false;
foreach ($this->updatePaths as $path) {
Expand All @@ -227,6 +239,7 @@ private function makeMigrationInstance(string $class): object
break;
}
}

if (!$isIncluded) {
throw new RuntimeException('Migration file not found.');
}
Expand Down Expand Up @@ -259,7 +272,7 @@ public function makeMigration(string $class): MigrationInterface
public function makeMigrations(array $classes): array
{
return array_map(
fn(string $class) => $this->makeMigration($class),
[$this, 'makeMigration'],
$classes
);
}
Expand All @@ -285,7 +298,7 @@ public function makeRevertibleMigration(string $class): RevertibleMigrationInter
public function makeRevertibleMigrations(array $classes): array
{
return array_map(
fn(string $class) => $this->makeRevertibleMigration($class),
[$this, 'makeRevertibleMigration'],
$classes
);
}
Expand Down Expand Up @@ -357,16 +370,13 @@ private function getPathFromNamespace(string $path): string
/** @psalm-suppress UnresolvableInclude */
$map = require $this->getVendorDir() . '/composer/autoload_psr4.php';

/**
* @psalm-var array<string, array<int, string>> $map
*/
/** @psalm-var array<string, array<int, string>> $map */
foreach ($map as $namespace => $directories) {
foreach ($directories as $directory) {
$namespacesPath[str_replace('\\', '/', trim($namespace, '\\'))] = $directory;
}
}

/** @psalm-var array<string, string> $namespacesPath */
return (new Aliases($namespacesPath))->get($path);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Common/AbstractMigrationBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ protected function assertInformerOutputContains(string $string): void
$this->assertStringContainsString($string, $this->informer->getOutput());
}

private function prepareVariables(int $maxSqlOutputLength = 0): void
private function prepareVariables(int|null $maxSqlOutputLength = null): void
{
$this->db = $this->container->get(ConnectionInterface::class);

Expand Down
42 changes: 42 additions & 0 deletions tests/Common/AbstractMigratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Migration\Informer\NullMigrationInformer;
use Yiisoft\Db\Migration\Migrator;
use Yiisoft\Db\Migration\Tests\Support\Migrations\M231015155500ExecuteSql;
use Yiisoft\Db\Migration\Tests\Support\Stub\StubMigration;
use Yiisoft\Db\Migration\Tests\Support\Stub\StubMigrationInformer;

abstract class AbstractMigratorTest extends TestCase
{
Expand Down Expand Up @@ -81,4 +83,44 @@ public function testGetMigrationNameLimitFromSchema(): void

$this->assertGreaterThan(180, $migrator->getMigrationNameLimit());
}

public function testMaxSqlOutputLength(): void
{
$informer = new StubMigrationInformer();

$migrator = new Migrator(
$this->container->get(ConnectionInterface::class),
$informer,
maxSqlOutputLength: 20,
);

$migrator->up(new M231015155500ExecuteSql());

$this->assertStringContainsString(
'Execute SQL: CREATE TABLE person [... hidden] ... Done',
$informer->getOutput(),
);

$migrator->down(new M231015155500ExecuteSql());
}

public function testZeroMaxSqlOutputLength(): void
{
$informer = new StubMigrationInformer();

$migrator = new Migrator(
$this->container->get(ConnectionInterface::class),
$informer,
maxSqlOutputLength: 0,
);

$migrator->up(new M231015155500ExecuteSql());

$this->assertStringContainsString(
'Execute SQL: [... hidden] ... Done',
$informer->getOutput(),
);

$migrator->down(new M231015155500ExecuteSql());
}
}
Loading

0 comments on commit 29e0e12

Please sign in to comment.