Skip to content

Commit

Permalink
add ezmobius/redis-rb
Browse files Browse the repository at this point in the history
  • Loading branch information
Jay Adkisson committed Jul 13, 2010
1 parent 7b0b5da commit 55215ae
Show file tree
Hide file tree
Showing 29 changed files with 5,501 additions and 0 deletions.
8 changes: 8 additions & 0 deletions vendor/redis-rb/.gitignore
@@ -0,0 +1,8 @@
nohup.out
redis/*
rdsrv
pkg/*
coverage/*
.idea
*.rdb
*.swp
20 changes: 20 additions & 0 deletions vendor/redis-rb/LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2009 Ezra Zygmuntowicz

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
120 changes: 120 additions & 0 deletions vendor/redis-rb/README.markdown
@@ -0,0 +1,120 @@
# redis-rb

A Ruby client library for the [Redis](http://code.google.com/p/redis) key-value store.

## A note about versions

Versions *1.0.x* target all versions of Redis. You have to use this one if you are using Redis < 1.2.

Version *2.0* is a big refactoring of the previous version and makes little effort to be
backwards-compatible when it shouldn't. It does not support Redis' original protocol, favoring the
new, binary-safe one. You should be using this version if you're running Redis 1.2+.

## Information about Redis

Redis is a key-value store with some interesting features:

1. It's fast.
2. Keys are strings but values are typed. Currently Redis supports strings, lists, sets, sorted sets and hashes. [Atomic operations](http://code.google.com/p/redis/wiki/CommandReference) can be done on all of these types.

See [the Redis homepage](http://code.google.com/p/redis/wiki/README) for more information.

## Getting started

You can connect to Redis by instantiating the `Redis` class:

require "redis"

redis = Redis.new

This assumes Redis was started with default values listening on `localhost`, port 6379. If you need to connect to a remote server or a different port, try:

redis = Redis.new(:host => "10.0.1.1", :port => 6380)

Once connected, you can start running commands against Redis:

>> redis.set "foo", "bar"
=> "OK"

>> redis.get "foo"
=> "bar"

>> redis.sadd "users", "albert"
=> true

>> redis.sadd "users", "bernard"
=> true

>> redis.sadd "users", "charles"
=> true

How many users?

>> redis.scard "users"
=> 3

Is `albert` a user?

>> redis.sismember "users", "albert"
=> true

Is `isabel` a user?

>> redis.sismember "users", "isabel"
=> false

Handle groups:

>> redis.sadd "admins", "albert"
=> true

>> redis.sadd "admins", "isabel"
=> true

Users who are also admins:

>> redis.sinter "users", "admins"
=> ["albert"]

Users who are not admins:

>> redis.sdiff "users", "admins"
=> ["bernard", "charles"]

Admins who are not users:

>> redis.sdiff "admins", "users"
=> ["isabel"]

All users and admins:

>> redis.sunion "admins", "users"
=> ["albert", "bernard", "charles", "isabel"]


## Storing objects

Redis only stores strings as values. If you want to store an object inside a key, you can use a serialization/deseralization mechanism like JSON:

>> redis.set "foo", [1, 2, 3].to_json
=> OK

>> JSON.parse(redis.get("foo"))
=> [1, 2, 3]

## Executing multiple commands atomically

You can use `MULTI/EXEC` to run arbitrary commands in an atomic fashion:

redis.multi do
redis.set "foo", "bar"
redis.incr "baz"
end

## More info

Check the [Redis Command Reference](http://code.google.com/p/redis/wiki/CommandReference) or check the tests to find out how to use this client.

## Contributing

[Fork the project](http://github.com/ezmobius/redis-rb) and send pull requests. You can also ask for help at `#redis-rb` on Freenode.
165 changes: 165 additions & 0 deletions vendor/redis-rb/Rakefile
@@ -0,0 +1,165 @@
require 'rubygems'
require 'rake/gempackagetask'
require 'rake/testtask'

$:.unshift File.join(File.dirname(__FILE__), 'lib')
require 'redis'

GEM = 'redis'
GEM_NAME = 'redis'
GEM_VERSION = Redis::VERSION
AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark', 'Brian McKinney', 'Salvatore Sanfilippo', 'Luca Guidi', 'Michel Martens', 'Damian Janowski']
EMAIL = "ez@engineyard.com"
HOMEPAGE = "http://github.com/ezmobius/redis-rb"
SUMMARY = "Ruby client library for Redis, the key value storage server"

spec = Gem::Specification.new do |s|
s.name = GEM
s.version = GEM_VERSION
s.platform = Gem::Platform::RUBY
s.has_rdoc = true
s.extra_rdoc_files = ["LICENSE"]
s.summary = SUMMARY
s.description = s.summary
s.authors = AUTHORS
s.email = EMAIL
s.homepage = HOMEPAGE
s.require_path = 'lib'
s.autorequire = GEM
s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("{lib,tasks,spec}/**/*")
end

