@@ -24,6 +24,7 @@ import (
24
24
"github.com/mongodb/mongo-go-driver/mongo/readpref"
25
25
"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
26
26
"github.com/mongodb/mongo-go-driver/x/bsonx"
27
+ "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
27
28
)
28
29
29
30
// TODO: add sessions options
@@ -116,7 +117,7 @@ func (b *Bucket) OpenUploadStream(filename string, opts ...*options.UploadOption
116
117
}
117
118
118
119
// OpenUploadStreamWithID creates a new upload stream for a file given the file ID and filename.
119
- func (b * Bucket ) OpenUploadStreamWithID (fileID primitive. ObjectID , filename string , opts ... * options.UploadOptions ) (* UploadStream , error ) {
120
+ func (b * Bucket ) OpenUploadStreamWithID (fileID interface {} , filename string , opts ... * options.UploadOptions ) (* UploadStream , error ) {
120
121
ctx , cancel := deadlineContext (b .writeDeadline )
121
122
if cancel != nil {
122
123
defer cancel ()
@@ -142,7 +143,7 @@ func (b *Bucket) UploadFromStream(filename string, source io.Reader, opts ...*op
142
143
}
143
144
144
145
// UploadFromStreamWithID uploads a file given a source stream.
145
- func (b * Bucket ) UploadFromStreamWithID (fileID primitive. ObjectID , filename string , source io.Reader , opts ... * options.UploadOptions ) error {
146
+ func (b * Bucket ) UploadFromStreamWithID (fileID interface {} , filename string , source io.Reader , opts ... * options.UploadOptions ) error {
146
147
us , err := b .OpenUploadStreamWithID (fileID , filename , opts ... )
147
148
if err != nil {
148
149
return err
@@ -177,15 +178,19 @@ func (b *Bucket) UploadFromStreamWithID(fileID primitive.ObjectID, filename stri
177
178
}
178
179
179
180
// OpenDownloadStream creates a stream from which the contents of the file can be read.
180
- func (b * Bucket ) OpenDownloadStream (fileID primitive.ObjectID ) (* DownloadStream , error ) {
181
+ func (b * Bucket ) OpenDownloadStream (fileID interface {}) (* DownloadStream , error ) {
182
+ id , err := convertFileID (fileID )
183
+ if err != nil {
184
+ return nil , err
185
+ }
181
186
return b .openDownloadStream (bsonx.Doc {
182
- {"_id" , bsonx . ObjectID ( fileID ) },
187
+ {"_id" , id },
183
188
})
184
189
}
185
190
186
191
// DownloadToStream downloads the file with the specified fileID and writes it to the provided io.Writer.
187
192
// Returns the number of bytes written to the steam and an error, or nil if there was no error.
188
- func (b * Bucket ) DownloadToStream (fileID primitive. ObjectID , stream io.Writer ) (int64 , error ) {
193
+ func (b * Bucket ) DownloadToStream (fileID interface {} , stream io.Writer ) (int64 , error ) {
189
194
ds , err := b .OpenDownloadStream (fileID )
190
195
if err != nil {
191
196
return 0 , err
@@ -225,15 +230,19 @@ func (b *Bucket) DownloadToStreamByName(filename string, stream io.Writer, opts
225
230
}
226
231
227
232
// Delete deletes all chunks and metadata associated with the file with the given file ID.
228
- func (b * Bucket ) Delete (fileID primitive. ObjectID ) error {
233
+ func (b * Bucket ) Delete (fileID interface {} ) error {
229
234
// delete document in files collection and then chunks to minimize race conditions
230
235
231
236
ctx , cancel := deadlineContext (b .writeDeadline )
232
237
if cancel != nil {
233
238
defer cancel ()
234
239
}
235
240
236
- res , err := b .filesColl .DeleteOne (ctx , bsonx.Doc {{"_id" , bsonx .ObjectID (fileID )}})
241
+ id , err := convertFileID (fileID )
242
+ if err != nil {
243
+ return err
244
+ }
245
+ res , err := b .filesColl .DeleteOne (ctx , bsonx.Doc {{"_id" , id }})
237
246
if err == nil && res .DeletedCount == 0 {
238
247
err = ErrFileNotFound
239
248
}
@@ -277,14 +286,18 @@ func (b *Bucket) Find(filter interface{}, opts ...*options.GridFSFindOptions) (*
277
286
}
278
287
279
288
// Rename renames the stored file with the specified file ID.
280
- func (b * Bucket ) Rename (fileID primitive. ObjectID , newFilename string ) error {
289
+ func (b * Bucket ) Rename (fileID interface {} , newFilename string ) error {
281
290
ctx , cancel := deadlineContext (b .writeDeadline )
282
291
if cancel != nil {
283
292
defer cancel ()
284
293
}
285
294
295
+ id , err := convertFileID (fileID )
296
+ if err != nil {
297
+ return err
298
+ }
286
299
res , err := b .filesColl .UpdateOne (ctx ,
287
- bsonx.Doc {{"_id" , bsonx . ObjectID ( fileID ) }},
300
+ bsonx.Doc {{"_id" , id }},
288
301
bsonx.Doc {{"$set" , bsonx .Document (bsonx.Doc {{"filename" , bsonx .String (newFilename )}})}},
289
302
)
290
303
if err != nil {
@@ -369,8 +382,12 @@ func (b *Bucket) downloadToStream(ds *DownloadStream, stream io.Writer) (int64,
369
382
return copied , ds .Close ()
370
383
}
371
384
372
- func (b * Bucket ) deleteChunks (ctx context.Context , fileID primitive.ObjectID ) error {
373
- _ , err := b .chunksColl .DeleteMany (ctx , bsonx.Doc {{"files_id" , bsonx .ObjectID (fileID )}})
385
+ func (b * Bucket ) deleteChunks (ctx context.Context , fileID interface {}) error {
386
+ id , err := convertFileID (fileID )
387
+ if err != nil {
388
+ return err
389
+ }
390
+ _ , err = b .chunksColl .DeleteMany (ctx , bsonx.Doc {{"files_id" , id }})
374
391
return err
375
392
}
376
393
@@ -388,9 +405,13 @@ func (b *Bucket) findFile(ctx context.Context, filter interface{}, opts ...*opti
388
405
return cursor , nil
389
406
}
390
407
391
- func (b * Bucket ) findChunks (ctx context.Context , fileID primitive.ObjectID ) (* mongo.Cursor , error ) {
408
+ func (b * Bucket ) findChunks (ctx context.Context , fileID interface {}) (* mongo.Cursor , error ) {
409
+ id , err := convertFileID (fileID )
410
+ if err != nil {
411
+ return nil , err
412
+ }
392
413
chunksCursor , err := b .chunksColl .Find (ctx ,
393
- bsonx.Doc {{"files_id" , bsonx . ObjectID ( fileID ) }},
414
+ bsonx.Doc {{"files_id" , id }},
394
415
options .Find ().SetSort (bsonx.Doc {{"n" , bsonx .Int32 (1 )}})) // sort by chunk index
395
416
if err != nil {
396
417
return nil , err
@@ -510,3 +531,22 @@ func (b *Bucket) parseUploadOptions(opts ...*options.UploadOptions) (*Upload, er
510
531
511
532
return upload , nil
512
533
}
534
+
535
+ type _convertFileID struct {
536
+ ID interface {} `bson:"_id"`
537
+ }
538
+
539
+ func convertFileID (fileID interface {}) (bsonx.Val , error ) {
540
+ id := _convertFileID {
541
+ ID : fileID ,
542
+ }
543
+
544
+ b , err := bson .Marshal (id )
545
+ if err != nil {
546
+ return bsonx.Val {}, err
547
+ }
548
+ val := bsoncore .Document (b ).Lookup ("_id" )
549
+ var res bsonx.Val
550
+ err = res .UnmarshalBSONValue (val .Type , val .Data )
551
+ return res , err
552
+ }
0 commit comments