redis_migrator 0.0.1 → 0.1.1

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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +3 -0
  4. data/README.md +13 -1
  5. data/Rakefile +6 -0
  6. data/lib/redis_migrator/redis_helper.rb +5 -36
  7. data/lib/redis_migrator/redis_native_migrator.rb +27 -0
  8. data/lib/redis_migrator/redis_pipe_migrator.rb +66 -0
  9. data/lib/redis_migrator/redis_populator.rb +1 -1
  10. data/lib/redis_migrator.rb +19 -20
  11. data/migrator_benchmark.rb +1 -2
  12. data/redis_migrator.gemspec +8 -4
  13. data/spec/different_redis_type_migrator.rb +67 -0
  14. data/spec/pretested_migrator.rb +47 -0
  15. data/spec/redis_migrator_spec.rb +41 -0
  16. data/spec/redis_native_migrator_spec.rb +44 -0
  17. data/spec/redis_pipe_migrator_spec.rb +51 -0
  18. data/spec/shared_hosts_context.rb +10 -0
  19. data/spec/spec_helper.rb +9 -7
  20. metadata +85 -49
  21. data/spec/migrator_spec.rb +0 -63
  22. data/spec/mock_redis/lib/mock_redis/assertions.rb +0 -13
  23. data/spec/mock_redis/lib/mock_redis/database.rb +0 -432
  24. data/spec/mock_redis/lib/mock_redis/distributed.rb +0 -6
  25. data/spec/mock_redis/lib/mock_redis/exceptions.rb +0 -3
  26. data/spec/mock_redis/lib/mock_redis/expire_wrapper.rb +0 -25
  27. data/spec/mock_redis/lib/mock_redis/hash_methods.rb +0 -118
  28. data/spec/mock_redis/lib/mock_redis/list_methods.rb +0 -187
  29. data/spec/mock_redis/lib/mock_redis/multi_db_wrapper.rb +0 -86
  30. data/spec/mock_redis/lib/mock_redis/set_methods.rb +0 -126
  31. data/spec/mock_redis/lib/mock_redis/string_methods.rb +0 -203
  32. data/spec/mock_redis/lib/mock_redis/transaction_wrapper.rb +0 -80
  33. data/spec/mock_redis/lib/mock_redis/undef_redis_methods.rb +0 -11
  34. data/spec/mock_redis/lib/mock_redis/utility_methods.rb +0 -25
  35. data/spec/mock_redis/lib/mock_redis/version.rb +0 -3
  36. data/spec/mock_redis/lib/mock_redis/zset.rb +0 -110
  37. data/spec/mock_redis/lib/mock_redis/zset_methods.rb +0 -210
  38. data/spec/mock_redis/lib/mock_redis.rb +0 -119
  39. data/spec/redis_helper_spec.rb +0 -58
