@@ -54,6 +54,7 @@ func New(bucket string, service GCSAPI) GCSStore {
5454func (store GCSStore ) UseIn (composer * handler.StoreComposer ) {
5555 composer .UseCore (store )
5656 composer .UseTerminater (store )
57+ composer .UseConcater (store )
5758}
5859
5960func (store GCSStore ) NewUpload (ctx context.Context , info handler.FileInfo ) (handler.Upload , error ) {
@@ -88,6 +89,10 @@ func (store GCSStore) AsTerminatableUpload(upload handler.Upload) handler.Termin
8889 return upload .(* gcsUpload )
8990}
9091
92+ func (store GCSStore ) AsConcatableUpload (upload handler.Upload ) handler.ConcatableUpload {
93+ return upload .(* gcsUpload )
94+ }
95+
9196func (upload gcsUpload ) WriteChunk (ctx context.Context , offset int64 , src io.Reader ) (int64 , error ) {
9297 id := upload .id
9398 store := upload .store
@@ -337,6 +342,32 @@ func (upload gcsUpload) GetReader(ctx context.Context) (io.ReadCloser, error) {
337342 return store .Service .ReadObject (ctx , params )
338343}
339344
345+ func (upload gcsUpload ) ConcatUploads (ctx context.Context , partialUploads []handler.Upload ) error {
346+ names := make ([]string , len (partialUploads ))
347+ store := upload .store
348+
349+ for i , partialUpload := range partialUploads {
350+ info , err := partialUpload .GetInfo (ctx )
351+ if err != nil {
352+ return err
353+ }
354+ names [i ] = store .keyWithPrefix (info .ID )
355+ }
356+
357+ composeParams := GCSComposeParams {
358+ Bucket : store .Bucket ,
359+ Destination : store .keyWithPrefix (upload .id ),
360+ Sources : names ,
361+ }
362+
363+ err := store .Service .ComposeObjects (ctx , composeParams )
364+ if err != nil {
365+ return err
366+ }
367+
368+ return nil
369+ }
370+
340371func (store GCSStore ) keyWithPrefix (key string ) string {
341372 prefix := store .ObjectPrefix
342373 if prefix != "" && ! strings .HasSuffix (prefix , "/" ) {
0 commit comments