Skip to content

Commit 52cb475

Browse files
committed
Allow migrations within existing SQLite transactions
- add migration executor for an existing SQLiteDbContext - add migration overloads accepting an active database context - preserve caller ownership of transaction commit and rollback - allow migrations and application operations to share one transaction
1 parent b793bca commit 52cb475

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace System.Data.SQLite;
2+
3+
/// <summary>
4+
/// Executes SQLite database migrations within an existing database context.
5+
/// </summary>
6+
internal sealed class SQLiteDbContextMigrationExecutor : IDbMigrationExecutor<SQLiteDbMigrationContext>
7+
{
8+
private readonly SQLiteDbContext _dbContext;
9+
10+
/// <summary>
11+
/// Initializes a new instance of the <see cref="SQLiteDbContextMigrationExecutor"/> class.
12+
/// </summary>
13+
/// <param name="dbContext">The existing SQLite database context.</param>
14+
/// <exception cref="ArgumentNullException"><paramref name="dbContext"/> is <see langword="null"/>.</exception>
15+
public SQLiteDbContextMigrationExecutor(SQLiteDbContext dbContext)
16+
{
17+
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
18+
}
19+
20+
/// <inheritdoc/>
21+
public void Execute(Action<SQLiteDbMigrationContext> operation, CancellationToken cancellationToken)
22+
{
23+
ArgumentNullException.ThrowIfNull(operation);
24+
cancellationToken.ThrowIfCancellationRequested();
25+
26+
operation(new SQLiteDbMigrationContext(_dbContext.Connection, cancellationToken));
27+
}
28+
}

‎src/System/Data/SQLite/SQLiteDbMigrationExtensions.cs‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,42 @@ public static void Migrate(this IEnumerable<SQLiteDbMigration> migrations, Func<
3636
var migrator = new DbMigrator<SQLiteDbMigrationContext>(executor, history, migrations, version);
3737
migrator.Migrate(cancellationToken);
3838
}
39+
40+
/// <summary>
41+
/// Applies all pending migrations using an existing SQLite database context.
42+
/// </summary>
43+
/// <param name="migrations">The migrations in the order in which they must be applied.</param>
44+
/// <param name="dbContext">The existing SQLite database context.</param>
45+
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
46+
/// <exception cref="ArgumentNullException"><paramref name="migrations"/> or <paramref name="dbContext"/> is <see langword="null"/>.</exception>
47+
/// <remarks>
48+
/// The caller owns the database context and is responsible for committing or rolling back its transaction.
49+
/// </remarks>
50+
public static void Migrate(this IEnumerable<SQLiteDbMigration> migrations, SQLiteDbContext dbContext, CancellationToken cancellationToken = default)
51+
{
52+
Migrate(migrations, dbContext, null, cancellationToken);
53+
}
54+
55+
/// <summary>
56+
/// Applies all pending migrations using an existing SQLite database context.
57+
/// </summary>
58+
/// <param name="migrations">The migrations in the order in which they must be applied.</param>
59+
/// <param name="dbContext">The existing SQLite database context.</param>
60+
/// <param name="version">Optional version information to record for each applied migration.</param>
61+
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
62+
/// <exception cref="ArgumentNullException"><paramref name="migrations"/> or <paramref name="dbContext"/> is <see langword="null"/>.</exception>
63+
/// <remarks>
64+
/// The caller owns the database context and is responsible for committing or rolling back its transaction.
65+
/// </remarks>
66+
public static void Migrate(this IEnumerable<SQLiteDbMigration> migrations, SQLiteDbContext dbContext, string? version, CancellationToken cancellationToken = default)
67+
{
68+
ArgumentNullException.ThrowIfNull(migrations);
69+
ArgumentNullException.ThrowIfNull(dbContext);
70+
cancellationToken.ThrowIfCancellationRequested();
71+
72+
var executor = new SQLiteDbContextMigrationExecutor(dbContext);
73+
var history = new SQLiteMigrationHistory();
74+
var migrator = new DbMigrator<SQLiteDbMigrationContext>(executor, history, migrations, version);
75+
migrator.Migrate(cancellationToken);
76+
}
3977
}

0 commit comments

Comments
 (0)