redis-cluster 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|