Skip to content

Commit

Permalink
Add missing migration parameters to Akka.Hosting extension method (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
Arkatufus authored Apr 19, 2023
1 parent 35eca99 commit 6893233
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 11 deletions.
13 changes: 12 additions & 1 deletion src/Akka.Persistence.Sql.Hosting/DatabaseMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static string Name(this DatabaseMapping map)
_ => throw new Exception($"Unknown DatabaseMapping: {map}")
};

public static JournalDatabaseOptions DatabaseOption(DatabaseMapping map)
public static JournalDatabaseOptions JournalOption(this DatabaseMapping map)
=> map switch
{
DatabaseMapping.Default => JournalDatabaseOptions.Default,
Expand All @@ -40,5 +40,16 @@ public static JournalDatabaseOptions DatabaseOption(DatabaseMapping map)
DatabaseMapping.MySql => JournalDatabaseOptions.MySql,
_ => throw new Exception($"Unknown DatabaseMapping: {map}")
};

public static SnapshotDatabaseOptions SnapshotOption(this DatabaseMapping map)
=> map switch
{
DatabaseMapping.Default => SnapshotDatabaseOptions.Default,
DatabaseMapping.SqlServer => SnapshotDatabaseOptions.SqlServer,
DatabaseMapping.Sqlite => SnapshotDatabaseOptions.Sqlite,
DatabaseMapping.PostgreSql => SnapshotDatabaseOptions.PostgreSql,
DatabaseMapping.MySql => SnapshotDatabaseOptions.MySql,
_ => throw new Exception($"Unknown DatabaseMapping: {map}")
};
}
}
96 changes: 86 additions & 10 deletions src/Akka.Persistence.Sql.Hosting/HostingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Akka.Actor;
using Akka.Hosting;
using Akka.Persistence.Hosting;
using Akka.Persistence.Sql.Config;
using Akka.Persistence.Sql.Hosting;

