Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit.

  • Loading branch information...
commit fbc4d1b3b92eb720d4494971cfc4b84ad1d3996c 0 parents
Michel Martens authored
1  .gitignore
... ...
@@ -0,0 +1 @@
  1
+/pkg
19  LICENSE
... ...
@@ -0,0 +1,19 @@
  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.
125  README.markdown
Source Rendered
... ...
@@ -0,0 +1,125 @@
  1
+Nest
  2
+====
  3
+
  4
+Generate nested namespaced keys for key-value databases.
  5
+
  6
+Description
  7
+-----------
  8
+
  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
  11
+[redis-namespace](http://github.com/defunkt/redis-namespace), you
  12
+already know how important it is to craft the keys that will hold the
  13
+data.
  14
+
  15
+    >> @redis.set "event:3:name", "Redis Meetup"
  16
+    >> @redis.get "event:3:name"
  17
+    => "Redis Meetup"
  18
+
  19
+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).
  22
+
  23
+Nest helps you generate those keys by providing chainable namespaces:
  24
+
  25
+    >> event = Nest.new("event")
  26
+    >> @redis.set event[3][:name], "Redis Meetup"
  27
+    >> @redis.get event[3][:name]
  28
+    => "Redis Meetup"
  29
+
  30
+Usage
  31
+-----
  32
+
  33
+To create a new namespace:
  34
+
  35
+    >> ns = Nest.new("foo")
  36
+    => "foo"
  37
+
  38
+    >> ns["bar"]
  39
+    => "foo:bar"
  40
+
  41
+    >> ns["bar"]["baz"]["qux"]
  42
+    => "foo:bar:baz:qux"
  43
+
  44
+And you can use any object as a key, not only strings:
  45
+
  46
+    >> ns[:foo][42]
  47
+    => "foo:42"
  48
+
  49
+In a more realistic tone, lets assume you are working with Redis and
  50
+dealing with users:
  51
+
  52
+    >> event = Nest.new("event")
  53
+    => "event"
  54
+
  55
+    >> redis = Redis.new
  56
+    => #<Redis::Client...>
  57
+
  58
+    >> id = redis.incr(event)
  59
+    => 1
  60
+
  61
+    >> redis.set event[id][:name], "Redis Meetup"
  62
+    => "OK"
  63
+
  64
+    >> redis.get event[id][:name]
  65
+    => "Redis Meetup"
  66
+
  67
+    >> meetup = event[id]
  68
+    => "event:1"
  69
+
  70
+    >> redis.get meetup[:name]
  71
+    => "Redis Meetup"
  72
+
  73
+Differences with redis-namespace
  74
+-------------------------------
  75
+
  76
+[redis-namespace](http://github.com/defunkt/redis-namespace) wraps Redis
  77
+and translates the keys back and forth transparently.
  78
+
  79
+Use redis-namespace when you want all your application keys to live in a
  80
+different scope.
  81
+
  82
+Use Nest when you want to use the keys to represent structure.
  83
+
  84
+Differences with Ohm
  85
+-------------------
  86
+
  87
+[Ohm](http://ohm.keyvalue.org) lets you map Ruby objects to Redis with
  88
+little effort. It not only alleviates you from the pain of generating
  89
+keys for each object, but also helps you when dealing with references
  90
+between objects.
  91
+
  92
+Use Ohm when you want to use Redis as your database.
  93
+
  94
+Use Nest when mapping objects with Ohm is not possible.
  95
+
  96
+Installation
  97
+------------
  98
+
  99
+    $ sudo gem install nest
  100
+
  101
+License
  102
+-------
  103
+
  104
+Copyright (c) 2010 Michel Martens
  105
+
  106
+Permission is hereby granted, free of charge, to any person
  107
+obtaining a copy of this software and associated documentation
  108
+files (the "Software"), to deal in the Software without
  109
+restriction, including without limitation the rights to use,
  110
+copy, modify, merge, publish, distribute, sublicense, and/or sell
  111
+copies of the Software, and to permit persons to whom the
  112
+Software is furnished to do so, subject to the following
  113
+conditions:
  114
+
  115
+The above copyright notice and this permission notice shall be
  116
+included in all copies or substantial portions of the Software.
  117
+
  118
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  119
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  120
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  121
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  122
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  123
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  124
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  125
+OTHER DEALINGS IN THE SOFTWARE.
5  Rakefile
... ...
@@ -0,0 +1,5 @@
  1
+task :test do
  2
+  system "cd test && ruby nest_test.rb"
  3
+end
  4
+
  5
+task :default => :test
7  lib/nest.rb
... ...
@@ -0,0 +1,7 @@
  1
+#! /usr/bin/env ruby
  2
+
  3
+class Nest < String
  4
+  def [](key)
  5
+    self.class.new("#{self}:#{key}")
  6
+  end
  7
+end
10  nest.gemspec
... ...
@@ -0,0 +1,10 @@
  1
+Gem::Specification.new do |s|
  2
+  s.name              = "nest"
  3
+  s.version           = "0.0.1"
  4
+  s.summary           = "Generate nested namespaced keys for key-value databases."
  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.authors           = ["Michel Martens"]
  7
+  s.email             = ["michel@soveran.com"]
  8
+  s.homepage          = "http://github.com/soveran/nest"
  9
+  s.files = ["LICENSE", "README.markdown", "Rakefile", "lib/nest.rb", "nest.gemspec", "test/commands.rb", "test/nest_test.rb", "test/test_helper.rb"]
  10
+end
17  nest.gemspec.erb
... ...
@@ -0,0 +1,17 @@
  1
+Gem::Specification.new do |s|
  2
+  s.name              = "nest"
  3
+  s.version           = "0.0.1"
  4
+  s.summary           = "Generate nested namespaced keys for key-value databases."
  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.authors           = ["Michel Martens"]
  7
+  s.email             = ["michel@soveran.com"]
  8
+  s.homepage          = "http://github.com/soveran/nest"
  9
+  s.files = <%= Dir[
  10
+    "LICENSE",
  11
+    "README.markdown",
  12
+    "Rakefile",
  13
+    "lib/**/*.rb",
  14
+    "*.gemspec",
  15
+    "test/*.*"
  16
+  ].inspect %>
  17
+end
34  test/nest_test.rb
... ...
@@ -0,0 +1,34 @@
  1
+require File.join(File.dirname(__FILE__), "test_helper")
  2
+
  3
+class TestNest < Test::Unit::TestCase
  4
+  should "return the namespace" do
  5
+    n1 = Nest.new("foo")
  6
+    assert_equal "foo", n1
  7
+  end
  8
+
  9
+  should "prepend the namespace" do
  10
+    n1 = Nest.new("foo")
  11
+    assert_equal "foo:bar", n1["bar"]
  12
+  end
  13
+
  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
  19
+
  20
+  should "be chainable" do
  21
+    n1 = Nest.new("foo")
  22
+    assert_equal "foo:bar:baz", n1["bar"]["baz"]
  23
+  end
  24
+
  25
+  should "accept symbols" do
  26
+    n1 = Nest.new(:foo)
  27
+    assert_equal "foo:bar", n1[:bar]
  28
+  end
  29
+
  30
+  should "accept numbers" do
  31
+    n1 = Nest.new("foo")
  32
+    assert_equal "foo:3", n1[3]
  33
+  end
  34
+end
3  test/test_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+require "rubygems"
  2
+require "contest"
  3
+require File.join(File.dirname(__FILE__), "..", "lib", "nest")

0 notes on commit fbc4d1b

Please sign in to comment.
Something went wrong with that request. Please try again.