github.com/therealbill/libredis@v0.0.0-20161227004305-7d50abda5ccf/client/lists.go (about)

     1  package client
     2  
     3  // BLPop is a blocking list pop primitive.
     4  // It is the blocking version of LPOP
     5  // because it blocks the connection when there are no elements to pop from any of the given lists.
     6  // An element is popped from the head of the first list that is non-empty,
     7  // with the given keys being checked in the order that they are given.
     8  // A nil multi-bulk when no element could be popped and the timeout expired.
     9  // A two-element multi-bulk with the first element being the name of the key where an element was popped
    10  // and the second element being the value of the popped element.
    11  func (r *Redis) BLPop(keys []string, timeout int) ([]string, error) {
    12  	args := packArgs("BLPOP", keys, timeout)
    13  	rp, err := r.ExecuteCommand(args...)
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  	if rp.Multi == nil {
    18  		return nil, nil
    19  	}
    20  	return rp.ListValue()
    21  }
    22  
    23  // BRPop pops elements from the tail of a list instead of popping from the head.
    24  func (r *Redis) BRPop(keys []string, timeout int) ([]string, error) {
    25  	args := packArgs("BRPOP", keys, timeout)
    26  	rp, err := r.ExecuteCommand(args...)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	if rp.Multi == nil {
    31  		return nil, nil
    32  	}
    33  	return rp.ListValue()
    34  }
    35  
    36  // BRPopLPush is the blocking variant of RPOPLPUSH.
    37  // When source contains elements,
    38  // this command behaves exactly like RPOPLPUSH.
    39  // When source is empty, Redis will block the connection until
    40  // another client pushes to it or until timeout is reached.
    41  // A timeout of zero can be used to block indefinitely.
    42  // Bulk reply: the element being popped from source and pushed to destination.
    43  // If timeout is reached, a Null multi-bulk reply is returned.
    44  func (r *Redis) BRPopLPush(source, destination string, timeout int) ([]byte, error) {
    45  	rp, err := r.ExecuteCommand("BRPOPLPUSH", source, destination, timeout)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	if rp.Type == MultiReply {
    50  		return nil, nil
    51  	}
    52  	return rp.BytesValue()
    53  }
    54  
    55  // LIndex returns the element at index index in the list stored at key.
    56  // The index is zero-based, so 0 means the first element,
    57  // 1 the second element and so on.
    58  // Negative indices can be used to designate elements starting at the tail of the list.
    59  // Here, -1 means the last element, -2 means the penultimate and so forth.
    60  // When the value at key is not a list, an error is returned.
    61  // Bulk reply: the requested element, or nil when index is out of range.
    62  func (r *Redis) LIndex(key string, index int) ([]byte, error) {
    63  	rp, err := r.ExecuteCommand("LINDEX", key, index)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	return rp.BytesValue()
    68  }
    69  
    70  // LInsert inserts value in the list stored at key either before or after the reference value pivot.
    71  // When key does not exist, it is considered an empty list and no operation is performed.
    72  // An error is returned when key exists but does not hold a list value.
    73  // Integer reply: the length of the list after the insert operation, or -1 when the value pivot was not found.
    74  func (r *Redis) LInsert(key, position, pivot, value string) (int64, error) {
    75  	rp, err := r.ExecuteCommand("LINSERT", key, position, pivot, value)
    76  	if err != nil {
    77  		return 0, err
    78  	}
    79  	return rp.IntegerValue()
    80  }
    81  
    82  // LLen returns the length of the list stored at key.
    83  // If key does not exist, it is interpreted as an empty list and 0 is returned.
    84  // An error is returned when the value stored at key is not a list.
    85  func (r *Redis) LLen(key string) (int64, error) {
    86  	rp, err := r.ExecuteCommand("LLEN", key)
    87  	if err != nil {
    88  		return 0, err
    89  	}
    90  	return rp.IntegerValue()
    91  }
    92  
    93  // LPop removes and returns the first element of the list stored at key.
    94  // Bulk reply: the value of the first element, or nil when key does not exist.
    95  func (r *Redis) LPop(key string) ([]byte, error) {
    96  	rp, err := r.ExecuteCommand("LPOP", key)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	return rp.BytesValue()
   101  }
   102  
   103  // LPush insert all the specified values at the head of the list stored at key.
   104  // If key does not exist, it is created as empty list before performing the push operations.
   105  // When key holds a value that is not a list, an error is returned.
   106  // Integer reply: the length of the list after the push operations.
   107  func (r *Redis) LPush(key string, values ...string) (int64, error) {
   108  	args := packArgs("LPUSH", key, values)
   109  	rp, err := r.ExecuteCommand(args...)
   110  	if err != nil {
   111  		return 0, err
   112  	}
   113  	return rp.IntegerValue()
   114  }
   115  
   116  // LPushx inserts value at the head of the list stored at key,
   117  // only if key already exists and holds a list.
   118  // In contrary to LPUSH, no operation will be performed when key does not yet exist.
   119  // Integer reply: the length of the list after the push operation.
   120  func (r *Redis) LPushx(key, value string) (int64, error) {
   121  	rp, err := r.ExecuteCommand("LPUSHX", key, value)
   122  	if err != nil {
   123  		return 0, err
   124  	}
   125  	return rp.IntegerValue()
   126  }
   127  
   128  // LRange returns the specified elements of the list stored at key.
   129  // The offsets start and stop are zero-based indexes,
   130  // with 0 being the first element of the list (the head of the list), 1 being the next element and so on.
   131  // These offsets can also be negative numbers indicating offsets starting at the end of the list.
   132  // For example, -1 is the last element of the list, -2 the penultimate, and so on.
   133  //
   134  // Note that if you have a list of numbers from 0 to 100, LRANGE list 0 10 will return 11 elements,
   135  // that is, the rightmost item is included.
   136  // Out of range indexes will not produce an error.
   137  // If start is larger than the end of the list, an empty list is returned.
   138  // If stop is larger than the actual end of the list, Redis will treat it like the last element of the list.
   139  // Multi-bulk reply: list of elements in the specified range.
   140  func (r *Redis) LRange(key string, start, end int) ([]string, error) {
   141  	rp, err := r.ExecuteCommand("LRANGE", key, start, end)
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  	return rp.ListValue()
   146  }
   147  
   148  // LRem removes the first count occurrences of elements equal to value from the list stored at key.
   149  // The count argument influences the operation in the following ways:
   150  // count > 0: Remove elements equal to value moving from head to tail.
   151  // count < 0: Remove elements equal to value moving from tail to head.
   152  // count = 0: Remove all elements equal to value.
   153  // Integer reply: the number of removed elements.
   154  func (r *Redis) LRem(key string, count int, value string) (int64, error) {
   155  	rp, err := r.ExecuteCommand("LREM", key, count, value)
   156  	if err != nil {
   157  		return 0, err
   158  	}
   159  	return rp.IntegerValue()
   160  }
   161  
   162  // LSet sets the list element at index to value. For more information on the index argument, see LINDEX.
   163  // An error is returned for out of range indexes.
   164  func (r *Redis) LSet(key string, index int, value string) error {
   165  	rp, err := r.ExecuteCommand("LSET", key, index, value)
   166  	if err != nil {
   167  		return err
   168  	}
   169  	return rp.OKValue()
   170  }
   171  
   172  // LTrim trim an existing list so that it will contain only the specified range of elements specified.
   173  // Both start and stop are zero-based indexes, where 0 is the first element of the list (the head),
   174  // 1 the next element and so on.
   175  func (r *Redis) LTrim(key string, start, stop int) error {
   176  	rp, err := r.ExecuteCommand("LTRIM", key, start, stop)
   177  	if err != nil {
   178  		return err
   179  	}
   180  	return rp.OKValue()
   181  }
   182  
   183  // RPop removes and returns the last element of the list stored at key.
   184  // Bulk reply: the value of the last element, or nil when key does not exist.
   185  func (r *Redis) RPop(key string) ([]byte, error) {
   186  	rp, err := r.ExecuteCommand("RPOP", key)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  	return rp.BytesValue()
   191  }
   192  
   193  // RPopLPush atomically returns and removes the last element (tail) of the list stored at source,
   194  // and pushes the element at the first element (head) of the list stored at destination.
   195  //
   196  // If source does not exist, the value nil is returned and no operation is performed.
   197  // If source and destination are the same,
   198  // the operation is equivalent to removing the last element from the list and pushing it as first element of the list,
   199  // so it can be considered as a list rotation command.
   200  func (r *Redis) RPopLPush(source, destination string) ([]byte, error) {
   201  	rp, err := r.ExecuteCommand("RPOPLPUSH", source, destination)
   202  	if err != nil {
   203  		return nil, err
   204  	}
   205  	return rp.BytesValue()
   206  }
   207  
   208  // RPush insert all the specified values at the tail of the list stored at key.
   209  // If key does not exist, it is created as empty list before performing the push operation.
   210  // When key holds a value that is not a list, an error is returned.
   211  func (r *Redis) RPush(key string, values ...string) (int64, error) {
   212  	args := packArgs("RPUSH", key, values)
   213  	rp, err := r.ExecuteCommand(args...)
   214  	if err != nil {
   215  		return 0, err
   216  	}
   217  	return rp.IntegerValue()
   218  }
   219  
   220  // RPushx inserts value at the tail of the list stored at key,
   221  // only if key already exists and holds a list.
   222  // In contrary to RPUSH, no operation will be performed when key does not yet exist.
   223  func (r *Redis) RPushx(key, value string) (int64, error) {
   224  	rp, err := r.ExecuteCommand("RPUSHX", key, value)
   225  	if err != nil {
   226  		return 0, err
   227  	}
   228  	return rp.IntegerValue()
   229  }