Files
filestore/remote/miniostorage/writer.go
T
2025-10-29 00:59:52 +03:00

90 lines
1.7 KiB
Go

package miniostorage
import (
"bytes"
"context"
"fmt"
"io"
"git.company.lan/gopkg/filestore/remote"
"github.com/minio/minio-go/v7"
)
// Убеждаемся в том, что мы всегда реализуем интерфейс io.WriteCloser.
var _ io.WriteCloser = (*minioWriter)(nil)
// minioWriter реализует интерфейс io.WriteCloser.
type minioWriter struct {
ctx context.Context
client *minio.Client
bucket string
path string
buffer *bytes.Buffer
metadata remote.Metadata
contentType string
}
func newMinioWriter(ctx context.Context, client *minio.Client, bucket, path string, opts ...remote.Option) *minioWriter {
o := &remote.Options{}
for _, opt := range opts {
opt(o)
}
writer := &minioWriter{
ctx: ctx,
client: client,
bucket: bucket,
path: path,
buffer: bytes.NewBuffer(nil),
}
if o.ContentType != "" {
writer.contentType = o.ContentType
}
if o.Metadata != nil {
writer.metadata = o.Metadata
}
return writer
}
func (w *minioWriter) Write(p []byte) (n int, err error) {
select {
case <-w.ctx.Done():
return 0, w.ctx.Err()
default:
return w.buffer.Write(p)
}
}
func (w *minioWriter) Close() error {
select {
case <-w.ctx.Done():
return w.ctx.Err()
default:
opts := minio.PutObjectOptions{}
if w.contentType != "" {
opts.ContentType = w.contentType
}
if w.metadata != nil {
userMetadata := make(map[string]string)
for k, v := range w.metadata {
userMetadata[k] = fmt.Sprintf("%v", v)
}
opts.UserMetadata = userMetadata
}
_, err := w.client.PutObject(
w.ctx,
w.bucket,
w.path,
bytes.NewReader(w.buffer.Bytes()),
int64(w.buffer.Len()),
opts,
)
return err
}
}