/// <inheritdoc />
        public async Task UpdateEntryAsync(ResourceEntry entry)
        {
            using (var connection = this.ConnectionSupplier.GetConnection(this.ConnectionString))
            {
                await connection.OpenAsync();

                long resourceId;
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = "SELECT ResourceId FROM StreamHash WHERE Hash LIKE @hash";
                    command.AddWithValue("hash", $"{entry.ResourceRoots.First()}%");

                    using (var result = await command.ExecuteReaderAsync())
                    {
                        if (result.Read())
                        {
                            resourceId = (long)result["ResourceId"];
                        }
                        else
                        {
                            throw new ResourceNotFoundException(entry.ResourceRoots.First());
                        }
                    }
                }

                using (var transaction = connection.BeginTransaction())
                {
                    foreach (var hash in entry.ResourceRoots)
                    {
                        using (var command = connection.CreateCommand())
                        {
                            command.CommandText = "INSERT OR IGNORE INTO StreamHash (Hash, ResourceId) VALUES (@hash, @resourceId)";
                            command.Transaction = transaction;

                            command.AddWithValue("hash", hash);
                            command.AddWithValue("resourceId", resourceId);

                            await command.ExecuteNonQueryAsync();
                        }
                    }

                    var encryptedChannel      = this.Encryption.Encrypt(entry.ChannelToJson());
                    var encryptedSubscription = this.Encryption.Encrypt(entry.SubscriptionToJson());

                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = $"UPDATE Resource SET Channel=@encryptedChannel, Subscription=@encryptedSubscription WHERE Id=@resourceId;";
                        command.Transaction = transaction;

                        command.AddWithValue("encryptedChannel", encryptedChannel);
                        command.AddWithValue("encryptedSubscription", encryptedSubscription);
                        command.AddWithValue("resourceId", resourceId);

                        await command.ExecuteNonQueryAsync();
                    }

                    transaction.Commit();
                }
            }
        }
 public static EncryptedResourceEntry FromResourceEntry(ResourceEntry resourceEntry, IEncryption encryption)
 {
     return(new EncryptedResourceEntry
     {
         Channel = encryption.Encrypt(resourceEntry.ChannelToJson()),
         Subscription = encryption.Encrypt(resourceEntry.SubscriptionToJson()),
         Roots = string.Join(";", resourceEntry.ResourceRoots),
         Id = resourceEntry.ResourceRoots[0].Substring(0, 64)
     });
 }
        /// <inheritdoc />
        public async Task AddEntryAsync(ResourceEntry entry)
        {
            using (var connection = this.ConnectionSupplier.GetConnection(this.ConnectionString))
            {
                await connection.OpenAsync();

                long resourceId;

                var encryptedChannel      = this.Encryption.Encrypt(entry.ChannelToJson());
                var encryptedSubscription = this.Encryption.Encrypt(entry.SubscriptionToJson());

                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        "INSERT INTO Resource (Channel, Subscription) VALUES (@encryptedChannel, @encryptedSubscription); SELECT last_insert_rowid();";

                    command.AddWithValue("encryptedChannel", encryptedChannel);
                    command.AddWithValue("encryptedSubscription", encryptedSubscription);

                    resourceId = (long)await command.ExecuteScalarAsync();
                }

                using (var transaction = connection.BeginTransaction())
                {
                    foreach (var hash in entry.ResourceRoots)
                    {
                        using (var command = connection.CreateCommand())
                        {
                            command.CommandText = "INSERT OR IGNORE INTO StreamHash (Hash, ResourceId) VALUES (@hash, @resourceId)";
                            command.Transaction = transaction;

                            command.AddWithValue("hash", hash);
                            command.AddWithValue("resourceId", resourceId);

                            await command.ExecuteNonQueryAsync();
                        }
                    }

                    transaction.Commit();
                }
            }
        }