Skip to content

Commit d4a1c6d

Browse files
author
Christian Hergert
committed
gridfs: add mongoc_gridfs_remove_by_filename()
1 parent 7adb189 commit d4a1c6d

File tree

7 files changed

+166
-0
lines changed

7 files changed

+166
-0
lines changed

build/cmake/libmongoc-ssl.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ mongoc_gridfs_find_one
116116
mongoc_gridfs_find_one_by_filename
117117
mongoc_gridfs_get_chunks
118118
mongoc_gridfs_get_files
119+
mongoc_gridfs_remove_by_filename
119120
mongoc_index_opt_get_default
120121
mongoc_index_opt_init
121122
mongoc_init

build/cmake/libmongoc.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ mongoc_gridfs_find_one
117117
mongoc_gridfs_find_one_by_filename
118118
mongoc_gridfs_get_chunks
119119
mongoc_gridfs_get_files
120+
mongoc_gridfs_remove_by_filename
120121
mongoc_index_opt_get_default
121122
mongoc_index_opt_init
122123
mongoc_init

src/libmongoc.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ mongoc_gridfs_find_one
117117
mongoc_gridfs_find_one_by_filename
118118
mongoc_gridfs_get_chunks
119119
mongoc_gridfs_get_files
120+
mongoc_gridfs_remove_by_filename
120121
mongoc_index_opt_get_default
121122
mongoc_index_opt_init
122123
mongoc_init

src/mongoc/mongoc-error.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef enum
4444
MONGOC_ERROR_NAMESPACE,
4545
MONGOC_ERROR_COMMAND,
4646
MONGOC_ERROR_COLLECTION,
47+
MONGOC_ERROR_GRIDFS,
4748
} mongoc_error_domain_t;
4849

4950

@@ -81,8 +82,12 @@ typedef enum
8182

8283
MONGOC_ERROR_COLLECTION_INSERT_FAILED,
8384

85+
MONGOC_ERROR_GRIDFS_INVALID_FILENAME,
86+
8487
MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND = 59,
8588
MONGOC_ERROR_QUERY_NOT_TAILABLE = 13051,
89+
90+
/* Dup with query failure. */
8691
MONGOC_ERROR_PROTOCOL_ERROR = 17,
8792
} mongoc_error_code_t;
8893

src/mongoc/mongoc-gridfs.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "mongoc-client-private.h"
2222
#include "mongoc-collection.h"
2323
#include "mongoc-collection-private.h"
24+
#include "mongoc-error.h"
2425
#include "mongoc-index.h"
2526
#include "mongoc-gridfs.h"
2627
#include "mongoc-gridfs-private.h"
@@ -301,3 +302,108 @@ mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs)
301302

302303
return gridfs->chunks;
303304
}
305+
306+
307+
bool
308+
mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs,
309+
const char *filename,
310+
bson_error_t *error)
311+
{
312+
mongoc_bulk_operation_t *bulk_files = NULL;
313+
mongoc_bulk_operation_t *bulk_chunks = NULL;
314+
mongoc_cursor_t *cursor = NULL;
315+
bson_error_t files_error;
316+
bson_error_t chunks_error;
317+
const bson_t *doc;
318+
const char *key;
319+
char keybuf[16];
320+
int count = 0;
321+
bool chunks_ret;
322+
bool files_ret;
323+
bool ret = false;
324+
bson_iter_t iter;
325+
bson_t *files_q;
326+
bson_t *chunks_q;
327+
bson_t q = BSON_INITIALIZER;
328+
bson_t fields = BSON_INITIALIZER;
329+
bson_t ar = BSON_INITIALIZER;
330+
331+
bson_return_val_if_fail (gridfs, false);
332+
333+
if (!filename) {
334+
bson_set_error (error,
335+
MONGOC_ERROR_GRIDFS,
336+
MONGOC_ERROR_GRIDFS_INVALID_FILENAME,
337+
"A non-NULL filename must be specified.");
338+
return false;
339+
}
340+
341+
/*
342+
* Find all files matching this filename. Hopefully just one, but not
343+
* strictly required!
344+
*/
345+
346+
BSON_APPEND_UTF8 (&q, "filename", filename);
347+
BSON_APPEND_INT32 (&fields, "_id", 1);
348+
349+
cursor = mongoc_collection_find (gridfs->files, MONGOC_QUERY_NONE, 0, 0, 0,
350+
&q, &fields, NULL);
351+
BSON_ASSERT (cursor);
352+
353+
while (mongoc_cursor_next (cursor, &doc)) {
354+
if (bson_iter_init_find (&iter, doc, "_id")) {
355+
const bson_value_t *value = bson_iter_value (&iter);
356+
357+
bson_uint32_to_string (count, &key, keybuf, sizeof keybuf);
358+
BSON_APPEND_VALUE (&ar, key, value);
359+
}
360+
}
361+
362+
if (mongoc_cursor_error (cursor, error)) {
363+
goto failure;
364+
}
365+
366+
bulk_files = mongoc_collection_create_bulk_operation (gridfs->files, false, NULL);
367+
bulk_chunks = mongoc_collection_create_bulk_operation (gridfs->chunks, false, NULL);
368+
369+
files_q = BCON_NEW ("_id", "{", "$in", BCON_ARRAY (&ar), "}");
370+
chunks_q = BCON_NEW ("files_id", "{", "$in", BCON_ARRAY (&ar), "}");
371+
372+
mongoc_bulk_operation_remove (bulk_files, files_q);
373+
mongoc_bulk_operation_remove (bulk_chunks, chunks_q);
374+
375+
files_ret = mongoc_bulk_operation_execute (bulk_files, NULL, &files_error);
376+
chunks_ret = mongoc_bulk_operation_execute (bulk_chunks, NULL, &chunks_error);
377+
378+
if (error) {
379+
if (!files_ret) {
380+
memcpy (error, &files_error, sizeof *error);
381+
} else if (!chunks_ret) {
382+
memcpy (error, &chunks_error, sizeof *error);
383+
}
384+
}
385+
386+
ret = (files_ret && chunks_ret);
387+
388+
failure:
389+
if (cursor) {
390+
mongoc_cursor_destroy (cursor);
391+
}
392+
if (bulk_files) {
393+
mongoc_bulk_operation_destroy (bulk_files);
394+
}
395+
if (bulk_chunks) {
396+
mongoc_bulk_operation_destroy (bulk_chunks);
397+
}
398+
bson_destroy (&q);
399+
bson_destroy (&fields);
400+
bson_destroy (&ar);
401+
if (files_q) {
402+
bson_destroy (files_q);
403+
}
404+
if (chunks_q) {
405+
bson_destroy (chunks_q);
406+
}
407+
408+
return ret;
409+
}

