redis-to-collection 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +21 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +204 -0
- data/Rakefile +11 -0
- data/lib/redis-to-collection.rb +17 -0
- data/lib/redis-to-collection/constants.rb +11 -0
- data/lib/redis-to-collection/dumpling.rb +60 -0
- data/lib/redis-to-collection/loadling.rb +48 -0
- data/lib/redis-to-collection/version.rb +5 -0
- data/redis-to-collection.gemspec +26 -0
- data/test/helper.rb +47 -0
- data/test/redis-to-collection/dumpling_test.rb +159 -0
- data/test/redis-to-collection/loadling_test.rb +139 -0
- data/test/redis-to-collection/version_test.rb +11 -0
- data/test/redis-to-collection_test.rb +81 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c11c2def8542f69fec00fc297ff00a3b5d96de3e
|
4
|
+
data.tar.gz: 4762d4b82d0e48a47bab1a0e8623f9c3b09e2e10
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d79c61a6c0993e67952ad5d31c3c949edd31bbc72c2be374c2d3158edf119f053d3a8a333914da964012786ae998adcf46133eecdc34f123ae4949ad5f7532f6
|
7
|
+
data.tar.gz: 7d4fc0ce8279c254b8e02352e175fdac4e117bdedfee115a3d4eb77f1bc65344fbd38b522f61675ee81dd53926c278a27ce727b2fd8a74f45c3da2316312e37e
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.bundle/
|
4
|
+
/.config
|
5
|
+
/.yardoc/
|
6
|
+
/Gemfile.lock
|
7
|
+
/InstalledFiles
|
8
|
+
/_yardoc/
|
9
|
+
/coverage/
|
10
|
+
/doc/
|
11
|
+
/lib/bundler/man/
|
12
|
+
/pkg/
|
13
|
+
/rdoc/
|
14
|
+
/spec/reports/
|
15
|
+
/test/tmp/
|
16
|
+
/test/version_tmp/
|
17
|
+
/tmp/
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
redis-to-collection
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/.travis.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
language: ruby
|
2
|
+
before_install:
|
3
|
+
- "gem install bundler -v '~> 1.5, != 1.5.0'"
|
4
|
+
rvm:
|
5
|
+
- 2.1.2
|
6
|
+
- 2.1.1
|
7
|
+
- 2.1.0
|
8
|
+
- 2.0.0
|
9
|
+
- 1.9.3
|
10
|
+
- jruby-19mode
|
11
|
+
- rbx-2.1.1
|
12
|
+
services:
|
13
|
+
- redis-server
|
14
|
+
notifications:
|
15
|
+
email:
|
16
|
+
recipients:
|
17
|
+
- tp@tiredpixel.com
|
18
|
+
matrix:
|
19
|
+
allow_failures:
|
20
|
+
- rvm: jruby-19mode
|
21
|
+
- rvm: rbx-2.1.1
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Redis To Collection (Ruby) Changelog
|
2
|
+
|
3
|
+
This changelog documents the main changes between released versions.
|
4
|
+
For a full list of changes, consult the commit history.
|
5
|
+
|
6
|
+
|
7
|
+
## 0.1.0
|
8
|
+
|
9
|
+
- first release!
|
10
|
+
- dump all Redis keys (`RedisToCollection.dump(redis)`)
|
11
|
+
- dump some Redis keys (`RedisToCollection.dump(redis, '*PATTERN*')`)
|
12
|
+
- load to Redis (`RedisToCollection.load(redis, collection)`)
|
13
|
+
- support for Redis strings, hashes, lists, sets, sorted sets
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 tiredpixel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# Redis To Collection (Ruby)
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/redis-to-collection.png)](http://badge.fury.io/rb/redis-to-collection)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/tiredpixel/redis-to-collection-rb.png)](https://codeclimate.com/github/tiredpixel/redis-to-collection-rb)
|
5
|
+
|
6
|
+
[Redis](http://redis.io/) to a collection. There and back again.
|
7
|
+
|
8
|
+
Redis To Collection dumps Redis to and loads Redis from a collection. Only a
|
9
|
+
tiny subset of the Redis data structure is supported, and that is how it is
|
10
|
+
intended to remain. This is not supposed to be used as any form of backup
|
11
|
+
(please, please don't do this); rather, it is a very small tool to assist with
|
12
|
+
using fixtures in testing. To that end, the collection format is intentionally
|
13
|
+
verbose, and should be quite readable with a little practice.
|
14
|
+
|
15
|
+
More sleep lost by [tiredpixel](http://www.tiredpixel.com).
|
16
|
+
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Install using:
|
21
|
+
|
22
|
+
gem 'redis-to-collection'
|
23
|
+
|
24
|
+
The default Ruby version supported is defined in `.ruby-version`.
|
25
|
+
Any other versions supported are defined in `.travis.yml`.
|
26
|
+
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
Create a Redis connection and require Redis To Collection:
|
31
|
+
|
32
|
+
require 'redis'
|
33
|
+
|
34
|
+
redis = Redis.new
|
35
|
+
|
36
|
+
require 'redis-to-collection'
|
37
|
+
|
38
|
+
Dump all Redis keys to a collection:
|
39
|
+
|
40
|
+
collection = RedisToCollection.dump(redis)
|
41
|
+
|
42
|
+
Or dump a subset of Redis keys to a collection:
|
43
|
+
|
44
|
+
collection = RedisToCollection.dump(redis, '*PATTERN*')
|
45
|
+
|
46
|
+
Load a collection to Redis:
|
47
|
+
|
48
|
+
RedisToCollection.load(redis, collection)
|
49
|
+
|
50
|
+
That's it!
|
51
|
+
|
52
|
+
|
53
|
+
## Examples
|
54
|
+
|
55
|
+
Load the following example collection to Redis:
|
56
|
+
|
57
|
+
collection = {:format=>"redis-to-collection", :version=>1, :data=>[{:k=>"And crawled head downward", :t=>:s, :v=>"down a blackened wall"}, {:k=>"The river bears no", :t=>:h, :v=>{"empty"=>"bottles", "sandwich"=>"papers", "silk"=>"handkerchiefs", "cardboard"=>"boxes", "cigarette"=>"ends"}}, {:k=>"London Bridge is", :t=>:l, :v=>["falling down", "falling down", "falling down"]}, {:k=>"165", :t=>:e, :v=>["HURRY", "UP", "PLEASE", "ITS", "TIME"]}, {:k=>"And if it rains", :t=>:z, :v=>[["The hot water", 10.0], ["a closed car", 4.0]]}]}
|
58
|
+
|
59
|
+
RedisToCollection.load(redis, collection)
|
60
|
+
|
61
|
+
### JSON
|
62
|
+
|
63
|
+
Dump all Redis keys to create a JSON fixture:
|
64
|
+
|
65
|
+
require 'json'
|
66
|
+
|
67
|
+
puts JSON.pretty_generate(RedisToCollection.dump(redis))
|
68
|
+
|
69
|
+
{
|
70
|
+
"format": "redis-to-collection",
|
71
|
+
"version": 1,
|
72
|
+
"data": [
|
73
|
+
{
|
74
|
+
"k": "165",
|
75
|
+
"t": "e",
|
76
|
+
"v": [
|
77
|
+
"ITS",
|
78
|
+
"PLEASE",
|
79
|
+
"UP",
|
80
|
+
"HURRY",
|
81
|
+
"TIME"
|
82
|
+
]
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"k": "And crawled head downward",
|
86
|
+
"t": "s",
|
87
|
+
"v": "down a blackened wall"
|
88
|
+
},
|
89
|
+
{
|
90
|
+
"k": "The river bears no",
|
91
|
+
"t": "h",
|
92
|
+
"v": {
|
93
|
+
"empty": "bottles",
|
94
|
+
"sandwich": "papers",
|
95
|
+
"silk": "handkerchiefs",
|
96
|
+
"cardboard": "boxes",
|
97
|
+
"cigarette": "ends"
|
98
|
+
}
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"k": "London Bridge is",
|
102
|
+
"t": "l",
|
103
|
+
"v": [
|
104
|
+
"falling down",
|
105
|
+
"falling down",
|
106
|
+
"falling down"
|
107
|
+
]
|
108
|
+
},
|
109
|
+
{
|
110
|
+
"k": "And if it rains",
|
111
|
+
"t": "z",
|
112
|
+
"v": [
|
113
|
+
[
|
114
|
+
"a closed car",
|
115
|
+
4.0
|
116
|
+
],
|
117
|
+
[
|
118
|
+
"The hot water",
|
119
|
+
10.0
|
120
|
+
]
|
121
|
+
]
|
122
|
+
}
|
123
|
+
]
|
124
|
+
}
|
125
|
+
|
126
|
+
### YAML
|
127
|
+
|
128
|
+
Dump all Redis keys to create a YAML fixture:
|
129
|
+
|
130
|
+
require 'yaml'
|
131
|
+
|
132
|
+
puts RedisToCollection.dump(redis).to_yaml
|
133
|
+
|
134
|
+
---
|
135
|
+
:format: redis-to-collection
|
136
|
+
:version: 1
|
137
|
+
:data:
|
138
|
+
- :k: '165'
|
139
|
+
:t: :e
|
140
|
+
:v:
|
141
|
+
- ITS
|
142
|
+
- PLEASE
|
143
|
+
- UP
|
144
|
+
- HURRY
|
145
|
+
- TIME
|
146
|
+
- :k: And crawled head downward
|
147
|
+
:t: :s
|
148
|
+
:v: down a blackened wall
|
149
|
+
- :k: The river bears no
|
150
|
+
:t: :h
|
151
|
+
:v:
|
152
|
+
empty: bottles
|
153
|
+
sandwich: papers
|
154
|
+
silk: handkerchiefs
|
155
|
+
cardboard: boxes
|
156
|
+
cigarette: ends
|
157
|
+
- :k: London Bridge is
|
158
|
+
:t: :l
|
159
|
+
:v:
|
160
|
+
- falling down
|
161
|
+
- falling down
|
162
|
+
- falling down
|
163
|
+
- :k: And if it rains
|
164
|
+
:t: :z
|
165
|
+
:v:
|
166
|
+
- - a closed car
|
167
|
+
- 4.0
|
168
|
+
- - The hot water
|
169
|
+
- 10.0
|
170
|
+
|
171
|
+
|
172
|
+
## Stay Tuned
|
173
|
+
|
174
|
+
We have a [Librelist](http://librelist.com) mailing list!
|
175
|
+
To subscribe, send an email to <redis.to.collection@librelist.com>.
|
176
|
+
To unsubscribe, send an email to <redis.to.collection-unsubscribe@librelist.com>.
|
177
|
+
There be [archives](http://librelist.com/browser/redis.to.collection/).
|
178
|
+
That was easy.
|
179
|
+
|
180
|
+
You can also become a [watcher](https://github.com/tiredpixel/redis-to-collection-rb/watchers)
|
181
|
+
on GitHub. And don't forget you can become a [stargazer](https://github.com/tiredpixel/redis-to-collection-rb/stargazers) if you are so minded. :D
|
182
|
+
|
183
|
+
|
184
|
+
## Contributions
|
185
|
+
|
186
|
+
Contributions are embraced with much love and affection!
|
187
|
+
Please fork the repository and wizard your magic.
|
188
|
+
Then send me a pull request. Simples!
|
189
|
+
If you'd like to discuss what you're doing or planning to do, or if you get
|
190
|
+
stuck on something, then just wave. :)
|
191
|
+
|
192
|
+
Do whatever makes you happy. We'll probably still like you. :)
|
193
|
+
|
194
|
+
|
195
|
+
## Blessing
|
196
|
+
|
197
|
+
May you find peace, and help others to do likewise.
|
198
|
+
|
199
|
+
|
200
|
+
## Licence
|
201
|
+
|
202
|
+
© [tiredpixel](http://www.tiredpixel.com) 2014.
|
203
|
+
It is free software, released under the MIT License, and may be redistributed
|
204
|
+
under the terms specified in `LICENSE`.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'redis-to-collection/version'
|
2
|
+
require_relative 'redis-to-collection/constants'
|
3
|
+
require_relative 'redis-to-collection/dumpling'
|
4
|
+
require_relative 'redis-to-collection/loadling'
|
5
|
+
|
6
|
+
|
7
|
+
module RedisToCollection
|
8
|
+
|
9
|
+
def self.dump(redis, pattern = nil)
|
10
|
+
RedisToCollection::Dumpling.new(redis, pattern).dump
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.load(redis, container)
|
14
|
+
RedisToCollection::Loadling.new(redis).load(container)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative 'constants'
|
2
|
+
|
3
|
+
|
4
|
+
module RedisToCollection
|
5
|
+
class Dumpling
|
6
|
+
|
7
|
+
CONTAINER_FORMAT = 'redis-to-collection'.freeze
|
8
|
+
CONTAINER_VERSION = 1
|
9
|
+
|
10
|
+
def initialize(redis, pattern = nil)
|
11
|
+
@redis = redis
|
12
|
+
@pattern = pattern || '*'
|
13
|
+
end
|
14
|
+
|
15
|
+
def dump
|
16
|
+
container = {
|
17
|
+
:format => CONTAINER_FORMAT,
|
18
|
+
:version => CONTAINER_VERSION,
|
19
|
+
:data => [],
|
20
|
+
}
|
21
|
+
|
22
|
+
@redis.keys(@pattern).each do |key|
|
23
|
+
type = @redis.type(key).to_sym
|
24
|
+
|
25
|
+
datum = {
|
26
|
+
:k => key,
|
27
|
+
:t => RedisToCollection::REDIS_TYPES[type],
|
28
|
+
:v => send("dump_#{type}_value", key)
|
29
|
+
}
|
30
|
+
|
31
|
+
container[:data] << datum
|
32
|
+
end
|
33
|
+
|
34
|
+
container
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def dump_string_value(key)
|
40
|
+
@redis.get(key)
|
41
|
+
end
|
42
|
+
|
43
|
+
def dump_hash_value(key)
|
44
|
+
@redis.hgetall(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def dump_list_value(key)
|
48
|
+
@redis.lrange(key, 0, -1)
|
49
|
+
end
|
50
|
+
|
51
|
+
def dump_set_value(key)
|
52
|
+
@redis.smembers(key)
|
53
|
+
end
|
54
|
+
|
55
|
+
def dump_zset_value(key)
|
56
|
+
@redis.zrange(key, 0, -1, :withscores => true)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'constants'
|
2
|
+
|
3
|
+
|
4
|
+
module RedisToCollection
|
5
|
+
class Loadling
|
6
|
+
|
7
|
+
def initialize(redis)
|
8
|
+
@redis = redis
|
9
|
+
end
|
10
|
+
|
11
|
+
def load(container)
|
12
|
+
format = container[:format].tr('-', '_')
|
13
|
+
|
14
|
+
send("load_#{format}_#{container[:version]}", container)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def load_redis_to_collection_1(container)
|
20
|
+
container[:data].each do |datum|
|
21
|
+
type = RedisToCollection::REDIS_TYPES.key(datum[:t])
|
22
|
+
|
23
|
+
send("load_#{type}", datum[:k], datum[:v])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_string(key, value)
|
28
|
+
@redis.set(key, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_hash(key, value)
|
32
|
+
@redis.hmset(key, value.to_a.flatten)
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_list(key, value)
|
36
|
+
@redis.rpush(key, value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_set(key, value)
|
40
|
+
@redis.sadd(key, value)
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_zset(key, value)
|
44
|
+
@redis.zadd(key, value.map(&:reverse))
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require_relative 'lib/redis-to-collection/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "redis-to-collection"
|
8
|
+
spec.version = RedisToCollection::VERSION
|
9
|
+
spec.authors = ["tiredpixel"]
|
10
|
+
spec.email = ["tp@tiredpixel.com"]
|
11
|
+
spec.summary = %q{Redis to a collection. There and back again.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = "https://github.com/tiredpixel/redis-to-collection-rb"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'redis', '~> 3.0'
|
22
|
+
spec.add_development_dependency 'redis-namespace', '~> 1.4'
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'redis'
|
4
|
+
require 'redis-namespace'
|
5
|
+
|
6
|
+
|
7
|
+
module RedisToCollection
|
8
|
+
module Test
|
9
|
+
|
10
|
+
def self.config
|
11
|
+
@config ||= {
|
12
|
+
:redis => {
|
13
|
+
:url => ENV['REDIS_URL'],
|
14
|
+
:namespace => 'redis-to-collection-rb:test',
|
15
|
+
},
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
module Redis
|
20
|
+
|
21
|
+
def self.connect
|
22
|
+
redis = ::Redis::Namespace.new(self.randomize_namespace,
|
23
|
+
:redis => ::Redis.connect(
|
24
|
+
:url => RedisToCollection::Test.config[:redis][:url]
|
25
|
+
)
|
26
|
+
)
|
27
|
+
|
28
|
+
flush_namespace(redis) # very, very likely already empty
|
29
|
+
|
30
|
+
redis
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.flush_namespace(redis)
|
34
|
+
# only namespaced keys removed because Redis::Namespace
|
35
|
+
redis.keys('*').each { |k| redis.del(k) }
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def self.randomize_namespace
|
41
|
+
"#{RedisToCollection::Test.config[:redis][:namespace]}:#{SecureRandom.hex}"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require_relative '../helper'
|
4
|
+
require_relative '../../lib/redis-to-collection/dumpling'
|
5
|
+
|
6
|
+
|
7
|
+
describe RedisToCollection::Dumpling do
|
8
|
+
|
9
|
+
describe "#dump" do
|
10
|
+
before do
|
11
|
+
@redis = RedisToCollection::Test::Redis.connect
|
12
|
+
|
13
|
+
@dumpling = RedisToCollection::Dumpling.new(@redis)
|
14
|
+
|
15
|
+
@container = {
|
16
|
+
:format => RedisToCollection::Dumpling::CONTAINER_FORMAT,
|
17
|
+
:version => RedisToCollection::Dumpling::CONTAINER_VERSION,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
RedisToCollection::Test::Redis.flush_namespace(@redis)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "dumps STRING" do
|
26
|
+
@redis.set("I will show you fear", "in a handful of dust.")
|
27
|
+
|
28
|
+
@dumpling.dump.must_equal @container.merge({:data => [
|
29
|
+
{
|
30
|
+
:k => "I will show you fear",
|
31
|
+
:t => :s,
|
32
|
+
:v => "in a handful of dust.",
|
33
|
+
},
|
34
|
+
]})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "dumps HASH" do
|
38
|
+
@redis.hmset("sections",
|
39
|
+
"I.", "THE BURIAL OF THE DEAD",
|
40
|
+
"II.", "A GAME OF CHESS",
|
41
|
+
"III.", "THE FIRE SERMON",
|
42
|
+
"IV.", "DEATH BY WATER",
|
43
|
+
"V.", "WHAT THE THUNDER SAID"
|
44
|
+
)
|
45
|
+
|
46
|
+
@dumpling.dump.must_equal @container.merge({:data => [
|
47
|
+
{
|
48
|
+
:k => "sections",
|
49
|
+
:t => :h,
|
50
|
+
:v => {
|
51
|
+
"I." => "THE BURIAL OF THE DEAD",
|
52
|
+
"II." => "A GAME OF CHESS",
|
53
|
+
"III." => "THE FIRE SERMON",
|
54
|
+
"IV." => "DEATH BY WATER",
|
55
|
+
"V." => "WHAT THE THUNDER SAID",
|
56
|
+
},
|
57
|
+
},
|
58
|
+
]})
|
59
|
+
end
|
60
|
+
|
61
|
+
it "dumps LIST" do
|
62
|
+
@redis.rpush("203", ["Twit", "twit", "twit", "Jug", "jug", "jug", "jug", "jug", "jug"])
|
63
|
+
|
64
|
+
@dumpling.dump.must_equal @container.merge({:data => [
|
65
|
+
{
|
66
|
+
:k => "203",
|
67
|
+
:t => :l,
|
68
|
+
:v => ["Twit", "twit", "twit", "Jug", "jug", "jug", "jug", "jug", "jug"],
|
69
|
+
},
|
70
|
+
]})
|
71
|
+
end
|
72
|
+
|
73
|
+
it "dumps SET" do
|
74
|
+
@redis.sadd("canoe", ["Highbury", "Richmond", "Kew"])
|
75
|
+
|
76
|
+
@dumpling.dump.must_equal @container.merge({:data => [
|
77
|
+
{
|
78
|
+
:k => "canoe",
|
79
|
+
:t => :e,
|
80
|
+
:v => ["Highbury", "Richmond", "Kew"],
|
81
|
+
},
|
82
|
+
]})
|
83
|
+
end
|
84
|
+
|
85
|
+
it "dumps ZSET" do
|
86
|
+
@redis.zadd("thunder", [
|
87
|
+
[327, "Of thunder of spring over distant mountains"],
|
88
|
+
[342, "But dry sterile thunder without rain"],
|
89
|
+
[399, "Then spoke the thunder"],
|
90
|
+
])
|
91
|
+
|
92
|
+
@dumpling.dump.must_equal @container.merge({:data => [
|
93
|
+
{
|
94
|
+
:k => "thunder",
|
95
|
+
:t => :z,
|
96
|
+
:v => [
|
97
|
+
["Of thunder of spring over distant mountains", 327],
|
98
|
+
["But dry sterile thunder without rain", 342],
|
99
|
+
["Then spoke the thunder", 399],
|
100
|
+
],
|
101
|
+
},
|
102
|
+
]})
|
103
|
+
end
|
104
|
+
|
105
|
+
it "dumps multiple" do
|
106
|
+
@redis.set("Who is the third", "who walks always beside you?")
|
107
|
+
|
108
|
+
@redis.rpush("363", ["Gliding", "wrapt", "in", "a", "brown", "mantle", "hooded"])
|
109
|
+
|
110
|
+
dump1 = @dumpling.dump
|
111
|
+
|
112
|
+
dump2 = @container.merge({:data => [
|
113
|
+
{
|
114
|
+
:k => "Who is the third",
|
115
|
+
:t => :s,
|
116
|
+
:v => "who walks always beside you?",
|
117
|
+
},
|
118
|
+
{
|
119
|
+
:k => "363",
|
120
|
+
:t => :l,
|
121
|
+
:v => ["Gliding", "wrapt", "in", "a", "brown", "mantle", "hooded"],
|
122
|
+
},
|
123
|
+
]})
|
124
|
+
|
125
|
+
# ignore internal order
|
126
|
+
dump1[:data] = dump1[:data].to_set
|
127
|
+
dump2[:data] = dump2[:data].to_set
|
128
|
+
|
129
|
+
dump1.must_equal dump2
|
130
|
+
end
|
131
|
+
|
132
|
+
it "dumps with pattern" do
|
133
|
+
@dumpling = RedisToCollection::Dumpling.new(@redis, 'city*')
|
134
|
+
|
135
|
+
@redis.set("What is the city", "over the mountains")
|
136
|
+
|
137
|
+
@redis.sadd("city", ["Jerusalem", "Athens", "Alexandria", "Vienna", "London"])
|
138
|
+
|
139
|
+
dump1 = @dumpling.dump
|
140
|
+
|
141
|
+
dump2 = @container.merge({:data => [
|
142
|
+
{
|
143
|
+
:k => "city",
|
144
|
+
:t => :e,
|
145
|
+
:v => ["Jerusalem", "Athens", "Alexandria", "Vienna", "London"],
|
146
|
+
},
|
147
|
+
]})
|
148
|
+
|
149
|
+
dump1[:data].count.must_equal 1
|
150
|
+
|
151
|
+
# ignore internal order
|
152
|
+
dump1[:data].first[:v] = dump1[:data].first[:v].to_set
|
153
|
+
dump2[:data].first[:v] = dump2[:data].first[:v].to_set
|
154
|
+
|
155
|
+
dump1.must_equal dump2
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require_relative '../../lib/redis-to-collection/loadling'
|
3
|
+
|
4
|
+
|
5
|
+
describe RedisToCollection::Loadling do
|
6
|
+
|
7
|
+
describe "#load" do
|
8
|
+
before do
|
9
|
+
@redis = RedisToCollection::Test::Redis.connect
|
10
|
+
|
11
|
+
@loadling = RedisToCollection::Loadling.new(@redis)
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
RedisToCollection::Test::Redis.flush_namespace(@redis)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "redis-to-collection/1" do
|
19
|
+
before do
|
20
|
+
@container = {
|
21
|
+
:format => 'redis-to-collection',
|
22
|
+
:version => 1,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "loads STRING" do
|
27
|
+
@loadling.load(@container.merge({:data => [
|
28
|
+
{
|
29
|
+
:k => "I will show you fear",
|
30
|
+
:t => :s,
|
31
|
+
:v => "in a handful of dust.",
|
32
|
+
},
|
33
|
+
]}))
|
34
|
+
|
35
|
+
@redis.keys.count.must_equal 1
|
36
|
+
|
37
|
+
@redis.get("I will show you fear").must_equal "in a handful of dust."
|
38
|
+
end
|
39
|
+
|
40
|
+
it "loads HASH" do
|
41
|
+
@loadling.load(@container.merge({:data => [
|
42
|
+
{
|
43
|
+
:k => "sections",
|
44
|
+
:t => :h,
|
45
|
+
:v => {
|
46
|
+
"I." => "THE BURIAL OF THE DEAD",
|
47
|
+
"II." => "A GAME OF CHESS",
|
48
|
+
"III." => "THE FIRE SERMON",
|
49
|
+
"IV." => "DEATH BY WATER",
|
50
|
+
"V." => "WHAT THE THUNDER SAID",
|
51
|
+
},
|
52
|
+
},
|
53
|
+
]}))
|
54
|
+
|
55
|
+
@redis.keys.count.must_equal 1
|
56
|
+
|
57
|
+
@redis.hgetall("sections").must_equal({
|
58
|
+
"I." => "THE BURIAL OF THE DEAD",
|
59
|
+
"II." => "A GAME OF CHESS",
|
60
|
+
"III." => "THE FIRE SERMON",
|
61
|
+
"IV." => "DEATH BY WATER",
|
62
|
+
"V." => "WHAT THE THUNDER SAID",
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
it "loads LIST" do
|
67
|
+
@loadling.load(@container.merge({:data => [
|
68
|
+
{
|
69
|
+
:k => "203",
|
70
|
+
:t => :l,
|
71
|
+
:v => ["Twit", "twit", "twit", "Jug", "jug", "jug", "jug", "jug", "jug"],
|
72
|
+
},
|
73
|
+
]}))
|
74
|
+
|
75
|
+
@redis.keys.count.must_equal 1
|
76
|
+
|
77
|
+
@redis.lrange("203", 0, -1).must_equal ["Twit", "twit", "twit", "Jug", "jug", "jug", "jug", "jug", "jug"]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "loads SET" do
|
81
|
+
@loadling.load(@container.merge({:data => [
|
82
|
+
{
|
83
|
+
:k => "canoe",
|
84
|
+
:t => :e,
|
85
|
+
:v => ["Highbury", "Richmond", "Kew"],
|
86
|
+
},
|
87
|
+
]}))
|
88
|
+
|
89
|
+
@redis.keys.count.must_equal 1
|
90
|
+
|
91
|
+
@redis.smembers("canoe").must_equal ["Highbury", "Richmond", "Kew"]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "loads ZSET" do
|
95
|
+
@loadling.load(@container.merge({:data => [
|
96
|
+
{
|
97
|
+
:k => "thunder",
|
98
|
+
:t => :z,
|
99
|
+
:v => [
|
100
|
+
["Of thunder of spring over distant mountains", 327],
|
101
|
+
["But dry sterile thunder without rain", 342],
|
102
|
+
["Then spoke the thunder", 399],
|
103
|
+
],
|
104
|
+
},
|
105
|
+
]}))
|
106
|
+
|
107
|
+
@redis.keys.count.must_equal 1
|
108
|
+
|
109
|
+
@redis.zrange("thunder", 0, -1, :withscores => true).must_equal [
|
110
|
+
["Of thunder of spring over distant mountains", 327],
|
111
|
+
["But dry sterile thunder without rain", 342],
|
112
|
+
["Then spoke the thunder", 399],
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "loads multiple" do
|
117
|
+
@loadling.load(@container.merge({:data => [
|
118
|
+
{
|
119
|
+
:k => "Who is the third",
|
120
|
+
:t => :s,
|
121
|
+
:v => "who walks always beside you?",
|
122
|
+
},
|
123
|
+
{
|
124
|
+
:k => "363",
|
125
|
+
:t => :l,
|
126
|
+
:v => ["Gliding", "wrapt", "in", "a", "brown", "mantle", "hooded"],
|
127
|
+
},
|
128
|
+
]}))
|
129
|
+
|
130
|
+
@redis.keys.count.must_equal 2
|
131
|
+
|
132
|
+
@redis.get("Who is the third").must_equal "who walks always beside you?"
|
133
|
+
|
134
|
+
@redis.lrange("363", 0, -1).must_equal ["Gliding", "wrapt", "in", "a", "brown", "mantle", "hooded"]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require_relative '../lib/redis-to-collection'
|
5
|
+
|
6
|
+
|
7
|
+
describe RedisToCollection do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@redis = RedisToCollection::Test::Redis.connect
|
11
|
+
|
12
|
+
@container = {
|
13
|
+
:format => 'redis-to-collection',
|
14
|
+
:version => 1,
|
15
|
+
}
|
16
|
+
|
17
|
+
@data = [
|
18
|
+
{
|
19
|
+
:k => "And crawled head downward",
|
20
|
+
:t => :s,
|
21
|
+
:v => "down a blackened wall",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
:k => "The river bears no",
|
25
|
+
:t => :h,
|
26
|
+
:v => {
|
27
|
+
"empty" => "bottles",
|
28
|
+
"sandwich" => "papers",
|
29
|
+
"silk" => "handkerchiefs",
|
30
|
+
"cardboard" => "boxes",
|
31
|
+
"cigarette" => "ends",
|
32
|
+
},
|
33
|
+
},
|
34
|
+
{
|
35
|
+
:k => "London Bridge is",
|
36
|
+
:t => :l,
|
37
|
+
:v => ["falling down", "falling down", "falling down"],
|
38
|
+
},
|
39
|
+
{
|
40
|
+
:k => "165",
|
41
|
+
:t => :e,
|
42
|
+
:v => ["HURRY", "UP", "PLEASE", "ITS", "TIME"],
|
43
|
+
},
|
44
|
+
{
|
45
|
+
:k => "And if it rains",
|
46
|
+
:t => :z,
|
47
|
+
:v => [
|
48
|
+
["The hot water", 10.0],
|
49
|
+
["a closed car", 4.0],
|
50
|
+
],
|
51
|
+
},
|
52
|
+
]
|
53
|
+
|
54
|
+
@dump = @container.merge({:data => @data})
|
55
|
+
end
|
56
|
+
|
57
|
+
after do
|
58
|
+
RedisToCollection::Test::Redis.flush_namespace(@redis)
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "::dump" do
|
62
|
+
it "dumps dump of correct length" do
|
63
|
+
@loadling = RedisToCollection::Loadling.new(@redis)
|
64
|
+
|
65
|
+
@loadling.load(@dump)
|
66
|
+
|
67
|
+
dump2 = RedisToCollection.dump(@redis)
|
68
|
+
|
69
|
+
dump2.to_json.length.must_equal @dump.to_json.length
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "::load" do
|
74
|
+
it "loads dump of correct keys count" do
|
75
|
+
RedisToCollection.load(@redis, @dump)
|
76
|
+
|
77
|
+
@redis.keys.count.must_equal 5
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redis-to-collection
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- tiredpixel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: redis-namespace
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ''
|
70
|
+
email:
|
71
|
+
- tp@tiredpixel.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".ruby-gemset"
|
78
|
+
- ".ruby-version"
|
79
|
+
- ".travis.yml"
|
80
|
+
- CHANGELOG.md
|
81
|
+
- Gemfile
|
82
|
+
- LICENSE.txt
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- lib/redis-to-collection.rb
|
86
|
+
- lib/redis-to-collection/constants.rb
|
87
|
+
- lib/redis-to-collection/dumpling.rb
|
88
|
+
- lib/redis-to-collection/loadling.rb
|
89
|
+
- lib/redis-to-collection/version.rb
|
90
|
+
- redis-to-collection.gemspec
|
91
|
+
- test/helper.rb
|
92
|
+
- test/redis-to-collection/dumpling_test.rb
|
93
|
+
- test/redis-to-collection/loadling_test.rb
|
94
|
+
- test/redis-to-collection/version_test.rb
|
95
|
+
- test/redis-to-collection_test.rb
|
96
|
+
homepage: https://github.com/tiredpixel/redis-to-collection-rb
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.2.2
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: Redis to a collection. There and back again.
|
120
|
+
test_files:
|
121
|
+
- test/helper.rb
|
122
|
+
- test/redis-to-collection/dumpling_test.rb
|
123
|
+
- test/redis-to-collection/loadling_test.rb
|
124
|
+
- test/redis-to-collection/version_test.rb
|
125
|
+
- test/redis-to-collection_test.rb
|