Skip to content

Commit 459368e

Browse files
author
Christian Hergert
committed
collection: add mongoc_collection_rename().
1 parent f851f6d commit 459368e

File tree

6 files changed

+135
-5
lines changed

6 files changed

+135
-5
lines changed

build/cmake/libmongoc-ssl.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ mongoc_collection_get_write_concern
3636
mongoc_collection_insert
3737
mongoc_collection_insert_bulk
3838
mongoc_collection_keys_to_index_string
39+
mongoc_collection_rename
3940
mongoc_collection_save
4041
mongoc_collection_set_read_prefs
4142
mongoc_collection_set_write_concern

build/cmake/libmongoc.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mongoc_collection_get_write_concern
3737
mongoc_collection_insert
3838
mongoc_collection_insert_bulk
3939
mongoc_collection_keys_to_index_string
40+
mongoc_collection_rename
4041
mongoc_collection_save
4142
mongoc_collection_set_read_prefs
4243
mongoc_collection_set_write_concern

src/libmongoc.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mongoc_collection_get_write_concern
3838
mongoc_collection_insert
3939
mongoc_collection_insert_bulk
4040
mongoc_collection_keys_to_index_string
41+
mongoc_collection_rename
4142
mongoc_collection_save
4243
mongoc_collection_set_read_prefs
4344
mongoc_collection_set_write_concern

src/mongoc/mongoc-collection.c

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@
3535
#define MONGOC_LOG_DOMAIN "collection"
3636

3737

38+
static bool
39+
validate_name (const char *str)
40+
{
41+
return (str &&
42+
*str &&
43+
(strlen (str) < 123) &&
44+
!strstr (str, "..") &&
45+
!!strncmp (str, "$cmd", 4) &&
46+
!!strncmp (str, "oplog.$main", 11) &&
47+
(*str != '.') &&
48+
(*(str + strlen (str) - 1) != '.'));
49+
}
50+
51+
3852
/*
3953
*--------------------------------------------------------------------------
4054
*
@@ -84,11 +98,9 @@ _mongoc_collection_new (mongoc_client_t *client,
8498
mongoc_read_prefs_copy(read_prefs) :
8599
mongoc_read_prefs_new(MONGOC_READ_PRIMARY);
86100

87-
bson_snprintf (col->ns, sizeof col->ns - 1, "%s.%s",
88-
db, collection);
89-
bson_snprintf (col->db, sizeof col->db - 1, "%s", db);
90-
bson_snprintf (col->collection, sizeof col->collection - 1,
91-
"%s", collection);
101+
bson_snprintf (col->ns, sizeof col->ns, "%s.%s", db, collection);
102+
bson_snprintf (col->db, sizeof col->db, "%s", db);
103+
bson_snprintf (col->collection, sizeof col->collection, "%s", collection);
92104

93105
col->collectionlen = (uint32_t)strlen(col->collection);
94106
col->nslen = (uint32_t)strlen(col->ns);
@@ -1374,3 +1386,82 @@ mongoc_collection_validate (mongoc_collection_t *collection, /* IN */
13741386

