- Wire up lists and todos to C# backend with full CRUD persistence - Add models, DTOs, repositories, and services for lists and todo lists/items - Preserve SQLite DB across vault rebuild/load cycles - Add session store for vault password persistence across navigation - Add inline name input for creating lists and todo lists in SidePanel - Clear editor panel on section change with empty state placeholder - Default markdown editor to preview mode on item selection - Decompose EditorPanel into sub-components: - editor/FragmentEditor, editor/TodoEditor, editor/MarkdownEditor - Shared markdown utilities in utils/markdown.ts - Strip verbose console/eprintln logging from frontend and Tauri backend - Add graceful shutdown with vault persistence on window close Co-Authored-By: Oz <oz-agent@warp.dev>
71 lines
1.8 KiB
C#
71 lines
1.8 KiB
C#
using Microsoft.Data.Sqlite;
|
|
|
|
namespace Journal.Core.Services.Database;
|
|
|
|
public sealed class DatabaseSessionService(IJournalDatabaseService database) : IDatabaseSessionService, IDisposable
|
|
{
|
|
private readonly IJournalDatabaseService _database = database;
|
|
private readonly Lock _lock = new();
|
|
private string? _password;
|
|
private string? _dataDirectory;
|
|
private SqliteConnection? _connection;
|
|
|
|
public bool IsUnlocked
|
|
{
|
|
get
|
|
{
|
|
lock (_lock) { return _password is not null; }
|
|
}
|
|
}
|
|
|
|
public void SetPassword(string password, string? dataDirectory = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(password))
|
|
throw new ArgumentException("Password cannot be empty.", nameof(password));
|
|
|
|
lock (_lock)
|
|
{
|
|
if (_connection is not null &&
|
|
(_password != password || _dataDirectory != dataDirectory))
|
|
{
|
|
_connection.Dispose();
|
|
_connection = null;
|
|
}
|
|
|
|
_password = password;
|
|
_dataDirectory = dataDirectory;
|
|
}
|
|
}
|
|
|
|
public SqliteConnection GetConnection()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_password is null)
|
|
throw new InvalidOperationException(
|
|
"Database is locked. Authenticate first (e.g. vault.load_all or db.hydrate_workspace).");
|
|
|
|
if (_connection is not null)
|
|
return _connection;
|
|
|
|
_connection = _database.OpenEncryptedConnection(_password, _dataDirectory);
|
|
_database.EnsureSchema(_connection);
|
|
return _connection;
|
|
}
|
|
}
|
|
|
|
public void CloseConnection()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_connection?.Dispose();
|
|
_connection = null;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
CloseConnection();
|
|
}
|
|
}
|