namespace Akka.Persistence.Sql.Hosting
{
Expand Down Expand Up @@ -65,11 +67,70 @@ public static class HostingExtensions
/// </para>
/// <b>Default</b>: <c>true</c>
/// </param>
/// <param name="journalDatabaseMapping">
/// <para>
/// The database options to modify database table column mapping for this journal.
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </param>
/// <param name="databaseMapping">
/// <para>
/// The database options to modify database table column mapping for this journal.
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </param>
/// <param name="tagStorageMode">
/// <para>
/// Describe how tags are being stored inside the database. Setting this to
/// <see cref="TagMode.Csv"/> will store the tags as a comma delimited value
/// in a column named <c>tags</c> inside the event journal. Setting this to
/// <see cref="TagMode.TagTable"/> will store the tags inside a separate
/// tag table instead.
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </param>
/// <param name="deleteCompatibilityMode">
/// <para>
/// If true, journal_metadata is created and used for deletes
/// and max sequence number queries.
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </param>
/// <param name="useWriterUuidColumn">
/// <para>
/// A flag to indicate if the writer_uuid column should be generated and be populated in run-time.
/// </para>
/// <b>Notes:</b>
/// <list type="number">
/// <item>
/// The column will only be generated if auto-initialize is set to true.
/// </item>
/// <item>
/// This feature is Akka.Persistence.Sql specific, setting this to true will break
/// backward compatibility with databases generated by other Akka.Persistence plugins.
/// </item>
/// <item>
/// <para>
/// To make this feature work with legacy plugins, you will have to alter the old
/// journal table:
/// </para>
/// <c>ALTER TABLE [journal_table_name] ADD [writer_uuid_column_name] VARCHAR(128);</c>
/// </item>
/// <item>
/// If set to true, the code will not check for backward compatibility. It will expect
/// that the `writer-uuid` column to be present inside the journal table.
/// </item>
/// </list>
/// </param>
/// <returns>
/// The same <see cref="AkkaConfigurationBuilder"/> instance originally passed in.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when <see cref="journalBuilder"/> is set and <see cref="mode"/> is set to
/// Thrown when <paramref name="journalBuilder"/> is set and <paramref name="mode"/> is set to
/// <see cref="PersistenceMode.SnapshotStore"/>
/// </exception>
public static AkkaConfigurationBuilder WithSqlPersistence(
Expand All @@ -81,7 +142,11 @@ public static AkkaConfigurationBuilder WithSqlPersistence(
Action<AkkaPersistenceJournalBuilder>? journalBuilder = null,
bool autoInitialize = true,
string pluginIdentifier = "sql",
bool isDefaultPlugin = true)
bool isDefaultPlugin = true,
DatabaseMapping? databaseMapping = null,
TagMode? tagStorageMode = null,
bool? deleteCompatibilityMode = null,
bool? useWriterUuidColumn = null)
{
if (mode == PersistenceMode.SnapshotStore && journalBuilder is { })
throw new Exception($"{nameof(journalBuilder)} can only be set when {nameof(mode)} is set to either {PersistenceMode.Both} or {PersistenceMode.Journal}");
Expand All @@ -97,14 +162,24 @@ public static AkkaConfigurationBuilder WithSqlPersistence(
ConnectionString = connectionString,
ProviderName = providerName,
AutoInitialize = autoInitialize,
TagStorageMode = tagStorageMode,
DeleteCompatibilityMode = deleteCompatibilityMode,
};

if (databaseMapping is { })
journalOpt.DatabaseOptions = databaseMapping.Value.JournalOption();

if (schemaName is { })
{
journalOpt.DatabaseOptions = new JournalDatabaseOptions(DatabaseMapping.Default)
{
SchemaName = schemaName
};
journalOpt.DatabaseOptions ??= JournalDatabaseOptions.Default;
journalOpt.DatabaseOptions.SchemaName = schemaName;
}

if (useWriterUuidColumn is { })
{
journalOpt.DatabaseOptions ??= JournalDatabaseOptions.Default;
journalOpt.DatabaseOptions.JournalTable ??= JournalTableOptions.Default;
journalOpt.DatabaseOptions.JournalTable.UseWriterUuidColumn = useWriterUuidColumn;
}

var adapters = new AkkaPersistenceJournalBuilder(journalOpt.Identifier, builder);
Expand All @@ -118,12 +193,13 @@ public static AkkaConfigurationBuilder WithSqlPersistence(
AutoInitialize = autoInitialize,
};

if (databaseMapping is { })
snapshotOpt.DatabaseOptions = databaseMapping.Value.SnapshotOption();

if (schemaName is { })
{
snapshotOpt.DatabaseOptions = new SnapshotDatabaseOptions(DatabaseMapping.Default)
{
SchemaName = schemaName
};
snapshotOpt.DatabaseOptions ??= new SnapshotDatabaseOptions(DatabaseMapping.Default);
snapshotOpt.DatabaseOptions.SchemaName = schemaName;
}

return mode switch
Expand Down
26 changes: 26 additions & 0 deletions src/Akka.Persistence.Sql.Hosting/JournalTableOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,32 @@ public sealed class JournalTableOptions
ManifestColumnName = "manifest",
};

/// <summary>
/// <para>
/// A flag to indicate if the writer_uuid column should be generated and be populated in run-time.
/// </para>
/// <b>Notes:</b>
/// <list type="number">
/// <item>
/// The column will only be generated if auto-initialize is set to true.
/// </item>
/// <item>
/// This feature is Akka.Persistence.Sql specific, setting this to true will break
/// backward compatibility with databases generated by other Akka.Persistence plugins.
/// </item>
/// <item>
/// <para>
/// To make this feature work with legacy plugins, you will have to alter the old
/// journal table:
/// </para>
/// <c>ALTER TABLE [journal_table_name] ADD [writer_uuid_column_name] VARCHAR(128);</c>
/// </item>
/// <item>
/// If set to true, the code will not check for backward compatibility. It will expect
/// that the `writer-uuid` column to be present inside the journal table.
/// </item>
/// </list>
/// </summary>
public bool? UseWriterUuidColumn { get; set; }
public string? TableName { get; set; }

Expand Down
13 changes: 13 additions & 0 deletions src/Akka.Persistence.Sql.Hosting/SqlJournalOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ public SqlJournalOptions(bool isDefaultPlugin, string identifier = "sql") : base
/// </summary>
public TagMode? TagStorageMode { get; set; }

/// <summary>
/// <para>
/// If true, journal_metadata is created and used for deletes
/// and max sequence number queries.
/// </para>
/// <b>NOTE</b>: This is used primarily for backward compatibility,
/// you leave this empty for greenfield projects.
/// </summary>
public bool? DeleteCompatibilityMode { get; set; }

protected override Configuration.Config InternalDefaultConfig => Default;

protected override StringBuilder Build(StringBuilder sb)
Expand All @@ -94,6 +104,9 @@ protected override StringBuilder Build(StringBuilder sb)
sb.AppendLine($"connection-string = {ConnectionString.ToHocon()}");
sb.AppendLine($"provider-name = {ProviderName.ToHocon()}");

if (DeleteCompatibilityMode is { })
sb.AppendLine($"delete-compatibility-mode = {DeleteCompatibilityMode.ToHocon()}");

if (TagStorageMode is { })
sb.AppendLine($"tag-write-mode = {TagStorageMode.ToString().ToHocon()}");

Expand Down

0 comments on commit 6893233

Please sign in to comment.