Skip to content

Commit db06619

Browse files
authored
PHPC-2440: Remove deprecated Query constructor options (#1707)
Removes "partial", "maxScan", "modifiers", "oplogReplay", and "snapshot" options. Removes negative "limit" implying true for "singleBatch".
1 parent 979cb4b commit db06619

16 files changed

+47
-717
lines changed

UPGRADE-2.0.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ UPGRADE FROM 1.x to 2.0
3434
ensure that it is detected by `pkg-config`.
3535
* The `--with-system-ciphers` configure option has been removed. Use
3636
`--enable-mongodb-crypto-system-profile` instead.
37+
* `MongoDB\Driver\Query` removes the following options: `partial` (use
38+
`allowPartialResults` instead), `maxScan`, `modifiers` (use alternative
39+
top-level options instead), `oplogReplay`, and `snapshot`. Support for
40+
negative `limit` values has been removed (use `singleBatch` instead).

src/MongoDB/Query.c

Lines changed: 31 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static bool php_phongo_query_opts_append_string(bson_t* opts, const char* opts_k
3939
zval* value = php_array_fetch_deref(zarr, zarr_key);
4040

4141
if (Z_TYPE_P(value) != IS_STRING) {
42-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be string, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
42+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be string, %s given", zarr_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
4343
return false;
4444
}
4545

@@ -59,7 +59,7 @@ static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts
5959
bson_t b = BSON_INITIALIZER;
6060

6161
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
62-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
62+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" option to be array or object, %s given", zarr_key, PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value));
6363
return false;
6464
}
6565

@@ -71,7 +71,7 @@ static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts
7171
}
7272

7373
if (!bson_validate(&b, BSON_VALIDATE_EMPTY_KEYS, NULL)) {
74-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in \"%s\" %s", zarr_key, zarr_key[0] == '$' ? "modifier" : "option");
74+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Cannot use empty keys in \"%s\" option", zarr_key);
7575
bson_destroy(&b);
7676
return false;
7777
}
@@ -110,20 +110,14 @@ static bool php_phongo_query_opts_append_value(bson_t* opts, const char* opts_ke
110110
return true;
111111
}
112112

113-
#define PHONGO_QUERY_OPT_BOOL_EX(opt, zarr, key, deprecated) \
114-
if ((zarr) && php_array_existsc((zarr), (key))) { \
115-
if ((deprecated)) { \
116-
php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
117-
} \
118-
if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \
119-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
120-
return false; \
121-
} \
113+
#define PHONGO_QUERY_OPT_BOOL(opt, zarr, key) \
114+
if ((zarr) && php_array_existsc((zarr), (key))) { \
115+
if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \
116+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
117+
return false; \
118+
} \
122119
}
123120

