예제 #1
0
        public async Task DeleteBlobAsync(BlobName name, CancellationToken cancellationToken = default)
        {
            var nameParameter = CreateSqlParameter(
                "@Name",
                SqlDbType.NVarChar,
                BlobName.MaxLength,
                name.ToString());

            using (var connection = new SqlConnection(_builder.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var transaction = connection.BeginTransaction(IsolationLevel.Snapshot))
                {
                    using (var command = new SqlCommand(_text.DeleteBlob(), connection, transaction)
                    {
                        CommandType = CommandType.Text,
                        Parameters = { nameParameter }
                    })
                    {
                        await command.ExecuteNonQueryAsync(cancellationToken);
                    }

                    transaction.Commit();
                }
            }
        }
예제 #2
0
        public async Task CreateBlobAsync(
            BlobName name,
            Metadata metadata,
            ContentType contentType,
            Stream content,
            CancellationToken cancellationToken = default)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            var nameParameter = CreateSqlParameter(
                "@Name",
                SqlDbType.NVarChar,
                BlobName.MaxLength,
                name.ToString());
            var metadataParameter = CreateSqlParameter(
                "@Metadata",
                SqlDbType.NVarChar,
                -1,
                MetadataToString(metadata));
            var contentTypeParameter = CreateSqlParameter(
                "@ContentType",
                SqlDbType.NVarChar,
                ContentType.MaxLength,
                contentType.ToString());
            var contentParameter = CreateSqlParameter(
                "@Content",
                SqlDbType.VarBinary,
                -1,
                content);

            using (var connection = new SqlConnection(_builder.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var transaction = connection.BeginTransaction(IsolationLevel.Snapshot))
                {
                    using (var command = new SqlCommand(_text.CreateBlob(), connection, transaction)
                    {
                        CommandType = CommandType.Text,
                        Parameters = { nameParameter, metadataParameter, contentTypeParameter, contentParameter }
                    })
                    {
                        try
                        {
                            await command.ExecuteNonQueryAsync(cancellationToken);
                        }
                        catch (SqlException exception) when(exception.Number == 2627)
                        {
                            throw new BlobAlreadyExistsException(name, exception);
                        }
                    }

                    transaction.Commit();
                }
            }
        }
예제 #3
0
 public async Task DeleteBlobAsync(BlobName name, CancellationToken cancellationToken = default)
 {
     await _client.DeleteObjectAsync(new DeleteObjectRequest
     {
         BucketName = _bucket,
         Key        = name.ToString()
     }, cancellationToken);
 }
