WingMan – Rev 37
?pathlinks?
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mono.Data.Sqlite;
namespace WingMan.AutoCompletion
{
public class AutoCompletion : IDisposable
{
public delegate void LoadFailed(object sender, AutoCompletionFailedEventArgs args);
public delegate void SaveFailed(object sender, AutoCompletionFailedEventArgs args);
public AutoCompletion()
{
}
public AutoCompletion(TaskScheduler taskScheduler, CancellationToken cancellationToken) : this()
{
TaskScheduler = taskScheduler;
CancellationToken = cancellationToken;
}
private TaskScheduler TaskScheduler { get; }
private CancellationToken CancellationToken { get; }
public void Dispose()
{
}
public event SaveFailed OnSaveFailed;
public event LoadFailed OnLoadFailed;
public async Task Save(string name, AutoCompleteStringCollection autoCompleteStringCollection)
{
try
{
using (var sqliteConnection =
new SqliteConnection($"URI=file:{"Autocomplete.db"}"))
{
await sqliteConnection.OpenAsync(CancellationToken);
// Create table if it does not exist.
using (var sqliteCommand =
new SqliteCommand($"CREATE TABLE IF NOT EXISTS {name} (data text UNIQUE NOT NULL)",
sqliteConnection))
{
using (var dbtransaction = sqliteConnection.BeginTransaction())
{
try
{
await sqliteCommand.ExecuteReaderAsync(CancellationToken);
dbtransaction.Commit();
}
catch
{
dbtransaction.Rollback();
throw;
}
}
}
// Add all items to the database.
await Task.Delay(0, CancellationToken).ContinueWith(async _ =>
{
foreach (var sourceItem in autoCompleteStringCollection)
{
var data = sourceItem.ToString();
using (var sqliteCommand =
new SqliteCommand($"REPLACE INTO {name} (data) VALUES (:data)",
sqliteConnection))
{
sqliteCommand
.Parameters
.Add(new SqliteParameter("data", data));
using (var dbtransaction = sqliteConnection.BeginTransaction())
{
try
{
await sqliteCommand.ExecuteReaderAsync(CancellationToken);
dbtransaction.Commit();
}
catch
{
dbtransaction.Rollback();
throw;
}
}
}
}
}, CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
}
}
catch (Exception ex)
{
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnSaveFailed?.Invoke(this,
new AutoCompletionFailedEventArgs(AutoCompletionFailedType.Save, name, ex)), CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
}
}
public async Task Load(string name, AutoCompleteStringCollection autoCompleteStringCollection)
{
try
{
using (var sqliteConnection =
new SqliteConnection($"URI=file:{"Autocomplete.db"}"))
{
await sqliteConnection.OpenAsync(CancellationToken);
// Create table if it does not exist.
using (var sqliteCommand =
new SqliteCommand($"CREATE TABLE IF NOT EXISTS {name} (data text UNIQUE NOT NULL)",
sqliteConnection))
{
using (var dbtransaction = sqliteConnection.BeginTransaction())
{
try
{
await sqliteCommand.ExecuteReaderAsync(CancellationToken);
dbtransaction.Commit();
}
catch
{
dbtransaction.Rollback();
throw;
}
}
}
using (var sqliteCommand =
new SqliteCommand($"SELECT data FROM {name}", sqliteConnection))
{
using (var dbtransaction = sqliteConnection.BeginTransaction())
{
try
{
using (var reader = await sqliteCommand.ExecuteReaderAsync(CancellationToken))
{
while (await reader.ReadAsync(CancellationToken))
for (var i = 0; i < reader.FieldCount; ++i)
{
var value = reader.GetString(i);
if (string.IsNullOrEmpty(value))
continue;
await Task.Delay(0, CancellationToken).ContinueWith(
_ => autoCompleteStringCollection.Add(value), CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
}
}
dbtransaction.Commit();
}
catch
{
dbtransaction.Rollback();
throw;
}
}
}
}
}
catch (Exception ex)
{
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnLoadFailed?.Invoke(this,
new AutoCompletionFailedEventArgs(AutoCompletionFailedType.Load, name, ex)), CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
}
}
}
}