src/mongoc/mongoc-gridfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ bool mongoc_gridfs_drop (mongoc_gridfs_
5656
void mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs);
5757
mongoc_collection_t *mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs);
5858
mongoc_collection_t *mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs);
59+
bool mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs,
60+
const char *filename,
61+
bson_error_t *error);
5962

6063

6164
BSON_END_DECLS

tests/test-mongoc-gridfs.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,54 @@ test_stream (void)
323323
}
324324

325325

326+
static void
327+
test_remove_by_filename (void)
328+
{
329+
mongoc_gridfs_t *gridfs;
330+
mongoc_gridfs_file_t *file;
331+
mongoc_gridfs_file_opt_t opt = { 0 };
332+
mongoc_client_t *client;
333+
bson_error_t error;
334+
bool ret;
335+
336+
client = mongoc_client_new (gTestUri);
337+
assert (client);
338+
339+
gridfs = get_test_gridfs (client, "fs_remove_by_filename", &error);
340+
assert (gridfs);
341+
342+
mongoc_gridfs_drop (gridfs, &error);
343+
344+
opt.filename = "foo_file_1.txt";
345+
file = mongoc_gridfs_create_file (gridfs, &opt);
346+
assert (file);
347+
assert (mongoc_gridfs_file_save (file));
348+
mongoc_gridfs_file_destroy (file);
349+
350+
opt.filename = "foo_file_2.txt";
351+
file = mongoc_gridfs_create_file (gridfs, &opt);
352+
assert (file);
353+
assert (mongoc_gridfs_file_save (file));
354+
355+
ret = mongoc_gridfs_remove_by_filename (gridfs, "foo_file_1.txt", &error);
356+
if (!ret) fprintf (stderr, "ERROR: %s\n", error.message);
357+
assert (ret);
358+
mongoc_gridfs_file_destroy (file);
359+
360+
file = mongoc_gridfs_find_one_by_filename (gridfs, "foo_file_1.txt", &error);
361+
assert (!file);
362+
363+
file = mongoc_gridfs_find_one_by_filename (gridfs, "foo_file_2.txt", &error);
364+
assert (file);
365+
mongoc_gridfs_file_destroy (file);
366+
367+
drop_collections (gridfs, &error);
368+
mongoc_gridfs_destroy (gridfs);
369+
370+
mongoc_client_destroy (client);
371+
}
372+
373+
326374
static void
327375
cleanup_globals (void)
328376
{
@@ -341,6 +389,7 @@ test_gridfs_install (TestSuite *suite)
341389
TestSuite_Add (suite, "/GridFS/read", test_read);
342390
TestSuite_Add (suite, "/GridFS/stream", test_stream);
343391
TestSuite_Add (suite, "/GridFS/write", test_write);
392+
TestSuite_Add (suite, "/GridFS/remove_by_filename", test_remove_by_filename);
344393

345394
atexit (cleanup_globals);
346395
}

0 commit comments

Comments
 (0)