nest 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.markdown +41 -13
  2. data/lib/nest.rb +28 -3
  3. data/nest.gemspec +1 -1
  4. data/test/nest_test.rb +52 -23
  5. metadata +9 -4
@@ -7,7 +7,8 @@ Description
7
7
  -----------
8
8
 
9
9
  If you are familiar with databases like
10
- [Redis](http://code.google.com/p/redis) and libraries like [Ohm](http://ohm.keyvalue.org) or
10
+ [Redis](http://code.google.com/p/redis) and
11
+ libraries like [Ohm](http://ohm.keyvalue.org) or
11
12
  [redis-namespace](http://github.com/defunkt/redis-namespace), you
12
13
  already know how important it is to craft the keys that will hold the
13
14
  data.
@@ -17,8 +18,8 @@ data.
17
18
  => "Redis Meetup"
18
19
 
19
20
  It is a design pattern in key-value databases to use the key to simulate
20
- structure, and you can read more about this in the [Twitter case
21
- study](http://code.google.com/p/redis/wiki/TwitterAlikeExample).
21
+ structure, and you can read more about this in the [case study for a
22
+ Twitter clone](http://code.google.com/p/redis/wiki/TwitterAlikeExample).
22
23
 
23
24
  Nest helps you generate those keys by providing chainable namespaces:
24
25
 
@@ -43,14 +44,14 @@ To create a new namespace:
43
44
 
44
45
  And you can use any object as a key, not only strings:
45
46
 
46
- >> ns[:foo][42]
47
- => "foo:42"
47
+ >> ns[:bar][42]
48
+ => "foo:bar:42"
48
49
 
49
50
  In a more realistic tone, lets assume you are working with Redis and
50
51
  dealing with events:
51
52
 
52
- >> event = Nest.new("event")
53
- => "event"
53
+ >> events = Nest.new("events")
54
+ => "events"
54
55
 
55
56
  >> redis = Redis.new
56
57
  => #<Redis::Client...>
@@ -58,20 +59,47 @@ dealing with events:
58
59
  >> id = redis.incr(event)
59
60
  => 1
60
61
 
61
- >> redis.set event[id][:name], "Redis Meetup"
62
+ >> redis.set events[id][:name], "Redis Meetup"
62
63
  => "OK"
63
64
 
64
- >> redis.get event[id][:name]
65
+ >> redis.get events[id][:name]
65
66
  => "Redis Meetup"
66
67
 
67
- >> meetup = event[id]
68
- => "event:1"
68
+ >> meetup = events[id]
69
+ => "events:1"
69
70
 
70
71
  >> redis.get meetup[:name]
71
72
  => "Redis Meetup"
72
73
 
74
+ Using Nest as an object oriented Redis key
75
+ ------------------------------------------
76
+
77
+ If you supply a Redis client as a second parameter, you can operate with
78
+ Redis directly:
79
+
80
+ >> redis = Redis.new
81
+ => #<Redis::Client...>
82
+
83
+ >> events = Nest.new("events", redis)
84
+ => "events"
85
+
86
+ >> events.sadd(meetup)
87
+ => true
88
+
89
+ >> events.sismember(meetup)
90
+ => true
91
+
92
+ >> events.smembers
93
+ => ["events:1"]
94
+
95
+ >> events.del
96
+ >> true
97
+
98
+ It allows you to execute all the Redis commands that expect a key as the
99
+ first parameter. Think of it as a curried Redis client.
100
+
73
101
  Differences with redis-namespace
74
- -------------------------------
102
+ --------------------------------
75
103
 
76
104
  [redis-namespace](http://github.com/defunkt/redis-namespace) wraps Redis
77
105
  and translates the keys back and forth transparently.
@@ -82,7 +110,7 @@ different scope.
82
110
  Use Nest when you want to use the keys to represent structure.
83
111
 
84
112
  Differences with Ohm
85
- -------------------
113
+ --------------------
86
114
 
87
115
  [Ohm](http://ohm.keyvalue.org) lets you map Ruby objects to Redis with
88
116
  little effort. It not only alleviates you from the pain of generating
@@ -1,9 +1,34 @@
1
- #! /usr/bin/env ruby
2
-
3
1
  class Nest < String
4
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
+
4
+ def initialize(key, redis = nil)
5
+ super(key)
6
+ @redis = redis
7
+ end
5
8
 
6
9
  def [](key)
7
10
  self.class.new("#{self}:#{key}")
8
11
  end
12
+
13
+ [:append, :blpop, :brpop, :decr, :decrby, :del, :exists, :expire,
14
+ :expireat, :get, :getset, :hdel, :hexists, :hget, :hgetall,
15
+ :hincrby, :hkeys, :hlen, :hmset, :hset, :hvals, :incr, :incrby,
16
+ :lindex, :llen, :lpop, :lpush, :lrange, :lrem, :lset, :ltrim, :move,
17
+ :rename, :renamenx, :rpop, :rpoplpush, :rpush, :sadd, :scard,
18
+ :sdiff, :sdiffstore, :set, :setex, :setnx, :sinter, :sinterstore,
19
+ :sismember, :smembers, :smove, :sort, :spop, :srandmember, :srem,
20
+ :substr, :sunion, :sunionstore, :ttl, :type, :zadd, :zcard,
21
+ :zincrby, :zinterstore, :zrange, :zrangebyscore, :zrank, :zrem,
22
+ :zremrangebyrank, :zremrangebyscore, :zrevrange, :zrevrank, :zscore,
23
+ :zunionstore].each do |meth|
24
+ define_method(meth) do |*args|
25
+ redis.send(meth, self, *args)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def redis
32
+ @redis
33
+ end
9
34
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "nest"
3
- s.version = "0.0.2"
3
+ s.version = "0.0.3"
4
4
  s.summary = "Generate nested namespaced keys for key-value databases."
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
6
  s.authors = ["Michel Martens"]
@@ -1,34 +1,63 @@
1
1
  require File.join(File.dirname(__FILE__), "test_helper")
2
2
 
3
3
  class TestNest < Test::Unit::TestCase
4
- should "return the namespace" do
5
- n1 = Nest.new("foo")
6
- assert_equal "foo", n1
7
- end
4
+ context "creating namespaces" do
5
+ should "return the namespace" do
6
+ n1 = Nest.new("foo")
7
+ assert_equal "foo", n1
8
+ end
8
9
 
9
- should "prepend the namespace" do
10
- n1 = Nest.new("foo")
11
- assert_equal "foo:bar", n1["bar"]
12
- end
10
+ should "prepend the namespace" do
11
+ n1 = Nest.new("foo")
12
+ assert_equal "foo:bar", n1["bar"]
13
+ end
13
14
 
14
- should "work in more than one level" do
15
- n1 = Nest.new("foo")
16
- n2 = Nest.new(n1["bar"])
17
- assert_equal "foo:bar:baz", n2["baz"]
18
- end
15
+ should "work in more than one level" do
16
+ n1 = Nest.new("foo")
17
+ n2 = Nest.new(n1["bar"])
18
+ assert_equal "foo:bar:baz", n2["baz"]
19
+ end
19
20
 
20
- should "be chainable" do
21
- n1 = Nest.new("foo")
22
- assert_equal "foo:bar:baz", n1["bar"]["baz"]
23
- end
21
+ should "be chainable" do
22
+ n1 = Nest.new("foo")
23
+ assert_equal "foo:bar:baz", n1["bar"]["baz"]
24
+ end
25
+
26
+ should "accept symbols" do
27
+ n1 = Nest.new(:foo)
28
+ assert_equal "foo:bar", n1[:bar]
29
+ end
24
30
 
25
- should "accept symbols" do
26
- n1 = Nest.new(:foo)
27
- assert_equal "foo:bar", n1[:bar]
31
+ should "accept numbers" do
32
+ n1 = Nest.new("foo")
33
+ assert_equal "foo:3", n1[3]
34
+ end
28
35
  end
29
36
 
30
- should "accept numbers" do
31
- n1 = Nest.new("foo")
32
- assert_equal "foo:3", n1[3]
37
+ context "operating with redis" do
38
+ require "redis"
39
+
40
+ setup do
41
+ @redis = Redis.new :db => 15
42
+ @redis.flushdb
43
+ end
44
+
45
+ should "raise if no redis instance was passed" do
46
+ n1 = Nest.new("foo")
47
+
48
+ assert_raises NoMethodError do
49
+ n1.set("s1")
50
+ end
51
+ end
52
+
53
+ should "work if a redis instance is supplied" do
54
+ n1 = Nest.new("foo", @redis)
55
+ n1.set("s")
56
+ n1.append("1")
57
+
58
+ assert_equal "s1", n1.get
59
+ assert_equal "string", n1.type
60
+ assert_equal true, n1.exists
61
+ end
33
62
  end
34
63
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nest
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 25
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 2
9
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - Michel Martens
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-06 00:00:00 -03:00
18
+ date: 2010-05-18 00:00:00 -03:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -45,23 +46,27 @@ rdoc_options: []
45
46
  require_paths:
46
47
  - lib
47
48
  required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
53
+ hash: 3
51
54
  segments:
52
55
  - 0
53
56
  version: "0"
54
57
  required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
55
59
  requirements:
56
60
  - - ">="
57
61
  - !ruby/object:Gem::Version
62
+ hash: 3
58
63
  segments:
59
64
  - 0
60
65
  version: "0"
61
66
  requirements: []
62
67
 
63
68
  rubyforge_project:
64
- rubygems_version: 1.3.6
69
+ rubygems_version: 1.3.7
65
70
  signing_key:
66
71
  specification_version: 3
67
72
  summary: Generate nested namespaced keys for key-value databases.