mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-05-08 23:54:10 -04:00
move new check into datalayer
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.2" />
|
||||
<PackageReference Include="CsvHelper" Version="33.1.0">
|
||||
<PrivateAssets>compile;contentFiles;build;buildMultitargeting;buildTransitive;analyzers;native</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using DataLayer;
|
||||
using LibationFileManager;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ApplicationServices;
|
||||
@@ -17,29 +14,9 @@ public static class DbContexts
|
||||
var context = !string.IsNullOrEmpty(Configuration.Instance.PostgresqlConnectionString)
|
||||
? LibationContextFactory.CreatePostgres(Configuration.Instance.PostgresqlConnectionString)
|
||||
: LibationContextFactory.CreateSqlite(SqliteStorage.ConnectionString);
|
||||
try
|
||||
{
|
||||
context.Database.Migrate();
|
||||
}
|
||||
// SQLITE_READONLY == 8 (https://www.sqlite.org/rescode.html)
|
||||
catch (SqliteException ex) when (ex.SqliteErrorCode == 8)
|
||||
{
|
||||
var dbPath = SqliteStorage.DatabasePath;
|
||||
throw new InvalidOperationException(
|
||||
$"""
|
||||
Libation cannot write its SQLite database (migrations need write access).
|
||||
|
||||
Database path:
|
||||
{dbPath}
|
||||
|
||||
This usually means the folder or the database file is not writable by your user (wrong owner or permissions), or the location is on a read-only or restricted filesystem.
|
||||
|
||||
On Linux: check ownership and permissions on that folder (for example chmod/chown). Snap installs often store data under ~/snap/libation/<revision>/.local/share/Libation — that entire tree must be writable.
|
||||
|
||||
If the problem continues, try moving the Libation Files location (Settings) to a folder you know is writable, or use the non-Snap build if Snap confinement is blocking writes.
|
||||
""",
|
||||
ex);
|
||||
}
|
||||
LibationContextFactory.ApplyMigrations(
|
||||
context,
|
||||
string.IsNullOrEmpty(Configuration.Instance.PostgresqlConnectionString) ? SqliteStorage.DatabasePath : null);
|
||||
|
||||
// Validate SQLite DB file was created and is accessible (once per process; OS may delay availability)
|
||||
if (!_sqliteDbValidated && string.IsNullOrEmpty(Configuration.Instance.PostgresqlConnectionString))
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DataLayer;
|
||||
|
||||
@@ -37,4 +40,59 @@ public class LibationContextFactory
|
||||
|
||||
return new LibationContext(options.Options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs EF migrations. For SQLite, wraps SQLITE_READONLY (8) with a clearer message including <paramref name="sqliteDatabaseFilePath"/>.
|
||||
/// Pass <paramref name="sqliteDatabaseFilePath"/> as null when the context is not SQLite.
|
||||
/// </summary>
|
||||
public static void ApplyMigrations(LibationContext context, string? sqliteDatabaseFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
context.Database.Migrate();
|
||||
}
|
||||
// SQLITE_READONLY == 8 (https://www.sqlite.org/rescode.html)
|
||||
catch (SqliteException ex) when (ex.SqliteErrorCode == 8 && sqliteDatabaseFilePath is not null)
|
||||
{
|
||||
throw CreateSqliteReadonlyException(sqliteDatabaseFilePath, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ApplyMigrations(LibationContext, string?)"/>
|
||||
public static async Task ApplyMigrationsAsync(LibationContext context, string? sqliteDatabaseFilePath, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await context.Database.MigrateAsync(cancellationToken);
|
||||
}
|
||||
// SQLITE_READONLY == 8 (https://www.sqlite.org/rescode.html)
|
||||
catch (SqliteException ex) when (ex.SqliteErrorCode == 8 && sqliteDatabaseFilePath is not null)
|
||||
{
|
||||
throw CreateSqliteReadonlyException(sqliteDatabaseFilePath, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static InvalidOperationException CreateSqliteReadonlyException(string sqliteDatabaseFilePath, SqliteException ex)
|
||||
{
|
||||
// Match LibationFileManager.Configuration.IsLinux (OperatingSystem.IsLinux); avoid referencing that project from DataLayer.
|
||||
var linuxSection = OperatingSystem.IsLinux()
|
||||
? "\n\nOn Linux: check ownership and permissions on that folder (for example chmod/chown). Snap installs often store data under ~/snap/libation/<revision>/.local/share/Libation — that entire tree must be writable."
|
||||
: "";
|
||||
var snapHint = OperatingSystem.IsLinux()
|
||||
? ", or use the non-Snap build if Snap confinement is blocking writes"
|
||||
: "";
|
||||
|
||||
return new InvalidOperationException(
|
||||
$"""
|
||||
Libation cannot write its SQLite database (migrations need write access).
|
||||
|
||||
Database path:
|
||||
{sqliteDatabaseFilePath}
|
||||
|
||||
This usually means the folder or the database file is not writable by your user (wrong owner or permissions), or the location is on a read-only or restricted filesystem.{linuxSection}
|
||||
|
||||
If the problem continues, try moving the Libation Files location (Settings) to a folder you know is writable{snapHint}.
|
||||
""",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ public class CopyDbOptions : OptionsBase
|
||||
using var source = LibationContextFactory.CreateSqlite(srcConnectionString);
|
||||
using var destination = LibationContextFactory.CreatePostgres(destConnectionString);
|
||||
|
||||
await source.Database.MigrateAsync();
|
||||
await LibationContextFactory.ApplyMigrationsAsync(source, SqliteStorage.DatabasePath);
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Creating destination database...");
|
||||
await destination.Database.MigrateAsync();
|
||||
await LibationContextFactory.ApplyMigrationsAsync(destination, null);
|
||||
Console.WriteLine("Destination database recreated.");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user