@@ -230,42 +230,70 @@ def _fix_outgoing(self, son, collection):
230230 def _command (self , command , allowable_errors = [], check = True , sock = None ):
231231 warnings .warn ("The '_command' method is deprecated. "
232232 "Please use 'command' instead." , DeprecationWarning )
233- return self .command (command , check , allowable_errors , sock )
233+ return self .command (command , check = check ,
234+ allowable_errors = allowable_errors , _sock = sock )
234235
235- # TODO api could be nicer like take a verb and a subject and then kwargs
236- # for options
237- def command (self , command , check = True , allowable_errors = [], _sock = None ):
236+ def command (self , command , value = 1 ,
237+ check = True , allowable_errors = [], _sock = None , ** kwargs ):
238238 """Issue a MongoDB command.
239239
240240 Send command `command` to the database and return the
241- response. If `command` is an instance of :class:`str` then the
242- command ``{command: 1}`` will be sent. Otherwise, `command`
243- must be an instance of :class:`dict` and will be sent as is.
241+ response. If `command` is an instance of :class:`basestring`
242+ then the command {`command`: `value`} will be sent. Otherwise,
243+ `command` must be an instance of :class:`dict` and will be
244+ sent as is.
245+
246+ Any additional keyword arguments will be added to the final
247+ command document before it is sent.
248+
249+ For example, a command like ``{buildinfo: 1}`` can be sent
250+ using:
251+
252+ >>> db.command("buildinfo")
253+
254+ For a command where the value matters, like ``{collstats:
255+ collection_name}`` we can do:
256+
257+ >>> db.command("collstats", collection_name)
258+
259+ For commands that take additional arguments we can use
260+ kwargs. So ``{filemd5: object_id, root: file_root}`` becomes:
261+
262+ >>> db.command("filemd5", object_id, root=file_root)
244263
245264 :Parameters:
246265 - `command`: document representing the command to be issued,
247266 or the name of the command (for simple commands only).
248267
249268 .. note:: the order of keys in the `command` document is
250269 significant (the "verb" must come first), so commands
251- which require multiple keys (eg, `findandmodify`)
252- should use an instance of :class:`~pymongo.son.SON`
253- instead of a Python `dict`.
270+ which require multiple keys (e.g. `findandmodify`)
271+ should use an instance of :class:`~pymongo.son.SON` or
272+ a string and kwargs instead of a Python `dict`.
254273
274+ - `value` (optional): value to use for the command verb when
275+ `command` is passed as a string
255276 - `check` (optional): check the response for errors, raising
256277 :class:`~pymongo.errors.OperationFailure` if there are any
257- - `allowable_errors`: if `check` is ``True``, error messages in this
258- list will be ignored by error-checking
278+ - `allowable_errors`: if `check` is ``True``, error messages
279+ in this list will be ignored by error-checking
280+ - `**kwargs` (optional): additional keyword arguments will
281+ be added to the command document before it is sent
259282
283+ .. versionchanged:: 1.5.1+
284+ Added the `value` argument for string commands, and keyword
285+ arguments for additional command options.
260286 .. versionchanged:: 1.5
261287 `command` can be a string in addition to a full document.
262288 .. versionadded:: 1.4
263289
264290 .. mongodoc:: commands
265291 """
266292
267- if isinstance (command , str ):
268- command = {command : 1 }
293+ if isinstance (command , basestring ):
294+ command = SON ([(command , value )])
295+
296+ command .update (kwargs )
269297
270298 result = self ["$cmd" ].find_one (command , _sock = _sock ,
271299 _must_use_master = True ,
@@ -308,7 +336,7 @@ def drop_collection(self, name_or_collection):
308336 if name not in self .collection_names ():
309337 return
310338
311- self .command ({ "drop" : unicode (name )} )
339+ self .command ("drop" , unicode (name ))
312340
313341 def validate_collection (self , name_or_collection ):
314342 """Validate a collection.
@@ -324,7 +352,7 @@ def validate_collection(self, name_or_collection):
324352 raise TypeError ("name_or_collection must be an instance of "
325353 "(Collection, str, unicode)" )
326354
327- result = self .command ({ "validate" : unicode (name )} )
355+ result = self .command ("validate" , unicode (name ))
328356
329357 info = result ["result" ]
330358 if info .find ("exception" ) != - 1 or info .find ("corrupt" ) != - 1 :
@@ -339,7 +367,7 @@ def profiling_level(self):
339367
340368 .. mongodoc:: profiling
341369 """
342- result = self .command ({ "profile" : - 1 } )
370+ result = self .command ("profile" , - 1 )
343371
344372 assert result ["was" ] >= 0 and result ["was" ] <= 2
345373 return result ["was" ]
@@ -359,7 +387,7 @@ def set_profiling_level(self, level):
359387 if not isinstance (level , int ) or level < 0 or level > 2 :
360388 raise ValueError ("level must be one of (OFF, SLOW_ONLY, ALL)" )
361389
362- self .command ({ "profile" : level } )
390+ self .command ("profile" , level )
363391
364392 def profiling_info (self ):
365393 """Returns a list containing current profiling information.
@@ -496,8 +524,7 @@ def authenticate(self, name, password):
496524 nonce = self .command ("getnonce" )["nonce" ]
497525 key = helpers ._auth_key (nonce , name , password )
498526 try :
499- self .command (SON ([("authenticate" , 1 ), ("user" , unicode (name )),
500- ("nonce" , nonce ), ("key" , key )]))
527+ self .command ("authenticate" , user = unicode (name ), nonce = nonce , key = key )
501528 return True
502529 except OperationFailure :
503530 return False
@@ -549,8 +576,7 @@ def eval(self, code, *args):
549576 if not isinstance (code , Code ):
550577 code = Code (code )
551578
552- command = SON ([("$eval" , code ), ("args" , list (args ))])
553- result = self .command (command )
579+ result = self .command ("$eval" , code , args = args )
554580 return result .get ("retval" , None )
555581
556582 def __call__ (self , * args , ** kwargs ):
0 commit comments