Ejemplo n.º 1
0
        /// <summary>
        /// Rebinds the currently-run migrations to the migrations grid.
        /// </summary>
        private void BindGrid()
        {
            var qry = new PluginMigrationService(new RockContext()).Queryable()
                      .Where(m => !m.PluginAssemblyName.StartsWith("Rock"))
                      .OrderBy(m => m.PluginAssemblyName)
                      .ThenByDescending(m => m.MigrationNumber);

            gMigrations.DataSource   = qry.ToList();
            gMigrations.EntityTypeId = EntityTypeCache.Read <PluginMigration>().Id;
            gMigrations.DataBind();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Executes a rollback of the given migration (after rolling back all dependent migrations).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void mdRollbackConfirm_DoRollback(object sender, EventArgs e)
        {
            int migrationDbKey = 0;

            if (!Int32.TryParse(hfRollbackId.Value, out migrationDbKey))
            {
                return;
            }

            PluginMigration migration = new PluginMigrationService(new RockContext()).Get(migrationDbKey);

            if (migration == null)
            {
                return;
            }

            // run the rollbacks
            var migrationTypes = GetMigrationsThatCanBeRolledBack(
                migration.PluginAssemblyName,
                migration.MigrationNumber
                );
            Exception rollbackError = null;

            try
            {
                RollbackMigrations(migrationTypes);
            }
            catch (Exception ex)
            {
                rollbackError = ex;
            }

            // reset the UI
            mdRollbackConfirm.Hide();
            hfRollbackId.Value = null;

            // show success/fail message
            if (rollbackError == null)
            {
                maRollbackStatus.Show("All rollbacks successful.", ModalAlertType.Information);
            }
            else
            {
                string error = "There was an error rolling back a migration. " +
                               "Check the exception log for more details. The migration has not been rolled back.";
                // TODO include exception message (can't right now--bug with string.EscapeQuotes() causes
                // the Rock:ModalAlert to issue a JS parse error)
                maRollbackStatus.Show(error, ModalAlertType.Warning);
            }

            BindGrid();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// The commands to run to migrate plugin to the specific version
        /// </summary>
        public override void Up()
        {
            var migrateNamespace = false;
            var oldNamespace     = "com.kfs.FTPStorageProvider";

            // check if migration has previously run
            using (var rockContext = new RockContext())
            {
                var migrationNumber = (System.Attribute.GetCustomAttribute(this.GetType(), typeof(MigrationNumberAttribute)) as MigrationNumberAttribute).Number;
                migrateNamespace = new PluginMigrationService(rockContext)
                                   .Queryable()
                                   .Where(m => m.PluginAssemblyName.Equals(oldNamespace, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                   .Any();
            }

            if (migrateNamespace)
            {
                Sql(@"
                    IF EXISTS ( SELECT [Id] FROM [EntityType] WHERE [Guid] = 'DB311F90-0415-4F83-8E61-16BE12C1F89B' )
                    BEGIN
                        UPDATE [EntityType]
                        SET [Name] = 'rocks.kfs.Storage.Provider.FTP.FTPStorage'
                        WHERE [Guid] = 'DB311F90-0415-4F83-8E61-16BE12C1F89B'
                    END
                ");
            }
            else
            {
                RockMigrationHelper.UpdateEntityType("rocks.kfs.Storage.Provider.FTP.FTPStorage", "DB311F90-0415-4F83-8E61-16BE12C1F89B", false, true);
                RockMigrationHelper.AddEntityAttribute("Rock.Model.BinaryFileType", "9C204CD0-1233-41C5-818A-C5DA439445AA", "StorageEntityTypeId", "0", "FTP Address", "", "Folder to which selected file will be uploaded. Note, the folder must exist on the FTP server. Example: 'ftp://ftp.mysite.com/audio/weekend/'", 0, "", "CC215A28-869A-4713-9AE4-9282562F59FD", null);
                RockMigrationHelper.AddEntityAttribute("Rock.Model.BinaryFileType", "36167F3E-8CB2-44F9-9022-102F171FBC9A", "StorageEntityTypeId", "0", "Username", "", "The Username to authenticate with.", 1, "", "6B78A006-C8CD-4420-B7FA-08800384402E", null);
                RockMigrationHelper.AddEntityAttribute("Rock.Model.BinaryFileType", "36167F3E-8CB2-44F9-9022-102F171FBC9A", "StorageEntityTypeId", "0", "Password", "", "The Password to authenticate with.", 2, "", "9B1425A7-6C65-4C87-AB72-AF508A4FF173", null);
                RockMigrationHelper.AddEntityAttribute("Rock.Model.BinaryFileType", "C0D0D7E2-C3B0-4004-ABEA-4BBFAD10D5D2", "StorageEntityTypeId", "0", "Public Access URL", "", "The public URL of the content folder. Example: 'https://www.mysite.com/ftp/audio/weekend/'", 3, "", "9F77C47E-D56A-498D-871D-D63A27E1E88C", null);

                Sql(@"
                    DECLARE @FTPStorageId int = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = 'DB311F90-0415-4F83-8E61-16BE12C1F89B' )
                    UPDATE [Attribute] SET [EntityTypeQualifierValue] = CAST(@FTPStorageId as varchar)
                    WHERE [Guid] IN ( 'CC215A28-869A-4713-9AE4-9282562F59FD', '6B78A006-C8CD-4420-B7FA-08800384402E', '9B1425A7-6C65-4C87-AB72-AF508A4FF173', '9F77C47E-D56A-498D-871D-D63A27E1E88C' )
                ");

                RockMigrationHelper.UpdateAttributeQualifier("9B1425A7-6C65-4C87-AB72-AF508A4FF173", "ispassword", "True", "BCAD2656-AB88-4120-954D-0C96142309F7");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Shows a dialog asking the user to confirm if they'd like to roll back the specified migration(s).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void gMigrations_ConfirmRollback(object sender, RowEventArgs e)
        {
            // determine the migrations that'll be rolled back
            int             migrationDbKey = (int)e.RowKeyValue;
            PluginMigration migration      = new PluginMigrationService(new RockContext()).Get(migrationDbKey);
            var             migrationTypes = GetMigrationsThatCanBeRolledBack(
                migration.PluginAssemblyName,
                migration.MigrationNumber
                );

            // populate the modal's contents
            hfRollbackId.Value = migrationDbKey.ToString();
            string warning = "<p>This will rollback the following migrations:</p>";

            warning += MigrationTypesToHtmlList(migrationTypes);
            warning += "<p>Are you sure you want to do this?</p>";
            nbRollbackInfo.Title = warning;
            mdRollbackConfirm.Show();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Rolls back the given migration type. That is, executes the Down() method on the migration and
        /// updates the plugin migrations table to show the migration isn't currently applied to the database.
        /// </summary>
        /// <param name="migrationType">The migration type to roll back.</param>
        /// <param name="con">The database connection on which to execute the rollback.</param>
        private void RollbackMigration(Type migrationType, SqlConnection con)
        {
            using (var sqlTxn = con.BeginTransaction())
            {
                bool transactionActive = true;
                try
                {
                    // Create an instance of the migration and run the down action
                    var migration = Activator.CreateInstance(migrationType) as Migration;
                    migration.SqlConnection  = con;
                    migration.SqlTransaction = sqlTxn;
                    migration.Down();
                    sqlTxn.Commit();
                    transactionActive = false;

                    // Remove the plugin migration record to indicate that this migration isn't currently applied
                    var    rockContext            = new RockContext();
                    var    pluginMigrationService = new PluginMigrationService(rockContext);
                    string assemblyName           = migrationType.Assembly.GetName().Name;
                    int    migrationNumber        = GetMigrationNumberForMigrationType(migrationType).Number;
                    string migrationName          = migrationType.Name;
                    var    migrationRecord        = pluginMigrationService
                                                    .Queryable()
                                                    .Where(pm => pm.PluginAssemblyName == assemblyName)
                                                    .Where(pm => pm.MigrationNumber == migrationNumber)
                                                    .Where(pm => pm.MigrationName == migrationName)
                                                    .First();
                    pluginMigrationService.Delete(migrationRecord);
                    rockContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    if (transactionActive)
                    {
                        sqlTxn.Rollback();
                    }
                    throw ex;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Runs the plugin migrations for the specified plugin assembly
        /// </summary>
        /// <param name="pluginAssembly">The plugin assembly.</param>
        /// <returns></returns>
        /// <exception cref="RockStartupException">
        /// The '{assemblyName}' plugin assembly contains duplicate migration numbers ({ migrationNumberAttr.Number}).
        /// or
        /// ##Plugin Migration error occurred in {assemblyMigrations.Key}, {migrationType.Value.Name}##
        /// </exception>
        public static bool RunPluginMigrations(Assembly pluginAssembly)
        {
            string pluginAssemblyName = pluginAssembly.GetName().Name;

            // Migrate any plugins from the plugin assembly that have pending migrations
            List <Type> pluginMigrationTypes = Rock.Reflection.SearchAssembly(pluginAssembly, typeof(Rock.Plugin.Migration)).Select(a => a.Value).ToList();

            // If any plugin migrations types were found
            if (!pluginMigrationTypes.Any())
            {
                return(false);
            }

            bool result = false;

            // Get the current rock version
            var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber());

            // put the migrations to run in a Dictionary so that we can run them in the correct order
            // based on MigrationNumberAttribute
            var migrationTypesByNumber = new Dictionary <int, Type>();

            // Iterate plugin migrations
            foreach (var migrationType in pluginMigrationTypes)
            {
                // Get the MigrationNumberAttribute for the migration
                var migrationNumberAttr = migrationType.GetCustomAttribute <Rock.Plugin.MigrationNumberAttribute>();
                if (migrationNumberAttr != null)
                {
                    // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                    var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion);
                    if (minRockVersion.CompareTo(rockVersion) <= 0)
                    {
                        // Check to make sure no another migration has same number
                        if (migrationTypesByNumber.ContainsKey(migrationNumberAttr.Number))
                        {
                            throw new RockStartupException($"The '{pluginAssemblyName}' plugin assembly contains duplicate migration numbers ({ migrationNumberAttr.Number}).");
                        }

                        migrationTypesByNumber.Add(migrationNumberAttr.Number, migrationType);
                    }
                }
            }

            // Create EF service for plugin migrations
            var rockContext            = new RockContext();
            var pluginMigrationService = new PluginMigrationService(rockContext);

            // Get the versions that have already been installed
            var installedMigrationNumbers = pluginMigrationService.Queryable()
                                            .Where(m => m.PluginAssemblyName == pluginAssemblyName)
                                            .Select(a => a.MigrationNumber);

            // narrow it down to migrations that haven't already been installed
            migrationTypesByNumber = migrationTypesByNumber
                                     .Where(a => !installedMigrationNumbers.Contains(a.Key))
                                     .ToDictionary(k => k.Key, v => v.Value);

            // Iterate each migration in the assembly in MigrationNumber order
            var migrationTypesToRun = migrationTypesByNumber.OrderBy(a => a.Key).Select(a => a.Value).ToList();

            var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"]?.ConnectionString;

            try
            {
                using (var sqlConnection = new SqlConnection(configConnectionString))
                {
                    try
                    {
                        sqlConnection.Open();
                    }
                    catch (SqlException ex)
                    {
                        throw new RockStartupException("Error connecting to the SQL database. Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex);
                    }

                    // Iterate thru each plugin migration in this assembly, if one fails, will log the exception and stop running migrations for this assembly
                    foreach (Type migrationType in migrationTypesToRun)
                    {
                        int migrationNumber = migrationType.GetCustomAttribute <Rock.Plugin.MigrationNumberAttribute>().Number;

                        using (var sqlTxn = sqlConnection.BeginTransaction())
                        {
                            bool transactionActive = true;
                            try
                            {
                                // Create an instance of the migration and run the up migration
                                var migration = Activator.CreateInstance(migrationType) as Rock.Plugin.Migration;
                                migration.SqlConnection  = sqlConnection;
                                migration.SqlTransaction = sqlTxn;
                                migration.Up();
                                sqlTxn.Commit();
                                transactionActive = false;

                                // Save the plugin migration version so that it is not run again
                                var pluginMigration = new PluginMigration();
                                pluginMigration.PluginAssemblyName = pluginAssemblyName;
                                pluginMigration.MigrationNumber    = migrationNumber;
                                pluginMigration.MigrationName      = migrationType.Name;
                                pluginMigrationService.Add(pluginMigration);
                                rockContext.SaveChanges();

                                result = true;
                            }
                            catch (Exception ex)
                            {
                                if (transactionActive)
                                {
                                    sqlTxn.Rollback();
                                }

                                throw new RockStartupException($"##Plugin Migration error occurred in { migrationNumber}, {migrationType.Name}##", ex);
                            }
                        }
                    }
                }
            }
            catch (RockStartupException rockStartupException)
            {
                // if a plugin migration got an error, it gets wrapped with a RockStartupException
                // If this occurs, we'll log the migration that occurred,  and stop running migrations for this assembly
                System.Diagnostics.Debug.WriteLine(rockStartupException.Message);
                LogError(rockStartupException, null);
            }
            catch (Exception ex)
            {
                // If an exception occurs in an an assembly, log the error, and stop running migrations for this assembly
                var startupException = new RockStartupException($"Error running migrations from {pluginAssemblyName}");
                System.Diagnostics.Debug.WriteLine(startupException.Message);
                LogError(ex, null);
            }

            return(result);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Migrates the plugins.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">
        /// Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.
        /// or
        /// </exception>
        public bool MigratePlugins(RockContext rockContext)
        {
            bool result = false;

            // Migrate any plugins that have pending migrations
            List <Type> migrationList = Rock.Reflection.FindTypes(typeof(Migration)).Select(a => a.Value).ToList();

            // If any plugin migrations types were found
            if (migrationList.Any())
            {
                // Create EF service for plugin migrations
                var pluginMigrationService = new PluginMigrationService(rockContext);

                // Get the current rock version
                var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber());

                // Create dictionary for holding migrations specific to an assembly
                var assemblies = new Dictionary <string, Dictionary <int, Type> >();

                // Iterate plugin migrations
                foreach (var migrationType in migrationList)
                {
                    // Get the MigrationNumberAttribute for the migration
                    var migrationNumberAttr = System.Attribute.GetCustomAttribute(migrationType, typeof(MigrationNumberAttribute)) as MigrationNumberAttribute;
                    if (migrationNumberAttr != null)
                    {
                        // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                        var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion);
                        if (minRockVersion.CompareTo(rockVersion) <= 0)
                        {
                            string assemblyName = migrationType.Assembly.GetName().Name;
                            if (!assemblies.ContainsKey(assemblyName))
                            {
                                assemblies.Add(assemblyName, new Dictionary <int, Type>());
                            }

                            // Check to make sure no another migration has same number
                            if (assemblies[assemblyName].ContainsKey(migrationNumberAttr.Number))
                            {
                                throw new Exception(string.Format("The '{0}' plugin assembly contains duplicate migration numbers ({1}).", assemblyName, migrationNumberAttr.Number));
                            }
                            assemblies[assemblyName].Add(migrationNumberAttr.Number, migrationType);
                        }
                    }
                }

                var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"];
                if (configConnectionString != null)
                {
                    string connectionString = configConnectionString.ConnectionString;
                    if (!string.IsNullOrWhiteSpace(connectionString))
                    {
                        using (SqlConnection con = new SqlConnection(connectionString))
                        {
                            try
                            {
                                con.Open();
                            }
                            catch (SqlException ex)
                            {
                                throw new Exception("Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex);
                            }

                            // Iterate each assembly that contains plugin migrations
                            foreach (var assemblyMigrations in assemblies)
                            {
                                try
                                {
                                    // Get the versions that have already been installed
                                    var installedVersions = pluginMigrationService.Queryable()
                                                            .Where(m => m.PluginAssemblyName == assemblyMigrations.Key)
                                                            .ToList();

                                    // Iterate each migration in the assembly in MigrationNumber order
                                    foreach (var migrationType in assemblyMigrations.Value.OrderBy(t => t.Key))
                                    {
                                        // Check to make sure migration has not already been run
                                        if (!installedVersions.Any(v => v.MigrationNumber == migrationType.Key))
                                        {
                                            using (var sqlTxn = con.BeginTransaction())
                                            {
                                                bool transactionActive = true;
                                                try
                                                {
                                                    // Create an instance of the migration and run the up migration
                                                    var migration = Activator.CreateInstance(migrationType.Value) as Rock.Plugin.Migration;
                                                    migration.SqlConnection  = con;
                                                    migration.SqlTransaction = sqlTxn;
                                                    migration.Up();
                                                    sqlTxn.Commit();
                                                    transactionActive = false;

                                                    // Save the plugin migration version so that it is not run again
                                                    var pluginMigration = new PluginMigration();
                                                    pluginMigration.PluginAssemblyName = assemblyMigrations.Key;
                                                    pluginMigration.MigrationNumber    = migrationType.Key;
                                                    pluginMigration.MigrationName      = migrationType.Value.Name;
                                                    pluginMigrationService.Add(pluginMigration);
                                                    rockContext.SaveChanges();

                                                    result = true;
                                                }
                                                catch (Exception ex)
                                                {
                                                    if (transactionActive)
                                                    {
                                                        sqlTxn.Rollback();
                                                    }
                                                    throw new Exception(string.Format("Plugin Migration error occurred in {0}, {1}",
                                                                                      assemblyMigrations.Key, migrationType.Value.Name), ex);
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    // If an exception occurs in an an assembly, log the error, and continue with next assembly
                                    LogError(ex, null);
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// The commands to run to migrate plugin to the specific version
        /// </summary>
        public override void Up()
        {
            var migrateNamespaceEmail = false;
            var migrateNamespaceSMS   = false;
            var oldNamespaceEmail     = "com.kfs.GroupScheduledEmails";
            var oldNamespaceSMS       = "com.kfs.GroupScheduledSMS";

            // check if migration has previously run
            using (var rockContext = new RockContext())
            {
                var migrationNumber = (System.Attribute.GetCustomAttribute(this.GetType(), typeof(MigrationNumberAttribute)) as MigrationNumberAttribute).Number;

                migrateNamespaceEmail = new PluginMigrationService(rockContext)
                                        .Queryable()
                                        .Where(m => m.PluginAssemblyName.Equals(oldNamespaceEmail, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                        .Any();

                migrateNamespaceSMS = new PluginMigrationService(rockContext)
                                      .Queryable()
                                      .Where(m => m.PluginAssemblyName.Equals(oldNamespaceSMS, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                      .Any();
            }

            #region Email Attributes

            if (migrateNamespaceEmail)
            {
                var attributeMatrixTemplateEmailId = new AttributeMatrixTemplateService(new RockContext()).Get(KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_EMAILS.AsGuid()).Id.ToString();

                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "rocks.kfs.ScheduledGroupCommunication.EmailSendDateTime", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.DATE_TIME, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_FROM_EMAIL, "rocks.kfs.ScheduledGroupCommunication.EmailFromAddress", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.EMAIL, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_FROM_NAME, "rocks.kfs.ScheduledGroupCommunication.EmailFromName", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.TEXT, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SUBJECT, "rocks.kfs.ScheduledGroupCommunication.EmailSubject", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.TEXT, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "rocks.kfs.ScheduledGroupCommunication.EmailMessage", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.HTML, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId);

                using (var rockContext = new RockContext())
                {
                    // look for any configured jobs and change the class name
                    var emailJobs = new ServiceJobService(rockContext)
                                    .Queryable()
                                    .Where(j => j.Class.Equals("com.kfs.GroupScheduledEmails.Jobs.SendScheduledGroupEmail", StringComparison.CurrentCultureIgnoreCase))
                                    .ToList();

                    foreach (var job in emailJobs)
                    {
                        job.Class = "rocks.kfs.ScheduledGroupCommunication.Jobs.SendScheduledGroupEmail";
                    }

                    // look for job attributes and change qualifier value
                    var attributes = new AttributeService(rockContext)
                                     .Queryable()
                                     .Where(a => a.EntityTypeQualifierValue.Equals("com.kfs.GroupScheduledEmails.Jobs.SendScheduledGroupEmail", StringComparison.CurrentCultureIgnoreCase))
                                     .ToList();

                    foreach (var attribute in attributes)
                    {
                        attribute.EntityTypeQualifierValue = "rocks.kfs.ScheduledGroupCommunication.Jobs.SendScheduledGroupEmail";
                    }

                    rockContext.SaveChanges();
                }
            }
            else
            {
                // create the attribute matrix template and get it's id to assign to the attributes we'll create
                var attributeMatrixTemplateEmail = new AttributeMatrixTemplate
                {
                    Name            = "Scheduled Emails",
                    Description     = "Used to create scheduled emails.",
                    IsActive        = true,
                    FormattedLava   = AttributeMatrixTemplate.FormattedLavaDefault,
                    CreatedDateTime = RockDateTime.Now,
                    Guid            = KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_EMAILS.AsGuid()
                };

                var rockContextEmail = new RockContext();
                rockContextEmail.WrapTransaction(() =>
                {
                    rockContextEmail.AttributeMatrixTemplates.Add(attributeMatrixTemplateEmail);
                    rockContextEmail.SaveChanges();
                });

                var attributeMatrixTemplateEmailId = new AttributeMatrixTemplateService(rockContextEmail).Get(KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_EMAILS.AsGuid()).Id.ToString();

                // send date time
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.DATE_TIME, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId, "Send Date Time", "", 0, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "rocks.kfs.ScheduledGroupCommunication.EmailSendDateTime");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "datePickerControlType", "Date Picker", "3C8A1A23-F2CD-42F6-BF1E-69AAE87A4701");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "displayCurrentOption", "False", "EE2C58B0-5A24-4957-A84D-94829985B2C1");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "displayDiff", "False", "B61EB1C8-D811-4D4A-9AC9-2E8B8381E468");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "format", "", "83C6F1A4-2514-4C62-A4EA-FD804ABC758C");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SEND_DATE, "futureYearCount", "", "1AFFC6EA-8C45-4125-94DC-25E0E73D8CC6");

                // from email
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.EMAIL, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId, "From Email", "", 1, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_FROM_EMAIL, "rocks.kfs.ScheduledGroupCommunication.EmailFromAddress");

                // from name
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.TEXT, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId, "From Name", "", 2, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_FROM_NAME, "rocks.kfs.ScheduledGroupCommunication.EmailFromName");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_FROM_NAME, "ispassword", "false", "1EE77F52-992D-43CE-8574-306E95A7D740");

                // subject
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.TEXT, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId, "Subject", "", 3, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SUBJECT, "rocks.kfs.ScheduledGroupCommunication.EmailSubject");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_SUBJECT, "ispassword", "false", "CEB3BEB8-20E9-4A8F-8530-2B68DA02B020");

                // message
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.HTML, "AttributeMatrixTemplateId", attributeMatrixTemplateEmailId, "Message", "", 4, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "rocks.kfs.ScheduledGroupCommunication.EmailMessage");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "documentfolderroot", "", "4B2FFA29-5B9C-4F74-ACE5-54C97B68E0B6");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "imagefolderroot", "", "77C6B7A9-69DF-466F-AFEC-DC41B33E0DF0");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "toolbar", "Light", "E1E5C3F2-F64C-4942-A5B3-B712125BF8CB");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_EMAIL_MESSAGE, "userspecificroot", "False", "C3FF1EBB-7EFF-4747-A326-F6BCD669DD35");

                // set all attributes to be required
                Sql(@"
                UPDATE [Attribute] SET [IsRequired] = 1
                WHERE (
                    [Guid] = '39A38B02-112C-4EDC-A30E-4BDB1B090EE4'
                    OR
                    [Guid] = 'F7C73002-6442-4756-BFDB-BC0BFE58EF15'
                    OR
                    [Guid] = '7BEE419A-8444-44E1-B7EB-451C038977B3'
                    OR
                    [Guid] = '9EC7C8A9-F4C9-421C-9129-2DD023E09D05'
                    OR
                    [Guid] = '8C4EE7A8-086D-42B7-908F-77A9A36E5342'
                )
                ");
            }

            #endregion

            #region SMS Attributes

            if (migrateNamespaceSMS)
            {
                var attributeMatrixTemplateSMSId = new AttributeMatrixTemplateService(new RockContext()).Get(KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_SMS.AsGuid()).Id.ToString();

                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "rocks.kfs.ScheduledGroupCommunication.SMSSendDateTime", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.DATE_TIME, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "rocks.kfs.ScheduledGroupCommunication.SMSFromNumber", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.DEFINED_VALUE, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId);
                RockMigrationHelper.EnsureAttributeByGuid(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "rocks.kfs.ScheduledGroupCommunication.SMSMessage", "3c9d5021-0484-4846-aef6-b6216d26c3c8", Rock.SystemGuid.FieldType.MEMO, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId);

                using (var rockContext = new RockContext())
                {
                    // look for any configured jobs and change the class name
                    var smsJobs = new ServiceJobService(rockContext)
                                  .Queryable()
                                  .Where(j => j.Class.Equals("com.kfs.GroupScheduledSMS.Jobs.SendScheduledGroupSMS", StringComparison.CurrentCultureIgnoreCase))
                                  .ToList();

                    foreach (var job in smsJobs)
                    {
                        job.Class = "rocks.kfs.ScheduledGroupCommunication.Jobs.SendScheduledGroupSMS";
                    }

                    // look for job attributes and change qualifier value
                    var attributes = new AttributeService(rockContext)
                                     .Queryable()
                                     .Where(a => a.EntityTypeQualifierValue.Equals("com.kfs.GroupScheduledSMS.Jobs.SendScheduledGroupSMS", StringComparison.CurrentCultureIgnoreCase))
                                     .ToList();

                    foreach (var attribute in attributes)
                    {
                        attribute.EntityTypeQualifierValue = "rocks.kfs.ScheduledGroupCommunication.Jobs.SendScheduledGroupSMS";
                    }

                    rockContext.SaveChanges();
                }
            }
            else
            {
                var attributeMatrixTemplateSMS = new AttributeMatrixTemplate
                {
                    Name            = "Scheduled SMS Messages",
                    Description     = "Used to create scheduled SMS messages.",
                    IsActive        = true,
                    FormattedLava   = AttributeMatrixTemplate.FormattedLavaDefault,
                    CreatedDateTime = RockDateTime.Now,
                    Guid            = KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_SMS.AsGuid()
                };

                var rockContextSMS = new RockContext();
                rockContextSMS.WrapTransaction(() =>
                {
                    rockContextSMS.AttributeMatrixTemplates.Add(attributeMatrixTemplateSMS);
                    rockContextSMS.SaveChanges();
                });

                var attributeMatrixTemplateSMSId = new AttributeMatrixTemplateService(rockContextSMS).Get(KFSConst.Attribute.ATTRIBUTE_MATRIX_TEMPLATE_SCHEDULED_SMS.AsGuid()).Id.ToString();

                // send date time
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.DATE_TIME, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId, "Send Date Time", "", 0, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "rocks.kfs.ScheduledGroupCommunication.SMSSendDateTime");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "datePickerControlType", "Date Picker", "3C8A1A23-F2CD-42F6-BF1E-69AAE87A4701");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "displayCurrentOption", "False", "EE2C58B0-5A24-4957-A84D-94829985B2C1");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "displayDiff", "False", "B61EB1C8-D811-4D4A-9AC9-2E8B8381E468");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "format", "", "83C6F1A4-2514-4C62-A4EA-FD804ABC758C");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_SEND_DATE, "futureYearCount", "", "1AFFC6EA-8C45-4125-94DC-25E0E73D8CC6");

                // from number
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.DEFINED_VALUE, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId, "From Number", "", 1, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "rocks.kfs.ScheduledGroupCommunication.SMSFromNumber");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "allowmultiple", "False", "90051033-C881-42E8-A0CE-4152527D6FA3");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "definedtype", "", "26143779-5747-416C-98B9-EBC86E4B8EE6");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "displaydescription", "True", "8AABC104-CFE5-4DF1-A164-2DA305F46BBC");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_FROM_NUMBER, "enhancedselection", "False", "B0008343-0033-4194-A1A8-F5AEF3B095AD");

                // message
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.AttributeMatrixItem", Rock.SystemGuid.FieldType.MEMO, "AttributeMatrixTemplateId", attributeMatrixTemplateSMSId, "Message", "", 2, "", KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "rocks.kfs.ScheduledGroupCommunication.SMSMessage");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "numberofrows", "3", "BB1F72CF-46E3-4ED5-B7C8-BAD274744435");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "allowhtml", "False", "0C97ED08-FF8D-4BF3-ADD1-C688EFB999D1");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "maxcharacters", "160", "A54E62A3-05BF-4458-8F56-408A2132BDA7");
                RockMigrationHelper.AddAttributeQualifier(KFSConst.Attribute.MATRIX_ATTRIBUTE_SMS_MESSAGE, "showcountdown", "True", "8808BF22-2051-488F-83E5-7188D2941334");

                // set all attributes to be required
                Sql(@"
                UPDATE [Attribute] SET [IsRequired] = 1
                WHERE (
                    [Guid] = 'B2125940-565B-42CE-82BE-CDA58FC65FDE'
                    OR
                    [Guid] = '1984A561-C4A9-4D4F-B366-23AD54BDCFE8'
                    OR
                    [Guid] = 'C57166D5-C0D3-4DA6-88DD-92AFA5126D69'
                )

                DECLARE @CommunicationSMSFromDefinedTypeId int = ( SELECT TOP 1 [Id] FROM [DefinedType] WHERE [Guid] = '611BDE1F-7405-4D16-8626-CCFEDB0E62BE' )

                UPDATE [AttributeQualifier] SET [Value] = CAST( @CommunicationSMSFromDefinedTypeId AS varchar )
                WHERE [Guid] = '26143779-5747-416C-98B9-EBC86E4B8EE6'
                ");
            }

            #endregion
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Migrates the database.
        /// </summary>
        /// <returns>True if at least one migration was run</returns>
        public bool MigrateDatabase( RockContext rockContext )
        {
            bool result = false;

            var fileInfo = new FileInfo( Server.MapPath( "~/App_Data/Run.Migration" ) );
            if ( fileInfo.Exists )
            {
                Database.SetInitializer( new MigrateDatabaseToLatestVersion<Rock.Data.RockContext, Rock.Migrations.Configuration>() );

                // explictly check if the database exists, and force create it if doesn't exist
                if ( !rockContext.Database.Exists() )
                {
                    // If database did not exist, initialize a database (which runs existing Rock migrations)
                    rockContext.Database.Initialize( true );
                    result = true;
                }
                else
                {
                    // If database does exist, run any pending Rock migrations
                    var migrator = new System.Data.Entity.Migrations.DbMigrator( new Rock.Migrations.Configuration() );
                    if ( migrator.GetPendingMigrations().Any() )
                    {
                        migrator.Update();
                        result = true;
                    }
                }

                fileInfo.Delete();
            }
            else
            {
                // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens
                Database.SetInitializer<Rock.Data.RockContext>( null );
            }

            // Migrate any plugins that have pending migrations
            List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList();

            // If any plugin migrations types were found
            if ( migrationList.Any() )
            {
                // Create EF service for plugin migrations
                var pluginMigrationService = new PluginMigrationService( rockContext );

                // Get the current rock version
                var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() );

                // Create dictionary for holding migrations specific to an assembly
                var assemblies = new Dictionary<string, Dictionary<int, Type>>();

                // Iterate plugin migrations
                foreach ( var migrationType in migrationList )
                {
                    // Get the MigrationNumberAttribute for the migration
                    var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute;
                    if ( migrationNumberAttr != null )
                    {
                        // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                        var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion );
                        if ( minRockVersion.CompareTo( rockVersion ) <= 0 )
                        {
                            string assemblyName = migrationType.Assembly.GetName().Name;
                            if ( !assemblies.ContainsKey( assemblyName ) )
                            {
                                assemblies.Add( assemblyName, new Dictionary<int, Type>() );
                            }
                            assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType );
                        }
                    }
                }

                var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"];
                if ( configConnectionString != null )
                {
                    string connectionString = configConnectionString.ConnectionString;
                    if ( !string.IsNullOrWhiteSpace( connectionString ) )
                    {
                        using ( SqlConnection con = new SqlConnection( connectionString ) )
                        {
                            con.Open();

                            // Iterate each assembly that contains plugin migrations
                            foreach ( var assemblyMigrations in assemblies )
                            {
                                try
                                {
                                    // Get the versions that have already been installed
                                    var installedVersions = pluginMigrationService.Queryable()
                                        .Where( m => m.PluginAssemblyName == assemblyMigrations.Key )
                                        .ToList();

                                    // Iterate each migration in the assembly in MigrationNumber order
                                    foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) )
                                    {
                                        // Check to make sure migration has not already been run
                                        if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) )
                                        {
                                            using ( var sqlTxn = con.BeginTransaction() )
                                            {
                                                bool transactionActive = true;
                                                try
                                                {
                                                    // Create an instance of the migration and run the up migration
                                                    var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration;
                                                    migration.SqlConnection = con;
                                                    migration.SqlTransaction = sqlTxn;
                                                    migration.Up();
                                                    sqlTxn.Commit();
                                                    transactionActive = false;

                                                    // Save the plugin migration version so that it is not run again
                                                    var pluginMigration = new PluginMigration();
                                                    pluginMigration.PluginAssemblyName = assemblyMigrations.Key;
                                                    pluginMigration.MigrationNumber = migrationType.Key;
                                                    pluginMigration.MigrationName = migrationType.Value.Name;
                                                    pluginMigrationService.Add( pluginMigration );
                                                    rockContext.SaveChanges();

                                                    result = true;
                                                }
                                                catch ( Exception ex )
                                                {
                                                    if ( transactionActive )
                                                    {
                                                        sqlTxn.Rollback();
                                                    }
                                                    throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}",
                                                        assemblyMigrations.Key, migrationType.Value.Name ), ex );
                                                }
                                            }
                                        }
                                    }
                                }
                                catch ( Exception ex )
                                {
                                    // If an exception occurs in an an assembly, log the error, and continue with next assembly
                                    LogError( ex, null );
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Migrates the plugins.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">
        /// Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.
        /// or
        /// </exception>
        public bool MigratePlugins( RockContext rockContext )
        {
            bool result = false;

            // Migrate any plugins that have pending migrations
            List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList();

            // If any plugin migrations types were found
            if ( migrationList.Any() )
            {
                // Create EF service for plugin migrations
                var pluginMigrationService = new PluginMigrationService( rockContext );

                // Get the current rock version
                var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() );

                // Create dictionary for holding migrations specific to an assembly
                var assemblies = new Dictionary<string, Dictionary<int, Type>>();

                // Iterate plugin migrations
                foreach ( var migrationType in migrationList )
                {
                    // Get the MigrationNumberAttribute for the migration
                    var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute;
                    if ( migrationNumberAttr != null )
                    {
                        // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                        var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion );
                        if ( minRockVersion.CompareTo( rockVersion ) <= 0 )
                        {
                            string assemblyName = migrationType.Assembly.GetName().Name;
                            if ( !assemblies.ContainsKey( assemblyName ) )
                            {
                                assemblies.Add( assemblyName, new Dictionary<int, Type>() );
                            }
                            assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType );
                        }
                    }
                }

                var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"];
                if ( configConnectionString != null )
                {
                    string connectionString = configConnectionString.ConnectionString;
                    if ( !string.IsNullOrWhiteSpace( connectionString ) )
                    {
                        using ( SqlConnection con = new SqlConnection( connectionString ) )
                        {
                            try
                            {
                                con.Open();
                            }
                            catch ( SqlException ex )
                            {
                                throw new Exception( "Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex );
                            }

                            // Iterate each assembly that contains plugin migrations
                            foreach ( var assemblyMigrations in assemblies )
                            {
                                try
                                {
                                    // Get the versions that have already been installed
                                    var installedVersions = pluginMigrationService.Queryable()
                                        .Where( m => m.PluginAssemblyName == assemblyMigrations.Key )
                                        .ToList();

                                    // Iterate each migration in the assembly in MigrationNumber order
                                    foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) )
                                    {
                                        // Check to make sure migration has not already been run
                                        if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) )
                                        {
                                            using ( var sqlTxn = con.BeginTransaction() )
                                            {
                                                bool transactionActive = true;
                                                try
                                                {
                                                    // Create an instance of the migration and run the up migration
                                                    var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration;
                                                    migration.SqlConnection = con;
                                                    migration.SqlTransaction = sqlTxn;
                                                    migration.Up();
                                                    sqlTxn.Commit();
                                                    transactionActive = false;

                                                    // Save the plugin migration version so that it is not run again
                                                    var pluginMigration = new PluginMigration();
                                                    pluginMigration.PluginAssemblyName = assemblyMigrations.Key;
                                                    pluginMigration.MigrationNumber = migrationType.Key;
                                                    pluginMigration.MigrationName = migrationType.Value.Name;
                                                    pluginMigrationService.Add( pluginMigration );
                                                    rockContext.SaveChanges();

                                                    result = true;
                                                }
                                                catch ( Exception ex )
                                                {
                                                    if ( transactionActive )
                                                    {
                                                        sqlTxn.Rollback();
                                                    }
                                                    throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}",
                                                        assemblyMigrations.Key, migrationType.Value.Name ), ex );
                                                }
                                            }
                                        }
                                    }
                                }
                                catch ( Exception ex )
                                {
                                    // If an exception occurs in an an assembly, log the error, and continue with next assembly
                                    LogError( ex, null );
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Migrates the database.
        /// </summary>
        public void MigrateDatabase()
        {
            // Check if database should be auto-migrated for the core and plugins
            if ( ConfigurationManager.AppSettings["AutoMigrateDatabase"].AsBoolean( true ) )
            {
                try
                {
                    Database.SetInitializer( new MigrateDatabaseToLatestVersion<Rock.Data.RockContext, Rock.Migrations.Configuration>() );

                    var rockContext = new RockContext();

                    // explictly check if the database exists, and force create it if doesn't exist
                    if ( !rockContext.Database.Exists() )
                    {
                        // If database did not exist, initialize a database (which runs existing Rock migrations)
                        rockContext.Database.Initialize( true );
                    }
                    else
                    {
                        // If database does exist, run any pending Rock migrations
                        var migrator = new System.Data.Entity.Migrations.DbMigrator( new Rock.Migrations.Configuration() );
                        migrator.Update();
                    }

                    // Migrate any plugins that have pending migrations
                    List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList();

                    // If any plugin migrations types were found
                    if ( migrationList.Any() )
                    {
                        // Create EF service for plugin migrations
                        var pluginMigrationService = new PluginMigrationService( rockContext );

                        // Get the current rock version
                        var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() );

                        // Create dictionary for holding migrations specific to an assembly
                        var assemblies = new Dictionary<string, Dictionary<int, Type>>();

                        // Iterate plugin migrations
                        foreach ( var migrationType in migrationList )
                        {
                            // Get the MigrationNumberAttribute for the migration
                            var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute;
                            if ( migrationNumberAttr != null )
                            {
                                // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                                var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion );
                                if ( minRockVersion.CompareTo( rockVersion ) <= 0 )
                                {
                                    string assemblyName = migrationType.Assembly.GetName().Name;
                                    if ( !assemblies.ContainsKey( assemblyName ) )
                                    {
                                        assemblies.Add( assemblyName, new Dictionary<int, Type>() );
                                    }
                                    assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType );
                                }
                            }
                        }

                        // Iterate each assembly that contains plugin migrations
                        foreach ( var assemblyMigrations in assemblies )
                        {
                            try
                            {
                                // Get the versions that have already been installed
                                var installedVersions = pluginMigrationService.Queryable()
                                    .Where( m => m.PluginAssemblyName == assemblyMigrations.Key )
                                    .ToList();

                                // Wrap the migrations for each assembly in a transaction so that if an error with one migration, none of the migrations are persisted
                                RockTransactionScope.WrapTransaction( () =>
                                {
                                    // Iterate each migration in the assembly in MigrationNumber order
                                    foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) )
                                    {
                                        // Check to make sure migration has not already been run
                                        if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) )
                                        {
                                            try
                                            {
                                                // Create an instance of the migration and run the up migration
                                                var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration;
                                                migration.Up();

                                                // Save the plugin migration version so that it is not run again
                                                var pluginMigration = new PluginMigration();
                                                pluginMigration.PluginAssemblyName = assemblyMigrations.Key;
                                                pluginMigration.MigrationNumber = migrationType.Key;
                                                pluginMigration.MigrationName = migrationType.Value.Name;
                                                pluginMigrationService.Add( pluginMigration );
                                                rockContext.SaveChanges();
                                            }
                                            catch ( Exception ex )
                                            {
                                                throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}",
                                                    assemblyMigrations.Key, migrationType.Value.Name ), ex );
                                            }
                                        }
                                    }
                                } );
                            }
                            catch ( Exception ex )
                            {
                                // If an exception occurs in an an assembly, log the error, and continue with next assembly
                                LogError( ex, null );
                            }
                        }
                    }
                }
                catch ( Exception ex )
                {
                    // if migrations fail, log error and attempt to continue
                    LogError( ex, null );
                }

            }
            else
            {
                // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens
                Database.SetInitializer<Rock.Data.RockContext>( null );
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Migrates the database.
        /// </summary>
        public void MigrateDatabase()
        {
            // Check if database should be auto-migrated for the core and plugins
            if (ConfigurationManager.AppSettings["AutoMigrateDatabase"].AsBoolean(true))
            {
                try
                {
                    Database.SetInitializer(new MigrateDatabaseToLatestVersion <Rock.Data.RockContext, Rock.Migrations.Configuration>());

                    var rockContext = new RockContext();

                    // explictly check if the database exists, and force create it if doesn't exist
                    if (!rockContext.Database.Exists())
                    {
                        // If database did not exist, initialize a database (which runs existing Rock migrations)
                        rockContext.Database.Initialize(true);
                    }
                    else
                    {
                        // If database does exist, run any pending Rock migrations
                        var migrator = new System.Data.Entity.Migrations.DbMigrator(new Rock.Migrations.Configuration());
                        migrator.Update();
                    }

                    // Migrate any plugins that have pending migrations
                    List <Type> migrationList = Rock.Reflection.FindTypes(typeof(Migration)).Select(a => a.Value).ToList();

                    // If any plugin migrations types were found
                    if (migrationList.Any())
                    {
                        // Create EF service for plugin migrations
                        var pluginMigrationService = new PluginMigrationService(rockContext);

                        // Get the current rock version
                        var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber());

                        // Create dictionary for holding migrations specific to an assembly
                        var assemblies = new Dictionary <string, Dictionary <int, Type> >();

                        // Iterate plugin migrations
                        foreach (var migrationType in migrationList)
                        {
                            // Get the MigrationNumberAttribute for the migration
                            var migrationNumberAttr = System.Attribute.GetCustomAttribute(migrationType, typeof(MigrationNumberAttribute)) as MigrationNumberAttribute;
                            if (migrationNumberAttr != null)
                            {
                                // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list
                                var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion);
                                if (minRockVersion.CompareTo(rockVersion) <= 0)
                                {
                                    string assemblyName = migrationType.Assembly.GetName().Name;
                                    if (!assemblies.ContainsKey(assemblyName))
                                    {
                                        assemblies.Add(assemblyName, new Dictionary <int, Type>());
                                    }
                                    assemblies[assemblyName].Add(migrationNumberAttr.Number, migrationType);
                                }
                            }
                        }

                        // Iterate each assembly that contains plugin migrations
                        foreach (var assemblyMigrations in assemblies)
                        {
                            try
                            {
                                // Get the versions that have already been installed
                                var installedVersions = pluginMigrationService.Queryable()
                                                        .Where(m => m.PluginAssemblyName == assemblyMigrations.Key)
                                                        .ToList();

                                // Wrap the migrations for each assembly in a transaction so that if an error with one migration, none of the migrations are persisted
                                RockTransactionScope.WrapTransaction(() =>
                                {
                                    // Iterate each migration in the assembly in MigrationNumber order
                                    foreach (var migrationType in assemblyMigrations.Value.OrderBy(t => t.Key))
                                    {
                                        // Check to make sure migration has not already been run
                                        if (!installedVersions.Any(v => v.MigrationNumber == migrationType.Key))
                                        {
                                            try
                                            {
                                                // Create an instance of the migration and run the up migration
                                                var migration = Activator.CreateInstance(migrationType.Value) as Rock.Plugin.Migration;
                                                migration.Up();

                                                // Save the plugin migration version so that it is not run again
                                                var pluginMigration = new PluginMigration();
                                                pluginMigration.PluginAssemblyName = assemblyMigrations.Key;
                                                pluginMigration.MigrationNumber    = migrationType.Key;
                                                pluginMigration.MigrationName      = migrationType.Value.Name;
                                                pluginMigrationService.Add(pluginMigration);
                                                rockContext.SaveChanges();
                                            }
                                            catch (Exception ex)
                                            {
                                                throw new Exception(string.Format("Plugin Migration error occurred in {0}, {1}",
                                                                                  assemblyMigrations.Key, migrationType.Value.Name), ex);
                                            }
                                        }
                                    }
                                });
                            }
                            catch (Exception ex)
                            {
                                // If an exception occurs in an an assembly, log the error, and continue with next assembly
                                LogError(ex, null);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // if migrations fail, log error and attempt to continue
                    LogError(ex, null);
                }
            }
            else
            {
                // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens
                Database.SetInitializer <Rock.Data.RockContext>(null);
            }
        }
        /// <summary>
        /// The commands to run to migrate plugin to the specific version
        /// </summary>
        public override void Up()
        {
            var migrateNamespace = false;
            var oldNamespace     = "com.kfs.ShelbyBatchExport";

            // check if migration has previously run
            using (var rockContext = new RockContext())
            {
                var migrationNumber = (System.Attribute.GetCustomAttribute(this.GetType(), typeof(MigrationNumberAttribute)) as MigrationNumberAttribute).Number;
                migrateNamespace = new PluginMigrationService(rockContext)
                                   .Queryable()
                                   .Where(m => m.PluginAssemblyName.Equals(oldNamespace, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                   .Any();
            }

            if (migrateNamespace)
            {
                //
                // keeping from old 1
                //
                // batch export date
                RockMigrationHelper.EnsureAttributeByGuid("4B6576DD-82F6-419F-8DF0-467D2636822D", "rocks.kfs.ShelbyFinancials.DateExported", Rock.SystemGuid.EntityType.FINANCIAL_BATCH, Rock.SystemGuid.FieldType.DATE_TIME, "", "");

                // transaction project
                RockMigrationHelper.EnsureAttributeByGuid("365134A6-D516-48E0-AC67-A011D5D59D99", "rocks.kfs.ShelbyFinancials.Project", Rock.SystemGuid.EntityType.FINANCIAL_TRANSACTION, Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "");

                // transaction detail project
                RockMigrationHelper.EnsureAttributeByGuid("951FAFFD-0513-4E31-9271-87853469E85E", "rocks.kfs.ShelbyFinancials.Project", Rock.SystemGuid.EntityType.FINANCIAL_TRANSACTION_DETAIL, Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "");

                // account default project
                RockMigrationHelper.EnsureAttributeByGuid("85422EA2-AC4E-44E5-99B9-30C131116734", "rocks.kfs.ShelbyFinancials.Project", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "");

                // account gl attributes
                RockMigrationHelper.EnsureAttributeByGuid("A211D2C9-249D-4D33-B120-A3EAB37C1EDF", "rocks.kfs.ShelbyFinancials.Company", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("B83D7934-F85A-42B7-AD0E-B4E16D63C189", "rocks.kfs.ShelbyFinancials.Fund", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("FD4EF8CC-DDB7-4DBD-9FD1-601A0119850B", "rocks.kfs.ShelbyFinancials.DebitAccount", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("2C1EE0CC-D329-453B-B4F0-29549E24ED05", "rocks.kfs.ShelbyFinancials.Department", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("0D114FB9-B1AA-4D6D-B0F3-9BB739710992", "rocks.kfs.ShelbyFinancials.CreditAccount", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");

                //
                // keeping from old 2
                //
                // create page for project defined type
                RockMigrationHelper.AddPage(true, Rock.SystemGuid.Page.ADMINISTRATION_FINANCE, "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Projects", "", "01DAC445-9C4A-4469-9F39-A39549D75CBF", "fa fa-clipboard", "2B630A3B-E081-4204-A3E4-17BB3A5F063D");

                // add defined value list block and set to projects defined type
                RockMigrationHelper.AddBlock(true, "01DAC445-9C4A-4469-9F39-A39549D75CBF", "", "0AB2D5E9-9272-47D5-90E4-4AA838D2D3EE", "Projects", "Main", "", "", 0, "23D1B7CE-D70C-4D81-B0D9-534A6D0542DC");
                RockMigrationHelper.AddBlockAttributeValue(true, "23D1B7CE-D70C-4D81-B0D9-534A6D0542DC", "9280D61F-C4F3-4A3E-A9BB-BCD67FF78637", "2CE68D65-7EAC-4D5E-80B6-6FB903726961");

                //
                // keeping from old 3
                //
                // nothing

                //
                // keeping from old 4
                //
                // transaction project
                RockMigrationHelper.UpdateAttributeQualifier("365134A6-D516-48E0-AC67-A011D5D59D99", "displaydescription", "True", "4287FEEF-4AB5-4F16-A872-546A393F2DB8");

                // transaction detail project
                RockMigrationHelper.UpdateAttributeQualifier("951FAFFD-0513-4E31-9271-87853469E85E", "displaydescription", "True", "A0679A5F-A76A-4408-9900-C576CC20E18F");

                // account default project
                RockMigrationHelper.UpdateAttributeQualifier("85422EA2-AC4E-44E5-99B9-30C131116734", "displaydescription", "True", "DA83FED2-1E06-44A7-8E40-AAECE75169D4");

                //
                // keeping from old 5
                //
                // Remove Batch Export Details Block from the Batch Details Page
                RockMigrationHelper.DeleteBlockAttributeValue("AB2F7C43-74F3-46A4-A005-F690D0A612D2", "DD9CD395-A4F0-4110-A349-C44EDFC0258B");
                RockMigrationHelper.DeleteBlock("AB2F7C43-74F3-46A4-A005-F690D0A612D2");

                // Remove the old export grid
                RockMigrationHelper.DeleteBlock("E209EFB6-DE18-4DD3-8B15-F7BE418C4955");

                // Change the Attribute name, and grid display
                Sql(@"
                    DECLARE @DateExportedAttributeId INT = (SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '4B6576DD-82F6-419F-8DF0-467D2636822D')

                    IF @DateExportedAttributeId IS NOT NULL
                    BEGIN
	                    UPDATE [Attribute]
	                    SET [Name] = 'Date Exported', [IsGridColumn] = 1
	                    WHERE [Id] = @DateExportedAttributeId
                    END
                ");

                // rename these attributes
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Debit Account", "", 3, "", "FD4EF8CC-DDB7-4DBD-9FD1-601A0119850B", "rocks.kfs.ShelbyFinancials.DebitAccount");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Revenue Department", "", 4, "", "2C1EE0CC-D329-453B-B4F0-29549E24ED05", "rocks.kfs.ShelbyFinancials.Department");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Revenue Account", "", 5, "", "0D114FB9-B1AA-4D6D-B0F3-9BB739710992", "rocks.kfs.ShelbyFinancials.CreditAccount");

                // make sure the key gets updated properly because we're not sure if the old migration ran or not and can't UpdateEntityAttiribute until they're ensured
                RockMigrationHelper.EnsureAttributeByGuid("9B67459C-3C61-491D-B072-9A9830FBB18F", "rocks.kfs.ShelbyFinancials.Region", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("8B8D8BBF-B763-4314-87D2-00B9B8BA5A0F", "rocks.kfs.ShelbyFinancials.SuperFund", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("22699ECA-BB71-4EFD-B416-17B41ED3DBEC", "rocks.kfs.ShelbyFinancials.Location", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("CD925E61-F87D-461F-9EFA-C1E14397FC4D", "rocks.kfs.ShelbyFinancials.CostCenter", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");
                RockMigrationHelper.EnsureAttributeByGuid("65D935EC-3501-41A6-A2C5-CABC62AB9EF1", "rocks.kfs.ShelbyFinancials.AccountSub", Rock.SystemGuid.EntityType.FINANCIAL_ACCOUNT, Rock.SystemGuid.FieldType.TEXT, "", "");

                // not all previous installs might have created these attributes.
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Region", "", 6, "", "9B67459C-3C61-491D-B072-9A9830FBB18F", "rocks.kfs.ShelbyFinancials.Region");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Super Fund", "", 7, "", "8B8D8BBF-B763-4314-87D2-00B9B8BA5A0F", "rocks.kfs.ShelbyFinancials.SuperFund");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Location", "", 8, "", "22699ECA-BB71-4EFD-B416-17B41ED3DBEC", "rocks.kfs.ShelbyFinancials.Location");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Cost Center", "", 9, "", "CD925E61-F87D-461F-9EFA-C1E14397FC4D", "rocks.kfs.ShelbyFinancials.CostCenter");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Account Sub", "", 10, "", "65D935EC-3501-41A6-A2C5-CABC62AB9EF1", "rocks.kfs.ShelbyFinancials.AccountSub");

                // delete old namespace block types from database by guid
                RockMigrationHelper.DeleteBlock("00FC3A61-775D-4DE5-BC19-A1556FF465EA");
                RockMigrationHelper.DeleteBlock("2DC7BB64-EBDB-4973-85A8-E2AF82F76256");
                RockMigrationHelper.DeleteBlockType("235C370C-2CD7-4289-8B68-A8617F58B22B");
                RockMigrationHelper.DeleteBlockType("B6F19C75-9B23-4EC5-810B-E05A5E11033F");
                RockMigrationHelper.DeleteAttribute("CBC91780-4D02-47D5-B4AD-55AE2D5EBB49");

                // Add new namespace blocks back
                RockMigrationHelper.UpdateBlockType("Shelby Financials Batch to Journal", "Block used to create Journal Entries in Shelby Financials from a Rock Financial Batch.", "~/Plugins/rocks_kfs/ShelbyFinancials/BatchToJournal.ascx", "KFS > Shelby Financials", "235C370C-2CD7-4289-8B68-A8617F58B22B");
                RockMigrationHelper.AddBlock(Rock.SystemGuid.Page.FINANCIAL_BATCH_DETAIL, "", "235C370C-2CD7-4289-8B68-A8617F58B22B", "Shelby Financials Batch To Journal", "Main", "", "", 0, "00FC3A61-775D-4DE5-BC19-A1556FF465EA");

                RockMigrationHelper.UpdateBlockType("Shelby Financials Batches to Journal", "Block used to create Journal Entries in Shelby Financials from multiple Rock Financial Batches.", "~/Plugins/rocks_kfs/ShelbyFinancials/BatchesToJournal.ascx", "KFS > Shelby Financials", "B6F19C75-9B23-4EC5-810B-E05A5E11033F");
                RockMigrationHelper.UpdateBlockTypeAttribute("B6F19C75-9B23-4EC5-810B-E05A5E11033F", Rock.SystemGuid.FieldType.PAGE_REFERENCE, "Detail Page", "DetailPage", "", "", 0, Rock.SystemGuid.Page.FINANCIAL_BATCH_DETAIL, "CBC91780-4D02-47D5-B4AD-55AE2D5EBB49");
                RockMigrationHelper.AddBlock(true, "3F123421-E5DE-474E-9F56-AAFCEDE115EF", "", "B6F19C75-9B23-4EC5-810B-E05A5E11033F", "Shelby Financials Batches To Journal", "Main", "", "", 0, "2DC7BB64-EBDB-4973-85A8-E2AF82F76256");

                //
                // keeping from old 6
                //
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "C19D547F-CD02-45C1-9962-FA1DBCEC2897");   // batch
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "DD221639-4EFF-4C16-9E7B-BE318E9E9F55");   // transaction
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "B097F23D-00D2-4216-916F-DA14335DA9CE");   // transaction detail
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "F8893830-B331-4C9F-AA4C-470F0C9B0D18");   // account

                Sql(@"
                    DECLARE @AccountCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = 'F8893830-B331-4C9F-AA4C-470F0C9B0D18' )
                    DECLARE @RegionAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '9B67459C-3C61-491D-B072-9A9830FBB18F' )
                    DECLARE @SuperFundAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '8B8D8BBF-B763-4314-87D2-00B9B8BA5A0F' )
                    DECLARE @LocationAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '22699ECA-BB71-4EFD-B416-17B41ED3DBEC' )
                    DECLARE @CostCenterAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = 'CD925E61-F87D-461F-9EFA-C1E14397FC4D' )
                    DECLARE @AccountSubAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '65D935EC-3501-41A6-A2C5-CABC62AB9EF1' )

                    IF NOT EXISTS (
                        SELECT *
                        FROM [AttributeCategory]
                        WHERE [AttributeId] = @RegionAttributeId
                        AND [CategoryId] = @AccountCategoryId )
                    BEGIN
                        INSERT INTO [AttributeCategory] ( [AttributeId], [CategoryId] )
                        VALUES( @RegionAttributeId, @AccountCategoryId )
                    END

                    IF NOT EXISTS (
                        SELECT *
                        FROM [AttributeCategory]
                        WHERE [AttributeId] = @SuperFundAttributeId
                        AND [CategoryId] = @AccountCategoryId )
                    BEGIN
                        INSERT INTO [AttributeCategory] ( [AttributeId], [CategoryId] )
                        VALUES( @SuperFundAttributeId, @AccountCategoryId )
                    END

                    IF NOT EXISTS (
                        SELECT *
                        FROM [AttributeCategory]
                        WHERE [AttributeId] = @LocationAttributeId
                        AND [CategoryId] = @AccountCategoryId )
                    BEGIN
                        INSERT INTO [AttributeCategory] ( [AttributeId], [CategoryId] )
                        VALUES( @LocationAttributeId, @AccountCategoryId )
                    END

                    IF NOT EXISTS (
                        SELECT *
                        FROM [AttributeCategory]
                        WHERE [AttributeId] = @CostCenterAttributeId
                        AND [CategoryId] = @AccountCategoryId )
                    BEGIN
                        INSERT INTO [AttributeCategory] ( [AttributeId], [CategoryId] )
                        VALUES( @CostCenterAttributeId, @AccountCategoryId )
                    END

                    IF NOT EXISTS (
                        SELECT *
                        FROM [AttributeCategory]
                        WHERE [AttributeId] = @AccountSubAttributeId
                        AND [CategoryId] = @AccountCategoryId )
                    BEGIN
                        INSERT INTO [AttributeCategory] ( [AttributeId], [CategoryId] )
                        VALUES( @AccountSubAttributeId, @AccountCategoryId )
                    END
                ");

                //
                // keeping from old 7
                //
                RockMigrationHelper.DeleteBlockType("1F50D804-67A0-4348-8DBB-7C1B46280025");
                RockMigrationHelper.DeleteBlockType("6A8AAA9A-67BD-47CA-8FF7-400BDA9FEB2E");
                RockMigrationHelper.DeleteAttribute("B72C0356-63AB-4E8B-8F43-40E994B94008");
            }
            else
            {
                // block and page
                RockMigrationHelper.AddPage(true, Rock.SystemGuid.Page.FUNCTIONS_FINANCE, "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Shelby GL Export", "", "3F123421-E5DE-474E-9F56-AAFCEDE115EF", "fa fa-archive", "EF65EFF2-99AC-4081-8E09-32A04518683A");

                // project defined type
                RockMigrationHelper.AddDefinedType("Financial", "Financial Projects", "Used to designate what Project a Transaction should be associated with.", "2CE68D65-7EAC-4D5E-80B6-6FB903726961");

                // batch export date
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialBatch", Rock.SystemGuid.FieldType.DATE_TIME, "", "", "Date Exported", "Date a batch was exported", 0, "", "4B6576DD-82F6-419F-8DF0-467D2636822D", "rocks.kfs.ShelbyFinancials.DateExported");
                RockMigrationHelper.UpdateAttributeQualifier("4B6576DD-82F6-419F-8DF0-467D2636822D", "displayDiff", "False", "B76CAB38-B1C8-4D81-B1F5-521A0B507053");
                RockMigrationHelper.UpdateAttributeQualifier("4B6576DD-82F6-419F-8DF0-467D2636822D", "format", "", "6AFC0F07-4706-4279-BDA4-204D57A4CC93");

                // Change the grid display
                Sql(@"
                    DECLARE @DateExportedAttributeId INT = (SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '4B6576DD-82F6-419F-8DF0-467D2636822D')

                    IF @DateExportedAttributeId IS NOT NULL
                    BEGIN
	                    UPDATE [Attribute]
	                    SET [IsGridColumn] = 1
	                    WHERE [Id] = @DateExportedAttributeId
                    END
                ");

                // transaction project
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialTransaction", Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "", "Transaction Project", "Designates the Project at the Financial Transaction Level", 0, "", "365134A6-D516-48E0-AC67-A011D5D59D99", "rocks.kfs.ShelbyFinancials.Project");
                RockMigrationHelper.UpdateAttributeQualifier("365134A6-D516-48E0-AC67-A011D5D59D99", "allowmultiple", "False", "B2205A7A-E11A-426C-9EF1-34CCD96F5047");
                RockMigrationHelper.UpdateAttributeQualifier("365134A6-D516-48E0-AC67-A011D5D59D99", "definedtype", "", "E88DAEFC-BEAE-43CE-8A0E-DF96AFB95FC7");
                RockMigrationHelper.UpdateAttributeQualifier("365134A6-D516-48E0-AC67-A011D5D59D99", "displaydescription", "True", "4287FEEF-4AB5-4F16-A872-546A393F2DB8");

                // transaction detail project
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialTransactionDetail", Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "", "Transaction Detail Project", "Designates the Project at the Financial Transaction Detail Level", 0, "", "951FAFFD-0513-4E31-9271-87853469E85E", "rocks.kfs.ShelbyFinancials.Project");
                RockMigrationHelper.UpdateAttributeQualifier("951FAFFD-0513-4E31-9271-87853469E85E", "allowmultiple", "False", "BA61B518-C7B7-4F33-8E23-8D2109DA49CB");
                RockMigrationHelper.UpdateAttributeQualifier("951FAFFD-0513-4E31-9271-87853469E85E", "definedtype", "", "408068EE-949F-41F5-8CC8-13C2DA6574FB");
                RockMigrationHelper.UpdateAttributeQualifier("951FAFFD-0513-4E31-9271-87853469E85E", "displaydescription", "True", "A0679A5F-A76A-4408-9900-C576CC20E18F");

                // account default project
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.DEFINED_VALUE, "", "", "Default Project", "Designates the Project at the Financial Account Level", 0, "", "85422EA2-AC4E-44E5-99B9-30C131116734", "rocks.kfs.ShelbyFinancials.Project");
                RockMigrationHelper.UpdateAttributeQualifier("85422EA2-AC4E-44E5-99B9-30C131116734", "allowmultiple", "False", "7B25D6C9-7182-4617-A561-1A52F8140110");
                RockMigrationHelper.UpdateAttributeQualifier("85422EA2-AC4E-44E5-99B9-30C131116734", "definedtype", "", "354F659B-06C1-4FEF-A88E-B9C0B1E64C08");
                RockMigrationHelper.UpdateAttributeQualifier("85422EA2-AC4E-44E5-99B9-30C131116734", "displaydescription", "True", "DA83FED2-1E06-44A7-8E40-AAECE75169D4");

                // set defined type qualifers
                Sql(@"
                    DECLARE @ProjectDefinedTypeId int = ( SELECT TOP 1 [Id] FROM [DefinedType] WHERE [Guid] = '2CE68D65-7EAC-4D5E-80B6-6FB903726961' )

                    UPDATE [AttributeQualifier] SET [Value] = CAST( @ProjectDefinedTypeId AS varchar )
                    WHERE [Guid] = 'E88DAEFC-BEAE-43CE-8A0E-DF96AFB95FC7'

                    UPDATE [AttributeQualifier] SET [Value] = CAST( @ProjectDefinedTypeId AS varchar )
                    WHERE [Guid] = '408068EE-949F-41F5-8CC8-13C2DA6574FB'

                    UPDATE [AttributeQualifier] SET [Value] = CAST( @ProjectDefinedTypeId AS varchar )
                    WHERE [Guid] = '354F659B-06C1-4FEF-A88E-B9C0B1E64C08'
                ");

                // account gl attributes
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Company", "", 1, "", "A211D2C9-249D-4D33-B120-A3EAB37C1EDF", "rocks.kfs.ShelbyFinancials.Company");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Fund", "", 2, "", "B83D7934-F85A-42B7-AD0E-B4E16D63C189", "rocks.kfs.ShelbyFinancials.Fund");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Debit Account", "", 3, "", "FD4EF8CC-DDB7-4DBD-9FD1-601A0119850B", "rocks.kfs.ShelbyFinancials.DebitAccount");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Revenue Department", "", 4, "", "2C1EE0CC-D329-453B-B4F0-29549E24ED05", "rocks.kfs.ShelbyFinancials.Department");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Revenue Account", "", 5, "", "0D114FB9-B1AA-4D6D-B0F3-9BB739710992", "rocks.kfs.ShelbyFinancials.CreditAccount");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Region", "", 6, "", "9B67459C-3C61-491D-B072-9A9830FBB18F", "rocks.kfs.ShelbyFinancials.Region");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Super Fund", "", 7, "", "8B8D8BBF-B763-4314-87D2-00B9B8BA5A0F", "rocks.kfs.ShelbyFinancials.SuperFund");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Location", "", 8, "", "22699ECA-BB71-4EFD-B416-17B41ED3DBEC", "rocks.kfs.ShelbyFinancials.Location");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Cost Center", "", 9, "", "CD925E61-F87D-461F-9EFA-C1E14397FC4D", "rocks.kfs.ShelbyFinancials.CostCenter");
                RockMigrationHelper.UpdateEntityAttribute("Rock.Model.FinancialAccount", Rock.SystemGuid.FieldType.TEXT, "", "", "Account Sub", "", 10, "", "65D935EC-3501-41A6-A2C5-CABC62AB9EF1", "rocks.kfs.ShelbyFinancials.AccountSub");

                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "C19D547F-CD02-45C1-9962-FA1DBCEC2897");   // batch
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "DD221639-4EFF-4C16-9E7B-BE318E9E9F55");   // transaction
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "B097F23D-00D2-4216-916F-DA14335DA9CE");   // transaction detail
                RockMigrationHelper.UpdateCategory("5997C8D3-8840-4591-99A5-552919F90CBD", "Shelby Financials Export", "fa fa-calculator", "", "F8893830-B331-4C9F-AA4C-470F0C9B0D18");   // account

                Sql(@"
                    DECLARE @BatchEntityTypeId int = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = 'BDD09C8E-2C52-4D08-9062-BE7D52D190C2' )
                    DECLARE @BatchCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = 'C19D547F-CD02-45C1-9962-FA1DBCEC2897' )

                    UPDATE [Category]
                    SET [EntityTypeQualifierColumn] = 'EntityTypeId',  [EntityTypeQualifierValue] = @BatchEntityTypeId
                    WHERE [Id] = @BatchCategoryId

                    INSERT INTO [AttributeCategory]
                    SELECT [Id], @BatchCategoryId
                    FROM [Attribute]
                    WHERE [Guid] = '4B6576DD-82F6-419F-8DF0-467D2636822D'

                    DECLARE @TransactionEntityTypeId int = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = '2C1CB26B-AB22-42D0-8164-AEDEE0DAE667' )
                    DECLARE @TransactionCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = 'DD221639-4EFF-4C16-9E7B-BE318E9E9F55' )

                    UPDATE [Category]
                    SET [EntityTypeQualifierColumn] = 'EntityTypeId',  [EntityTypeQualifierValue] = @TransactionEntityTypeId
                    WHERE [Id] = @TransactionCategoryId

                    INSERT INTO [AttributeCategory]
                    SELECT [Id], @TransactionCategoryId
                    FROM [Attribute]
                    WHERE [Guid] = '365134A6-D516-48E0-AC67-A011D5D59D99'

                    DECLARE @TransactionDetailEntityTypeId int = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = 'AC4AC28B-8E7E-4D7E-85DB-DFFB4F3ADCCE' )
                    DECLARE @TransactionDetailCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = 'B097F23D-00D2-4216-916F-DA14335DA9CE' )

                    UPDATE [Category]
                    SET [EntityTypeQualifierColumn] = 'EntityTypeId',  [EntityTypeQualifierValue] = @TransactionDetailEntityTypeId
                    WHERE [Id] = @TransactionDetailCategoryId

                    INSERT INTO [AttributeCategory]
                    SELECT [Id], @TransactionDetailCategoryId
                    FROM [Attribute]
                    WHERE [Guid] = '951FAFFD-0513-4E31-9271-87853469E85E'

                    DECLARE @AccountEntityTypeId int = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = '798BCE48-6AA7-4983-9214-F9BCEFB4521D' )
                    DECLARE @AccountCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = 'F8893830-B331-4C9F-AA4C-470F0C9B0D18' )

                    UPDATE [Category]
                    SET [EntityTypeQualifierColumn] = 'EntityTypeId',  [EntityTypeQualifierValue] = @AccountEntityTypeId
                    WHERE [Id] = @AccountCategoryId

                    INSERT INTO [AttributeCategory]
                    SELECT [Id], @AccountCategoryId
                    FROM [Attribute]
                    WHERE [Guid] = '85422EA2-AC4E-44E5-99B9-30C131116734'
                       OR [Guid] = 'A211D2C9-249D-4D33-B120-A3EAB37C1EDF'
                       OR [Guid] = 'B83D7934-F85A-42B7-AD0E-B4E16D63C189'
                       OR [Guid] = 'FD4EF8CC-DDB7-4DBD-9FD1-601A0119850B'
                       OR [Guid] = '2C1EE0CC-D329-453B-B4F0-29549E24ED05'
                       OR [Guid] = '0D114FB9-B1AA-4D6D-B0F3-9BB739710992'
                       OR [Guid] = '9B67459C-3C61-491D-B072-9A9830FBB18F'
                       OR [Guid] = '8B8D8BBF-B763-4314-87D2-00B9B8BA5A0F'
                       OR [Guid] = '22699ECA-BB71-4EFD-B416-17B41ED3DBEC'
                       OR [Guid] = 'CD925E61-F87D-461F-9EFA-C1E14397FC4D'
                       OR [Guid] = '65D935EC-3501-41A6-A2C5-CABC62AB9EF1'
                ");

                // create page for project defined type
                RockMigrationHelper.AddPage(true, Rock.SystemGuid.Page.ADMINISTRATION_FINANCE, "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Projects", "", "01DAC445-9C4A-4469-9F39-A39549D75CBF", "fa fa-clipboard", "2B630A3B-E081-4204-A3E4-17BB3A5F063D");

                // add defined value list block and set to projects defined type
                RockMigrationHelper.AddBlock(true, "01DAC445-9C4A-4469-9F39-A39549D75CBF", "", "0AB2D5E9-9272-47D5-90E4-4AA838D2D3EE", "Projects", "Main", "", "", 0, "23D1B7CE-D70C-4D81-B0D9-534A6D0542DC");
                RockMigrationHelper.AddBlockAttributeValue(true, "23D1B7CE-D70C-4D81-B0D9-534A6D0542DC", "9280D61F-C4F3-4A3E-A9BB-BCD67FF78637", "2CE68D65-7EAC-4D5E-80B6-6FB903726961");

                // add new blocks
                RockMigrationHelper.UpdateBlockType("Shelby Financials Batch to Journal", "Block used to create Journal Entries in Shelby Financials from a Rock Financial Batch.", "~/Plugins/rocks_kfs/ShelbyFinancials/BatchToJournal.ascx", "KFS > Shelby Financials", "235C370C-2CD7-4289-8B68-A8617F58B22B");
                RockMigrationHelper.AddBlock(true, Rock.SystemGuid.Page.FINANCIAL_BATCH_DETAIL, "", "235C370C-2CD7-4289-8B68-A8617F58B22B", "Shelby Financial Batches To Journal", "Main", "", "", 0, "00FC3A61-775D-4DE5-BC19-A1556FF465EA");

                // block type
                RockMigrationHelper.UpdateBlockType("Shelby Financials Batches to Journal", "Block used to create Journal Entries in Shelby Financials from multiple Rock Financial Batches.", "~/Plugins/rocks_kfs/ShelbyFinancials/BatchesToJournal.ascx", "KFS > Shelby Financials", "B6F19C75-9B23-4EC5-810B-E05A5E11033F");
                RockMigrationHelper.AddBlockTypeAttribute("B6F19C75-9B23-4EC5-810B-E05A5E11033F", Rock.SystemGuid.FieldType.PAGE_REFERENCE, "Detail Page", "DetailPage", "", "", 0, Rock.SystemGuid.Page.FINANCIAL_BATCH_DETAIL, "CBC91780-4D02-47D5-B4AD-55AE2D5EBB49", true);

                // block on the Shelby batch export page
                RockMigrationHelper.AddBlock("3F123421-E5DE-474E-9F56-AAFCEDE115EF", "", "B6F19C75-9B23-4EC5-810B-E05A5E11033F", "Shelby Financials Batches To Journal", "Main", "", "", 0, "2DC7BB64-EBDB-4973-85A8-E2AF82F76256");
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Ups this instance.
        /// </summary>
        public override void Up()
        {
            // check if grouptype already exists
            using (var rockContext = new RockContext())
            {
                var eventGuid = AdvancedEventGuid.AsGuid();
                if (new GroupTypeService(rockContext).Queryable().Any(gt => gt.Name == "Advanced Event Registration" || gt.Guid.Equals(eventGuid)))
                {
                    return;
                }
            }

            var migrateNamespace = false;
            var oldNamespace     = "com.kfs.EventRegistration.Advanced";

            // check if migration has previously run in case the grouptype check doesn't escape
            using (var rockContext = new RockContext())
            {
                var migrationNumber = (System.Attribute.GetCustomAttribute(this.GetType(), typeof(MigrationNumberAttribute)) as MigrationNumberAttribute).Number;
                migrateNamespace = new PluginMigrationService(rockContext)
                                   .Queryable()
                                   .Where(m => m.PluginAssemblyName.Equals(oldNamespace, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                   .Any();
            }

            // add primary grouptype
            RockMigrationHelper.AddGroupType("Advanced Event Registration", "This template triggers advanced features for the Event Registration module.", "Advanced Events", "Member", false, true, true, "fa fa-fire", 0, "", 0, "", AdvancedEventGuid, false);

            // add grouptype attributes to the primary grouptype
            AddGroupTypeAttribute("Rock.Model.GroupType", AdvancedEventGuid, BooleanFieldTypeGuid, "Allow Multiple Registrations", @"Should registrants be allowed to join multiple groups of this type?", 0, "False", true, "4F9CA590-882A-4A2A-9262-C9350953C996");
            AddGroupTypeAttribute("Rock.Model.GroupType", AdvancedEventGuid, BooleanFieldTypeGuid, "Allow Volunteer Assignment", @"Should volunteers be allowed to join groups of this type?", 1, "False", true, "7129D352-5468-4BD9-BF2E-5CF9758D83BF");
            AddGroupTypeAttribute("Rock.Model.GroupType", AdvancedEventGuid, BooleanFieldTypeGuid, "Show On Grid", @"Should the Registrants grid show assignment columns for this type?", 2, "False", true, "60BD7029-9D83-42CC-B904-9A1F3A89C1E6");
            AddGroupTypeAttribute("Rock.Model.GroupType", AdvancedEventGuid, BooleanFieldTypeGuid, "Display Combined Memberships", @"Should the resource panel display a combined list of groups? If not, each group will be listed separately.", 3, "False", true, "7DD366B4-0A8C-4DA0-B14E-A17A1AFF55A6");
            AddGroupTypeAttribute("Rock.Model.GroupType", AdvancedEventGuid, BooleanFieldTypeGuid, "Display Separate Roles", @"Should the resource panel display group members separately by role?  If not, group members will be listed together.", 4, "False", true, "469BA2BC-FEB5-4C95-9BA2-B382F01C88E3");

            // add child grouptypes
            RockMigrationHelper.AddGroupType("Event Activities", "Activity Groups for Advanced Events.", "Activity", "Participant", false, true, true, "fa fa-futbol-o", 0, AdvancedEventGuid, 0, "", EventActivityGuid, false);
            RockMigrationHelper.AddGroupType("Event Lodging", "Lodging Groups for Advanced Events.", "Lodging", "Occupant", false, true, true, "fa fa-bed", 0, AdvancedEventGuid, 0, "", EventLodgingGuid, false);
            RockMigrationHelper.AddGroupType("Event Transportation", "Transportation Groups for Advanced Events.", "Vehicle", "Passenger", false, true, true, "fa fa-bus", 0, AdvancedEventGuid, 0, "", EventTransportationGuid, false);
            RockMigrationHelper.AddGroupType("Event Volunteers", "Volunteer Groups for Advanced Events.", "Group", "Volunteer", false, true, true, "fa fa-handshake-o", 0, AdvancedEventGuid, 0, GroupTypePurposeServingAreaGuid, EventVolunteerGuid, false);

            // only add the association if this is the first time
            if (!migrateNamespace)
            {
                Sql($@"
                    DECLARE @AdvancedEventId INT = (SELECT [ID] FROM GroupType WHERE [Guid] = '{AdvancedEventGuid}')
                    INSERT GroupTypeAssociation (GroupTypeId, ChildGroupTypeId)
                    VALUES (@AdvancedEventId, (SELECT [ID] FROM GroupType WHERE [Guid] = '{EventActivityGuid}')),
                        (@AdvancedEventId, (SELECT [ID] FROM GroupType WHERE [Guid] = '{EventLodgingGuid}')),
                        (@AdvancedEventId, (SELECT [ID] FROM GroupType WHERE [Guid] = '{EventTransportationGuid}')),
                        (@AdvancedEventId, (SELECT [ID] FROM GroupType WHERE [Guid] = '{EventVolunteerGuid}'))
                ");
            }

            // add group roles
            RockMigrationHelper.AddGroupTypeRole(AdvancedEventGuid, "Member", "Member of Advanced Events (not used)", 0, null, null, Guid.NewGuid().ToString(), false, false, true);
            RockMigrationHelper.AddGroupTypeRole(EventActivityGuid, "Participant", "Participant role for Advanced Event Activity Groups", 0, null, null, Guid.NewGuid().ToString(), false, false, true);
            RockMigrationHelper.AddGroupTypeRole(EventLodgingGuid, "Leader", "Leader role for Advanced Event Lodging Groups", 0, null, null, Guid.NewGuid().ToString(), false, true, false);
            RockMigrationHelper.AddGroupTypeRole(EventLodgingGuid, "Occupant", "Occupant role for Advanced Event Lodging Groups", 0, null, null, Guid.NewGuid().ToString(), false, false, true);
            RockMigrationHelper.AddGroupTypeRole(EventTransportationGuid, "Driver", "Driver role for Advanced Event Transportation Groups", 0, null, null, Guid.NewGuid().ToString(), false, true, false);
            RockMigrationHelper.AddGroupTypeRole(EventTransportationGuid, "Passenger", "Passenger role for Advanced Event Transportation Groups", 0, null, null, Guid.NewGuid().ToString(), false, false, true);
            RockMigrationHelper.AddGroupTypeRole(EventVolunteerGuid, "Member", "Member role for Advanced Event Volunteer Groups", 0, null, null, Guid.NewGuid().ToString(), false, false, true);
        }
        /// <summary>
        /// The commands to run to migrate plugin to the specific version
        /// </summary>
        public override void Up()
        {
            var migrateNamespace = false;
            var oldNamespace     = "com.kfs.GroupRSVP";

            // check if migration has previously run
            using (var rockContext = new RockContext())
            {
                var migrationNumber = (System.Attribute.GetCustomAttribute(this.GetType(), typeof(MigrationNumberAttribute)) as MigrationNumberAttribute).Number;
                migrateNamespace = new PluginMigrationService(rockContext)
                                   .Queryable()
                                   .Where(m => m.PluginAssemblyName.Equals(oldNamespace, StringComparison.CurrentCultureIgnoreCase) && m.MigrationNumber == migrationNumber)
                                   .Any();
            }

            if (migrateNamespace)
            {
                UpdateBlockTypeByGuid("RSVP Group Registration", "Allows a person to register for an RSVP Group.", "~/Plugins/rocks_kfs/RsvpGroups/RsvpGroupRegistration.ascx", "KFS > RSVP Groups", "F7B249C3-7FFD-483D-820F-A44D04E2BAB1");
                UpdateBlockTypeByGuid("Group List Lava", "Lists groups for lava display.", "~/Plugins/rocks_kfs/Groups/GroupListLava.ascx", "KFS > Groups", "6731AF9D-F3CB-4CCB-AA42-19C9CB15CBF5");   // shared block type
            }
            else
            {
                // group type
                RockMigrationHelper.AddGroupType("RSVP Group", "A group that can be used to manage RSVP counts for the group members.", "Group", "Member", false, true, true, "fa fa-clipboard-list", 0, "", 0, "", "1A082EFF-30DA-44B2-8E48-02385C20828E", true);

                // group type role
                RockMigrationHelper.AddGroupTypeRole("1A082EFF-30DA-44B2-8E48-02385C20828E", "Member", "", 0, null, null, "60E0B95A-04D3-4839-917B-6BDAF9808EB5", true, false, true);

                // max rsvp
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.INTEGER, "Max RSVP", "The RSVP limit for this group. '0' is unlimited.", 0, "", "AE34AFA5-8CB0-4BDA-8ACB-BAB661803BDC", true);

                // send email
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.BOOLEAN, "Send Email", "Flag indicating if the group email should be sent when someone joins this group.", 1, "False", "9B67F3BF-5F7A-4A9E-A352-67F3D515F63A", true);

                // from email
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.EMAIL, "From Email", "", 2, "", "6F8FB284-4CCB-45C1-A99E-F8ADA93856B1");

                // from name
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.TEXT, "From Name", "", 3, "", "9BBE3207-1939-45E3-8A26-6519045E8EA9");
                RockMigrationHelper.AddAttributeQualifier("9BBE3207-1939-45E3-8A26-6519045E8EA9", "ispassword", "false", "8F791A08-72BC-482E-8FBC-8F6463C9669E");

                // subject
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.TEXT, "Subject", "", 4, "", "C0AD8B37-4D7F-4C17-9B4E-1E8D4352E22D");
                RockMigrationHelper.AddAttributeQualifier("C0AD8B37-4D7F-4C17-9B4E-1E8D4352E22D", "ispassword", "false", "7284B714-AF12-440C-91FE-C4850F0D75F8");

                // message
                RockMigrationHelper.AddGroupTypeGroupAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.HTML, "Message", "", 5, "", "7DCB5A58-1FD2-4261-9483-EA65A97151CD");
                RockMigrationHelper.AddAttributeQualifier("7DCB5A58-1FD2-4261-9483-EA65A97151CD", "documentfolderroot", "", "B3C8C1C5-2DEB-49DA-87A8-8B87D48C9ED2");
                RockMigrationHelper.AddAttributeQualifier("7DCB5A58-1FD2-4261-9483-EA65A97151CD", "imagefolderroot", "", "C5CA6A49-E7A7-45AA-B9F4-85F8F6FA8B5D");
                RockMigrationHelper.AddAttributeQualifier("7DCB5A58-1FD2-4261-9483-EA65A97151CD", "toolbar", "Light", "242E3FFC-0680-494F-9EA3-55E8BEF11477");
                RockMigrationHelper.AddAttributeQualifier("7DCB5A58-1FD2-4261-9483-EA65A97151CD", "userspecificroot", "False", "A59A34A7-0EA8-414C-A78F-034FFE954768");

                // member rsvp
                RockMigrationHelper.AddGroupTypeGroupMemberAttribute("1A082EFF-30DA-44B2-8E48-02385C20828E", Rock.SystemGuid.FieldType.INTEGER, "RSVP Count", "", 0, "1", "877D17DD-6303-4863-B87C-F8D05111E835", true);

                // set member rsvp to display in grid, set the association to be self referenced, and set role to view
                Sql(@"
                    DECLARE @GroupMemberRsvpCount INT = (SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '877D17DD-6303-4863-B87C-F8D05111E835')
                    UPDATE [Attribute]
                    SET [IsGridColumn] = 1
                    WHERE [Id] = @GroupMemberRsvpCount

                    DECLARE @RsvpGroupTypeId INT = (SELECT TOP 1 [Id] FROM [GroupType] WHERE [Guid] = '1A082EFF-30DA-44B2-8E48-02385C20828E')
                    INSERT INTO [GroupTypeAssociation] ( [GroupTypeId], [ChildGroupTypeId] )
                    SELECT @RsvpGroupTypeId, @RsvpGroupTypeId

                    UPDATE [GroupTypeRole]
                    SET [CanView] = 1
                    WHERE [GroupTypeId] = @RsvpGroupTypeId
                ");

                // register blocks
                UpdateBlockTypeByGuid("RSVP Group Registration", "Allows a person to register for an RSVP Group.", "~/Plugins/rocks_kfs/RsvpGroups/RsvpGroupRegistration.ascx", "KFS > RSVP Groups", "F7B249C3-7FFD-483D-820F-A44D04E2BAB1");
                UpdateBlockTypeByGuid("Group List Lava", "Lists groups for lava display.", "~/Plugins/rocks_kfs/Groups/GroupListLava.ascx", "KFS > Groups", "6731AF9D-F3CB-4CCB-AA42-19C9CB15CBF5");   // shared block type
            }
        }