@@ -1,3 +0,0 @@
1
- class MockRedis
2
- WouldBlock = Class.new(StandardError)
3
- end
@@ -1,25 +0,0 @@
1
- require 'mock_redis/undef_redis_methods'
2
-
3
- class MockRedis
4
- class ExpireWrapper
5
- include UndefRedisMethods
6
-
7
- def respond_to?(method, include_private=false)
8
- super || @db.respond_to?(method)
9
- end
10
-
11
- def initialize(db)
12
- @db = db
13
- end
14
-
15
- def method_missing(method, *args)
16
- @db.expire_keys
17
- @db.send(method, *args)
18
- end
19
-
20
- def initialize_copy(source)
21
- super
22
- @db = @db.clone
23
- end
24
- end
25
- end
@@ -1,118 +0,0 @@
1
- require 'mock_redis/assertions'
2
- require 'mock_redis/utility_methods'
3
-
4
- class MockRedis
5
- module HashMethods
6
- include Assertions
7
- include UtilityMethods
8
-
9
- def hdel(key, field)
10
- with_hash_at(key) do |hash|
11
- hash.delete(field.to_s) ? 1 : 0
12
- end
13
- end
14
-
15
- def hexists(key, field)
16
- with_hash_at(key) {|h| h.has_key?(field.to_s)}
17
- end
18
-
19
- def hget(key, field)
20
- with_hash_at(key) {|h| h[field.to_s]}
21
- end
22
-
23
- def hgetall(key)
24
- with_hash_at(key) {|h| h}
25
- end
26
-
27
- def hincrby(key, field, increment)
28
- with_hash_at(key) do |hash|
29
- field = field.to_s
30
- unless can_incr?(data[key][field])
31
- raise RuntimeError, "ERR hash value is not an integer"
32
- end
33
- unless looks_like_integer?(increment.to_s)
34
- raise RuntimeError, "ERR value is not an integer or out of range"
35
- end
36
-
37
- new_value = (hash[field] || "0").to_i + increment.to_i
38
- hash[field] = new_value.to_s
39
- new_value
40
- end
41
- end
42
-
43
- def hkeys(key)
44
- with_hash_at(key, &:keys)
45
- end
46
-
47
- def hlen(key)
48
- hkeys(key).length
49
- end
50
-
51
- def hmget(key, *fields)
52
- assert_has_args(fields, 'hmget')
53
- fields.map{|f| hget(key, f)}
54
- end
55
-
56
- def mapped_hmget(key, *fields)
57
- reply = hmget(key, *fields)
58
- Hash[*fields.zip(reply).flatten]
59
- end
60
-
61
- def hmset(key, *kvpairs)
62
- assert_has_args(kvpairs, 'hmset')
63
- if kvpairs.length.odd?
64
- raise RuntimeError, "ERR wrong number of arguments for HMSET"
65
- end
66
-
67
- kvpairs.each_slice(2) do |(k,v)|
68
- hset(key, k, v)
69
- end
70
- 'OK'
71
- end
72
-
73
- def mapped_hmset(key, hash)
74
- kvpairs = hash.to_a.flatten
75
- assert_has_args(kvpairs, 'hmset')
76
- if kvpairs.length.odd?
77
- raise RuntimeError, "ERR wrong number of arguments for 'hmset' command"
78
- end
79
-
80
- hmset(key, *kvpairs)
81
- end
82
-
83
- def hset(key, field, value)
84
- with_hash_at(key) {|h| h[field.to_s] = value.to_s}
85
- true
86
- end
87
-
88
- def hsetnx(key, field, value)
89
- if hget(key, field)
90
- false
91
- else
92
- hset(key, field, value)
93
- true
94
- end
95
- end
96
-
97
- def hvals(key)
98
- with_hash_at(key, &:values)
99
- end
100
-
101
- private
102
-
103
- def with_hash_at(key, &blk)
104
- with_thing_at(key, :assert_hashy, proc {{}}, &blk)
105
- end
106
-
107
- def hashy?(key)
108
- data[key].nil? || data[key].kind_of?(Hash)
109
- end
110
-
111
- def assert_hashy(key)
112
- unless hashy?(key)
113
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
114
- end
115
- end
116
-
117
- end
118
- end
@@ -1,187 +0,0 @@
1
- require 'mock_redis/assertions'
2
- require 'mock_redis/utility_methods'
3
-
4
- class MockRedis
5
- module ListMethods
6
- include Assertions
7
- include UtilityMethods
8
-
9
- def blpop(*args)
10
- lists, timeout = extract_timeout(args)
11
- nonempty_list = first_nonempty_list(lists)
12
-
13
- if nonempty_list
14
- [nonempty_list, lpop(nonempty_list)]
15
- elsif timeout > 0
16
- nil
17
- else
18
- raise MockRedis::WouldBlock, "Can't block forever"
19
- end
20
- end
21
-
22
- def brpop(*args)
23
- lists, timeout = extract_timeout(args)
24
- nonempty_list = first_nonempty_list(lists)
25
-
26
- if nonempty_list
27
- [nonempty_list, rpop(nonempty_list)]
28
- elsif timeout > 0
29
- nil
30
- else
31
- raise MockRedis::WouldBlock, "Can't block forever"
32
- end
33
- end
34
-
35
- def brpoplpush(source, destination, timeout)
36
- assert_valid_timeout(timeout)
37
-
38
- if llen(source) > 0
39
- rpoplpush(source, destination)
40
- elsif timeout > 0
41
- nil
42
- else
43
- raise MockRedis::WouldBlock, "Can't block forever"
44
- end
45
- end
46
-
47
- def lindex(key, index)
48
- with_list_at(key) {|l| l[index]}
49
- end
50
-
51
- def linsert(key, position, pivot, value)
52
- unless %w[before after].include?(position.to_s)
53
- raise RuntimeError, "ERR syntax error"
54
- end
55
-
56
- assert_listy(key)
57
- return 0 unless data[key]
58
-
59
- pivot_position = (0..llen(key) - 1).find do |i|
60
- data[key][i] == pivot.to_s
61
- end
62
-
63
- return -1 unless pivot_position
64
-
65
- insertion_index = if position.to_s == 'before'
66
- pivot_position
67
- else
68
- pivot_position + 1
69
- end
70
-
71
- data[key].insert(insertion_index, value.to_s)
72
- llen(key)
73
- end
74
-
75
- def llen(key)
76
- with_list_at(key, &:length)
77
- end
78
-
79
- def lpop(key)
80
- with_list_at(key, &:shift)
81
- end
82
-
83
- def lpush(key, value)
84
- with_list_at(key) {|l| l.unshift(value.to_s)}
85
- llen(key)
86
- end
87
-
88
- def lpushx(key, value)
89
- assert_listy(key)
90
- return 0 unless list_at?(key)
91
- lpush(key, value)
92
- end
93
-
94
- def lrange(key, start, stop)
95
- with_list_at(key) {|l| l[start..stop]}
96
- end
97
-
98
- def lrem(key, count, value)
99
- count = count.to_i
100
- value = value.to_s
101
-
102
- with_list_at(key) do |list|
103
- indices_with_value = (0..(llen(key) - 1)).find_all do |i|
104
- list[i] == value
105
- end
106
-
107
- indices_to_delete = if count == 0
108
- indices_with_value.reverse
109
- elsif count > 0
110
- indices_with_value.take(count).reverse
111
- else
112
- indices_with_value.reverse.take(-count)
113
- end
114
-
115
- indices_to_delete.each {|i| list.delete_at(i)}.length
116
- end
117
- end
118
-
119
- def lset(key, index, value)
120
- assert_listy(key)
121
-
122
- unless list_at?(key)
123
- raise RuntimeError, "ERR no such key"
124
- end
125
-
126
- unless (0...llen(key)).include?(index)
127
- raise RuntimeError, "ERR index out of range"
128
- end
129
-
130
- data[key][index] = value.to_s
131
- 'OK'
132
- end
133
-
134
- def ltrim(key, start, stop)
135
- with_list_at(key) do |list|
136
- list.replace(list[start..stop] || []) if list
137
- 'OK'
138
- end
139
- end
140
-
141
- def rpop(key)
142
- with_list_at(key) {|list| list.pop if list}
143
- end
144
-
145
- def rpoplpush(source, destination)
146
- value = rpop(source)
147
- lpush(destination, value)
148
- value
149
- end
150
-
151
- def rpush(key, value)
152
- with_list_at(key) {|l| l.push(value.to_s)}
153
- llen(key)
154
- end
155
-
156
- def rpushx(key, value)
157
- assert_listy(key)
158
- return 0 unless list_at?(key)
159
- rpush(key, value)
160
- end
161
-
162
- private
163
- def list_at?(key)
164
- data[key] && listy?(key)
165
- end
166
-
167
- def with_list_at(key, &blk)
168
- with_thing_at(key, :assert_listy, proc {[]}, &blk)
169
- end
170
-
171
- def listy?(key)
172
- data[key].nil? || data[key].kind_of?(Array)
173
- end
174
-
175
- def assert_listy(key)
176
- unless listy?(key)
177
- # Not the most helpful error, but it's what redis-rb barfs up
178
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
179
- end
180
- end
181
-
182
- def first_nonempty_list(keys)
183
- keys.find{|k| llen(k) > 0}
184
- end
185
-
186
- end
187
- end
@@ -1,86 +0,0 @@
1
- require 'mock_redis/undef_redis_methods'
2
-
3
- class MockRedis
4
- class MultiDbWrapper
5
- include UndefRedisMethods
6
-
7
- def initialize(db)
8
- @db_index = 0
9
-
10
- @prototype_db = db.clone
11
-
12
- @databases = Hash.new {|h,k| h[k] = @prototype_db.clone}
13
- @databases[@db_index] = db
14
- end
15
-
16
- def respond_to?(method, include_private=false)
17
- super || current_db.respond_to?(method, include_private)
18
- end
19
-
20
- def method_missing(method, *args)
21
- current_db.send(method, *args)
22
- end
23
-
24
- def initialize_copy(source)
25
- super
26
- @databases = @databases.clone
27
- @databases.keys.each do |k|
28
- @databases[k] = @databases[k].clone
29
- end
30
- end
31
-
32
- # Redis commands
33
- def flushall
34
- @databases.values.each(&:flushdb)
35
- 'OK'
36
- end
37
-
38
- def move(key, db_index)
39
- src = current_db
40
- dest = db(db_index)
41
-
42
- if !src.exists(key) || dest.exists(key)
43
- false
44
- else
45
- case current_db.type(key)
46
- when 'hash'
47
- dest.hmset(key, *(src.hgetall(key).map{|k,v| [k,v]}.flatten))
48
- when 'list'
49
- while value = src.rpop(key)
50
- dest.lpush(key, value)
51
- end
52
- when 'set'
53
- while value = src.spop(key)
54
- dest.sadd(key, value)
55
- end
56
- when 'string'
57
- dest.set(key, src.get(key))
58
- when 'zset'
59
- src.zrange(key, 0, -1, :with_scores => true).each_slice(2) do |(m,s)|
60
- dest.zadd(key, s, m)
61
- end
62
- else
63
- raise ArgumentError,
64
- "Can't move a key of type #{current_db.type(key).inspect}"
65
- end
66
-
67
- src.del(key)
68
- true
69
- end
70
- end
71
-
72
- def select(db_index)
73
- @db_index = db_index.to_i
74
- 'OK'
75
- end
76
-
77
- private
78
- def current_db
79
- @databases[@db_index]
80
- end
81
-
82
- def db(index)
83
- @databases[index]
84
- end
85
- end
86
- end
@@ -1,126 +0,0 @@
1
- require 'mock_redis/assertions'
2
- require 'mock_redis/utility_methods'
3
-
4
- class MockRedis
5
- module SetMethods
6
- include Assertions
7
- include UtilityMethods
8
-
9
- def sadd(key, member)
10
- with_set_at(key) {|s| !!s.add?(member.to_s)}
11
- end
12
-
13
- def scard(key)
14
- with_set_at(key) {|s| s.length}
15
- end
16
-
17
- def sdiff(*keys)
18
- assert_has_args(keys, 'sdiff')
19
- with_sets_at(*keys) {|*sets| sets.reduce(&:-)}.to_a
20
- end
21
-
22
- def sdiffstore(destination, *keys)
23
- assert_has_args(keys, 'sdiffstore')
24
- with_set_at(destination) do |set|
25
- set.replace(sdiff(*keys))
26
- end
27
- scard(destination)
28
- end
29
-
30
- def sinter(*keys)
31
- assert_has_args(keys, 'sinter')
32
-
33
- with_sets_at(*keys) do |*sets|
34
- sets.reduce(&:&).to_a
35
- end
36
- end
37
-
38
- def sinterstore(destination, *keys)
39
- assert_has_args(keys, 'sinterstore')
40
- with_set_at(destination) do |set|
41
- set.replace(sinter(*keys))
42
- end
43
- scard(destination)
44
- end
45
-
46
- def sismember(key, member)
47
- with_set_at(key) {|s| s.include?(member.to_s)}
48
- end
49
-
50
- def smembers(key)
51
- with_set_at(key, &:to_a)
52
- end
53
-
54
- def smove(src, dest, member)
55
- member = member.to_s
56
-
57
- with_sets_at(src, dest) do |src_set, dest_set|
58
- if src_set.delete?(member)
59
- dest_set.add(member)
60
- true
61
- else
62
- false
63
- end
64
- end
65
- end
66
-
67
- def spop(key)
68
- with_set_at(key) do |set|
69
- member = set.first
70
- set.delete(member)
71
- member
72
- end
73
- end
74
-
75
- def srandmember(key)
76
- members = with_set_at(key, &:to_a)
77
- members[rand(members.length)]
78
- end
79
-
80
- def srem(key, member)
81
- with_set_at(key) {|s| !!s.delete?(member.to_s)}
82
- end
83
-
84
- def sunion(*keys)
85
- assert_has_args(keys, 'sunion')
86
- with_sets_at(*keys) {|*sets| sets.reduce(&:+).to_a}
87
- end
88
-
89
- def sunionstore(destination, *keys)
90
- assert_has_args(keys, 'sunionstore')
91
- with_set_at(destination) do |dest_set|
92
- dest_set.replace(sunion(*keys))
93
- end
94
- scard(destination)
95
- end
96
-
97
- private
98
- def with_set_at(key, &blk)
99
- with_thing_at(key, :assert_sety, proc {Set.new}, &blk)
100
- end
101
-
102
- def with_sets_at(*keys, &blk)
103
- if keys.length == 1
104
- with_set_at(keys.first, &blk)
105
- else
106
- with_set_at(keys.first) do |set|
107
- with_sets_at(*(keys[1..-1])) do |*sets|
108
- blk.call(*([set] + sets))
109
- end
110
- end
111
- end
112
- end
113
-
114
- def sety?(key)
115
- data[key].nil? || data[key].kind_of?(Set)
116
- end
117
-
118
- def assert_sety(key)
119
- unless sety?(key)
120
- # Not the most helpful error, but it's what redis-rb barfs up
121
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
122
- end
123
- end
124
-
125
- end
126
- end