@@ -1272,9 +1272,9 @@ find q@Query{selection, batchSize} = do
1272
1272
qr <- queryRequestOpMsg False q
1273
1273
let newQr =
1274
1274
case fst qr of
1275
- Req qry ->
1276
- let coll = last $ T. splitOn " ." ( qFullCollection qry)
1277
- in (Req $ qry {qSelector = merge ( qSelector qry) [ " find" =: coll ]}, snd qr)
1275
+ Req P. Query { .. } ->
1276
+ let coll = last $ T. splitOn " ." qFullCollection
1277
+ in (Req $ P. Query {qSelector = merge qSelector [ " find" =: coll ], .. }, snd qr)
1278
1278
-- queryRequestOpMsg only returns Cmd types constructed via Req
1279
1279
_ -> error " impossible"
1280
1280
dBatch <- liftIO $ requestOpMsg pipe newQr []
@@ -1312,6 +1312,9 @@ findCommand q@Query{..} = do
1312
1312
| predicate a = Just (f a)
1313
1313
| otherwise = Nothing
1314
1314
1315
+ isHandshake :: Document -> Bool
1316
+ isHandshake = (== [" isMaster" =: (1 :: Int32 )])
1317
+
1315
1318
findOne :: (MonadIO m ) => Query -> Action m (Maybe Document )
1316
1319
-- ^ Fetch first document satisfying query or @Nothing@ if none satisfy it
1317
1320
findOne q = do
@@ -1321,8 +1324,7 @@ findOne q = do
1321
1324
rq <- liftIO $ request pipe [] qr
1322
1325
Batch _ _ docs <- liftDB $ fulfill rq
1323
1326
return (listToMaybe docs)
1324
- isHandshake = (== [" isMaster" =: (1 :: Int32 )]) $ selector $ selection q :: Bool
1325
- if isHandshake
1327
+ if isHandshake (selector $ selection q)
1326
1328
then legacyQuery
1327
1329
else do
1328
1330
let sd = P. serverData pipe
@@ -1332,14 +1334,14 @@ findOne q = do
1332
1334
qr <- queryRequestOpMsg False q {limit = 1 }
1333
1335
let newQr =
1334
1336
case fst qr of
1335
- Req qry ->
1336
- let coll = last $ T. splitOn " ." ( qFullCollection qry)
1337
+ Req P. Query { .. } ->
1338
+ let coll = last $ T. splitOn " ." qFullCollection
1337
1339
-- We have to understand whether findOne is called as
1338
1340
-- command directly. This is necessary since findOne is used via
1339
1341
-- runCommand as a vehicle to execute any type of commands and notices.
1340
- labels = catMaybes $ map (\ f -> look f $ qSelector qry ) (noticeCommands ++ adminCommands) :: [Value ]
1342
+ labels = catMaybes $ map (\ f -> look f qSelector) (noticeCommands ++ adminCommands) :: [Value ]
1341
1343
in if null labels
1342
- then (Req $ qry {qSelector = merge ( qSelector qry) [ " find" =: coll ]}, snd qr)
1344
+ then (Req P. Query {qSelector = merge qSelector [ " find" =: coll ], .. }, snd qr)
1343
1345
else qr
1344
1346
_ -> error " impossible"
1345
1347
rq <- liftIO $ requestOpMsg pipe newQr []
@@ -1526,7 +1528,7 @@ requestOpMsg pipe (Req r, remainingLimit) params = do
1526
1528
promise <- liftIOE ConnectionFailure $ P. callOpMsg pipe r Nothing params
1527
1529
let protectedPromise = liftIOE ConnectionFailure promise
1528
1530
return $ fromReply remainingLimit =<< protectedPromise
1529
- requestOpMsg _ ( Nc _, _) _ = error " requestOpMsg: Only messages of type Query are supported"
1531
+ requestOpMsg _ _ _ = error " requestOpMsg: Only messages of type Query are supported"
1530
1532
1531
1533
fromReply :: Maybe Limit -> Reply -> DelayedBatch
1532
1534
-- ^ Convert Reply to Batch or Failure
@@ -1844,9 +1846,29 @@ type Command = Document
1844
1846
-- ^ A command is a special query or action against the database. See <http://www.mongodb.org/display/DOCS/Commands> for details.
1845
1847
1846
1848
runCommand :: (MonadIO m ) => Command -> Action m Document
1847
- -- ^ Run command against the database and return its result
1848
- runCommand c = fromMaybe err <$> findOne (query c " $cmd" ) where
1849
- err = error $ " Nothing returned for command: " ++ show c
1849
+ runCommand params = do
1850
+ pipe <- asks mongoPipe
1851
+ if isHandshake params || maxWireVersion (P. serverData pipe) < 17
1852
+ then runCommandLegacy pipe params
1853
+ else runCommand' pipe params
1854
+
1855
+ runCommandLegacy :: MonadIO m => Pipe -> Selector -> ReaderT MongoContext m Document
1856
+ runCommandLegacy pipe params = do
1857
+ qr <- queryRequest False (query params " $cmd" ) {limit = 1 }
1858
+ rq <- liftIO $ request pipe [] qr
1859
+ Batch _ _ docs <- liftDB $ fulfill rq
1860
+ case docs of
1861
+ [doc] -> pure doc
1862
+ _ -> error $ " Nothing returned for command: " <> show params
1863
+
1864
+ runCommand' :: MonadIO m => Pipe -> Selector -> ReaderT MongoContext m Document
1865
+ runCommand' pipe params = do
1866
+ ctx <- ask
1867
+ rq <- liftIO $ requestOpMsg pipe ( Req (P. Message (mongoDatabase ctx) params), Just 1 ) []
1868
+ Batch _ _ docs <- liftDB $ fulfill rq
1869
+ case docs of
1870
+ [doc] -> pure doc
1871
+ _ -> error $ " Nothing returned for command: " <> show params
1850
1872
1851
1873
runCommand1 :: (MonadIO m ) => Text -> Action m Document
1852
1874
-- ^ @runCommand1 foo = runCommand [foo =: 1]@
0 commit comments