私はこれを解決しました。解決策はそれほど素晴らしいものではありませんが、それでも、他の人にとっては役立つと思います。私はCLIを使用しています。実際、すべての移行でデータベース内の番号を更新するファイルを作成しました。これは、この質問をする前のTimoの回答と同様ですが、それでもあまり効果的ではありませんが、とにかく行う価値があります。
私が次に行ったことは、問題を解決し
doctrine/lib/Doctrine/Migration/Builder.php
ます。531行目に進みます。すべての移行が拡張するデフォルトのクラスの定義があります。CLIを使用していて、この場所にパラメーターを渡す方法が見つからなかったため、以下Doctrine_Migration_Base
の別のクラスMY_Doctrine_Migration_Base
に置き換えました。
CLIを使用していない場合は、ソースを置き換えるのではなく、オプションを渡すようにしてください。
したがって、以下のクラスはDoctrine_Migration_Base
、一連のメソッドを拡張して上書きし、変更を加えてもよいかどうかを確認してから、親メソッドを呼び出して変更を行います。現在すべてのメソッドを網羅しているわけではなく、これを書いたときに遭遇したメソッドだけを網羅しています。
これで、Doctrineが作成するすべての移行により、最初に述べた問題を防ぐことを目的としたクラスが拡張されます。
<?php
class MY_Doctrine_Migration_Base extends Doctrine_Migration_Base {
public function __construct() {
$this->connection = Doctrine_Manager::getInstance()->getCurrentConnection();
}
public function addIndex($tableName, $indexName, array $definition) {
foreach ($this->connection->execute("SHOW INDEXES IN $tableName")->fetchAll(PDO::FETCH_ASSOC) as $index) {
if ($index['Key_name'] === $indexName.'_idx') {
echo "Index $indexName already exists in table $tableName. Skipping\n";
return;
}
}
parent::addIndex($tableName, $indexName, $definition);
}
public function removeColumn($tableName, $columnName) {
if ($this->column_exists($tableName, $columnName)) {
parent::removeColumn($tableName, $columnName);
} else {
echo "Column $columnName doesn't exist in $tableName. Can't drop\n";
}
}
public function createTable($tableName, array $fields = array(), array $options = array()) {
if ($this->connection->execute("SHOW TABLES LIKE '$tableName'")->fetchAll(PDO::FETCH_ASSOC)) {
echo "Table $tableName already exists. Can't create\n";
} else {
parent::createTable($tableName, $fields, $options);
}
}
public function addColumn($tableName, $columnName, $type, $length = null, array $options = array()) {
if (! $this->column_exists($tableName, $columnName)) {
parent::addColumn($tableName, $columnName, $type, $length, $options);
} else {
echo "Column $columnName already exists in $tableName. Can't add\n";
}
}
private function column_exists($tableName, $columnName) {
$exception = FALSE;
try { //parsing information_schema sucks because security will hurt too bad if we have access to it. This lame shit is still better
$this->connection->execute("SELECT $columnName FROM $tableName")->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $exception) {}
//if someone knows how to check for column existence without exceptions AND WITHOUT INFORMATION SCHEMA please rewrite this stuff
return $exception === FALSE;
}
}
これを改善する方法についての提案を歓迎します。