Horizon

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 11  →  ?path2? @ 12
/Horizon/Database/SnapshotDatabase.cs
@@ -46,6 +46,12 @@
private const string RemoveSnapshotFromHashSql =
"DELETE FROM \"Snapshots\" WHERE Hash = @hash";
 
private const string GetTransferSnapshotFromHashSql =
"SELECT \"Name\", \"Path\", \"Time\", \"Data\", \"Shot\", \"Color\", \"Hash\", \"Note\" FROM \"Snapshots\" WHERE Hash = @hash";
 
private const string SetTransferSnapshotSql =
"INSERT INTO \"Snapshots\" ( \"Name\", \"Path\", \"Time\", \"Data\", \"Shot\", \"Color\", \"Hash\", \"Note\" ) VALUES ( @name, @path, @time, zeroblob(@dataLength), zeroblob(@shotLength), @color, @hash, @note )";
 
private const string RemoveScreenshotFromHashSql =
"UPDATE \"Snapshots\" SET Shot = null WHERE Hash = @hash";
 
@@ -376,6 +382,282 @@
}
}
 
public async Task SetCompleteSnapshotAsync(TransferSnapshot transferSnapshot, CancellationToken cancellationToken)
{
await _databaseLock.WaitAsync(cancellationToken);
try
{
using (var sqliteConnection =
new SQLiteConnection(_sqliteConnectionStringBuilder.ConnectionString))
{
await sqliteConnection.OpenAsync(cancellationToken);
 
using (var dbTransaction = sqliteConnection.BeginTransaction())
{
try
{
using (var dataMemoryStream = new MemoryStream())
{
using (var dataZipStream =
new GZipStream(dataMemoryStream, CompressionMode.Compress, true))
{
dataMemoryStream.Position = 0L;
await dataZipStream.WriteAsync(transferSnapshot.Data, 0,
transferSnapshot.Data.Length, cancellationToken);
dataZipStream.Close();
 
using (var bitmapMemoryStream = new MemoryStream())
{
bitmapMemoryStream.Position = 0L;
using (var bitmapZipStream =
new GZipStream(bitmapMemoryStream, CompressionMode.Compress,
true))
{
using (var transferImageStream = new MemoryStream(transferSnapshot.Shot))
{
transferImageStream.Position = 0L;
await transferImageStream.CopyToAsync(bitmapZipStream);
bitmapZipStream.Close();
bitmapMemoryStream.Position = 0L;
 
var a = bitmapMemoryStream.ToArray();
 
// Insert the file change.
using (var sqliteCommand =
new SQLiteCommand(SetTransferSnapshotSql, sqliteConnection,
dbTransaction))
{
sqliteCommand.Parameters.AddRange(new[]
{
new SQLiteParameter("@name", transferSnapshot.Name),
new SQLiteParameter("@path", transferSnapshot.Path),
new SQLiteParameter("@time", transferSnapshot.Time),
new SQLiteParameter("@dataLength",
dataMemoryStream.Length),
new SQLiteParameter("@shotLength",
bitmapMemoryStream.Length),
new SQLiteParameter("@hash", transferSnapshot.Hash),
new SQLiteParameter("@note", transferSnapshot.Note)
});
 
var numeric = transferSnapshot.Color;
switch (numeric)
{
case 0:
sqliteCommand.Parameters.Add(
new SQLiteParameter("@color", null));
break;
default:
sqliteCommand.Parameters.Add(
new SQLiteParameter("@color", numeric));
break;
}
 
sqliteCommand.Prepare();
 
await sqliteCommand.ExecuteNonQueryAsync(cancellationToken);
}
 
// Insert the data blobs.
using (var sqliteCommand =
new SQLiteCommand(GetLastRowInsertSql, sqliteConnection,
dbTransaction))
{
sqliteCommand.Prepare();
 
var rowId =
(long)await sqliteCommand.ExecuteScalarAsync(
cancellationToken);
 
using (var sqliteBlob =
SQLiteBlob.Create(sqliteConnection, "main",
"Snapshots",
"Data",
rowId,
false))
{
var fileMemoryStreamData = dataMemoryStream.ToArray();
 
sqliteBlob.Write(fileMemoryStreamData,
fileMemoryStreamData.Length,
0);
}
 
using (var sqliteBlob =
SQLiteBlob.Create(sqliteConnection, "main",
"Snapshots",
"Shot",
rowId,
false))
{
var bitmapMemoryStreamData =
bitmapMemoryStream.ToArray();
 
sqliteBlob.Write(bitmapMemoryStreamData,
bitmapMemoryStreamData.Length,
0);
}
}
 
dbTransaction.Commit();
 
SnapshotCreate?.Invoke(this,
new SnapshotCreateSuccessEventArgs(transferSnapshot.Name,
transferSnapshot.Time, transferSnapshot.Path,
Color.FromArgb(transferSnapshot.Color),
transferSnapshot.Hash));
}
}
}
}
}
}
catch (SQLiteException exception)
{
dbTransaction.Rollback();
 
if (exception.ResultCode != SQLiteErrorCode.Constraint)
{
SnapshotCreate?.Invoke(this,
new SnapshotCreateFailureEventArgs(transferSnapshot.Name, transferSnapshot.Path,
Color.FromArgb(transferSnapshot.Color), exception));
}
 
throw;
}
catch (Exception exception)
{
dbTransaction.Rollback();
 
SnapshotCreate?.Invoke(this,
new SnapshotCreateFailureEventArgs(transferSnapshot.Name, transferSnapshot.Path,
Color.FromArgb(transferSnapshot.Color), exception));
 
throw;
}
}
}
}
finally
{
_databaseLock.Release();
}
}
 
 
public async Task<TransferSnapshot> GetCompleteSnapshot(string hash, CancellationToken cancellationToken)
{
await _databaseLock.WaitAsync(cancellationToken);
try
{
using (var sqliteConnection =
new SQLiteConnection(_sqliteConnectionStringBuilder.ConnectionString))
{
await sqliteConnection.OpenAsync(cancellationToken);
 
// Insert the file change.
using (var sqliteCommand = new SQLiteCommand(GetTransferSnapshotFromHashSql, sqliteConnection))
{
 
sqliteCommand.Parameters.AddRange(new[]
{
new SQLiteParameter("@hash", hash)
});
 
sqliteCommand.Prepare();
 
using (var sqlDataReader = await sqliteCommand.ExecuteReaderAsync(cancellationToken))
{
//var snapshots = new List<Snapshot>();
while (await sqlDataReader.ReadAsync(cancellationToken))
{
var name = (string)sqlDataReader["Name"];
var path = (string)sqlDataReader["Path"];
var time = (string)sqlDataReader["Time"];
 
var color = Color.Empty;
 
if (!(sqlDataReader["Color"] is DBNull))
{
var dbColor = Convert.ToInt32(sqlDataReader["Color"]);
 
switch (dbColor)
{
case 0:
color = Color.Empty;
break;
default:
color = Color.FromArgb(dbColor);
break;
}
}
 
var note = string.Empty;
 
if (!(sqlDataReader["Note"] is DBNull))
{
note = (string)sqlDataReader["Note"];
}
 
Bitmap shot = null;
 
if (!(sqlDataReader["Shot"] is DBNull))
{
var readStream = sqlDataReader.GetStream(4);
 
readStream.Position = 0L;
 
using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress))
{
using (var image = Image.FromStream(zipStream))
{
shot = new Bitmap(image);
}
}
}
 
byte[] data = null;
if (!(sqlDataReader["Data"] is DBNull))
{
using (var readStream = sqlDataReader.GetStream(3))
{
using (var memoryStream = new MemoryStream())
{
readStream.Position = 0L;
 
await readStream.CopyToAsync(memoryStream);
 
memoryStream.Position = 0L;
 
using (var zipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
// Do not dispose the returned stream and leave it up to callers to dispose.
var outputStream = new MemoryStream();
 
await zipStream.CopyToAsync(outputStream);
 
outputStream.Position = 0L;
 
data = outputStream.ToArray();
}
}
}
}
 
return new TransferSnapshot(name, path, time, hash, color, shot, note, data);
}
}
}
}
}
finally
{
_databaseLock.Release();
}
 
return null;
}
 
public async Task CreateSnapshotAsync(string name, string path, Color color, CancellationToken cancellationToken)
{
await _databaseLock.WaitAsync(cancellationToken);
@@ -1095,13 +1377,21 @@
 
readStream.Position = 0L;
 
using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress))
try
{
using (var image = Image.FromStream(zipStream))
using (var zipStream = new GZipStream(readStream, CompressionMode.Decompress))
{
shot = new Bitmap(image);
using (var image = Image.FromStream(zipStream))
{
shot = new Bitmap(image);
}
}
}
catch (Exception exception)
{
Log.Error(exception, $"Could not retrieve image preview for snapshot {hash}.");
return null;
}
}
 
return new SnapshotPreview(hash, shot, note);
@@ -1501,5 +1791,7 @@
}
 
#endregion
 
 
}
}