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 }