redis_migrator 0.0.1 → 0.1.1

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