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
27 changes: 26 additions & 1 deletion src/Besql/Bit.Besql/BesqlDbContextInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ namespace Bit.Besql;

public class BesqlDbContextInterceptor(IBesqlStorage storage) : IDbCommandInterceptor, ISingletonInterceptor
{
private string[] keywords = ["INSERT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP"];

public DbDataReader ReaderExecuted(
DbCommand command,
CommandExecutedEventData eventData,
DbDataReader result)
{
throw new BesqlNonAsyncOperationException();
}

public async ValueTask<DbDataReader> ReaderExecutedAsync(
DbCommand command,
CommandExecutedEventData eventData,
Expand All @@ -21,6 +31,14 @@ public async ValueTask<DbDataReader> ReaderExecutedAsync(
return result;
}

public int NonQueryExecuted(
DbCommand command,
CommandExecutedEventData eventData,
int result)
{
throw new BesqlNonAsyncOperationException();
}

public async ValueTask<int> NonQueryExecutedAsync(
DbCommand command,
CommandExecutedEventData eventData,
Expand All @@ -35,6 +53,14 @@ public async ValueTask<int> NonQueryExecutedAsync(
return result;
}

public object? ScalarExecuted(
DbCommand command,
CommandExecutedEventData eventData,
object? result)
{
throw new BesqlNonAsyncOperationException();
}

public async ValueTask<object?> ScalarExecutedAsync(
DbCommand command,
CommandExecutedEventData eventData,
Expand All @@ -50,7 +76,6 @@ public async ValueTask<int> NonQueryExecutedAsync(

protected virtual bool IsTargetedCommand(string sql)
{
var keywords = new[] { "INSERT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP" };
return keywords.Any(k => sql.Contains(k, StringComparison.OrdinalIgnoreCase));
}

Expand Down
5 changes: 5 additions & 0 deletions src/Besql/Bit.Besql/BesqlNonAsyncOperationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Bit.Besql;

public class BesqlNonAsyncOperationException() : ApplicationException("bit Besql only supports async operations.")
{
}
27 changes: 27 additions & 0 deletions src/Besql/Bit.Besql/BrowserCacheBesqlStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,40 @@ namespace Bit.Besql;

public sealed class BrowserCacheBesqlStorage(IJSRuntime jsRuntime) : IBesqlStorage
{
HashSet<string>? pausedFilesList;

public async Task Init(string filename)
{
await jsRuntime.InvokeVoidAsync("BitBesql.init", filename).ConfigureAwait(false);
}

public async Task Persist(string filename)
{
if (pausedFilesList is not null)
{
pausedFilesList.Add(filename);
return;
}

await jsRuntime.InvokeVoidAsync("BitBesql.persist", filename).ConfigureAwait(false);
}

public void PauseSync()
{
pausedFilesList = [];
}

public async Task ResumeSync()
{
if (pausedFilesList is null)
throw new InvalidOperationException("bit Besql storage is not paused.");

var files = pausedFilesList;
pausedFilesList = null;

foreach (var file in files)
{
await Persist(file).ConfigureAwait(false);
}
}
}
4 changes: 4 additions & 0 deletions src/Besql/Bit.Besql/IBesqlStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ public interface IBesqlStorage
Task Init(string filename);

Task Persist(string filename);

void PauseSync();

Task ResumeSync();
}
9 changes: 9 additions & 0 deletions src/Besql/Bit.Besql/NoopBesqlStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ public Task Persist(string filename)
{
return Task.CompletedTask;
}

public void PauseSync()
{
}

public Task ResumeSync()
{
return Task.CompletedTask;
}
}
47 changes: 37 additions & 10 deletions src/Besql/Demo/Bit.Besql.Demo.Client/Pages/Weather.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@using Microsoft.EntityFrameworkCore
@using Bit.Besql.Demo.Client.Data

@inject IBesqlStorage BesqlStorage;
@inject IDbContextFactory<OfflineDbContext> DbContextFactory

<PageTitle>Weather</PageTitle>
Expand All @@ -20,6 +21,8 @@ else
{
<button class="btn btn-primary" @onclick="AddWeatherForecast">Add weather forecast</button>
<button class="btn btn-primary" @onclick="DeleteSomeForecasts">Delete some forecasts</button>
<button class="btn btn-primary" @onclick="PauseResumeSync">Pause / resume sync</button>
<button class="btn btn-primary" @onclick="NonAsyncOperationError">Non async operation error</button>

<h1>@forecastsCount</h1>
}
Expand All @@ -32,17 +35,17 @@ else
{
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
await dbContext.WeatherForecasts.AddAsync(new()
{
Date = new DateTimeOffset(2024, 1, 4, 10, 10, 10, TimeSpan.Zero),
Summary = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z ",
TemperatureC = Random.Shared.Next(1, 30)
});
{
Date = new DateTimeOffset(2024, 1, 4, 10, 10, 10, TimeSpan.Zero),
Summary = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z ",
TemperatureC = Random.Shared.Next(1, 30)
});
await dbContext.WeatherForecasts.AddAsync(new()
{
Date = new DateTimeOffset(2024, 1, 4, 10, 10, 10, TimeSpan.Zero),
Summary = "Test",
TemperatureC = Random.Shared.Next(1, 30)
});
{
Date = new DateTimeOffset(2024, 1, 4, 10, 10, 10, TimeSpan.Zero),
Summary = "Test",
TemperatureC = Random.Shared.Next(1, 30)
});
await dbContext.SaveChangesAsync();
forecastsCount += 2;
}
Expand All @@ -59,6 +62,30 @@ else
forecastsCount -= deletedCount;
}

private async Task PauseResumeSync()
{
BesqlStorage.PauseSync();

try
{
await AddWeatherForecast();

await Task.Delay(5_000);

await AddWeatherForecast();
}
finally
{
await BesqlStorage.ResumeSync();
}
}

private void NonAsyncOperationError()
{
using var dbContext = DbContextFactory.CreateDbContext();
forecastsCount = dbContext.WeatherForecasts.Count(); // This wouldn't work in blazor wasm / besql.
}

protected override async Task OnInitializedAsync()
{
await using var dbContext = await DbContextFactory.CreateDbContextAsync();
Expand Down
Loading