redis-cluster 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +36 -0
- data/lib/redis-cluster.rb +208 -0
- data/lib/redis_cluster/client.rb +54 -0
- data/lib/redis_cluster/cluster.rb +179 -0
- data/lib/redis_cluster/function.rb +23 -0
- data/lib/redis_cluster/function/hash.rb +150 -0
- data/lib/redis_cluster/function/key.rb +107 -0
- data/lib/redis_cluster/function/list.rb +139 -0
- data/lib/redis_cluster/function/scan.rb +90 -0
- data/lib/redis_cluster/function/set.rb +83 -0
- data/lib/redis_cluster/function/sorted_set.rb +375 -0
- data/lib/redis_cluster/function/string.rb +234 -0
- data/lib/redis_cluster/future.rb +28 -0
- data/lib/redis_cluster/version.rb +5 -0
- metadata +72 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'function/set'
|
4
|
+
require_relative 'function/key'
|
5
|
+
require_relative 'function/list'
|
6
|
+
require_relative 'function/hash'
|
7
|
+
require_relative 'function/string'
|
8
|
+
require_relative 'function/sorted_set'
|
9
|
+
require_relative 'function/scan'
|
10
|
+
|
11
|
+
class RedisCluster
|
12
|
+
|
13
|
+
# Function include necessary redis function.
|
14
|
+
module Function
|
15
|
+
include Function::Set
|
16
|
+
include Function::Key
|
17
|
+
include Function::List
|
18
|
+
include Function::Hash
|
19
|
+
include Function::String
|
20
|
+
include Function::SortedSet
|
21
|
+
include Function::Scan
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
class RedisCluster
|
5
|
+
module Function
|
6
|
+
|
7
|
+
# Hash implement redis hashes commands. There will be some adjustment for cluster.
|
8
|
+
# see https://redis.io/commands#hash. Most of the code are copied from
|
9
|
+
# https://github.com/redis/redis-rb/blob/master/lib/redis.rb.
|
10
|
+
#
|
11
|
+
# SETTER = [:hdel, :hincrby, :hincrbyfloat, :hmset, :hset, :hsetnx]
|
12
|
+
# GETTER = [:hexists, :hget, :hgetall, :hkeys, :hlen, :hmget, :hstrlen, :hvals, :hscan]
|
13
|
+
module Hash
|
14
|
+
|
15
|
+
# Delete one or more hash fields.
|
16
|
+
#
|
17
|
+
# @param [String] key
|
18
|
+
# @param [String, Array<String>] field
|
19
|
+
# @return [Fixnum] the number of fields that were removed from the hash
|
20
|
+
def hdel(key, field)
|
21
|
+
call(key, [:hdel, key, field])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Increment the integer value of a hash field by the given integer number.
|
25
|
+
#
|
26
|
+
# @param [String] key
|
27
|
+
# @param [String] field
|
28
|
+
# @param [Fixnum] increment
|
29
|
+
# @return [Fixnum] value of the field after incrementing it
|
30
|
+
def hincrby(key, field, increment)
|
31
|
+
call(key, [:hincrby, key, field, increment])
|
32
|
+
end
|
33
|
+
|
34
|
+
# Increment the numeric value of a hash field by the given float number.
|
35
|
+
#
|
36
|
+
# @param [String] key
|
37
|
+
# @param [String] field
|
38
|
+
# @param [Float] increment
|
39
|
+
# @return [Float] value of the field after incrementing it
|
40
|
+
def hincrbyfloat(key, field, increment)
|
41
|
+
call(key, [:hincrbyfloat, key, field, increment], transform: Redis::Floatify)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Set one or more hash values.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# redis.hmset("hash", "f1", "v1", "f2", "v2")
|
48
|
+
# # => "OK"
|
49
|
+
#
|
50
|
+
# @param [String] key
|
51
|
+
# @param [Array<String>] attrs array of fields and values
|
52
|
+
# @return [String] `"OK"`
|
53
|
+
def hmset(key, *attrs)
|
54
|
+
call(key, [:hmset, key] + attrs)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set the string value of a hash field.
|
58
|
+
#
|
59
|
+
# @param [String] key
|
60
|
+
# @param [String] field
|
61
|
+
# @param [String] value
|
62
|
+
# @return [Boolean] whether or not the field was **added** to the hash
|
63
|
+
def hset(key, field, value)
|
64
|
+
call(key, [:hset, key, field, value], transform: Redis::Boolify)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set the value of a hash field, only if the field does not exist.
|
68
|
+
#
|
69
|
+
# @param [String] key
|
70
|
+
# @param [String] field
|
71
|
+
# @param [String] value
|
72
|
+
# @return [Boolean] whether or not the field was **added** to the hash
|
73
|
+
def hsetnx(key, field, value)
|
74
|
+
call(key, [:hsetnx, key, field, value], transform: Redis::Boolify)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Determine if a hash field exists.
|
78
|
+
#
|
79
|
+
# @param [String] key
|
80
|
+
# @param [String] field
|
81
|
+
# @return [Boolean] whether or not the field exists in the hash
|
82
|
+
def hexists(key, field)
|
83
|
+
call(key, [:hexists, key, field], transform: Redis::Boolify, read: true)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get the value of a hash field.
|
87
|
+
#
|
88
|
+
# @param [String] key
|
89
|
+
# @param [String] field
|
90
|
+
# @return [String]
|
91
|
+
def hget(key, field)
|
92
|
+
call(key, [:hget, key, field], read: true)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get all the fields and values in a hash.
|
96
|
+
#
|
97
|
+
# @param [String] key
|
98
|
+
# @return [Hash<String, String>]
|
99
|
+
def hgetall(key)
|
100
|
+
call(key, [:hgetall, key], transform: Redis::Hashify, read: true)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Get all the fields in a hash.
|
104
|
+
#
|
105
|
+
# @param [String] key
|
106
|
+
# @return [Array<String>]
|
107
|
+
def hkeys(key)
|
108
|
+
call(key, [:hkeys, key], read: true)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get all the values in a hash.
|
112
|
+
#
|
113
|
+
# @param [String] key
|
114
|
+
# @return [Array<String>]
|
115
|
+
def hvals(key)
|
116
|
+
call(key, [:hvals, key], read: true)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Get the number of fields in a hash.
|
120
|
+
#
|
121
|
+
# @param [String] key
|
122
|
+
# @return [Fixnum] number of fields in the hash
|
123
|
+
def hlen(key)
|
124
|
+
call(key, [:hlen, key], read: true)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get the values of all the given hash fields.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# redis.hmget("hash", "f1", "f2")
|
131
|
+
# # => ["v1", "v2"]
|
132
|
+
#
|
133
|
+
# @param [String] key
|
134
|
+
# @param [Array<String>] fields array of fields
|
135
|
+
# @return [Array<String>] an array of values for the specified fields
|
136
|
+
def hmget(key, *fields)
|
137
|
+
call(key, [:hmget, key] + fields, read: true)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns the string length of the value associated with field in the hash stored at key.
|
141
|
+
#
|
142
|
+
# @param [String] key
|
143
|
+
# @param [String] field
|
144
|
+
# @return [Fixnum] String lenght
|
145
|
+
def hstrlen(key, field)
|
146
|
+
call(key, [:hstrlen, key, field], read: true)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
class RedisCluster
|
5
|
+
module Function
|
6
|
+
|
7
|
+
# Key implement redis keys commands. There will be some adjustment for cluster.
|
8
|
+
# see https://redis.io/commands#generic. Most of the code are copied from
|
9
|
+
# https://github.com/redis/redis-rb/blob/master/lib/redis.rb.
|
10
|
+
#
|
11
|
+
# SETTER = [:del, :expire, :pexpire, :restore]
|
12
|
+
# GETTER = [:exists, :ttl, :pttl, :type]
|
13
|
+
module Key
|
14
|
+
|
15
|
+
# Delete one key.
|
16
|
+
#
|
17
|
+
# @param [String] key
|
18
|
+
# @return [Boolean] whether the key was deleted or not
|
19
|
+
def del(key)
|
20
|
+
call(key, [:del, key], transform: Redis::Boolify)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set a key's time to live in seconds.
|
24
|
+
#
|
25
|
+
# @param [String] key
|
26
|
+
# @param [Fixnum] seconds time to live
|
27
|
+
# @return [Boolean] whether the timeout was set or not
|
28
|
+
def expire(key, seconds)
|
29
|
+
call(key, [:expire, key, seconds], transform: Redis::Boolify)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Set a key's time to live in milliseconds.
|
33
|
+
#
|
34
|
+
# @param [String] key
|
35
|
+
# @param [Fixnum] milliseconds time to live
|
36
|
+
# @return [Boolean] whether the timeout was set or not
|
37
|
+
def pexpire(key, milliseconds)
|
38
|
+
call(key, [:pexpire, key, milliseconds], transform: Redis::Boolify)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Determine if a key exists.
|
42
|
+
#
|
43
|
+
# @param [String] key
|
44
|
+
# @return [Boolean]
|
45
|
+
def exists(key)
|
46
|
+
call(key, [:exists, key], transform: Redis::Boolify, read: true)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get the time to live (in seconds) for a key.
|
50
|
+
#
|
51
|
+
# @param [String] key
|
52
|
+
# @return [Fixnum] remaining time to live in seconds.
|
53
|
+
#
|
54
|
+
# Starting with Redis 2.8 the return value in case of error changed:
|
55
|
+
#
|
56
|
+
# - The command returns -2 if the key does not exist.
|
57
|
+
# - The command returns -1 if the key exists but has no associated expire.
|
58
|
+
def ttl(key)
|
59
|
+
call(key, [:ttl, key], read: true)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get the time to live (in milliseconds) for a key.
|
63
|
+
#
|
64
|
+
# @param [String] key
|
65
|
+
# @return [Fixnum] remaining time to live in milliseconds
|
66
|
+
#
|
67
|
+
# Starting with Redis 2.8 the return value in case of error changed:
|
68
|
+
#
|
69
|
+
# - The command returns -2 if the key does not exist.
|
70
|
+
# - The command returns -1 if the key exists but has no associated expire.
|
71
|
+
def pttl(key)
|
72
|
+
call(key, [:pttl, key], read: true)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Determine the type stored at key.
|
76
|
+
#
|
77
|
+
# @param [String] key
|
78
|
+
# @return [String] `string`, `list`, `set`, `zset`, `hash` or `none`
|
79
|
+
def type(key)
|
80
|
+
call(key, [:type, key], read: true)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Create a key using the serialized value, previously obtained using DUMP.
|
84
|
+
#
|
85
|
+
# @param [String] key
|
86
|
+
# @param [String] ttl
|
87
|
+
# @param [String] serialized_value
|
88
|
+
# @param [Hash] options
|
89
|
+
# - `replace: true`: replace existing key
|
90
|
+
# @return [String] `"OK"`
|
91
|
+
def restore(key, ttl, serialized_value, option = {})
|
92
|
+
args = [:restore, key, ttl, serialized_value]
|
93
|
+
args << 'REPLACE' if option[:replace]
|
94
|
+
|
95
|
+
call(key, args)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return a serialized version of the value stored at a key.
|
99
|
+
#
|
100
|
+
# @param [String] key
|
101
|
+
# @return [String] serialized_value
|
102
|
+
def dump(key)
|
103
|
+
call(key, [:dump, key], read: true)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RedisCluster
|
4
|
+
module Function
|
5
|
+
|
6
|
+
# List implement redis lists commands. There will be some adjustment for cluster.
|
7
|
+
# see https://redis.io/commands#list. Most of the code are copied from
|
8
|
+
# https://github.com/redis/redis-rb/blob/master/lib/redis.rb.
|
9
|
+
#
|
10
|
+
# SETTER = [:linsert, :lpop, :lpush, :lpushx, :lrem, :lset, :ltrim, :rpop, :rpush, :rpushx]
|
11
|
+
# GETTER = [:lindex, :llen, :lrange]
|
12
|
+
module List
|
13
|
+
|
14
|
+
# Get the length of a list.
|
15
|
+
#
|
16
|
+
# @param [String] key
|
17
|
+
# @return [Fixnum]
|
18
|
+
def llen(key)
|
19
|
+
call(key, [:llen, key], read: true)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Prepend one or more values to a list, creating the list if it doesn't exist
|
23
|
+
#
|
24
|
+
# @param [String] key
|
25
|
+
# @param [String, Array] value string value, or array of string values to push
|
26
|
+
# @return [Fixnum] the length of the list after the push operation
|
27
|
+
def lpush(key, value)
|
28
|
+
call(key, [:lpush, key, value])
|
29
|
+
end
|
30
|
+
|
31
|
+
# Prepend a value to a list, only if the list exists.
|
32
|
+
#
|
33
|
+
# @param [String] key
|
34
|
+
# @param [String] value
|
35
|
+
# @return [Fixnum] the length of the list after the push operation
|
36
|
+
def lpushx(key, value)
|
37
|
+
call(key, [:lpushx, key, value])
|
38
|
+
end
|
39
|
+
|
40
|
+
# Append one or more values to a list, creating the list if it doesn't exist
|
41
|
+
#
|
42
|
+
# @param [String] key
|
43
|
+
# @param [String] value
|
44
|
+
# @return [Fixnum] the length of the list after the push operation
|
45
|
+
def rpush(key, value)
|
46
|
+
call(key, [:rpush, key, value])
|
47
|
+
end
|
48
|
+
|
49
|
+
# Append a value to a list, only if the list exists.
|
50
|
+
#
|
51
|
+
# @param [String] key
|
52
|
+
# @param [String] value
|
53
|
+
# @return [Fixnum] the length of the list after the push operation
|
54
|
+
def rpushx(key, value)
|
55
|
+
call(key, [:rpushx, key, value])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Remove and get the first element in a list.
|
59
|
+
#
|
60
|
+
# @param [String] key
|
61
|
+
# @return [String]
|
62
|
+
def lpop(key)
|
63
|
+
call(key, [:lpop, key])
|
64
|
+
end
|
65
|
+
|
66
|
+
# Remove and get the last element in a list.
|
67
|
+
#
|
68
|
+
# @param [String] key
|
69
|
+
# @return [String]
|
70
|
+
def rpop(key)
|
71
|
+
call(key, [:rpop, key])
|
72
|
+
end
|
73
|
+
|
74
|
+
# Get an element from a list by its index.
|
75
|
+
#
|
76
|
+
# @param [String] key
|
77
|
+
# @param [Fixnum] index
|
78
|
+
# @return [String]
|
79
|
+
def lindex(key, index)
|
80
|
+
call(key, [:lindex, key, index], read: true)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Insert an element before or after another element in a list.
|
84
|
+
#
|
85
|
+
# @param [String] key
|
86
|
+
# @param [String, Symbol] where `BEFORE` or `AFTER`
|
87
|
+
# @param [String] pivot reference element
|
88
|
+
# @param [String] value
|
89
|
+
# @return [Fixnum] length of the list after the insert operation, or `-1`
|
90
|
+
# when the element `pivot` was not found
|
91
|
+
def linsert(key, where, pivot, value)
|
92
|
+
call(key, [:linsert, key, where, pivot, value])
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get a range of elements from a list.
|
96
|
+
#
|
97
|
+
# @param [String] key
|
98
|
+
# @param [Fixnum] start start index
|
99
|
+
# @param [Fixnum] stop stop index
|
100
|
+
# @return [Array<String>]
|
101
|
+
def lrange(key, start, stop)
|
102
|
+
call(key, [:lrange, key, start, stop], read: true)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Remove elements from a list.
|
106
|
+
#
|
107
|
+
# @param [String] key
|
108
|
+
# @param [Fixnum] count number of elements to remove. Use a positive
|
109
|
+
# value to remove the first `count` occurrences of `value`. A negative
|
110
|
+
# value to remove the last `count` occurrences of `value`. Or zero, to
|
111
|
+
# remove all occurrences of `value` from the list.
|
112
|
+
# @param [String] value
|
113
|
+
# @return [Fixnum] the number of removed elements
|
114
|
+
def lrem(key, count, value)
|
115
|
+
call(key, [:lrem, key, count, value])
|
116
|
+
end
|
117
|
+
|
118
|
+
# Set the value of an element in a list by its index.
|
119
|
+
#
|
120
|
+
# @param [String] key
|
121
|
+
# @param [Fixnum] index
|
122
|
+
# @param [String] value
|
123
|
+
# @return [String] `OK`
|
124
|
+
def lset(key, index, value)
|
125
|
+
call(key, [:lset, key, index, value])
|
126
|
+
end
|
127
|
+
|
128
|
+
# Trim a list to the specified range.
|
129
|
+
#
|
130
|
+
# @param [String] key
|
131
|
+
# @param [Fixnum] start start index
|
132
|
+
# @param [Fixnum] stop stop index
|
133
|
+
# @return [String] `OK`
|
134
|
+
def ltrim(key, start, stop)
|
135
|
+
call(key, [:ltrim, key, start, stop])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
class RedisCluster
|
5
|
+
module Function
|
6
|
+
|
7
|
+
# Scan is a collection of redis scan functions
|
8
|
+
module Scan
|
9
|
+
HSCAN = ->(v){ [v[0], v[1].each_slice(2).to_a] }
|
10
|
+
ZSCAN = ->(v){ [v[0], Redis::FloatifyPairs.call(v[1])] }
|
11
|
+
|
12
|
+
# Scan a sorted set
|
13
|
+
#
|
14
|
+
# @example Retrieve the first batch of key/value pairs in a hash
|
15
|
+
# redis.zscan("zset", 0)
|
16
|
+
#
|
17
|
+
# @param [String, Integer] cursor the cursor of the iteration
|
18
|
+
# @param [Hash] options
|
19
|
+
# - `:match => String`: only return keys matching the pattern
|
20
|
+
# - `:count => Integer`: return count keys at most per iteration
|
21
|
+
#
|
22
|
+
# @return [String, Array<[String, Float]>] the next cursor and all found
|
23
|
+
# members and scores
|
24
|
+
def zscan(key, cursor, options = {})
|
25
|
+
args = [:zscan, key, cursor]
|
26
|
+
args.push('MATCH', options[:match]) if options[:match]
|
27
|
+
args.push('COUNT', options[:count]) if options[:count]
|
28
|
+
|
29
|
+
call(key, args, transform: ZSCAN, read: true)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Scan a hash
|
33
|
+
#
|
34
|
+
# @example Retrieve the first batch of key/value pairs in a hash
|
35
|
+
# redis.hscan("hash", 0)
|
36
|
+
#
|
37
|
+
# @param [String, Integer] cursor the cursor of the iteration
|
38
|
+
# @param [Hash] options
|
39
|
+
# - `:match => String`: only return keys matching the pattern
|
40
|
+
# - `:count => Integer`: return count keys at most per iteration
|
41
|
+
#
|
42
|
+
# @return [String, Array<[String, String]>] the next cursor and all found keys
|
43
|
+
def hscan(key, cursor, options = {})
|
44
|
+
args = [:hscan, key, cursor]
|
45
|
+
args.push('MATCH', options[:match]) if options[:match]
|
46
|
+
args.push('COUNT', options[:count]) if options[:count]
|
47
|
+
|
48
|
+
call(key, args, transform: HSCAN, read: true)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Scan a set
|
52
|
+
#
|
53
|
+
# @example Retrieve the first batch of keys in a set
|
54
|
+
# redis.sscan("set", 0)
|
55
|
+
#
|
56
|
+
# @param [String, Integer] cursor the cursor of the iteration
|
57
|
+
# @param [Hash] options
|
58
|
+
# - `:match => String`: only return keys matching the pattern
|
59
|
+
# - `:count => Integer`: return count keys at most per iteration
|
60
|
+
#
|
61
|
+
# @return [String, Array<String>] the next cursor and all found members
|
62
|
+
def sscan(key, cursor, options = {})
|
63
|
+
args = [:sscan, key, cursor]
|
64
|
+
args.push('MATCH', options[:match]) if options[:match]
|
65
|
+
args.push('COUNT', options[:count]) if options[:count]
|
66
|
+
|
67
|
+
call(key, args, read: true)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Convenient method for iterating a hash or sorted_set.
|
71
|
+
#
|
72
|
+
# @param [String] key
|
73
|
+
# @param [Hash] options
|
74
|
+
# - `:match => String`: only return keys matching the pattern
|
75
|
+
# - `:count => Integer`: return count keys at most per iteration
|
76
|
+
[:zscan, :hscan, :sscan].each do |method|
|
77
|
+
define_method "#{method}_each" do |key, options = {}, &block|
|
78
|
+
return if block.nil?
|
79
|
+
|
80
|
+
cursor = '0'
|
81
|
+
loop do
|
82
|
+
cursor, values = public_send(method, key, cursor, options)
|
83
|
+
values.each(&block)
|
84
|
+
break if cursor == '0'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|