13751387
return ret;
13761388
}
1389+
1390+
1391+
/*
1392+
*--------------------------------------------------------------------------
1393+
*
1394+
* mongoc_collection_rename --
1395+
*
1396+
* Rename the collection to @new_name.
1397+
*
1398+
* If @new_db is NULL, the same db will be used.
1399+
*
1400+
* If @drop_target_before_rename is true, then a collection named
1401+
* @new_name will be dropped before renaming @collection to
1402+
* @new_name.
1403+
*
1404+
* Returns:
1405+
* true on success; false on failure and @error is set.
1406+
*
1407+
* Side effects:
1408+
* @error is set on failure.
1409+
*
1410+
*--------------------------------------------------------------------------
1411+
*/
1412+
1413+
bool
1414+
mongoc_collection_rename (mongoc_collection_t *collection,
1415+
const char *new_db,
1416+
const char *new_name,
1417+
bool drop_target_before_rename,
1418+
bson_error_t *error)
1419+
{
1420+
bson_t cmd = BSON_INITIALIZER;
1421+
char newns [MONGOC_NAMESPACE_MAX + 1];
1422+
bool ret;
1423+
1424+
bson_return_val_if_fail (collection, false);
1425+
bson_return_val_if_fail (new_name, false);
1426+
1427+
if (!validate_name (new_name)) {
1428+
bson_set_error (error,
1429+
MONGOC_ERROR_NAMESPACE,
1430+
MONGOC_ERROR_NAMESPACE_INVALID,
1431+
"\"%s\" is an invalid collection name.",
1432+
new_name);
1433+
return false;
1434+
}
1435+
1436+
bson_snprintf (newns, sizeof newns, "%s.%s",
1437+
new_db ? new_db : collection->db,
1438+
new_name);
1439+
1440+
BSON_APPEND_UTF8 (&cmd, "renameCollection", collection->ns);
1441+
BSON_APPEND_UTF8 (&cmd, "to", newns);
1442+
1443+
if (drop_target_before_rename) {
1444+
BSON_APPEND_BOOL (&cmd, "dropTarget", true);
1445+
}
1446+
1447+
ret = mongoc_client_command_simple (collection->client, "admin",
1448+
&cmd, NULL, NULL, error);
1449+
1450+
if (ret) {
1451+
if (new_db) {
1452+
bson_snprintf (collection->db, sizeof collection->db, "%s", new_db);
1453+
}
1454+
1455+
bson_snprintf (collection->collection, sizeof collection->collection,
1456+
"%s", new_name);
1457+
collection->collectionlen = strlen (collection->collection);
1458+
1459+
bson_snprintf (collection->ns, sizeof collection->ns,
1460+
"%s.%s", collection->db, new_name);
1461+
collection->nslen = strlen (collection->ns);
1462+
}
1463+
1464+
bson_destroy (&cmd);
1465+
1466+
return ret;
1467+
}

src/mongoc/mongoc-collection.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ bool mongoc_collection_save (mongoc_col
107107
const bson_t *document,
108108
const mongoc_write_concern_t *write_concern,
109109
bson_error_t *error);
110+
bool mongoc_collection_rename (mongoc_collection_t *collection,
111+
const char *new_db,
112+
const char *new_name,
113+
bool drop_target_before_rename,
114+
bson_error_t *error);
110115
const mongoc_read_prefs_t *mongoc_collection_get_read_prefs (const mongoc_collection_t *collection);
111116
void mongoc_collection_set_read_prefs (mongoc_collection_t *collection,
112117
const mongoc_read_prefs_t *read_prefs);

tests/test-mongoc-collection.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,36 @@ test_validate (void)
677677
}
678678

679679

680+
static void
681+
test_rename (void)
682+
{
683+
mongoc_collection_t *collection;
684+
mongoc_client_t *client;
685+
bson_error_t error;
686+
bson_t doc = BSON_INITIALIZER;
687+
bool r;
688+
689+
client = mongoc_client_new (gTestUri);
690+
ASSERT (client);
691+
692+
collection = get_test_collection (client, "test_rename");
693+
ASSERT (collection);
694+
695+
r = mongoc_collection_insert (collection, MONGOC_INSERT_NONE, &doc, NULL, &error);
696+
assert (r);
697+
698+
r = mongoc_collection_rename (collection, "test", "test_rename_2", false, &error);
699+
assert (r);
700+
701+
r = mongoc_collection_drop (collection, &error);
702+
assert (r);
703+
704+
mongoc_collection_destroy (collection);
705+
mongoc_client_destroy (client);
706+
bson_destroy (&doc);
707+
}
708+
709+
680710
static void
681711
cleanup_globals (void)
682712
{
@@ -700,6 +730,7 @@ test_collection_install (TestSuite *suite)
700730
TestSuite_Add (suite, "/Collection/drop", test_drop);
701731
TestSuite_Add (suite, "/Collection/aggregate", test_aggregate);
702732
TestSuite_Add (suite, "/Collection/validate", test_validate);
733+
TestSuite_Add (suite, "/Collection/rename", test_rename);
703734

704735
atexit (cleanup_globals);
705736
}

0 commit comments

Comments
 (0)