Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/Besql/Bit.Besql/BesqlPooledDbContextFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Data.Common;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

Expand Down Expand Up @@ -36,11 +35,6 @@ protected override async Task InitializeDbContext()
{
await _storage.Load(_fileName).ConfigureAwait(false);
}
await using var connection = new SqliteConnection(_connectionString);
await connection.OpenAsync().ConfigureAwait(false);
await using var command = connection.CreateCommand();
command.CommandText = "PRAGMA synchronous = FULL;";
await command.ExecuteNonQueryAsync().ConfigureAwait(false);

await base.InitializeDbContext().ConfigureAwait(false);
}
Expand Down
27 changes: 27 additions & 0 deletions src/Besql/Bit.Besql/DatabaseFacadeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace Microsoft.EntityFrameworkCore;

public static class DatabaseFacadeExtensions
{
/// <summary>
/// This method must be called before invoking Database.MigrateAsync or Database.EnsureCreatedAsync, to ensure proper functionality of bit Besql.
/// </summary>
public static async Task<DatabaseFacade> ConfigureSqliteSynchronous(this DatabaseFacade database)
{
if (database.ProviderName!.EndsWith("Sqlite", StringComparison.InvariantCulture) is false)
throw new InvalidOperationException("It's not supposed to call this method on any database other than sqlite.");

if (OperatingSystem.IsBrowser() is false)
return database;

await using var connection = new SqliteConnection(database.GetConnectionString());
await connection.OpenAsync().ConfigureAwait(false);
await using var command = connection.CreateCommand();
command.CommandText = "PRAGMA synchronous = FULL;";
await command.ExecuteNonQueryAsync().ConfigureAwait(false);

return database;
}
}
6 changes: 5 additions & 1 deletion src/Besql/Bit.Besql/IServiceCollectionBesqlExtentions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ public static IServiceCollection AddBesqlDbContextFactory<TDbContext>(this IServ
optionsAction ??= (_, _) => { };
dbContextInitializer ??= async (_, _) => { };

services.AddSingleton(dbContextInitializer);
services.AddSingleton(async (IServiceProvider sp, TDbContext dbContext) =>
{
await dbContext.Database.ConfigureSqliteSynchronous();
await dbContextInitializer(sp, dbContext);
});

if (OperatingSystem.IsAndroid() || OperatingSystem.IsBrowser())
{
Expand Down
19 changes: 17 additions & 2 deletions src/Besql/Demo/Bit.Besql.Demo.Client/Pages/Weather.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<button class="btn btn-primary" @onclick="DeleteSomeForecastsSample">Delete some forecasts</button>
<button class="btn btn-primary" @onclick="PauseResumeSyncSample">Pause / resume sync</button>
<button class="btn btn-primary" @onclick="UsePrePopulatedDatabaseSample">Use pre populated database</button>
<button class="btn btn-primary" @onclick="ReCreateDatabase">Re-create database</button>

<h1>@forecastsCount</h1>

Expand Down Expand Up @@ -83,8 +84,9 @@

private async Task UsePrePopulatedDatabaseSample()
{
// This functionality can also be implemented as an API that dynamically populates a SQLite database.
// Important: Ensure the SQLite database is created with `PRAGMA synchronous = FULL` from the start.
// This feature can alternatively be implemented as an API that dynamically fills a SQLite database.
// Note: If the `dbContext` used to populate the SQLite database file is not instantiated by `bit Besql`,
// you must manually call `dbContext.Database.ConfigureSqliteSynchronous()`.
await using var prePopulatedDatabase = await HttpClient.GetStreamAsync("https://localhost:5050/Pre-Populated-Offline-Client.db");

var fileName = "Offline-Client.db";
Expand All @@ -96,4 +98,17 @@

await ReadDataSample();
}

private async Task ReCreateDatabase()
{
await using var dbContext = await DbContextFactory.CreateDbContextAsync();

await dbContext.Database.EnsureDeletedAsync();

// This method is automatically invoked by Besql the first time the app runs.
// If you need to drop and recreate the database multiple times within the same app session, you must call this method manually.
await dbContext.Database.ConfigureSqliteSynchronous();

await dbContext.Database.MigrateAsync();
}
}
Loading