Skip to content

Commit

Permalink
Defensive migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed Sep 4, 2013
1 parent 6db7a24 commit 8e7ab7b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 72 deletions.
97 changes: 52 additions & 45 deletions src/migrations/m130910_000001_entry_types.php
Expand Up @@ -13,60 +13,67 @@ class m130910_000001_entry_types extends BaseMigration
*/
public function safeUp()
{
// Create the new entrytypes table
$this->createTable('entrytypes', array(
'sectionId' => array('column' => ColumnType::Int, 'null' => false),
'fieldLayoutId' => array('column' => ColumnType::Int),
'name' => array('column' => ColumnType::Varchar, 'null' => false),
'handle' => array('column' => ColumnType::Varchar, 'null' => false),
'titleLabel' => array('column' => ColumnType::Varchar),
));
$this->createIndex('entrytypes', 'name,sectionId', true);
$this->createIndex('entrytypes', 'handle,sectionId', true);
$this->addForeignKey('entrytypes', 'sectionId', 'sections', 'id', 'CASCADE', null);
$this->addForeignKey('entrytypes', 'fieldLayoutId', 'fieldlayouts', 'id', 'SET NULL', null);
if (!craft()->db->tableExists('entrytypes'))
{
// Create the new entrytypes table
$this->createTable('entrytypes', array(
'sectionId' => array('column' => ColumnType::Int, 'null' => false),
'fieldLayoutId' => array('column' => ColumnType::Int),
'name' => array('column' => ColumnType::Varchar, 'null' => false),
'handle' => array('column' => ColumnType::Varchar, 'null' => false),
'titleLabel' => array('column' => ColumnType::Varchar),
));
$this->createIndex('entrytypes', 'name,sectionId', true);
$this->createIndex('entrytypes', 'handle,sectionId', true);
$this->addForeignKey('entrytypes', 'sectionId', 'sections', 'id', 'CASCADE', null);
$this->addForeignKey('entrytypes', 'fieldLayoutId', 'fieldlayouts', 'id', 'SET NULL', null);

// Add the 'typeId' column to the entries table
$this->addColumnAfter('entries', 'typeId', array('column' => ColumnType::Int), 'sectionId');
// Add the 'typeId' column to the entries table
$this->addColumnAfter('entries', 'typeId', array('column' => ColumnType::Int), 'sectionId');

// Create an entry type for each section
// Create an entry type for each section

$sections = craft()->db->createCommand()
->select('id, fieldLayoutId, name, handle, titleLabel')
->from('sections')
->queryAll();
$sections = craft()->db->createCommand()
->select('id, fieldLayoutId, name, handle, titleLabel')
->from('sections')
->queryAll();

foreach ($sections as $section)
{
$this->insert('entrytypes', array(
'sectionId' => $section['id'],
'fieldLayoutId' => $section['fieldLayoutId'],
'name' => $section['name'],
'handle' => $section['handle'],
'titleLabel' => $section['titleLabel']
));
foreach ($sections as $section)
{
$this->insert('entrytypes', array(
'sectionId' => $section['id'],
'fieldLayoutId' => $section['fieldLayoutId'],
'name' => $section['name'],
'handle' => $section['handle'],
'titleLabel' => $section['titleLabel']
));

$entryTypeId = craft()->db->getLastInsertID();
$entryTypeId = craft()->db->getLastInsertID();

// Update the existing entries
$this->update('entries', array(
'typeId' => $entryTypeId
), array(
'sectionId' => $section['id']
));
}
// Update the existing entries
$this->update('entries', array(
'typeId' => $entryTypeId
), array(
'sectionId' => $section['id']
));
}

// Why not.
$this->delete('entries', 'typeId = 0');
// Why not.
$this->delete('entries', 'typeId = 0');

// Now add the index and FK
$this->createIndex('entries', 'typeId', false);
$this->addForeignKey('entries', 'typeId', 'entrytypes', 'id', 'CASCADE', null);
// Now add the index and FK
$this->createIndex('entries', 'typeId', false);
$this->addForeignKey('entries', 'typeId', 'entrytypes', 'id', 'CASCADE', null);

// Now delete the old sections.fieldLayoutId and titleLabel columns
MigrationHelper::dropForeignKeyIfExists('sections', array('fieldLayoutId'));
$this->dropColumn('sections', 'fieldLayoutId');
$this->dropColumn('sections', 'titleLabel');
// Now delete the old sections.fieldLayoutId and titleLabel columns
MigrationHelper::dropForeignKeyIfExists('sections', array('fieldLayoutId'));
$this->dropColumn('sections', 'fieldLayoutId');
$this->dropColumn('sections', 'titleLabel');
}
else
{
Craft::log('Tried to add the `entrytypes` table, but it already exists.', LogLevel::Warning, true);
}

return true;
}
Expand Down
59 changes: 32 additions & 27 deletions src/migrations/m130910_000002_section_types.php
Expand Up @@ -13,34 +13,39 @@ class m130910_000002_section_types extends BaseMigration
*/
public function safeUp()
{
// Add the type and maxDepth columns to the sections table
$this->addColumnAfter('sections', 'type', array('column' => ColumnType::Enum, 'values' => array(SectionType::Single, SectionType::Channel, SectionType::Structure), 'default' => SectionType::Channel, 'null' => false), 'handle');
$this->addColumnAfter('sections', 'maxDepth', array('column' => ColumnType::Int, 'maxLength' => 11, 'decimals' => 0, 'default' => 1, 'unsigned' => true, 'length' => 10), 'template');

// Add the 'nestedUrlFormat' column to the sections_i18n table
$this->addColumnAfter('sections_i18n', 'nestedUrlFormat', array('column' => ColumnType::Varchar), 'urlFormat');

// entries.authorId is no longer required, since Singles don't have an author
$this->alterColumn('entries', 'authorId', array('column' => ColumnType::Int));

// Add the parentId column to entries
$this->addColumnAfter('entries', 'parentId', array('column' => ColumnType::Int), 'sectionId');
$this->addForeignKey('entries', 'parentId', 'entries', 'id', 'CASCADE', null);

// Add the hierarchy columns to the entries table
$cols = array(
'root' => array('column' => ColumnType::Int, 'unsigned' => true),
'lft' => array('column' => ColumnType::Int, 'unsigned' => true),
'rgt' => array('column' => ColumnType::Int, 'unsigned' => true),
'depth' => array('column' => ColumnType::SmallInt, 'unsigned' => true),
);
$lastCol = 'typeId';

foreach ($cols as $name => $type)
$sectionsTable = $this->dbConnection->schema->getTable('{{sections}}');

if ($sectionsTable->getColumn('type') === null)
{
$this->addColumnAfter('entries', $name, $type, $lastCol);
$this->createIndex('entries', $name, false);
$lastCol = $name;
// Add the type and maxDepth columns to the sections table
$this->addColumnAfter('sections', 'type', array('column' => ColumnType::Enum, 'values' => array(SectionType::Single, SectionType::Channel, SectionType::Structure), 'default' => SectionType::Channel, 'null' => false), 'handle');
$this->addColumnAfter('sections', 'maxDepth', array('column' => ColumnType::Int, 'maxLength' => 11, 'decimals' => 0, 'default' => 1, 'unsigned' => true, 'length' => 10), 'template');

// Add the 'nestedUrlFormat' column to the sections_i18n table
$this->addColumnAfter('sections_i18n', 'nestedUrlFormat', array('column' => ColumnType::Varchar), 'urlFormat');

// entries.authorId is no longer required, since Singles don't have an author
$this->alterColumn('entries', 'authorId', array('column' => ColumnType::Int));

// Add the parentId column to entries
$this->addColumnAfter('entries', 'parentId', array('column' => ColumnType::Int), 'sectionId');
$this->addForeignKey('entries', 'parentId', 'entries', 'id', 'CASCADE', null);

// Add the hierarchy columns to the entries table
$cols = array(
'root' => array('column' => ColumnType::Int, 'unsigned' => true),
'lft' => array('column' => ColumnType::Int, 'unsigned' => true),
'rgt' => array('column' => ColumnType::Int, 'unsigned' => true),
'depth' => array('column' => ColumnType::SmallInt, 'unsigned' => true),
);
$lastCol = 'typeId';

foreach ($cols as $name => $type)
{
$this->addColumnAfter('entries', $name, $type, $lastCol);
$this->createIndex('entries', $name, false);
$lastCol = $name;
}
}

return true;
Expand Down

0 comments on commit 8e7ab7b

Please sign in to comment.