fix(DbExporter): fix compressed size calculation and clean up

- Move file size read after streams are disposed to get accurate compressed size
- Clean up definition files to use working example queries
- Add .gitignore for output directory
This commit is contained in:
Joseph Doherty
2026-01-06 17:06:16 -05:00
parent f61a64b059
commit d2136cacf7
16 changed files with 795 additions and 84 deletions
+18 -12
View File
@@ -29,30 +29,36 @@ public sealed class DatabaseExporter
await using var baseReader = await command.ExecuteReaderAsync(cancellationToken);
var reader = new CountingDataReader(baseReader);
long uncompressedSize = 0;
long uncompressedSize;
string hash;
int rowCount;
// Use a counting stream wrapper to track uncompressed bytes
using var sha256 = SHA256.Create();
await using var outputFile = new FileStream(definition.OutputPath, FileMode.Create, FileAccess.Write, FileShare.None, 256 * 1024);
await using var compressStream = new CompressionStream(outputFile, definition.CompressionLevel);
await using var countingStream = new CountingStream(compressStream);
await using var hashStream = new CryptoStream(countingStream, sha256, CryptoStreamMode.Write);
using (var sha256 = SHA256.Create())
{
await using var outputFile = new FileStream(definition.OutputPath, FileMode.Create, FileAccess.Write, FileShare.None, 256 * 1024);
await using var compressStream = new CompressionStream(outputFile, definition.CompressionLevel);
await using var countingStream = new CountingStream(compressStream);
await using var hashStream = new CryptoStream(countingStream, sha256, CryptoStreamMode.Write);
// Serialize to protobuf
DataSerializer.Serialize(hashStream, reader);
// Serialize to protobuf
DataSerializer.Serialize(hashStream, reader);
hashStream.FlushFinalBlock();
uncompressedSize = countingStream.BytesWritten;
hashStream.FlushFinalBlock();
uncompressedSize = countingStream.BytesWritten;
rowCount = reader.RowCount;
var hash = Convert.ToHexString(sha256.Hash!).ToLowerInvariant();
hash = Convert.ToHexString(sha256.Hash!).ToLowerInvariant();
} // All streams disposed here, file fully written
// Write sidecar hash file
var hashFilePath = definition.OutputPath + ".sha256";
await File.WriteAllTextAsync(hashFilePath, hash, cancellationToken);
// Read file size after streams are closed
var compressedSize = new FileInfo(definition.OutputPath).Length;
return new ExportResult(reader.RowCount, uncompressedSize, compressedSize, hash);
return new ExportResult(rowCount, uncompressedSize, compressedSize, hash);
}
private static DbConnection CreateConnection(string providerType, string connectionString)