3232    RequestSelect ,
3333    RequestSubscribe ,
3434    RequestUpdate ,
35+     RequestUpsert ,
3536    RequestAuthenticate )
3637
3738from  tarantool .space  import  Space 
@@ -331,7 +332,7 @@ def eval(self, expr, *args):
331332    def  replace (self , space_name , values ):
332333        ''' 
333334        Execute REPLACE request. 
334-         It will  throw error if there's no tuple with this PK exists 
335+         It won't  throw error if there's no tuple with this PK exists 
335336
336337        :param int space_name: space id to insert a record 
337338        :type space_name: int or str 
@@ -347,6 +348,14 @@ def replace(self, space_name, values):
347348        return  self ._send_request (request )
348349
349350    def  authenticate (self , user , password ):
351+         ''' 
352+         Execute AUTHENTICATE request. 
353+ 
354+         :param string user: user to authenticate with 
355+         :param string password: password for the user 
356+ 
357+         :rtype: `Response` instance 
358+         ''' 
350359        self .user  =  user 
351360        self .password  =  password 
352361        if  not  self ._socket :
@@ -408,7 +417,8 @@ def insert(self, space_name, values):
408417    def  delete (self , space_name , key , ** kwargs ):
409418        ''' 
410419        Execute DELETE request. 
411-         Delete single record identified by `key` (using primary index). 
420+         Delete single record identified by `key`. If you're using secondary 
421+         index, it must be unique. 
412422
413423        :param space_name: space number or name to delete a record 
414424        :type space_name: int or name 
@@ -427,25 +437,139 @@ def delete(self, space_name, key, **kwargs):
427437        request  =  RequestDelete (self , space_name , index_name , key )
428438        return  self ._send_request (request )
429439
440+     def  upsert (self , space_name , tuple_value , op_list , ** kwargs ):
441+         ''' 
442+         Execute UPSERT request. 
443+ 
444+         If there is an existing tuple which matches the key fields of 
445+         `tuple_value`, then the request has the same effect as UPDATE 
446+         and the [(field_1, symbol_1, arg_1), ...] parameter is used. 
447+ 
448+         If there is no existing tuple which matches the key fields of 
449+         `tuple_value`, then the request has the same effect as INSERT 
450+         and the `tuple_value` parameter is used. However, unlike insert 
451+         or update, upsert will not read a tuple and perform error checks 
452+         before returning -- this is a design feature which enhances 
453+         throughput but requires more caution on the part of the user. 
454+ 
455+         If you're using secondary index, it must be unique. 
456+ 
457+         List of operations allows to update individual fields. 
458+ 
459+         *Allowed operations:* 
460+ 
461+         (For every operation you must provide field number, to apply this 
462+         operation to) 
463+ 
464+         * `+` for addition (values must be numeric) 
465+         * `-` for subtraction (values must be numeric) 
466+         * `&` for bitwise AND (values must be unsigned numeric) 
467+         * `|` for bitwise OR (values must be unsigned numeric) 
468+         * `^` for bitwise XOR (values must be unsigned numeric) 
469+         * `:` for string splice (you must provide `offset`, `count` and `value` 
470+           for this operation) 
471+         * `!` for insertion (provide any element to insert) 
472+         * `=` for assignment (provide any element to assign) 
473+         * `#` for deletion (provide count of fields to delete) 
474+ 
475+         :param space_name: space number or name to update a record 
476+         :type space_name: int or str 
477+         :param index: index number or name to update a record 
478+         :type index: int or str 
479+         :param tuple_value: tuple, that 
480+         :type tuple_value: 
481+         :param op_list: list of operations. Each operation 
482+             is tuple of three (or more) values 
483+         :type op_list: a list of the form [(symbol_1, field_1, arg_1), 
484+             (symbol_2, field_2, arg_2_1, arg_2_2, arg_2_3),...] 
485+ 
486+         :rtype: `Response` instance 
487+ 
488+         Operation examples: 
489+ 
490+         .. code-block:: python 
491+ 
492+             # 'ADD' 55 to second field 
493+             # Assign 'x' to third field 
494+             [('+', 2, 55), ('=', 3, 'x')] 
495+             # 'OR' third field with '1' 
496+             # Cut three symbols starting from second and replace them with '!!' 
497+             # Insert 'hello, world' field before fifth element of tuple 
498+             [('|', 3, 1), (':', 2, 2, 3, '!!'), ('!', 5, 'hello, world')] 
499+             # Delete two fields starting with second field 
500+             [('#', 2, 2)] 
501+         ''' 
502+         index_name  =  kwargs .get ("index" , 0 )
503+ 
504+         if  isinstance (space_name , six .string_types ):
505+             space_name  =  self .schema .get_space (space_name ).sid 
506+         if  isinstance (index_name , six .string_types ):
507+             index_name  =  self .schema .get_index (space_name , index_name ).iid 
508+         request  =  RequestUpsert (self , space_name , index_name , tuple_value , op_list )
509+         return  self ._send_request (request )
510+ 
430511    def  update (self , space_name , key , op_list , ** kwargs ):
431512        ''' 
432513        Execute UPDATE request. 
433-         Update single record identified by `key` (using primary index). 
514+ 
515+         The `update` function supports operations on fields — assignment, 
516+         arithmetic (if the field is unsigned numeric), cutting and pasting 
517+         fragments of a field, deleting or inserting a field. Multiple 
518+         operations can be combined in a single update request, and in this 
519+         case they are performed atomically and sequentially. Each operation 
520+         requires specification of a field number. When multiple operations are 
521+         present, the field number for each operation is assumed to be relative 
522+         to the most recent state of the tuple, that is, as if all previous 
523+         operations in a multi-operation update have already been applied. 
524+         In other words, it is always safe to merge multiple update invocations 
525+         into a single invocation, with no change in semantics. 
526+ 
527+         Update single record identified by `key`. 
434528
435529        List of operations allows to update individual fields. 
436530
531+         *Allowed operations:* 
532+ 
533+         (For every operation you must provide field number, to apply this 
534+         operation to) 
535+ 
536+         * `+` for addition (values must be numeric) 
537+         * `-` for subtraction (values must be numeric) 
538+         * `&` for bitwise AND (values must be unsigned numeric) 
539+         * `|` for bitwise OR (values must be unsigned numeric) 
540+         * `^` for bitwise XOR (values must be unsigned numeric) 
541+         * `:` for string splice (you must provide `offset`, `count` and `value` 
542+           for this operation) 
543+         * `!` for insertion (before) (provide any element to insert) 
544+         * `=` for assignment (provide any element to assign) 
545+         * `#` for deletion (provide count of fields to delete) 
546+ 
437547        :param space_name: space number or name to update a record 
438548        :type space_name: int or str 
439549        :param index: index number or name to update a record 
440550        :type index: int or str 
441551        :param key: key that identifies a record 
442552        :type key: int or str 
443553        :param op_list: list of operations. Each operation 
444-             is tuple of three values 
445-         :type op_list: a list of the form 
446-             [(field_1, symbol_1, arg_1), (field_2, symbol_2, arg_2), ...] 
554+             is tuple of three (or more)  values 
555+         :type op_list: a list of the form [(symbol_1, field_1, arg_1),  
556+             (symbol_2, field_2, arg_2_1, arg_2_2, arg_2_3),  ...] 
447557
448-         :rtype: `Response` instance 
558+         :rtype: ``Response`` instance 
559+ 
560+         Operation examples: 
561+ 
562+         .. code-block:: python 
563+ 
564+             # 'ADD' 55 to second field 
565+             # Assign 'x' to third field 
566+             [('+', 2, 55), ('=', 3, 'x')] 
567+             # 'OR' third field with '1' 
568+             # Cut three symbols starting from second and replace them with '!!' 
569+             # Insert 'hello, world' field before fifth element of tuple 
570+             [('|', 3, 1), (':', 2, 2, 3, '!!'), ('!', 5, 'hello, world')] 
571+             # Delete two fields starting with second field 
572+             [('#', 2, 2)] 
449573        ''' 
450574        index_name  =  kwargs .get ("index" , 0 )
451575
0 commit comments