kiki 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ group :development do
4
+ gem "bundler", "~> 1.0.0"
5
+ gem "jeweler", "~> 1.6.0"
6
+ gem "yard", "~> 0.6.0"
7
+ gem "rcov", ">= 0"
8
+ end
9
+
10
+ group :test do
11
+ gem "rspec", "~> 2.3.0"
12
+ end
@@ -0,0 +1,74 @@
1
+
2
+
3
+ /~\
4
+ C oo
5
+ _( ^) kiki
6
+ / ~\
7
+
8
+
9
+
10
+
11
+ A lightweight, flexible key generator for NoSQL / Key-Value stores, such as Redis, Memcached, Riak, Tokyo Cabinet, etc.
12
+
13
+ == Examples
14
+
15
+ class User
16
+ include Kiki
17
+
18
+ cache_key :redis
19
+
20
+ cache_key :memcached,
21
+ :domain => 'people',
22
+ :delimiter => '/',
23
+ :identifier => :username
24
+ end
25
+
26
+ User.redis_key # => #<Keytar::Key:0x000001008ea9a8 @namespace="redis", @delimitter=":", @domain="users", @identifier=:id>
27
+ User.redis_key("count") # => redis:users:count
28
+ User.find(1).redis_key # => redis:users:1
29
+ User.find(1).redis_key("items") # => redis:users:1:items
30
+
31
+ User.find(1).memcached_key # => memcached/people/schneems
32
+
33
+ # Configuration can be done on the key object
34
+ User.memcached_key.identifier = :email
35
+ User.find(1).memcached_key # => memcached/people/mistersnowman@example.com
36
+
37
+ == Configuration
38
+
39
+ [namespace] the first argument for +cache_key+, the instance and class method +[namespace]_key+ will be added, which generate keys prefixed by the namespace (eg. "redis" would add the method "redis_key", generating a key like "redis:users:1")
40
+
41
+ [domain] optional, defaults to the downcase, pluralized name of your class (eg. "class User" would have the domain "users")
42
+
43
+ [delimiter] optional, defaults to ":"
44
+
45
+ [identifier] this is the method that is sent when calling "*_key" on an instance, or passing non-string / non-numeric arguments into a "*_key" method. optional, defaults to ":id"
46
+
47
+ == Credit
48
+
49
+ This project was inspired by [Richard Schneeman](https://github.com/schneems/)'s awesome library [Keytar](https://github.com/schneems/keytar/). Essentially, this my alternative take on the problem, focusing on simplicity of API and implementation.
50
+
51
+ == License
52
+
53
+ kiki is licensed under the MIT License:
54
+
55
+ Copyright (c) 2011 Mattt Thompson (http://mattt.me/)
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining a copy
58
+ of this software and associated documentation files (the "Software"), to deal
59
+ in the Software without restriction, including without limitation the rights
60
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61
+ copies of the Software, and to permit persons to whom the Software is
62
+ furnished to do so, subject to the following conditions:
63
+
64
+ The above copyright notice and this permission notice shall be included in
65
+ all copies or substantial portions of the Software.
66
+
67
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
72
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
73
+ THE SOFTWARE.
74
+
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development, :test)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ gem.name = "kiki"
17
+ gem.homepage = "http://github.com/mattt/kiki"
18
+ gem.license = "MIT"
19
+ gem.summary = %Q{A lightweight, flexible key generator for NoSQL / Key-Value stores, such as Redis, Memcached, Riak, Tokyo Cabinet, etc.}
20
+ gem.description = %Q{kiki is a dead-simple module that you can include in your Models that provides convenient, DRY way of generating unique keys for your favorite K/V or NoSQL databases. }
21
+ gem.email = "m@mattt.me"
22
+ gem.authors = ["Mattt Thompson"]
23
+ end
24
+ Jeweler::RubygemsDotOrgTasks.new
25
+
26
+ require 'rspec/core'
27
+ require 'rspec/core/rake_task'
28
+ RSpec::Core::RakeTask.new(:spec) do |spec|
29
+ spec.pattern = FileList['spec/**/*_spec.rb']
30
+ end
31
+
32
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov = true
35
+ end
36
+
37
+ task :default => :spec
38
+
39
+ require 'yard'
40
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'kiki/extensions'
4
+
5
+ module Kiki
6
+ autoload :Key, 'kiki/key'
7
+ autoload :Version, 'kiki/version'
8
+
9
+ def self.included(klass)
10
+ klass.class_eval { extend ClassMethods }
11
+ end
12
+
13
+ module ClassMethods
14
+ def cache_key(namespace, options = {})
15
+ class_eval(<<-EVAL, __FILE__, __LINE__)
16
+ class << self
17
+ @@#{namespace}_key = Key.new "#{namespace}",
18
+ "#{options[:delimiter] || ":"}",
19
+ "#{options[:domain] || self.name.downcase.pluralize}",
20
+ :"#{options[:identifier] || :id}"
21
+
22
+ def #{namespace}_key(*args)
23
+ return args.empty? ? @@#{namespace}_key : @@#{namespace}_key.for(*args)
24
+ end
25
+ end
26
+
27
+ def #{namespace}_key(*args)
28
+ return self.class.#{namespace}_key(*[self, *args])
29
+ end
30
+ EVAL
31
+
32
+ return self.send("#{namespace}_key")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ # Fallback to monkeypatch version of +String#pluralize+ if ActiveSupport Inflector (or another class) has not defined it already
4
+ unless String.respond_to? :pluralize
5
+ String.class_eval do
6
+ def pluralize
7
+ self[(self.length - 1), 1] =~ /s/i ? self : "#{self}s"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module Kiki
4
+ class Key
5
+ attr_reader :namespace
6
+ attr_accessor :delimiter, :domain, :identifier
7
+
8
+ def initialize(namespace, delimiter, domain, identifier)
9
+ @namespace = namespace
10
+ @delimiter = delimiter
11
+ @domain = domain
12
+ @identifier = identifier
13
+ end
14
+
15
+ def for(*args)
16
+ components = [@namespace, @domain] + args.collect do |arg|
17
+ case arg
18
+ when String, Numeric then arg
19
+ else
20
+ arg.respond_to?(@identifier) ? arg.send(@identifier) : arg.to_s
21
+ end
22
+ end
23
+
24
+ components.compact.join(@delimiter)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Kiki
4
+ Version = '0.1.1'
5
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ describe "Kiki" do
6
+
7
+ before :each do
8
+ @user = User.new(3, "ramona")
9
+ end
10
+
11
+ it "should add *_key class methods" do
12
+ User.should respond_to(:redis_key)
13
+ User.should respond_to(:memcached_key)
14
+ end
15
+
16
+ it "should add *_key instance methods" do
17
+ @user.should respond_to(:redis_key)
18
+ @user.should respond_to(:memcached_key)
19
+ end
20
+
21
+ it "should respond to configuration" do
22
+ User.redis_key.identifier = :username
23
+ @user.redis_key("likes").should eql("redis:users:ramona:likes")
24
+
25
+ User.redis_key.identifier = :id
26
+ @user.redis_key("likes").should eql("redis:users:3:likes")
27
+ end
28
+
29
+ describe "Redis key" do
30
+ it "should be correct for instance" do
31
+ @user.redis_key.should eql("redis:users:3")
32
+ end
33
+
34
+ it "should be correct with arguments" do
35
+ User.redis_key("stats").should eql("redis:users:stats")
36
+ @user.redis_key("likes").should eql("redis:users:3:likes")
37
+ @user.redis_key("likes", "recent").should eql("redis:users:3:likes:recent")
38
+ end
39
+ end
40
+
41
+ describe "Memcached key" do
42
+ it "should be correct for instance" do
43
+ @user.memcached_key.should eql("memcached/people/ramona")
44
+ end
45
+
46
+ it "should be correct with arguments" do
47
+ User.memcached_key("comments").should eql("memcached/people/comments")
48
+ @user.memcached_key("comments").should eql("memcached/people/ramona/comments")
49
+ @user.memcached_key("comments", 42).should eql("memcached/people/ramona/comments/42")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ require 'rspec'
6
+ require 'kiki'
7
+
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ class User < Struct.new(:id, :username)
4
+ include Kiki
5
+
6
+ cache_key :redis
7
+
8
+ cache_key :memcached,
9
+ :delimiter => '/',
10
+ :domain => 'people',
11
+ :identifier => :username
12
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kiki
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Mattt Thompson
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-28 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :development
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ name: bundler
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ type: :development
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 6
49
+ - 0
50
+ version: 1.6.0
51
+ name: jeweler
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ type: :development
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 7
62
+ segments:
63
+ - 0
64
+ - 6
65
+ - 0
66
+ version: 0.6.0
67
+ name: yard
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ type: :development
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ name: rcov
82
+ version_requirements: *id004
83
+ description: "kiki is a dead-simple module that you can include in your Models that provides convenient, DRY way of generating unique keys for your favorite K/V or NoSQL databases. "
84
+ email: m@mattt.me
85
+ executables: []
86
+
87
+ extensions: []
88
+
89
+ extra_rdoc_files:
90
+ - README.rdoc
91
+ files:
92
+ - .document
93
+ - .rspec
94
+ - Gemfile
95
+ - README.rdoc
96
+ - Rakefile
97
+ - VERSION
98
+ - lib/kiki.rb
99
+ - lib/kiki/extensions.rb
100
+ - lib/kiki/key.rb
101
+ - lib/kiki/version.rb
102
+ - spec/kiki_spec.rb
103
+ - spec/spec_helper.rb
104
+ - spec/support/user.rb
105
+ has_rdoc: true
106
+ homepage: http://github.com/mattt/kiki
107
+ licenses:
108
+ - MIT
109
+ post_install_message:
110
+ rdoc_options: []
111
+
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
131
+ version: "0"
132
+ requirements: []
133
+
134
+ rubyforge_project:
135
+ rubygems_version: 1.6.2
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: A lightweight, flexible key generator for NoSQL / Key-Value stores, such as Redis, Memcached, Riak, Tokyo Cabinet, etc.
139
+ test_files: []
140
+