1 | <?php |
||
39 | class DiffCommand extends GenerateCommand |
||
40 | { |
||
41 | /** |
||
42 | * @var SchemaProviderInterface |
||
43 | */ |
||
44 | protected $schemaProvider; |
||
45 | |||
46 | 5 | public function __construct(SchemaProviderInterface $schemaProvider=null) |
|
51 | |||
52 | 5 | protected function configure() |
|
74 | |||
75 | 5 | public function execute(InputInterface $input, OutputInterface $output) |
|
76 | { |
||
77 | 5 | $isDbalOld = (DbalVersion::compare('2.2.0') > 0); |
|
78 | 5 | $configuration = $this->getMigrationConfiguration($input, $output); |
|
79 | |||
80 | 5 | $conn = $configuration->getConnection(); |
|
81 | 5 | $platform = $conn->getDatabasePlatform(); |
|
82 | |||
83 | 5 | if ($filterExpr = $input->getOption('filter-expression')) { |
|
84 | if ($isDbalOld) { |
||
85 | throw new \InvalidArgumentException('The "--filter-expression" option can only be used as of Doctrine DBAL 2.2'); |
||
86 | } |
||
87 | |||
88 | $conn->getConfiguration() |
||
89 | ->setFilterSchemaAssetsExpression($filterExpr); |
||
90 | } |
||
91 | |||
92 | 5 | $fromSchema = $conn->getSchemaManager()->createSchema(); |
|
93 | 5 | $toSchema = $this->getSchemaProvider()->createSchema(); |
|
94 | |||
95 | //Not using value from options, because filters can be set from config.yml |
||
96 | 5 | if ( ! $isDbalOld && $filterExpr = $conn->getConfiguration()->getFilterSchemaAssetsExpression()) { |
|
97 | 2 | foreach ($toSchema->getTables() as $table) { |
|
98 | 2 | $tableName = $table->getName(); |
|
99 | 2 | if ( ! preg_match($filterExpr, $this->resolveTableName($tableName))) { |
|
100 | 1 | $toSchema->dropTable($tableName); |
|
101 | 1 | } |
|
102 | 2 | } |
|
103 | 2 | } |
|
104 | |||
105 | 5 | $up = $this->buildCodeFromSql($configuration, $input, $fromSchema->getMigrateToSql($toSchema, $platform)); |
|
106 | 5 | $down = $this->buildCodeFromSql($configuration, $input, $fromSchema->getMigrateFromSql($toSchema, $platform)); |
|
107 | |||
108 | 5 | if (! $up && ! $down) { |
|
109 | $output->writeln('No changes detected in your mapping information.', 'ERROR'); |
||
110 | |||
111 | return; |
||
112 | } |
||
113 | |||
114 | 5 | $version = date('YmdHis'); |
|
115 | 5 | $path = $this->generateMigration($configuration, $input, $version, $up, $down); |
|
116 | |||
117 | 5 | $output->writeln(sprintf('Generated new migration class to "<info>%s</info>" from schema differences.', $path)); |
|
118 | 5 | } |
|
119 | |||
120 | 5 | private function buildCodeFromSql(Configuration $configuration, InputInterface $input, array $sql) |
|
121 | { |
||
122 | 5 | $currentPlatform = $configuration->getConnection()->getDatabasePlatform()->getName(); |
|
123 | 5 | $code = []; |
|
124 | 5 | foreach ($sql as $query) { |
|
125 | 5 | if (stripos($query, $configuration->getMigrationsTableName()) !== false) { |
|
126 | continue; |
||
127 | } |
||
128 | |||
129 | 5 | if ($input->getOption('formatted')) { |
|
130 | 1 | if (!class_exists('\SqlFormatter')) { |
|
131 | throw new \InvalidArgumentException( |
||
132 | 'The "--formatted" option can only be used if the sql formatter is installed.'. |
||
133 | 'Please run "composer require jdorn/sql-formatter".' |
||
134 | ); |
||
135 | } |
||
136 | |||
137 | 1 | $maxLength = $input->getOption('line-length') - 18 - 8; // max - php code length - indentation |
|
138 | |||
139 | 1 | if (strlen($query) > $maxLength) { |
|
140 | 1 | $query = \SqlFormatter::format($query, false); |
|
141 | 1 | } |
|
142 | 1 | } |
|
143 | |||
144 | 5 | $code[] = sprintf("\$this->addSql(%s);", var_export($query, true)); |
|
145 | 5 | } |
|
146 | |||
147 | 5 | if (!empty($code)) { |
|
148 | 5 | array_unshift( |
|
149 | 5 | $code, |
|
150 | 5 | sprintf( |
|
151 | 5 | "\$this->abortIf(\$this->connection->getDatabasePlatform()->getName() != %s, %s);", |
|
152 | 5 | var_export($currentPlatform, true), |
|
153 | 5 | var_export(sprintf("Migration can only be executed safely on '%s'.", $currentPlatform), true) |
|
154 | 5 | ), |
|
155 | "" |
||
156 | 5 | ); |
|
157 | 5 | } |
|
158 | |||
159 | 5 | return implode("\n", $code); |
|
160 | } |
||
161 | |||
162 | 5 | private function getSchemaProvider() |
|
170 | |||
171 | /** |
||
172 | * Resolve a table name from its fully qualified name. The `$name` argument |
||
173 | * comes from Doctrine\DBAL\Schema\Table#getName which can sometimes return |
||
174 | * a namespaced name with the form `{namespace}.{tableName}`. This extracts |
||
175 | * the table name from that. |
||
176 | * |
||
177 | * @param string $name |
||
178 | * @return string |
||
179 | */ |
||
180 | 2 | private function resolveTableName($name) |
|
186 | } |
||
187 |