124-
#define PHONGO_QUERY_OPT_BOOL(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 0)
125-
#define PHONGO_QUERY_OPT_BOOL_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_BOOL_EX((opt), (zarr), (key), 1)
126-
127121
#define PHONGO_QUERY_OPT_BSON_VALUE(opt, zarr, key) \
128122
if ((zarr) && php_array_existsc((zarr), (key))) { \
129123
if (!php_phongo_query_opts_append_value(intern->opts, (opt), (zarr), (key))) { \
@@ -140,21 +134,14 @@ static bool php_phongo_query_opts_append_value(bson_t* opts, const char* opts_ke
140134

141135
/* Note: handling of integer options will depend on SIZEOF_ZEND_LONG and we
142136
* are not converting strings to 64-bit integers for 32-bit platforms. */
143-
144-
#define PHONGO_QUERY_OPT_INT64_EX(opt, zarr, key, deprecated) \
145-
if ((zarr) && php_array_existsc((zarr), (key))) { \
146-
if ((deprecated)) { \
147-
php_error_docref(NULL, E_DEPRECATED, "The \"%s\" option is deprecated and will be removed in a future release", key); \
148-
} \
149-
if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \
150-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
151-
return false; \
152-
} \
137+
#define PHONGO_QUERY_OPT_INT64(opt, zarr, key) \
138+
if ((zarr) && php_array_existsc((zarr), (key))) { \
139+
if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \
140+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"%s\" option", (opt)); \
141+
return false; \
142+
} \
153143
}
154144

155-
#define PHONGO_QUERY_OPT_INT64(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 0)
156-
#define PHONGO_QUERY_OPT_INT64_DEPRECATED(opt, zarr, key) PHONGO_QUERY_OPT_INT64_EX((opt), (zarr), (key), 1)
157-
158145
#define PHONGO_QUERY_OPT_STRING(opt, zarr, key) \
159146
if ((zarr) && php_array_existsc((zarr), (key))) { \
160147
if (!php_phongo_query_opts_append_string(intern->opts, (opt), (zarr), (key))) { \
@@ -165,12 +152,10 @@ static bool php_phongo_query_opts_append_value(bson_t* opts, const char* opts_ke
165152
/* Initialize the "hint" option. Returns true on success; otherwise, false is
166153
* returned and an exception is thrown.
167154
*
168-
* The "hint" option (or "$hint" modifier) must be a string or document. Check
169-
* for both types and merge into BSON options accordingly. */
170-
static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options, zval* modifiers)
155+
* The "hint" option must be a string or document. Check for both types and
156+
* merge into BSON options accordingly. */
157+
static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options)
171158
{
172-
/* The "hint" option (or "$hint" modifier) must be a string or document.
173-
* Check for both types and merge into BSON options accordingly. */
174159
if (php_array_existsc(options, "hint")) {
175160
zend_uchar type = Z_TYPE_P(php_array_fetchc_deref(options, "hint"));
176161

@@ -182,50 +167,6 @@ static bool php_phongo_query_init_hint(php_phongo_query_t* intern, zval* options
182167
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type));
183168
return false;
184169
}
185-
} else if (modifiers && php_array_existsc(modifiers, "$hint")) {
186-
zend_uchar type = Z_TYPE_P(php_array_fetchc_deref(modifiers, "$hint"));
187-
188-
if (type == IS_STRING) {
189-
PHONGO_QUERY_OPT_STRING("hint", modifiers, "$hint");
190-
} else if (type == IS_OBJECT || type == IS_ARRAY) {
191-
PHONGO_QUERY_OPT_DOCUMENT("hint", modifiers, "$hint");
192-
} else {
193-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"$hint\" modifier to be string, array, or object, %s given", zend_get_type_by_const(type));
194-
return false;
195-
}
196-
}
197-
198-
return true;
199-
}
200-
201-
/* Initialize the "limit" and "singleBatch" options. Returns true on success;
202-
* otherwise, false is returned and an exception is thrown.
203-
*
204-
* mongoc_collection_find_with_opts() requires a non-negative limit. For
205-
* backwards compatibility, a negative limit should be set as a positive value
206-
* and default singleBatch to true. */
207-
static bool php_phongo_query_init_limit_and_singlebatch(php_phongo_query_t* intern, zval* options)
208-
{
209-
if (php_array_fetchc_long(options, "limit") < 0) {
210-
zend_long limit = php_array_fetchc_long(options, "limit");
211-
212-
if (!BSON_APPEND_INT64(intern->opts, "limit", -limit)) {
213-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"limit\" option");
214-
return false;
215-
}
216-
217-
if (php_array_existsc(options, "singleBatch") && !php_array_fetchc_bool(options, "singleBatch")) {
218-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Negative \"limit\" option conflicts with false \"singleBatch\" option");
219-
return false;
220-
} else {
221-
if (!BSON_APPEND_BOOL(intern->opts, "singleBatch", true)) {
222-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Error appending \"singleBatch\" option");
223-
return false;
224-
}
225-
}
226-
} else {
227-
PHONGO_QUERY_OPT_INT64("limit", options, "limit");
228-
PHONGO_QUERY_OPT_BOOL("singleBatch", options, "singleBatch");
229170
}
230171

231172
return true;
@@ -287,14 +228,10 @@ static bool php_phongo_query_init_max_await_time_ms(php_phongo_query_t* intern,
287228
}
288229

289230
/* Initializes the query from filter and options arguments and returns whether
290-
* an error occurred. If query is undefined, it will be initialized.
291-
*
292-
* This function will fall back to a modifier in the absence of a top-level
293-
* option (where applicable). */
231+
* an error occurred. If query is undefined, it will be initialized. */
294232
bool phongo_query_init(zval* return_value, zval* filter, zval* options)
295233
{
296234
php_phongo_query_t* intern;
297-
zval* modifiers = NULL;
298235

299236
if (Z_ISUNDEF_P(return_value)) {
300237
object_init_ex(return_value, php_phongo_query_ce);
@@ -330,59 +267,28 @@ bool phongo_query_init(zval* return_value, zval* filter, zval* options)
330267
return true;
331268
}
332269

333-
if (php_array_existsc(options, "modifiers")) {
334-
modifiers = php_array_fetchc_deref(options, "modifiers");
335-
336-
if (Z_TYPE_P(modifiers) != IS_ARRAY) {
337-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"modifiers\" option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(modifiers));
338-
return false;
339-
}
340-
341-
php_error_docref(NULL, E_DEPRECATED, "The \"modifiers\" option is deprecated and will be removed in a future release");
342-
}
343-
344-
PHONGO_QUERY_OPT_BOOL("allowDiskUse", options, "allowDiskUse")
345-
PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "allowPartialResults")
346-
else PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "partial");
270+
PHONGO_QUERY_OPT_BOOL("allowDiskUse", options, "allowDiskUse");
271+
PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "allowPartialResults");
347272
PHONGO_QUERY_OPT_BOOL("awaitData", options, "awaitData");
348273
PHONGO_QUERY_OPT_INT64("batchSize", options, "batchSize");
349274
PHONGO_QUERY_OPT_DOCUMENT("collation", options, "collation");
350-
PHONGO_QUERY_OPT_BSON_VALUE("comment", options, "comment")
351-
else PHONGO_QUERY_OPT_BSON_VALUE("comment", modifiers, "$comment");
275+
PHONGO_QUERY_OPT_BSON_VALUE("comment", options, "comment");
352276
PHONGO_QUERY_OPT_BOOL("exhaust", options, "exhaust");
353277
PHONGO_QUERY_OPT_DOCUMENT("let", options, "let");
354-
PHONGO_QUERY_OPT_DOCUMENT("max", options, "max")
355-
else PHONGO_QUERY_OPT_DOCUMENT("max", modifiers, "$max");
356-
PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", options, "maxScan")
357-
else PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", modifiers, "$maxScan");
358-
PHONGO_QUERY_OPT_INT64("maxTimeMS", options, "maxTimeMS")
359-
else PHONGO_QUERY_OPT_INT64("maxTimeMS", modifiers, "$maxTimeMS");
360-
PHONGO_QUERY_OPT_DOCUMENT("min", options, "min")
361-
else PHONGO_QUERY_OPT_DOCUMENT("min", modifiers, "$min");
278+
PHONGO_QUERY_OPT_INT64("limit", options, "limit");
279+
PHONGO_QUERY_OPT_DOCUMENT("max", options, "max");
280+
PHONGO_QUERY_OPT_INT64("maxTimeMS", options, "maxTimeMS");
281+
PHONGO_QUERY_OPT_DOCUMENT("min", options, "min");
362282
PHONGO_QUERY_OPT_BOOL("noCursorTimeout", options, "noCursorTimeout");
363-
PHONGO_QUERY_OPT_BOOL_DEPRECATED("oplogReplay", options, "oplogReplay");
364283
PHONGO_QUERY_OPT_DOCUMENT("projection", options, "projection");
365-
PHONGO_QUERY_OPT_BOOL("returnKey", options, "returnKey")
366-
else PHONGO_QUERY_OPT_BOOL("returnKey", modifiers, "$returnKey");
367-
PHONGO_QUERY_OPT_BOOL("showRecordId", options, "showRecordId")
368-
else PHONGO_QUERY_OPT_BOOL("showRecordId", modifiers, "$showDiskLoc");
284+
PHONGO_QUERY_OPT_BOOL("returnKey", options, "returnKey");
285+
PHONGO_QUERY_OPT_BOOL("showRecordId", options, "showRecordId");
286+
PHONGO_QUERY_OPT_BOOL("singleBatch", options, "singleBatch");
369287
PHONGO_QUERY_OPT_INT64("skip", options, "skip");
370-
PHONGO_QUERY_OPT_DOCUMENT("sort", options, "sort")
371-
else PHONGO_QUERY_OPT_DOCUMENT("sort", modifiers, "$orderby");
372-
PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", options, "snapshot")
373-
else PHONGO_QUERY_OPT_BOOL_DEPRECATED("snapshot", modifiers, "$snapshot");
288+
PHONGO_QUERY_OPT_DOCUMENT("sort", options, "sort");
374289
PHONGO_QUERY_OPT_BOOL("tailable", options, "tailable");
375290

376-
/* The "$explain" modifier should be converted to an "explain" option, which
377-
* libmongoc will later convert back to a modifier for the OP_QUERY code
378-
* path. This modifier will be ignored for the find command code path. */
379-
PHONGO_QUERY_OPT_BOOL("explain", modifiers, "$explain");
380-
381-
if (!php_phongo_query_init_hint(intern, options, modifiers)) {
382-
return false;
383-
}
384-
385-
if (!php_phongo_query_init_limit_and_singlebatch(intern, options)) {
291+
if (!php_phongo_query_init_hint(intern, options)) {
386292
return false;
387293
}
388294

@@ -397,14 +303,10 @@ bool phongo_query_init(zval* return_value, zval* filter, zval* options)
397303
return true;
398304
}
399305

400-
#undef PHONGO_QUERY_OPT_BOOL_EX
401306
#undef PHONGO_QUERY_OPT_BOOL
402-
#undef PHONGO_QUERY_OPT_BOOL_DEPRECATED
403307
#undef PHONGO_QUERY_OPT_BSON_VALUE
404308
#undef PHONGO_QUERY_OPT_DOCUMENT
405-
#undef PHONGO_QUERY_OPT_INT64_EX
406309
#undef PHONGO_QUERY_OPT_INT64
407-
#undef PHONGO_QUERY_OPT_INT64_DEPRECATED
408310
#undef PHONGO_QUERY_OPT_STRING
409311

410312
/* Constructs a new Query */

tests/query/query-ctor-002.phpt

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ var_dump(new MongoDB\Driver\Query(
1515
'exhaust' => false,
1616
'limit' => 20,
1717
'max' => ['y' => 100],
18-
'maxScan' => 50,
1918
'maxTimeMS' => 1000,
2019
'min' => ['y' => 1],
2120
'noCursorTimeout' => false,
22-
'oplogReplay' => false,
2321
'projection' => ['x' => 1, 'y' => 1],
2422
'returnKey' => false,
2523
'showRecordId' => false,
2624
'singleBatch' => false,
2725
'skip' => 5,
2826
'sort' => ['y' => -1],
29-
'snapshot' => false,
3027
'tailable' => false,
3128
]
3229
));
@@ -50,11 +47,6 @@ var_dump(new MongoDB\Driver\Query(
5047
===DONE===
5148
<?php exit(0); ?>
5249
--EXPECTF--
53-
Deprecated: MongoDB\Driver\Query::__construct(): The "maxScan" option is deprecated and will be removed in a future release in %s on line %d
54-
55-
Deprecated: MongoDB\Driver\Query::__construct(): The "oplogReplay" option is deprecated and will be removed in a future release in %s on line %d
56-
57-
Deprecated: MongoDB\Driver\Query::__construct(): The "snapshot" option is deprecated and will be removed in a future release in %s on line %d
5850
object(MongoDB\Driver\Query)#%d (%d) {
5951
["filter"]=>
6052
object(stdClass)#%d (%d) {
@@ -80,13 +72,13 @@ object(MongoDB\Driver\Query)#%d (%d) {
8072
string(3) "foo"
8173
["exhaust"]=>
8274
bool(false)
75+
["limit"]=>
76+
int(20)
8377
["max"]=>
8478
object(stdClass)#%d (%d) {
8579
["y"]=>
8680
int(100)
8781
}
88-
["maxScan"]=>
89-
int(50)
9082
["maxTimeMS"]=>
9183
int(1000)
9284
["min"]=>
@@ -96,8 +88,6 @@ object(MongoDB\Driver\Query)#%d (%d) {
9688
}
9789
["noCursorTimeout"]=>
9890
bool(false)
99-
["oplogReplay"]=>
100-
bool(false)
10191
["projection"]=>
10292
object(stdClass)#%d (%d) {
10393
["x"]=>
@@ -109,21 +99,17 @@ object(MongoDB\Driver\Query)#%d (%d) {
10999
bool(false)
110100
["showRecordId"]=>
111101
bool(false)
102+
["singleBatch"]=>
103+
bool(false)
112104
["skip"]=>
113105
int(5)
114106
["sort"]=>
115107
object(stdClass)#%d (%d) {
116108
["y"]=>
117109
int(-1)
118110
}
119-
["snapshot"]=>
120-
bool(false)
121111
["tailable"]=>
122112
bool(false)
123-
["limit"]=>
124-
int(20)
125-
["singleBatch"]=>
126-
bool(false)
127113
}
128114
["readConcern"]=>
129115
NULL

0 commit comments

Comments
 (0)