REDIS_DIR = File.expand_path(File.join("..", "test"), __FILE__)
REDIS_CNF = File.join(REDIS_DIR, "test.conf")
REDIS_PID = File.join(REDIS_DIR, "db", "redis.pid")

task :default => :run

desc "Run tests and manage server start/stop"
task :run => [:start, :test, :stop]

desc "Start the Redis server"
task :start do
redis_running = \
begin
File.exists?(REDIS_PID) && Process.kill(0, File.read(REDIS_PID).to_i)
rescue Errno::ESRCH
FileUtils.rm REDIS_PID
false
end

system "redis-server #{REDIS_CNF}" unless redis_running
end

desc "Stop the Redis server"
task :stop do
if File.exists?(REDIS_PID)
Process.kill "INT", File.read(REDIS_PID).to_i
FileUtils.rm REDIS_PID
end
end

Rake::TestTask.new(:test) do |t|
t.pattern = 'test/**/*_test.rb'
end

Rake::GemPackageTask.new(spec) do |pkg|
pkg.gem_spec = spec
end

desc "install the gem locally"
task :install => [:package] do
sh %{gem install pkg/#{GEM}-#{GEM_VERSION}}
end

desc "create a gemspec file"
task :gemspec do
File.open("#{GEM}.gemspec", "w") do |file|
file.puts spec.to_ruby
end
end

desc "Generate YARDoc"
task :yardoc do
require "yard"

opts = ["--title", "A Ruby client for Redis"]

YARD::CLI::Yardoc.run(*opts)
end

namespace :commands do
def redis_commands
$redis_commands ||= begin
require "open-uri"
require "nokogiri"

doc = Nokogiri::HTML(open("http://code.google.com/p/redis/wiki/CommandReference"))

commands = {}

doc.xpath("//ul/li").each do |node|
node.at_xpath("./a").text.split("/").each do |name|
if name =~ /^[A-Z]+$/
commands[name.downcase] = node.at_xpath("./tt").text
end
end
end

commands
end
end

task :doc do
source = File.read("lib/redis.rb")

redis_commands.each do |name, text|
source.sub!(/(?:^ *#.*\n)*^( *)def #{name}(\(|$)/) do
indent, extra_args = $1, $2
comment = "#{indent}# #{text.strip}"

IO.popen("par p#{2 + indent.size} 80", "r+") do |io|
io.puts comment
io.close_write
comment = io.read
end

"#{comment}#{indent}def #{name}#{extra_args}"
end
end

File.open("lib/redis.rb", "w") { |f| f.write(source) }
end

task :verify do
require "redis"

Dir["test/**/*_test.rb"].each { |f| require "./#{f}" }

log = StringIO.new

RedisTest::OPTIONS[:logger] = Logger.new(log)

redis = Redis.new

Test::Unit::AutoRunner.run

report = ["Command", "\033[0mDefined?\033[0m", "\033[0mTested?\033[0m"]

yes, no = "\033[1;32mYes\033[0m", "\033[1;31mNo\033[0m"

redis_commands.sort.each do |name, _|
defined, tested = redis.respond_to?(name), log.string[">> #{name.upcase}"]

next if defined && tested

report << name
report << (defined ? yes : no)
report << (tested ? yes : no)
end

IO.popen("rs 0 3", "w") do |io|
io.puts report.join("\n")
end
end
end
62 changes: 62 additions & 0 deletions vendor/redis-rb/benchmarking/logging.rb
@@ -0,0 +1,62 @@
# Run with
#
# $ ruby -Ilib benchmarking/logging.rb
#

begin
require "bench"
rescue LoadError
$stderr.puts "`gem install bench` and try again."
exit 1
end

require "redis"
require "logger"

def log(level, namespace = nil)
logger = (namespace || Kernel).const_get(:Logger).new("/dev/null")
logger.level = (namespace || Logger).const_get(level)
logger
end

def stress(redis)
redis.flushdb

n = (ARGV.shift || 2000).to_i

n.times do |i|
key = "foo:#{i}"
redis.set key, i
redis.get key
end
end

default = Redis.new

logging_redises = [
Redis.new(:logger => log(:DEBUG)),
Redis.new(:logger => log(:INFO)),
]

begin
require "log4r"

logging_redises += [
Redis.new(:logger => log(:DEBUG, Log4r)),
Redis.new(:logger => log(:INFO, Log4r)),
]
rescue LoadError
$stderr.puts "Log4r not installed. `gem install log4r` if you want to compare it against Ruby's Logger (spoiler: it's much faster)."
end

benchmark "Default options (no logger)" do
stress(default)
end

logging_redises.each do |redis|
benchmark "#{redis.client.logger.class} on #{Logger::SEV_LABEL[redis.client.logger.level]}" do
stress(redis)
end
end

run 10

0 comments on commit 55215ae

Please sign in to comment.