nest 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gems +2 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +9 -0
- data/CONTRIBUTING +19 -0
- data/LICENSE +1 -1
- data/README.md +23 -38
- data/lib/nest.rb +42 -30
- data/makefile +7 -0
- data/nest.gemspec +4 -12
- data/test/nest_test.rb +11 -11
- metadata +7 -3
- data/Rakefile +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1aceadee837f1ac2bba7fd3840c7c35ffadf777f
|
4
|
+
data.tar.gz: e82ff489cdde15c5edbe643d64c1a99e80a13d21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a07fe72c0f5f84a2460767986a3b084a6b5a47bf79cf74841d1c5c34b427c2d321f63f76f81afc36651fa372f77281c0715e5b1ddac04ef94d8befcf4fc5254
|
7
|
+
data.tar.gz: 788ffc225cc8cf912fa628e949cab221c717cc72628be46f640acfee3a904972886748bfb96bb4cffab5beff1a62b8719b06ec2c6f4695458e4db9347bb5c210
|
data/.gems
ADDED
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/pkg
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
## 3.0.0
|
2
|
+
|
3
|
+
- Use `call` for interacting with Redis
|
4
|
+
|
5
|
+
In previous versions, all the allowed Redis commands were defined
|
6
|
+
in Ruby. The downside of that approach was the fact Nest had to
|
7
|
+
be kept in sync with Redis as new commands were added to the
|
8
|
+
later. The new approach is more verbose, but the maintenance is
|
9
|
+
now close to non-existent.
|
data/CONTRIBUTING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
This code tries to solve a particular problem with a very simple
|
2
|
+
implementation. We try to keep the code to a minimum while making
|
3
|
+
it as clear as possible. The design is very likely finished, and
|
4
|
+
if some feature is missing it is possible that it was left out on
|
5
|
+
purpose. That said, new usage patterns may arise, and when that
|
6
|
+
happens we are ready to adapt if necessary.
|
7
|
+
|
8
|
+
A good first step for contributing is to meet us on IRC and discuss
|
9
|
+
ideas. We spend a lot of time on #lesscode at freenode, always ready
|
10
|
+
to talk about code and simplicity. If connecting to IRC is not an
|
11
|
+
option, you can create an issue explaining the proposed change and
|
12
|
+
a use case. We pay a lot of attention to use cases, because our
|
13
|
+
goal is to keep the code base simple. Usually the result of a
|
14
|
+
conversation is the creation of a different tool.
|
15
|
+
|
16
|
+
Please don't start the conversation with a pull request. The code
|
17
|
+
should come at last, and even though it may help to convey an idea,
|
18
|
+
more often than not it draws the attention to a particular
|
19
|
+
implementation.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -12,9 +12,9 @@ important it is to craft the keys that will hold the data.
|
|
12
12
|
|
13
13
|
```ruby
|
14
14
|
>> redis = Redic.new
|
15
|
-
>> redis.call("
|
16
|
-
>> redis.call("
|
17
|
-
=> ["
|
15
|
+
>> redis.call("HSET", "Event:3", "name", "Redis Meetup")
|
16
|
+
>> redis.call("HGET", "Event:3", "name")
|
17
|
+
=> ["Redis Meetup"]
|
18
18
|
```
|
19
19
|
|
20
20
|
It is a design pattern in key-value databases to use the key to simulate
|
@@ -25,10 +25,10 @@ Nest helps you generate those keys by providing chainable namespaces that are
|
|
25
25
|
already connected to Redis:
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
>> event = Nest.new("
|
29
|
-
>> event[3]
|
30
|
-
>> event[3]
|
31
|
-
=> ["
|
28
|
+
>> event = Nest.new("Event")
|
29
|
+
>> event[3].call("HSET", "name", "Redis Meetup")
|
30
|
+
>> event[3].call("HGET", "name")
|
31
|
+
=> ["Redis Meetup"]
|
32
32
|
```
|
33
33
|
|
34
34
|
Usage
|
@@ -58,20 +58,20 @@ In a more realistic tone, lets assume you are working with Redis and
|
|
58
58
|
dealing with events:
|
59
59
|
|
60
60
|
```ruby
|
61
|
-
>>
|
62
|
-
=> "
|
61
|
+
>> event = Nest.new("Event")
|
62
|
+
=> "Event"
|
63
63
|
|
64
|
-
>> id =
|
64
|
+
>> id = event[:id].call("INCR")
|
65
65
|
=> 1
|
66
66
|
|
67
|
-
>>
|
68
|
-
=>
|
67
|
+
>> event[id].call("HSET", "name", "Redis Meetup")
|
68
|
+
=> 1
|
69
69
|
|
70
|
-
>> meetup =
|
71
|
-
=> "
|
70
|
+
>> meetup = event[id]
|
71
|
+
=> "Event:1"
|
72
72
|
|
73
|
-
>> meetup
|
74
|
-
=> ["
|
73
|
+
>> meetup.call("HGET", "name")
|
74
|
+
=> ["Redis Meetup"]
|
75
75
|
```
|
76
76
|
|
77
77
|
Supplying your existing Redis instance
|
@@ -84,14 +84,11 @@ a second parameter. If you don't, a default instance is created for you:
|
|
84
84
|
>> redis = Redic.new("redis://localhost:6379")
|
85
85
|
=> #<Redic:0x007fa640845f10 ...>
|
86
86
|
|
87
|
-
>>
|
88
|
-
=> "
|
89
|
-
|
90
|
-
>> id = users[:id].incr
|
91
|
-
=> 1
|
87
|
+
>> event = Nest.new("Event", redis)
|
88
|
+
=> "Event"
|
92
89
|
|
93
|
-
>>
|
94
|
-
=> "
|
90
|
+
>> event[:id].call("TYPE")
|
91
|
+
=> "string"
|
95
92
|
```
|
96
93
|
|
97
94
|
`Nest` objects respond to `redis` and return a `Redic` instance. It is
|
@@ -99,24 +96,12 @@ automatically reused when you create a new namespace, and you can reuse it when
|
|
99
96
|
creating a new instance of Nest:
|
100
97
|
|
101
98
|
```ruby
|
102
|
-
>>
|
103
|
-
=> "
|
104
|
-
|
105
|
-
>> events.sadd(meetup)
|
106
|
-
=> true
|
107
|
-
|
108
|
-
>> events.sismember(meetup)
|
109
|
-
=> true
|
110
|
-
|
111
|
-
>> events.smembers
|
112
|
-
=> ["events:1"]
|
113
|
-
|
114
|
-
>> events.del
|
115
|
-
>> true
|
99
|
+
>> event = Nest.new("Event", meetup.redis)
|
100
|
+
=> "Event"
|
116
101
|
```
|
117
102
|
|
118
103
|
Nest allows you to execute all the Redis commands that expect a key as the
|
119
|
-
first parameter.
|
104
|
+
first parameter. If you use any other command, the result can be unexpected.
|
120
105
|
|
121
106
|
Differences with redis-namespace
|
122
107
|
--------------------------------
|
data/lib/nest.rb
CHANGED
@@ -1,40 +1,52 @@
|
|
1
|
+
# Copyright (c) 2010 Michel Martens
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
#
|
1
21
|
require "redic"
|
2
22
|
|
3
|
-
class Nest
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
:hexists, :hget, :hgetall, :hincrby, :hincrbyfloat, :hkeys, :hlen,
|
9
|
-
:hmget, :hmset, :hset, :hsetnx, :hstrlen, :hvals, :incr, :incrby,
|
10
|
-
:incrbyfloat, :lindex, :linsert, :llen, :lpop, :lpush, :lpushx,
|
11
|
-
:lrange, :lrem, :lset, :ltrim, :move, :persist, :pexpire, :pexpireat,
|
12
|
-
:pfadd, :pfcount, :pfmerge, :psetex, :pttl, :publish, :rename,
|
13
|
-
:renamenx, :restore, :rpop, :rpoplpush, :rpush, :rpushx, :sadd,
|
14
|
-
:scard, :sdiff, :sdiffstore, :set, :setbit, :setex, :setnx,
|
15
|
-
:setrange, :sinter, :sinterstore, :sismember, :smembers, :smove,
|
16
|
-
:sort, :spop, :srandmember, :srem, :strlen, :subscribe, :sunion,
|
17
|
-
:sunionstore, :touch, :ttl, :type, :unsubscribe, :watch, :zadd,
|
18
|
-
:zcard, :zcount, :zincrby, :zinterstore, :zlexcount, :zrange,
|
19
|
-
:zrangebylex, :zrevrangebylex, :zrangebyscore, :zrank, :zrem,
|
20
|
-
:zremrangebylex, :zremrangebyrank, :zremrangebyscore, :zrevrange,
|
21
|
-
:zrevrangebyscore, :zrevrank, :zscore, :zunionstore, :sscan,
|
22
|
-
:hscan, :zscan]
|
23
|
+
class Nest
|
24
|
+
def initialize(ns, rc = Redic.new)
|
25
|
+
@ns = ns.to_s
|
26
|
+
@rc = rc
|
27
|
+
end
|
23
28
|
|
24
|
-
|
29
|
+
def [](key)
|
30
|
+
Nest.new("#{@ns}:#{key}", @rc)
|
31
|
+
end
|
25
32
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
33
|
+
def redis
|
34
|
+
@rc
|
35
|
+
end
|
36
|
+
|
37
|
+
def hash
|
38
|
+
@ns.hash
|
29
39
|
end
|
30
40
|
|
31
|
-
def
|
32
|
-
|
41
|
+
def to_s
|
42
|
+
@ns
|
43
|
+
end
|
44
|
+
|
45
|
+
def call(command, *args)
|
46
|
+
@rc.call(command, to_s, *args)
|
33
47
|
end
|
34
48
|
|
35
|
-
|
36
|
-
|
37
|
-
redis.call(meth, self, *args)
|
38
|
-
end
|
49
|
+
def inspect
|
50
|
+
@ns.inspect
|
39
51
|
end
|
40
52
|
end
|
data/makefile
ADDED
data/nest.gemspec
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "nest"
|
3
|
-
s.version = "
|
3
|
+
s.version = "3.0.0"
|
4
4
|
s.summary = "Object-oriented keys for Redis."
|
5
5
|
s.description = "It is a design pattern in key-value databases to use the key to simulate structure, and Nest can take care of that."
|
6
|
-
s.
|
6
|
+
s.license = "MIT"
|
7
7
|
s.authors = ["Michel Martens"]
|
8
8
|
s.email = ["michel@soveran.com"]
|
9
9
|
s.homepage = "http://github.com/soveran/nest"
|
10
10
|
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
|
11
13
|
s.add_dependency "redic"
|
12
|
-
|
13
|
-
s.files = Dir[
|
14
|
-
"LICENSE",
|
15
|
-
"README.md",
|
16
|
-
"Rakefile",
|
17
|
-
"lib/**/*.rb",
|
18
|
-
"*.gemspec",
|
19
|
-
"test/*.*"
|
20
|
-
]
|
21
|
-
|
22
14
|
s.add_development_dependency "cutest"
|
23
15
|
end
|
data/test/nest_test.rb
CHANGED
@@ -3,34 +3,34 @@ require_relative "helper"
|
|
3
3
|
# Creating namespaces.
|
4
4
|
scope do
|
5
5
|
test "return the namespace" do
|
6
|
-
n1 = Nest.new("foo")
|
7
|
-
assert "foo" == n1
|
6
|
+
n1 = Nest.new("foo", Redic.new)
|
7
|
+
assert "foo" == n1.to_s
|
8
8
|
end
|
9
9
|
|
10
10
|
test "prepend the namespace" do
|
11
11
|
n1 = Nest.new("foo")
|
12
|
-
assert "foo:bar" == n1["bar"]
|
12
|
+
assert "foo:bar" == n1["bar"].to_s
|
13
13
|
end
|
14
14
|
|
15
15
|
test "work in more than one level" do
|
16
16
|
n1 = Nest.new("foo")
|
17
17
|
n2 = Nest.new(n1["bar"])
|
18
|
-
assert "foo:bar:baz" == n2["baz"]
|
18
|
+
assert "foo:bar:baz" == n2["baz"].to_s
|
19
19
|
end
|
20
20
|
|
21
21
|
test "be chainable" do
|
22
22
|
n1 = Nest.new("foo")
|
23
|
-
assert "foo:bar:baz" == n1["bar"]["baz"]
|
23
|
+
assert "foo:bar:baz" == n1["bar"]["baz"].to_s
|
24
24
|
end
|
25
25
|
|
26
26
|
test "accept symbols" do
|
27
27
|
n1 = Nest.new(:foo)
|
28
|
-
assert "foo:bar" == n1[:bar]
|
28
|
+
assert "foo:bar" == n1[:bar].to_s
|
29
29
|
end
|
30
30
|
|
31
31
|
test "accept numbers" do
|
32
32
|
n1 = Nest.new("foo")
|
33
|
-
assert "foo:3" == n1[3]
|
33
|
+
assert "foo:3" == n1[3].to_s
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,16 +43,16 @@ scope do
|
|
43
43
|
|
44
44
|
test "work if no redis instance was passed" do
|
45
45
|
n1 = Nest.new("foo")
|
46
|
-
n1.
|
46
|
+
n1.call("SET", "s1")
|
47
47
|
|
48
|
-
assert "s1" == n1.
|
48
|
+
assert "s1" == n1.call("GET")
|
49
49
|
end
|
50
50
|
|
51
51
|
test "work if a redis instance is supplied" do
|
52
52
|
n1 = Nest.new("foo", @redis)
|
53
|
-
n1.
|
53
|
+
n1.call("SET", "s1")
|
54
54
|
|
55
|
-
assert "s1" == n1.
|
55
|
+
assert "s1" == n1.call("GET")
|
56
56
|
end
|
57
57
|
|
58
58
|
test "pass the redis instance to new keys" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redic
|
@@ -46,10 +46,14 @@ executables: []
|
|
46
46
|
extensions: []
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
|
+
- ".gems"
|
50
|
+
- ".gitignore"
|
51
|
+
- CHANGELOG.md
|
52
|
+
- CONTRIBUTING
|
49
53
|
- LICENSE
|
50
54
|
- README.md
|
51
|
-
- Rakefile
|
52
55
|
- lib/nest.rb
|
56
|
+
- makefile
|
53
57
|
- nest.gemspec
|
54
58
|
- test/helper.rb
|
55
59
|
- test/nest_test.rb
|
data/Rakefile
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
task :test do
|
2
|
-
require "cutest"
|
3
|
-
Cutest.run(Dir["test/nest*"])
|
4
|
-
end
|
5
|
-
|
6
|
-
task :default => :test
|
7
|
-
|
8
|
-
task :commands do
|
9
|
-
require "open-uri"
|
10
|
-
require "json"
|
11
|
-
|
12
|
-
file = File.expand_path("lib/nest.rb", File.dirname(__FILE__))
|
13
|
-
path = "https://github.com/antirez/redis-doc/raw/master/commands.json"
|
14
|
-
|
15
|
-
commands = JSON.parse(open(path).read).select do |name, command|
|
16
|
-
# Skip all DEBUG commands
|
17
|
-
next if command["group"] == "server"
|
18
|
-
|
19
|
-
# If the command has no arguments, it doesn't operate on a key
|
20
|
-
next if command["arguments"].nil?
|
21
|
-
|
22
|
-
arg = command["arguments"].first
|
23
|
-
|
24
|
-
arg["type"] == "key" ||
|
25
|
-
Array(arg["name"]) == ["channel"]
|
26
|
-
end
|
27
|
-
|
28
|
-
commands = commands.keys.map { |key| key.downcase.to_sym }
|
29
|
-
|
30
|
-
commands.delete(:mget)
|
31
|
-
|
32
|
-
source = File.read(file).sub(/ METHODS = .+?\n\n/m) do
|
33
|
-
" METHODS = #{commands.inspect}\n\n"
|
34
|
-
end
|
35
|
-
|
36
|
-
File.open(file, "w") { |f| f.write source }
|
37
|
-
|
38
|
-
system "git diff --color-words #{file}"
|
39
|
-
end
|