Skip to content

Instantly share code, notes, and snippets.

@nul800sebastiaan
Created February 4, 2025 10:54
Show Gist options
  • Save nul800sebastiaan/99c4d683ccdeb71e2f4416464b394073 to your computer and use it in GitHub Desktop.
Save nul800sebastiaan/99c4d683ccdeb71e2f4416464b394073 to your computer and use it in GitHub Desktop.
AddTableMigration
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Migrations;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Migrations;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
namespace TestingMigration;
public class AddTableMigration
{
public class RunBlogCommentsMigration : INotificationHandler<UmbracoApplicationStartingNotification>
{
private readonly IMigrationPlanExecutor _migrationPlanExecutor;
private readonly ICoreScopeProvider _coreScopeProvider;
private readonly IKeyValueService _keyValueService;
private readonly IRuntimeState _runtimeState;
public RunBlogCommentsMigration(
ICoreScopeProvider coreScopeProvider,
IMigrationPlanExecutor migrationPlanExecutor,
IKeyValueService keyValueService,
IRuntimeState runtimeState)
{
_migrationPlanExecutor = migrationPlanExecutor;
_coreScopeProvider = coreScopeProvider;
_keyValueService = keyValueService;
_runtimeState = runtimeState;
}
public void Handle(UmbracoApplicationStartingNotification notification)
{
if (_runtimeState.Level < RuntimeLevel.Run)
{
return;
}
// Create a migration plan for a specific project/feature
// We can then track that latest migration state/step for this project/feature
var migrationPlan = new MigrationPlan("BlogComments");
// This is the steps we need to take
// Each step in the migration adds a unique value
migrationPlan.From(string.Empty)
.To<AddCommentsTable>("blogcomments-db");
// Go and upgrade our site (Will check if it needs to do the work or not)
// Based on the current/latest step
var upgrader = new Upgrader(migrationPlan);
upgrader.Execute(
_migrationPlanExecutor,
_coreScopeProvider,
_keyValueService);
}
}
}
public class AddCommentsTable : MigrationBase
{
public AddCommentsTable(IMigrationContext context) : base(context)
{
}
protected override void Migrate()
{
Logger.LogDebug("Running migration {MigrationStep}", "AddCommentsTable");
// Lots of methods available in the MigrationBase class - discover with this.
if (TableExists("BlogComments") == false)
{
Create.Table<BlogCommentSchema>().Do();
}
else
{
Logger.LogDebug("The database table {DbTable} already exists, skipping", "BlogComments");
}
}
[TableName("BlogComments")]
[PrimaryKey("Id", AutoIncrement = true)]
[ExplicitColumns]
public class BlogCommentSchema
{
[PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
[Column("Id")]
public int Id { get; set; }
[Column("BlogPostUmbracoId")]
public int BlogPostUmbracoId { get; set; }
[Column("Name")]
public required string Name { get; set; }
[Column("Email")]
public required string Email { get; set; }
[Column("Website")]
public required string Website { get; set; }
[Column("Message")]
[SpecialDbType(SpecialDbTypes.NVARCHARMAX)]
public string Message { get; set; }
}
}
public class BlogCommentsComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.AddNotificationHandler<UmbracoApplicationStartingNotification, AddTableMigration.RunBlogCommentsMigration>();
}
}
@nul800sebastiaan
Copy link
Author

using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Migrations;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Migrations;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;

namespace TestingMigration;

public class AddTableMigration
{
    public class RunBlogCommentsMigration : INotificationHandler<UmbracoApplicationStartingNotification>
    {
        private readonly IMigrationPlanExecutor _migrationPlanExecutor;
        private readonly ICoreScopeProvider _coreScopeProvider;
        private readonly IKeyValueService _keyValueService;
        private readonly IRuntimeState _runtimeState;

        public RunBlogCommentsMigration(
            ICoreScopeProvider coreScopeProvider,
            IMigrationPlanExecutor migrationPlanExecutor,
            IKeyValueService keyValueService,
            IRuntimeState runtimeState)
        {
            _migrationPlanExecutor = migrationPlanExecutor;
            _coreScopeProvider = coreScopeProvider;
            _keyValueService = keyValueService;
            _runtimeState = runtimeState;
        }

        public void Handle(UmbracoApplicationStartingNotification notification)
        {
            if (_runtimeState.Level < RuntimeLevel.Run)
            {
                return;
            }

            var migrationPlan = new PreLaunchMigrationPlan();
            var upgrader = new Upgrader(migrationPlan);
            upgrader.Execute(
                _migrationPlanExecutor,
                _coreScopeProvider,
                _keyValueService);
        }
    }
}

public class PreLaunchMigrationPlan : MigrationPlan
{
    public PreLaunchMigrationPlan() : base("PreLaunchMigrationPlan")
    {
        From(string.Empty)
            .To<AddCommentsTable>("ciwf0");
    }
}

public class AddCommentsTable : MigrationBase
{
    public AddCommentsTable(IMigrationContext context) : base(context)
    {
    }
    protected override void Migrate()
    {
        Logger.LogDebug("Running migration {MigrationStep}", "AddCommentsTable");

        // Lots of methods available in the MigrationBase class - discover with this.
        if (TableExists("ciwf0") == false)
        {
            Create.Table<BlogCommentSchema>().Do();
        }
        else
        {
            Logger.LogDebug("The database table {DbTable} already exists, skipping", "ciwf0");
        }
    }

    [TableName("ciwf0")]
    [PrimaryKey("Id", AutoIncrement = true)]
    [ExplicitColumns]
    public class BlogCommentSchema
    {
        [PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
        [Column("Id")]
        public int Id { get; set; }

        [Column("BlogPostUmbracoId")]
        public int BlogPostUmbracoId { get; set; }

        [Column("Name")]
        public required string Name { get; set; }

        [Column("Email")]
        public required string Email { get; set; }

        [Column("Website")]
        public required string Website { get; set; }

        [Column("Message")]
        [SpecialDbType(SpecialDbTypes.NVARCHARMAX)]
        public string Message { get; set; }
    }
}

public class BlogCommentsComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.AddNotificationHandler<UmbracoApplicationStartingNotification, AddTableMigration.RunBlogCommentsMigration>();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment