@@ -1530,12 +1530,14 @@ void OperationDefinitionVisitor::visit(const std::string& operationType, const p
1530
1530
}, std::cref (*operationDefinition.children .back ()));
1531
1531
}
1532
1532
1533
- SubscriptionData::SubscriptionData (std::shared_ptr<OperationData>&& data, SubscriptionName&& field, response::Value&& arguments,
1533
+ SubscriptionData::SubscriptionData (std::shared_ptr<OperationData>&& data, SubscriptionName&& field,
1534
+ response::Value&& arguments, response::Value&& fieldDirectives,
1534
1535
peg::ast&& query, std::string&& operationName, SubscriptionCallback&& callback,
1535
1536
const peg::ast_node& selection)
1536
1537
: data(std::move(data))
1537
1538
, field(std::move(field))
1538
1539
, arguments(std::move(arguments))
1540
+ , fieldDirectives(std::move(fieldDirectives))
1539
1541
, query(std::move(query))
1540
1542
, operationName(std::move(operationName))
1541
1543
, callback(std::move(callback))
@@ -1566,6 +1568,7 @@ class SubscriptionDefinitionVisitor
1566
1568
const std::shared_ptr<Object>& _subscriptionObject;
1567
1569
SubscriptionName _field;
1568
1570
response::Value _arguments;
1571
+ response::Value _fieldDirectives;
1569
1572
std::shared_ptr<SubscriptionData> _result;
1570
1573
};
1571
1574
@@ -1630,6 +1633,7 @@ void SubscriptionDefinitionVisitor::visit(const peg::ast_node& operationDefiniti
1630
1633
std::move (_fragments)),
1631
1634
std::move (_field),
1632
1635
std::move (_arguments),
1636
+ std::move (_fieldDirectives),
1633
1637
std::move (_params.query ),
1634
1638
std::move (_params.operationName ),
1635
1639
std::move (_callback),
@@ -1670,6 +1674,8 @@ void SubscriptionDefinitionVisitor::visitField(const peg::ast_node& field)
1670
1674
return ;
1671
1675
}
1672
1676
1677
+ _fieldDirectives = directiveVisitor.getDirectives ();
1678
+
1673
1679
response::Value arguments (response::Type::Map);
1674
1680
1675
1681
peg::on_first_child<peg::arguments>(field,
@@ -2176,35 +2182,76 @@ void Request::deliver(const SubscriptionName& name, const std::shared_ptr<Object
2176
2182
deliver (std::launch::deferred, name, subscriptionObject);
2177
2183
}
2178
2184
2179
- void Request::deliver (std::launch launch , const SubscriptionName& name , const std::shared_ptr<Object>& subscriptionObject) const
2185
+ void Request::deliver (const SubscriptionName& name , const SubscriptionArguments& arguments , const std::shared_ptr<Object>& subscriptionObject) const
2180
2186
{
2181
- deliver (launch, name, SubscriptionArguments {} , subscriptionObject);
2187
+ deliver (std:: launch::deferred , name, arguments , subscriptionObject);
2182
2188
}
2183
2189
2184
- void Request::deliver (const SubscriptionName& name, const SubscriptionArguments& arguments, const std::shared_ptr<Object>& subscriptionObject) const
2190
+ void Request::deliver (const SubscriptionName& name, const SubscriptionArguments& arguments,
2191
+ const SubscriptionArguments& directives, const std::shared_ptr<Object>& subscriptionObject) const
2185
2192
{
2186
- deliver (std::launch::deferred, name, arguments, subscriptionObject);
2193
+ deliver (std::launch::deferred, name, arguments, directives, subscriptionObject);
2194
+ }
2195
+
2196
+ void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments,
2197
+ const std::shared_ptr<Object>& subscriptionObject) const
2198
+ {
2199
+ deliver (std::launch::deferred, name, applyArguments, subscriptionObject);
2200
+ }
2201
+
2202
+ void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments,
2203
+ const SubscriptionFilterCallback& applyDirectives, const std::shared_ptr<Object>& subscriptionObject) const
2204
+ {
2205
+ deliver (std::launch::deferred, name, applyArguments, applyDirectives, subscriptionObject);
2206
+ }
2207
+
2208
+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2209
+ const std::shared_ptr<Object>& subscriptionObject) const
2210
+ {
2211
+ deliver (launch, name, SubscriptionArguments {}, SubscriptionArguments {}, subscriptionObject);
2187
2212
}
2188
2213
2189
2214
void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionArguments& arguments, const std::shared_ptr<Object>& subscriptionObject) const
2190
2215
{
2191
- SubscriptionFilterCallback exactMatch = [&arguments](response::MapType::const_reference required) noexcept -> bool
2192
- {
2216
+ deliver (launch, name, arguments, SubscriptionArguments {}, subscriptionObject);
2217
+ }
2218
+
2219
+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2220
+ const SubscriptionArguments& arguments, const SubscriptionArguments& directives,
2221
+ const std::shared_ptr<Object>& subscriptionObject) const
2222
+ {
2223
+ SubscriptionFilterCallback argumentsMatch =
2224
+ [&arguments](response::MapType::const_reference required) noexcept -> bool {
2193
2225
auto itrArgument = arguments.find (required.first );
2194
2226
2195
- return (itrArgument != arguments.cend ()
2196
- && itrArgument->second == required.second );
2227
+ return (itrArgument != arguments.cend () && itrArgument->second == required.second );
2197
2228
};
2198
2229
2199
- deliver (launch, name, exactMatch, subscriptionObject);
2230
+ SubscriptionFilterCallback directivesMatch =
2231
+ [&directives](response::MapType::const_reference required) noexcept -> bool {
2232
+ auto itrDirective = directives.find (required.first );
2233
+
2234
+ return (itrDirective != directives.cend () && itrDirective->second == required.second );
2235
+ };
2236
+
2237
+ deliver (launch, name, argumentsMatch, directivesMatch, subscriptionObject);
2200
2238
}
2201
2239
2202
- void Request::deliver (const SubscriptionName& name, const SubscriptionFilterCallback& apply , const std::shared_ptr<Object>& subscriptionObject) const
2240
+ void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionFilterCallback& applyArguments , const std::shared_ptr<Object>& subscriptionObject) const
2203
2241
{
2204
- deliver (std::launch::deferred, name, apply, subscriptionObject);
2242
+ deliver (
2243
+ launch,
2244
+ name,
2245
+ applyArguments,
2246
+ [](response::MapType::const_reference) noexcept {
2247
+ return true ;
2248
+ },
2249
+ subscriptionObject);
2205
2250
}
2206
2251
2207
- void Request::deliver (std::launch launch, const SubscriptionName& name, const SubscriptionFilterCallback& apply, const std::shared_ptr<Object>& subscriptionObject) const
2252
+ void Request::deliver (std::launch launch, const SubscriptionName& name,
2253
+ const SubscriptionFilterCallback& applyArguments, const SubscriptionFilterCallback& applyDirectives,
2254
+ const std::shared_ptr<Object>& subscriptionObject) const
2208
2255
{
2209
2256
const auto & optionalOrDefaultSubscription = subscriptionObject
2210
2257
? subscriptionObject
@@ -2230,7 +2277,7 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
2230
2277
// in this event, don't deliver the event to this subscription
2231
2278
for (const auto & required : subscriptionArguments)
2232
2279
{
2233
- if (!apply (required))
2280
+ if (!applyArguments (required))
2234
2281
{
2235
2282
matchedArguments = false ;
2236
2283
break ;
@@ -2242,6 +2289,25 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
2242
2289
continue ;
2243
2290
}
2244
2291
2292
+ // If the field in this subscription had field directives that did not match what was
2293
+ // provided in this event, don't deliver the event to this subscription
2294
+ const auto & subscriptionFieldDirectives = registration->fieldDirectives ;
2295
+ bool matchedFieldDirectives = true ;
2296
+
2297
+ for (const auto & required : subscriptionFieldDirectives)
2298
+ {
2299
+ if (!applyDirectives (required))
2300
+ {
2301
+ matchedFieldDirectives = false ;
2302
+ break ;
2303
+ }
2304
+ }
2305
+
2306
+ if (!matchedFieldDirectives)
2307
+ {
2308
+ continue ;
2309
+ }
2310
+
2245
2311
std::future<response::Value> result;
2246
2312
response::Value emptyFragmentDirectives (response::Type::Map);
2247
2313
const SelectionSetParams selectionSetParams {
@@ -2257,13 +2323,17 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
2257
2323
2258
2324
try
2259
2325
{
2260
- result = std::async (launch,
2261
- [registration](std::future<response::Value> document)
2262
- {
2263
- return document.get ();
2264
- }, optionalOrDefaultSubscription->resolve (selectionSetParams, registration->selection , registration->data ->fragments , registration->data ->variables ));
2326
+ result = std::async (
2327
+ launch,
2328
+ [registration](std::future<response::Value> document) {
2329
+ return document.get ();
2330
+ },
2331
+ optionalOrDefaultSubscription->resolve (selectionSetParams,
2332
+ registration->selection ,
2333
+ registration->data ->fragments ,
2334
+ registration->data ->variables ));
2265
2335
}
2266
- catch (schema_exception & ex)
2336
+ catch (schema_exception& ex)
2267
2337
{
2268
2338
std::promise<response::Value> promise;
2269
2339
response::Value document (response::Type::Map);
@@ -2275,11 +2345,12 @@ void Request::deliver(std::launch launch, const SubscriptionName& name, const Su
2275
2345
result = promise.get_future ();
2276
2346
}
2277
2347
2278
- callbacks.push (std::async (launch,
2279
- [registration](std::future<response::Value> document)
2280
- {
2281
- registration->callback (std::move (document));
2282
- }, std::move (result)));
2348
+ callbacks.push (std::async (
2349
+ launch,
2350
+ [registration](std::future<response::Value> document) {
2351
+ registration->callback (std::move (document));
2352
+ },
2353
+ std::move (result)));
2283
2354
}
2284
2355
2285
2356
while (!callbacks.empty ())
0 commit comments