mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-05 02:47:21 +00:00
Added a way to read what the AI received from your sources (#1100)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
e0d8e18f34
commit
cbc4ce5413
229 files changed
+12739
-1269
No files matched your search
@@ -0,0 +1,85 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace AIStudio.Tools.Databases;
|
||||
|
||||
/// <summary>
|
||||
/// Copies a SQLite database while AI Studio keeps using it, e.g., for a backup.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// VACUUM INTO writes a consistent snapshot of the database, including what the write-ahead log
|
||||
/// still holds, and in WAL mode, reading it holds back no writer.<br/><br/>
|
||||
///
|
||||
/// It runs on connections of their own, although the databases guide has raw SQL go through
|
||||
/// GetDbConnection. The connections of a context share one cache, and a shared cache locks whole
|
||||
/// tables: reading the whole database for the copy would hold back every writer until the copy is
|
||||
/// done. Without pooling, nothing keeps the copy open afterward, so the caller can delete it on
|
||||
/// every OS.<br/><br/>
|
||||
///
|
||||
/// SQLite runs its async methods synchronously, and copying and checking a large database takes a
|
||||
/// while. The callers therefore run this on a thread of their own, so that it never holds up theirs.
|
||||
/// </remarks>
|
||||
internal static class SqliteDatabaseCopy
|
||||
{
|
||||
/// <summary>
|
||||
/// Copies a database into a file and checks the copy.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A copy which fails its check is removed, and an InvalidOperationException says so.
|
||||
/// </remarks>
|
||||
/// <param name="databasePath">The database to copy.</param>
|
||||
/// <param name="targetPath">The file of the copy. A file there is replaced.</param>
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
public static async Task CopyAndCheckAsync(string databasePath, string targetPath, CancellationToken token)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
|
||||
|
||||
// VACUUM INTO refuses to write into a file which holds anything:
|
||||
if (File.Exists(targetPath))
|
||||
File.Delete(targetPath);
|
||||
|
||||
try
|
||||
{
|
||||
await using (var connection = new SqliteConnection(BuildConnectionString(databasePath, SqliteOpenMode.ReadWrite)))
|
||||
{
|
||||
await connection.OpenAsync(token);
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = "VACUUM INTO $targetPath;";
|
||||
command.Parameters.AddWithValue("$targetPath", targetPath);
|
||||
await command.ExecuteNonQueryAsync(token);
|
||||
}
|
||||
|
||||
await using (var connection = new SqliteConnection(BuildConnectionString(targetPath, SqliteOpenMode.ReadOnly)))
|
||||
{
|
||||
await connection.OpenAsync(token);
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = "PRAGMA quick_check;";
|
||||
|
||||
var checkResult = (await command.ExecuteScalarAsync(token))?.ToString();
|
||||
if (checkResult is not "ok")
|
||||
throw new InvalidOperationException($"The copy of the database at '{targetPath}' failed its check: '{checkResult}'.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (File.Exists(targetPath))
|
||||
File.Delete(targetPath);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the connection string for a connection of its own, which shares no cache and stays in no pool.
|
||||
/// </summary>
|
||||
/// <param name="path">The database.</param>
|
||||
/// <param name="mode">How to open it.</param>
|
||||
/// <returns>The connection string.</returns>
|
||||
public static string BuildConnectionString(string path, SqliteOpenMode mode) => new SqliteConnectionStringBuilder
|
||||
{
|
||||
DataSource = path,
|
||||
Mode = mode,
|
||||
Cache = SqliteCacheMode.Private,
|
||||
Pooling = false,
|
||||
DefaultTimeout = 30,
|
||||
}.ToString();
|
||||
}
|
||||
Reference in new issue
Block a user