Developer Docs - 202 - Ignition - Data Migration Helper Methods

Creating data migrations can be a bit of a chore, but we created some migration helper methods to give you super powers. These methods will help you to add/register new blocks, add pages, add blocks to pages, add groups, add defined types, etc. So instead of writing something like this:

Sql( string.Format( @"     
DECLARE @FieldTypeId int
SET @FieldTypeId = (SELECT [Id] FROM [FieldType] WHERE [Guid] = '{1}')
DELETE [Attribute] 
WHERE [EntityTypeId] IS NULL
AND [Key] = '{2}'
AND [EntityTypeQualifierColumn] = '{8}'
AND [EntityTypeQualifierValue] = '{9}'
INSERT INTO [Attribute] ( 
    [IsSystem],[FieldTypeId],[EntityTypeId],
    [EntityTypeQualifierColumn],[EntityTypeQualifierValue],
    [Key],[Name],[Description],
    [Order],[IsGridColumn],[DefaultValue],[IsMultiValue],
    [IsRequired],[Guid])
VALUES(
    1, @FieldTypeId, NULL,
    '{8}', '{9}',
    '{2}', '{3}', '{4}',
    {5}, 0, '{6}', 0, 
    0, '{7}')
    ",
    "",
    "C28C7BF3-A552-4D77-9408-DEDCF760CED0",
    "Safe Sender Domains".Replace( " ", string.Empty ),
    "Safe Sender Domains",
    "Delimited list of domains that can be used to send emails. It's simple.".Replace( "'", "''" ),
    0,
    "",
    "CDD29C51-5D33-435F-96AB-2C06BA772F88",
    "",
    "")
);

You can just write it like this:

RockMigrationHelper.AddGlobalAttribute( "C28C7BF3-A552-4D77-9408-DEDCF760CED0", "", "", "Safe Sender Domains", "Delimited list of domains that can be used to send emails. It's simple.", 0, "", "CDD29C51-5D33-435F-96AB-2C06BA772F88" );

Helper Method Reference

We've listed all the helper methods for you by entity type for your review.

ActionTypeAttributeValue

ActionTypePersonAttributeValue

Attribute

AttributeQualifier

AttributeValue

BinaryFileType

Block

BlockAttribute

BlockAttributeValue

BlockType

BlockTypeAttribute

Category

DefinedType

DefinedTypeAttribute

DefinedValue

DefinedValueAttributeValue

DefinedValueAttributeValueByValue

DefinedValueByValue

EntityAttribute

EntityType

EntityTypeMultiValueFieldType

EntityTypeSingleValueFieldType

FieldType

GlobalAttribute

Group

GroupMemberAttributeDefinedValue

GroupType

GroupTypeGroupAttribute

GroupTypeRole

HtmlContentBlock

Layout

Page

PageContext

PageRoute

PersonAttribute

PersonAttributeCategory

PersonBadge

PersonBadgeAttribute

PersonBadgeAttributeValue

Report

ReportField

RestAction

RestController

SecurityAuth

SecurityAuthForAttribute

SecurityAuthForBinaryFileType

SecurityAuthForBlock

SecurityAuthForCategory

SecurityAuthForEntityType

SecurityAuthForGroupType

SecurityAuthForPage

SecurityAuthForRestAction

SecurityAuthForRestController

SecurityRoleGroup

Site

SystemEmail

WorkflowActionEntityAttribute

WorkflowActivityTypeAttribute

WorkflowTypeAttribute

When creating your SQL migrations be sure to watch out for the common gotchas in the next section.

Double The Quotes

Be sure to double any quotes that you have within your own SQL as seen here:

Sql( @"
  UPDATE 
     [Attribute]
  SET 
     [Description] = 'He said ""Rock"" is fun. Don''t you agree?'
  WHERE 
     [Guid] = 'ABCDEFG9-1111-2222-3333-1213456789ABC'
" );

Don't Quote Your Nulls

Just pass the null keyword as seen below:

RockMigrationHelper.UpdateGroupTypeRole( "E0C5A0E2-B7B3-4EF4-820D-BBF7F9A374EF", "Facebook Friend", "A Facebook friend.",
0, null, null, "AB69816C-4DFA-4A7A-86A5-9BFCBA6FED1E" );

Migration Generation Tools

You may find yourself creating a new page with child pages that use your new blocks, or your block may use a new custom workflow that you need to distribute with your package. Depending on the situation, creating a migration by hand can be a daunting task. We've felt that pain too and created a few more helper tools.

If you look in the Rock\Dev Tools\Sql folder, you'll notice several sql scripts that start with the prefix CodeGen*_. These scripts can help generate many of the needed MigrationHelper methods for your stuff.

For example, when executed, the CodeGen_PagesBlocksAttributesMigration_ForAPage.sql script takes the PageId parameter (which you set to the id of your choice):

DECLARE @PageId int = 226

...and outputs the needed MigrationHelper methods for the Up() and Down() methods of your migration.

// MigrationUp
// -----------
// Page: Layout Detail
RockMigrationHelper.AddPage("A2991117-0B85-4209-9008-254929C6E00F","D65F783D-87A9-4CC9-8110-E83466A0EADB","Layout Detail","","E6217A2B-B16F-4E84-BF67-795CA7F5F9AA","fa fa-th"); // Site:Rock RMS
RockMigrationHelper.UpdateBlockType("Layout Detail","Displays the details for a specific layout.","/Blocks/Cms/LayoutDetail.ascx","CMS","68B9D63D-D714-473A-89F2-62EB1602E00A");
RockMigrationHelper.UpdateBlockType("Layout Block List","Lists blocks that are on a given site layout.","/Blocks/Cms/LayoutBlockList.ascx","CMS","CD3C0C1D-2171-4FCC-B840-FC6E6F72EEEF");
RockMigrationHelper.AddBlock("E6217A2B-B16F-4E84-BF67-795CA7F5F9AA","","68B9D63D-D714-473A-89F2-62EB1602E00A","Layout Detail","Main","","",0,"C04C6905-C156-49D3-832D-D09F3B0E1BF1"); 

RockMigrationHelper.AddBlock("E6217A2B-B16F-4E84-BF67-795CA7F5F9AA","","CD3C0C1D-2171-4FCC-B840-FC6E6F72EEEF","Layout Block List","Main","","",1,"5FB1CC3B-4550-4099-8C83-044FF57CEAD8"); 

// MigrationDown
// -------------
RockMigrationHelper.DeleteBlock("5FB1CC3B-4550-4099-8C83-044FF57CEAD8");
RockMigrationHelper.DeleteBlock("C04C6905-C156-49D3-832D-D09F3B0E1BF1");
RockMigrationHelper.DeleteBlockType("CD3C0C1D-2171-4FCC-B840-FC6E6F72EEEF");
RockMigrationHelper.DeleteBlockType("68B9D63D-D714-473A-89F2-62EB1602E00A");
RockMigrationHelper.DeletePage("E6217A2B-B16F-4E84-BF67-795CA7F5F9AA"); //  Page: Layout Detail

Don't forget to really look closely at the code these scripts generate. It's always a good idea to verify that it did not include any extra bits, pages, items, etc.

You may need to experiment with each one to become familiar with how it works, but they all work similarly. Scripts like CodeGen_WorkflowTypeMigration.sql can save you tons of hours, but you need to know it works a little differently. That script outputs all Workflow related records except the ones defined in its #knownGuidsToIgnore table.