Skip to content
This repository was archived by the owner on Feb 1, 2022. It is now read-only.

Commit ca02282

Browse files
committed
Merge pull request #876
2 parents 2bae534 + ac32b93 commit ca02282

File tree

5 files changed

+288
-8
lines changed

5 files changed

+288
-8
lines changed

collection.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,7 @@ static void php_mongo_collection_insert(zval *z_collection, zval *document, zval
11261126
mongoclient *link;
11271127
mongo_collection *c;
11281128
mongo_connection *connection;
1129+
int is_acknowledged, supports_command, supports_opcode;
11291130

11301131
PHP_MONGO_GET_COLLECTION(z_collection);
11311132
PHP_MONGO_GET_LINK(c->link);
@@ -1134,7 +1135,14 @@ static void php_mongo_collection_insert(zval *z_collection, zval *document, zval
11341135
RETURN_FALSE;
11351136
}
11361137

1137-
if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API)) {
1138+
is_acknowledged = is_gle_op(z_collection, z_write_options, &link->servers->options TSRMLS_CC);
1139+
supports_command = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API);
1140+
supports_opcode = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE);
1141+
1142+
/* Allow unacknowledged writes to be routed through legacy opcodes for
1143+
* performance, unless the server no longer supports the legacy opcode.
1144+
* This applies to the insert(), remove(), save(), and update() methods. */
1145+
if (supports_command && (is_acknowledged || !supports_opcode)) {
11381146
php_mongo_write_options write_options = {-1, {-1}, -1, -1, -1, -1};
11391147
int retval;
11401148
mongo_db *db;
@@ -1160,7 +1168,7 @@ static void php_mongo_collection_insert(zval *z_collection, zval *document, zval
11601168
}
11611169
}
11621170
return;
1163-
} else if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE)) {
1171+
} else if (supports_opcode) {
11641172
int retval;
11651173
mongo_buffer buf;
11661174

@@ -1481,7 +1489,7 @@ static void mongo_apply_update_options_from_bits(php_mongo_write_update_args *up
14811489

14821490
static void php_mongocollection_update(zval *this_ptr, mongo_collection *c, zval *criteria, zval *newobj, zval *z_write_options, zval *return_value TSRMLS_DC)
14831491
{
1484-
int bit_opts = 0;
1492+
int bit_opts = 0, is_acknowledged, supports_command, supports_opcode;
14851493
mongo_connection *connection;
14861494
mongoclient *link;
14871495

@@ -1510,7 +1518,14 @@ static void php_mongocollection_update(zval *this_ptr, mongo_collection *c, zval
15101518
RETURN_FALSE;
15111519
}
15121520

1513-
if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API)) {
1521+
is_acknowledged = is_gle_op(this_ptr, z_write_options, &link->servers->options TSRMLS_CC);
1522+
supports_command = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API);
1523+
supports_opcode = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE);
1524+
1525+
/* Allow unacknowledged writes to be routed through legacy opcodes for
1526+
* performance, unless the server no longer supports the legacy opcode.
1527+
* This applies to the insert(), remove(), save(), and update() methods. */
1528+
if (supports_command && (is_acknowledged || !supports_opcode)) {
15141529
php_mongo_write_options write_options = {-1, {-1}, -1, -1, -1, -1};
15151530
php_mongo_write_update_args update_options = { NULL, NULL, -1, -1 };
15161531
int retval;
@@ -1536,7 +1551,7 @@ static void php_mongocollection_update(zval *this_ptr, mongo_collection *c, zval
15361551
mongo_convert_write_api_return_to_legacy_retval(return_value, MONGODB_API_COMMAND_UPDATE, write_options.wtype == 1 ? write_options.write_concern.w : 1 TSRMLS_CC);
15371552
}
15381553
zval_ptr_dtor(&z_write_options);
1539-
} else if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE)) {
1554+
} else if (supports_opcode) {
15401555
int retval = 1;
15411556
mongo_buffer buf;
15421557

@@ -1591,7 +1606,7 @@ static void mongo_apply_delete_options_from_bits(php_mongo_write_delete_args *de
15911606

15921607
static void php_mongocollection_remove(zval *this_ptr, mongo_collection *c, zval *criteria, zval *z_write_options, zval *return_value TSRMLS_DC)
15931608
{
1594-
int bit_opts = 0;
1609+
int bit_opts = 0, is_acknowledged, supports_command, supports_opcode;
15951610
mongo_connection *connection;
15961611
mongoclient *link;
15971612

@@ -1622,7 +1637,14 @@ static void php_mongocollection_remove(zval *this_ptr, mongo_collection *c, zval
16221637
RETURN_FALSE;
16231638
}
16241639

1625-
if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API)) {
1640+
is_acknowledged = is_gle_op(this_ptr, z_write_options, &link->servers->options TSRMLS_CC);
1641+
supports_command = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_WRITE_API);
1642+
supports_opcode = php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE);
1643+
1644+
/* Allow unacknowledged writes to be routed through legacy opcodes for
1645+
* performance, unless the server no longer supports the legacy opcode.
1646+
* This applies to the insert(), remove(), save(), and update() methods. */
1647+
if (supports_command && (is_acknowledged || !supports_opcode)) {
16261648
php_mongo_write_options write_options = {-1, {-1}, -1, -1, -1, -1};
16271649
php_mongo_write_delete_args delete_options = { NULL, -1 };
16281650
int retval;
@@ -1648,7 +1670,7 @@ static void php_mongocollection_remove(zval *this_ptr, mongo_collection *c, zval
16481670
}
16491671
zval_ptr_dtor(&z_write_options);
16501672
zval_ptr_dtor(&criteria);
1651-
} else if (php_mongo_api_connection_supports_feature(connection, PHP_MONGO_API_RELEASE_2_4_AND_BEFORE)) {
1673+
} else if (supports_opcode) {
16521674
mongo_buffer buf;
16531675
int retval = 1;
16541676

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
MongoCollection::insert() routes unacknowledged write through legacy op code
3+
--SKIPIF--
4+
<?php $needs = "2.5.5"; ?>
5+
<?php require_once "tests/utils/standalone.inc";?>
6+
--FILE--
7+
<?php
8+
require_once "tests/utils/server.inc";
9+
10+
function stream_notify($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
11+
if ($notificationCode != MONGO_STREAM_NOTIFY_TYPE_LOG) {
12+
return;
13+
}
14+
15+
$data = unserialize($message);
16+
17+
switch ($messageCode) {
18+
case MONGO_STREAM_NOTIFY_LOG_CMD_INSERT:
19+
printf("Issuing insert command. Write concern: %s\n", json_encode($data['write_options']['writeConcern']));
20+
break;
21+
22+
case MONGO_STREAM_NOTIFY_LOG_INSERT:
23+
printf("Issuing OP_INSERT. Write concern: %s\n", json_encode($data['options']));
24+
break;
25+
}
26+
}
27+
28+
$ctx = stream_context_create(
29+
array(),
30+
array('notification' => 'stream_notify')
31+
);
32+
33+
$host = MongoShellServer::getStandaloneInfo();
34+
$m = new MongoClient($host, array(), array('context' => $ctx));
35+
36+
$c = $m->selectCollection(dbname(), collname(__FILE__));
37+
$c->drop();
38+
39+
echo "Acknowledged writes will use the insert command:\n";
40+
$c->insert(array('x' => 1));
41+
$c->insert(array('x' => 1), array('w' => 1));
42+
$c->insert(array('x' => 1), array('w' => 0, 'j' => true));
43+
44+
echo "\nUnacknowledged writes will use OP_INSERT:\n";
45+
$c->insert(array('x' => 1), array('w' => 0));
46+
$c->w = 0;
47+
$c->insert(array('x' => 1));
48+
49+
?>
50+
==DONE==
51+
--EXPECTF--
52+
Acknowledged writes will use the insert command:
53+
Issuing insert command. Write concern: {"w":1}
54+
Issuing insert command. Write concern: {"w":1}
55+
Issuing insert command. Write concern: {"j":true,"w":0}
56+
57+
Unacknowledged writes will use OP_INSERT:
58+
Issuing OP_INSERT. Write concern: {"w":0}
59+
Issuing OP_INSERT. Write concern: null
60+
==DONE==
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
MongoCollection::remove() routes unacknowledged write through legacy op code
3+
--SKIPIF--
4+
<?php $needs = "2.5.5"; ?>
5+
<?php require_once "tests/utils/standalone.inc";?>
6+
--FILE--
7+
<?php
8+
require_once "tests/utils/server.inc";
9+
10+
function stream_notify($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
11+
if ($notificationCode != MONGO_STREAM_NOTIFY_TYPE_LOG) {
12+
return;
13+
}
14+
15+
$data = unserialize($message);
16+
17+
switch ($messageCode) {
18+
case MONGO_STREAM_NOTIFY_LOG_CMD_DELETE:
19+
printf("Issuing delete command. Write concern: %s\n", json_encode($data['write_options']['writeConcern']));
20+
break;
21+
22+
case MONGO_STREAM_NOTIFY_LOG_DELETE:
23+
printf("Issuing OP_DELETE. Write concern: %s\n", json_encode($data['options']));
24+
break;
25+
}
26+
}
27+
28+
$ctx = stream_context_create(
29+
array(),
30+
array('notification' => 'stream_notify')
31+
);
32+
33+
$host = MongoShellServer::getStandaloneInfo();
34+
$m = new MongoClient($host, array(), array('context' => $ctx));
35+
36+
$c = $m->selectCollection(dbname(), collname(__FILE__));
37+
$c->drop();
38+
39+
echo "Acknowledged writes will use the delete command:\n";
40+
$c->remove(array('x' => 1));
41+
$c->remove(array('x' => 1), array('w' => 1));
42+
$c->remove(array('x' => 1), array('w' => 0, 'j' => true));
43+
44+
echo "\nUnacknowledged writes will use OP_DELETE:\n";
45+
$c->remove(array('x' => 1), array('w' => 0));
46+
$c->w = 0;
47+
$c->remove(array('x' => 1));
48+
49+
?>
50+
==DONE==
51+
--EXPECTF--
52+
Acknowledged writes will use the delete command:
53+
Issuing delete command. Write concern: {"w":1}
54+
Issuing delete command. Write concern: {"w":1}
55+
Issuing delete command. Write concern: {"j":true,"w":0}
56+
57+
Unacknowledged writes will use OP_DELETE:
58+
Issuing OP_DELETE. Write concern: {"w":0}
59+
Issuing OP_DELETE. Write concern: []
60+
==DONE==
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
MongoCollection::save() routes unacknowledged write through legacy op code
3+
--SKIPIF--
4+
<?php $needs = "2.5.5"; ?>
5+
<?php require_once "tests/utils/standalone.inc";?>
6+
--FILE--
7+
<?php
8+
require_once "tests/utils/server.inc";
9+
10+
function stream_notify($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
11+
if ($notificationCode != MONGO_STREAM_NOTIFY_TYPE_LOG) {
12+
return;
13+
}
14+
15+
$data = unserialize($message);
16+
17+
switch ($messageCode) {
18+
case MONGO_STREAM_NOTIFY_LOG_CMD_INSERT:
19+
printf("Issuing insert command. Write concern: %s\n", json_encode($data['write_options']['writeConcern']));
20+
break;
21+
22+
case MONGO_STREAM_NOTIFY_LOG_INSERT:
23+
printf("Issuing OP_INSERT. Write concern: %s\n", json_encode($data['options']));
24+
break;
25+
26+
case MONGO_STREAM_NOTIFY_LOG_CMD_UPDATE:
27+
printf("Issuing update command. Write concern: %s\n", json_encode($data['write_options']['writeConcern']));
28+
break;
29+
30+
case MONGO_STREAM_NOTIFY_LOG_UPDATE:
31+
printf("Issuing OP_UPDATE. Write concern: %s\n", json_encode($data['options']));
32+
break;
33+
}
34+
}
35+
36+
$ctx = stream_context_create(
37+
array(),
38+
array('notification' => 'stream_notify')
39+
);
40+
41+
$host = MongoShellServer::getStandaloneInfo();
42+
$m = new MongoClient($host, array(), array('context' => $ctx));
43+
44+
$c = $m->selectCollection(dbname(), collname(__FILE__));
45+
$c->drop();
46+
47+
echo "Acknowledged writes will use the insert command:\n";
48+
$c->save(array('x' => 1));
49+
$c->save(array('_id' => 1));
50+
$c->save(array('x' => 1), array('w' => 1));
51+
$c->save(array('_id' => 2), array('w' => 1));
52+
$c->save(array('x' => 1), array('w' => 0, 'j' => true));
53+
$c->save(array('_id' => 3), array('w' => 0, 'j' => true));
54+
55+
echo "\nUnacknowledged writes will use OP_INSERT:\n";
56+
$c->save(array('x' => 1), array('w' => 0));
57+
$c->save(array('_id' => 1), array('w' => 0));
58+
$c->w = 0;
59+
$c->save(array('x' => 1));
60+
$c->save(array('_id' => 1));
61+
62+
?>
63+
==DONE==
64+
--EXPECTF--
65+
Acknowledged writes will use the insert command:
66+
Issuing insert command. Write concern: {"w":1}
67+
Issuing update command. Write concern: {"w":1}
68+
Issuing insert command. Write concern: {"w":1}
69+
Issuing update command. Write concern: {"w":1}
70+
Issuing insert command. Write concern: {"j":true,"w":0}
71+
Issuing update command. Write concern: {"j":true,"w":0}
72+
73+
Unacknowledged writes will use OP_INSERT:
74+
Issuing OP_INSERT. Write concern: {"w":0}
75+
Issuing OP_UPDATE. Write concern: {"w":0,"upsert":true}
76+
Issuing OP_INSERT. Write concern: []
77+
Issuing OP_UPDATE. Write concern: {"upsert":true}
78+
==DONE==
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
MongoCollection::update() routes unacknowledged write through legacy op code
3+
--SKIPIF--
4+
<?php $needs = "2.5.5"; ?>
5+
<?php require_once "tests/utils/standalone.inc";?>
6+
--FILE--
7+
<?php
8+
require_once "tests/utils/server.inc";
9+
10+
function stream_notify($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
11+
if ($notificationCode != MONGO_STREAM_NOTIFY_TYPE_LOG) {
12+
return;
13+
}
14+
15+
$data = unserialize($message);
16+
17+
switch ($messageCode) {
18+
case MONGO_STREAM_NOTIFY_LOG_CMD_UPDATE:
19+
printf("Issuing update command. Write concern: %s\n", json_encode($data['write_options']['writeConcern']));
20+
break;
21+
22+
case MONGO_STREAM_NOTIFY_LOG_UPDATE:
23+
printf("Issuing OP_UPDATE. Write concern: %s\n", json_encode($data['options']));
24+
break;
25+
}
26+
}
27+
28+
$ctx = stream_context_create(
29+
array(),
30+
array('notification' => 'stream_notify')
31+
);
32+
33+
$host = MongoShellServer::getStandaloneInfo();
34+
$m = new MongoClient($host, array(), array('context' => $ctx));
35+
36+
$c = $m->selectCollection(dbname(), collname(__FILE__));
37+
$c->drop();
38+
39+
echo "Acknowledged writes will use the update command:\n";
40+
$c->update(array('x' => 1), array('$set' => array('y' => 1)));
41+
$c->update(array('x' => 1), array('$set' => array('y' => 1)), array('w' => 1));
42+
$c->update(array('x' => 1), array('$set' => array('y' => 1)), array('w' => 0, 'j' => true));
43+
44+
echo "\nUnacknowledged writes will use OP_UPDATE:\n";
45+
$c->update(array('x' => 1), array('$set' => array('y' => 1)), array('w' => 0));
46+
$c->w = 0;
47+
$c->update(array('x' => 1), array('$set' => array('y' => 1)));
48+
49+
?>
50+
==DONE==
51+
--EXPECTF--
52+
Acknowledged writes will use the update command:
53+
Issuing update command. Write concern: {"w":1}
54+
Issuing update command. Write concern: {"w":1}
55+
Issuing update command. Write concern: {"j":true,"w":0}
56+
57+
Unacknowledged writes will use OP_UPDATE:
58+
Issuing OP_UPDATE. Write concern: {"w":0}
59+
Issuing OP_UPDATE. Write concern: []
60+
==DONE==

0 commit comments

Comments
 (0)