예제 #4
0
        public async Task <BlobObject> GetBlobAsync(BlobName name, CancellationToken cancellationToken = default)
        {
            try
            {
                var response = await _client.GetObjectAsync(new GetObjectRequest
                {
                    BucketName = _bucket,
                    Key        = name.ToString(),
                    ByteRange  = NoData
                }, cancellationToken);

                return(new BlobObject(
                           name,
                           ConvertMetadataFromMetadataCollection(response),
                           ContentType.Parse(response.Headers.ContentType),
                           async contentCancellationToken =>
                {
                    try
                    {
                        var contentResponse = await _client.GetObjectAsync(new GetObjectRequest
                        {
                            BucketName = _bucket,
                            Key = name.ToString()
                        }, contentCancellationToken);
                        return new ForwardOnlyStream(contentResponse.ResponseStream);
                    }
                    catch (AmazonS3Exception exception) when(
                        exception.ErrorType == ErrorType.Sender &&
                        string.Equals(exception.ErrorCode, "NoSuchKey", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new BlobNotFoundException(name, exception);
                    }
                }));
            }
            catch (AmazonS3Exception exception) when(
                exception.ErrorType == ErrorType.Sender &&
                string.Equals(exception.ErrorCode, "NoSuchKey", StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }
        }
예제 #5
0
        public static string From(BlobName name)
        {
            var value   = name.ToString().ToCharArray();
            var builder = new StringBuilder(value.Length);

            for (var index = 0; index < value.Length; index++)
            {
                switch (value[index])
                {
                case '!':
                    builder.Append(Convert.ToByte('!').ToString("x"));
                    break;

                case '/':
                    builder.Append(Convert.ToByte('/').ToString("x"));
                    break;

                case '-':
                    builder.Append(Convert.ToByte('-').ToString("x"));
                    break;

                case '_':
                    builder.Append(Convert.ToByte('_').ToString("x"));
                    break;

                case '.':
                    builder.Append(Convert.ToByte('.').ToString("x"));
                    break;

                case '*':
                    builder.Append(Convert.ToByte('*').ToString("x"));
                    break;

                case '\'':
                    builder.Append(Convert.ToByte('\'').ToString("x"));
                    break;

                case '(':
                    builder.Append(Convert.ToByte('(').ToString("x"));
                    break;

                case ')':
                    builder.Append(Convert.ToByte(')').ToString("x"));
                    break;

                default:
                    builder.Append(value[index]);
                    break;
                }
            }
            return(builder.ToString());
        }
예제 #6
0
        public async Task <bool> BlobExistsAsync(BlobName name, CancellationToken cancellationToken = default)
        {
            try
            {
                await _client.GetObjectAsync(new GetObjectRequest
                {
                    BucketName = _bucket,
                    Key        = name.ToString(),
                    ByteRange  = NoData
                }, cancellationToken);

                return(true);
            }
            catch (AmazonS3Exception exception) when(
                exception.ErrorType == ErrorType.Sender &&
                string.Equals(exception.ErrorCode, "NoSuchKey", StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }
        }
예제 #7
0
        public async Task CreateBlobAsync(BlobName name, Metadata metadata, ContentType contentType, Stream content,
                                          CancellationToken cancellationToken = default)
        {
            // S3 does not have real concurrency control, this is simply a best effort approach
            if (await BlobExistsAsync(name, cancellationToken))
            {
                throw new BlobAlreadyExistsException(name);
            }

            var request = new PutObjectRequest
            {
                BucketName              = _bucket,
                Key                     = name.ToString(),
                ContentType             = contentType.ToString(),
                InputStream             = content,
                AutoResetStreamPosition = false,
                AutoCloseStream         = false
            };

            CopyMetadataToMetadataCollection(metadata, request.Metadata);
            await _client.PutObjectAsync(request, cancellationToken);
        }
예제 #8
0
        public async Task <bool> BlobExistsAsync(BlobName name, CancellationToken cancellationToken = default)
        {
            var nameParameter = CreateSqlParameter(
                "@Name",
                SqlDbType.NVarChar,
                BlobName.MaxLength,
                name.ToString());

            using (var connection = new SqlConnection(_builder.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var command = new SqlCommand(_text.BlobExists(), connection)
                {
                    CommandType = CommandType.Text,
                    Parameters = { nameParameter }
                })
                {
                    return(0 != (int)await command.ExecuteScalarAsync(cancellationToken));
                }
            }
        }
예제 #9
0
        public async Task <BlobObject> GetBlobAsync(BlobName name, CancellationToken cancellationToken = default)
        {
            var nameParameter = CreateSqlParameter(
                "@Name",
                SqlDbType.NVarChar,
                BlobName.MaxLength,
                name.ToString());

            using (var connection = new SqlConnection(_builder.ConnectionString))
            {
                await connection.OpenAsync(cancellationToken);

                using (var command = new SqlCommand(_text.GetBlob(), connection)
                {
                    CommandType = CommandType.Text,
                    Parameters = { nameParameter }
                })
                {
                    using (var reader = await command.ExecuteReaderAsync(ReaderBehavior, cancellationToken))
                    {
                        if (!reader.IsClosed && reader.Read())
                        {
                            return(new BlobObject(
                                       name,
                                       MetadataFromString(reader.GetString(0)),
                                       ContentType.Parse(reader.GetString(1)),
                                       async contentCancellationToken =>
                            {
                                var contentConnection = new SqlConnection(_builder.ConnectionString);
                                await contentConnection.OpenAsync(contentCancellationToken);
                                var contentCommand = new SqlCommand(_text.GetBlobContent(), contentConnection)
                                {
                                    CommandType = CommandType.Text,
                                    Parameters =
                                    {
                                        CreateSqlParameter(
                                            "@Name",
                                            SqlDbType.NVarChar,
                                            BlobName.MaxLength,
                                            name.ToString()
                                            )
                                    }
                                };
                                var contentReader =
                                    await contentCommand.ExecuteReaderAsync(ReaderBehavior,
                                                                            contentCancellationToken);
                                if (!contentReader.IsClosed && contentReader.Read())
                                {
                                    return new ForwardOnlyStream(
                                        new DisposableStream(
                                            contentReader.GetStream(0),
                                            contentReader,
                                            contentCommand,
                                            contentConnection)
                                        );
                                }

                                throw new BlobNotFoundException(name);
                            }));
                        }

                        return(null);
                    }
                }
            }
        }
예제 #10
0
 /// <summary>Shorthand constructor.</summary>
 public BlobCounter(IBlobStorageProvider provider, BlobName<decimal> fullName)
     : this(provider, fullName.ContainerName, fullName.ToString())
 {
 }
예제 #11
0
 /// <summary>Shorthand constructor.</summary>
 public BlobCounter(IBlobStorageProvider provider, BlobName <decimal> fullName)
     : this(provider, fullName.ContainerName, fullName.ToString())
 {
 }