From afd626528877f48f5ea9f509474ababcdbe3aacb Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Mon, 19 Jul 2010 00:57:23 +0300 Subject: [PATCH] initial import --- .gitignore | 2 + Rakefile | 34 ++++++++++++ lib/redistat.rb | 83 ++++++++++++++++++++++++++++ lib/redistat/database.rb | 7 +++ lib/redistat/date.rb | 50 +++++++++++++++++ lib/redistat/event.rb | 18 ++++++ lib/redistat/extensions/date_time.rb | 11 ++++ lib/redistat/key.rb | 28 ++++++++++ lib/redistat/label.rb | 28 ++++++++++ lib/redistat/model.rb | 13 +++++ spec/_redistat_spec.rb | 10 ++++ spec/date_spec.rb | 42 ++++++++++++++ spec/db/dump.rdb | 1 + spec/key_spec.rb | 7 +++ spec/label_spec.rb | 12 ++++ spec/redis-test.conf | 9 +++ spec/spec_helper.rb | 5 ++ 17 files changed, 360 insertions(+) create mode 100644 .gitignore create mode 100644 Rakefile create mode 100644 lib/redistat.rb create mode 100644 lib/redistat/database.rb create mode 100644 lib/redistat/date.rb create mode 100644 lib/redistat/event.rb create mode 100644 lib/redistat/extensions/date_time.rb create mode 100644 lib/redistat/key.rb create mode 100644 lib/redistat/label.rb create mode 100644 lib/redistat/model.rb create mode 100644 spec/_redistat_spec.rb create mode 100644 spec/date_spec.rb create mode 100644 spec/db/dump.rdb create mode 100644 spec/key_spec.rb create mode 100644 spec/label_spec.rb create mode 100644 spec/redis-test.conf create mode 100644 spec/spec_helper.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dc2650c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +spec/db/*.pid diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..7352f59 --- /dev/null +++ b/Rakefile @@ -0,0 +1,34 @@ +require "rubygems" + +require "spec" +require "spec/rake/spectask" + +REDIS_DIR = File.expand_path(File.join("..", "spec"), __FILE__) +REDIS_CNF = File.join(REDIS_DIR, "redis-test.conf") +REDIS_PID = File.join(REDIS_DIR, "db", "redis.pid") + + +task :default => [:start, :spec, :stop] + + +# define the spec task +Spec::Rake::SpecTask.new do |t| + t.spec_opts = %w(--format specdoc --colour) + t.libs = ["spec"] +end + + +desc "Start the Redis test server" +task :start do + unless File.exists?(REDIS_PID) + system "redis-server #{REDIS_CNF}" + end +end + +desc "Stop the Redis test server" +task :stop do + if File.exists?(REDIS_PID) + system "kill #{File.read(REDIS_PID)}" + system "rm #{REDIS_PID}" + end +end \ No newline at end of file diff --git a/lib/redistat.rb b/lib/redistat.rb new file mode 100644 index 0000000..4d9dd5c --- /dev/null +++ b/lib/redistat.rb @@ -0,0 +1,83 @@ + +require "redis" +require "yaml" +require "time" +require "digest/sha1" + +require "redistat/extensions/date_time" +require "redistat/database" +require "redistat/model" +require "redistat/event" +require "redistat/key" +require "redistat/label" +require "redistat/date" + +module Redistat + + # Provides access to the Redis database. This is shared accross all models and instances. + def redis + threaded[:redis] ||= connection(*options) + end + + def redis=(connection) + threaded[:redis] = connection + end + + def threaded + Thread.current[:redistat] ||= {} + end + + # Connect to a redis database. + # + # @param options [Hash] options to create a message with. + # @option options [#to_s] :host ('127.0.0.1') Host of the redis database. + # @option options [#to_s] :port (6379) Port number. + # @option options [#to_s] :db (0) Database number. + # @option options [#to_s] :timeout (0) Database timeout in seconds. + # @example Connect to a database in port 6380. + # Ohm.connect(:port => 6380) + def connect(*options) + self.redis = nil + @options = options + end + + # Return a connection to Redis. + # + # This is a wapper around Redis.new(options) + def connection(*options) + Redis.new(*options) + end + + def options + @options = [] unless defined? @options + @options + end + + # Clear the database. + def flush + redis.flushdb + end + + module_function :connect, :connection, :flush, :redis, :redis=, :options, :threaded + +end + + + + + + + + + + + + + + + + + + + + diff --git a/lib/redistat/database.rb b/lib/redistat/database.rb new file mode 100644 index 0000000..46d2502 --- /dev/null +++ b/lib/redistat/database.rb @@ -0,0 +1,7 @@ +module Redistat + module Database + def db + Redistat.redis + end + end +end \ No newline at end of file diff --git a/lib/redistat/date.rb b/lib/redistat/date.rb new file mode 100644 index 0000000..ce8b335 --- /dev/null +++ b/lib/redistat/date.rb @@ -0,0 +1,50 @@ +module Redistat + class Date + + attr_accessor :year + attr_accessor :month + attr_accessor :day + attr_accessor :hour + attr_accessor :min + attr_accessor :sec + + def initialize(input) + if input.is_a?(::Time) + from_time(input) + elsif input.is_a?(::Date) + from_date(input) + elsif input.is_a?(::String) + from_string(input) + end + end + + def from_time(input) + [:year, :month, :day, :hour, :min, :sec].each do |k| + self.send("#{k}=", input.send(k)) + end + end + + def from_date(input) + [:year, :month, :day].each do |k| + self.send("#{k}=", input.send(k)) + end + end + + def from_string(input) + from_time(Time.parse(input)) + end + + def to_s(depth = :sec) + output = "" + [:year, :month, :day, :hour, :min, :sec].each_with_index do |current, i| + break if self.send(current).nil? + output << self.send(current).to_s.rjust((i <= 0) ? 4 : 2, '0') + break if current == depth + end + output + end + + alias :to_string :to_s + + end +end \ No newline at end of file diff --git a/lib/redistat/event.rb b/lib/redistat/event.rb new file mode 100644 index 0000000..a718eab --- /dev/null +++ b/lib/redistat/event.rb @@ -0,0 +1,18 @@ +module Redistat + class Event + + attr_accessor :label + attr_reader :options + + def initialize(scope, options, data = {}, label = nil, time = nil) + key = [scope] + key << Digest::SHA1.hexdigest(label) if !label.nil? + + time ||= Time.now + key << time.to_redistat(options ||= nil) + + puts key.inspect + end + + end +end \ No newline at end of file diff --git a/lib/redistat/extensions/date_time.rb b/lib/redistat/extensions/date_time.rb new file mode 100644 index 0000000..a2ec874 --- /dev/null +++ b/lib/redistat/extensions/date_time.rb @@ -0,0 +1,11 @@ +class Date + def to_redistat(depth = nil) + Redistat::Date.new(self).to_s(depth) + end +end + +class Time + def to_redistat(depth = nil) + Redistat::Date.new(self).to_s(depth) + end +end \ No newline at end of file diff --git a/lib/redistat/key.rb b/lib/redistat/key.rb new file mode 100644 index 0000000..10f3e1a --- /dev/null +++ b/lib/redistat/key.rb @@ -0,0 +1,28 @@ +module Redistat + class Key + + attr_accessor :scope + attr_accessor :label + attr_accessor :date + + def initialize(scope, label = nil, date = nil, options = {}) + @scope = scope + @label = Label.create(label) if !label.nil? + @date = date ||= Time.now + @options = options + end + + def label + if !@label.nil? + (options[:hash_label] ||= true) ? @label.hash : @label.name + end + end + + def to_s + key = "#{@scope}" + key << "/#{label}" if !label.nil? + key << ":#{@date.to_redistat(@options[:depth] ||= nil)}" + end + + end +end \ No newline at end of file diff --git a/lib/redistat/label.rb b/lib/redistat/label.rb new file mode 100644 index 0000000..5f53dbc --- /dev/null +++ b/lib/redistat/label.rb @@ -0,0 +1,28 @@ +module Redistat + class Label + include Database + + attr_reader :name + attr_reader :hash + + def initialize(str) + @name = str + @hash = Digest::SHA1.hexdigest(@name) + end + + def save + db.set("Redistat:lables:#{@hash}", @name) + @saved = true + self + end + + def saved? + @saved ||= false + end + + def self.create(name) + self.new(name).save + end + + end +end \ No newline at end of file diff --git a/lib/redistat/model.rb b/lib/redistat/model.rb new file mode 100644 index 0000000..07bd330 --- /dev/null +++ b/lib/redistat/model.rb @@ -0,0 +1,13 @@ +module Redistat + class Model + + def self.create(*args) + Event.new(self.name, self.options, *args) + end + + def self.options + @options ||= {} + end + + end +end \ No newline at end of file diff --git a/spec/_redistat_spec.rb b/spec/_redistat_spec.rb new file mode 100644 index 0000000..ce63f68 --- /dev/null +++ b/spec/_redistat_spec.rb @@ -0,0 +1,10 @@ +require "spec_helper" + +describe Redistat do + + it "should create a valid redis connection to correct server" do + Redistat.redis.should_not be_nil + Redistat.redis.client.port.should == 8379 + end + +end \ No newline at end of file diff --git a/spec/date_spec.rb b/spec/date_spec.rb new file mode 100644 index 0000000..b1457ae --- /dev/null +++ b/spec/date_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" + +describe Redistat::Date do + + it "should initialize from Time object" do + now = Time.now + rdate = Redistat::Date.new(now) + [:year, :month, :day, :hour, :min, :sec].each { |k| rdate.send(k).should == now.send(k) } + end + + it "should initialize from Date object" do + today = Date.today + rdate = Redistat::Date.new(today) + [:year, :month, :day].each { |k| rdate.send(k).should == today.send(k) } + [:hour, :min, :sec].each { |k| rdate.send(k).should == nil } + end + + it "should initialize from String object" do + now = Time.now + rdate = Redistat::Date.new(now.to_s) + [:year, :month, :day, :hour, :min, :sec].each { |k| rdate.send(k).should == now.send(k) } + end + + it "should convert to string with correct depths" do + today = Date.today + rdate = Redistat::Date.new(today) + props = [:year, :month, :day, nil] + props.each do + rdate.to_s(props.last).should == props.map { |k| today.send(k).to_s.rjust(2, '0') if !k.nil? }.join + props.pop + end + + now = Time.now + rdate = Redistat::Date.new(now) + props = [:year, :month, :day, :hour, :min, :sec, nil] + props.each do + rdate.to_s(props.last).should == props.map { |k| now.send(k).to_s.rjust(2, '0') if !k.nil? }.join + props.pop + end + end + +end \ No newline at end of file diff --git a/spec/db/dump.rdb b/spec/db/dump.rdb new file mode 100644 index 0000000..f3fec53 --- /dev/null +++ b/spec/db/dump.rdb @@ -0,0 +1 @@ +REDIS0001ÿ \ No newline at end of file diff --git a/spec/key_spec.rb b/spec/key_spec.rb new file mode 100644 index 0000000..a92687b --- /dev/null +++ b/spec/key_spec.rb @@ -0,0 +1,7 @@ +require "spec_helper" + +describe Redistat::Key do + + + +end \ No newline at end of file diff --git a/spec/label_spec.rb b/spec/label_spec.rb new file mode 100644 index 0000000..3f520a2 --- /dev/null +++ b/spec/label_spec.rb @@ -0,0 +1,12 @@ +require "spec_helper" + +describe Redistat::Label do + + it "should initialize and SHA1 hash the label name" do + name = "/about/us" + label = Redistat::Label.new(name) + label.name.should == name + label.hash.should == Digest::SHA1.hexdigest(name) + end + +end \ No newline at end of file diff --git a/spec/redis-test.conf b/spec/redis-test.conf new file mode 100644 index 0000000..8ee6d76 --- /dev/null +++ b/spec/redis-test.conf @@ -0,0 +1,9 @@ +daemonize yes +dir ./spec/db +pidfile ./redis.pid +port 8379 +bind 127.0.0.1 +timeout 300 +loglevel debug +logfile stdout +databases 16 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..9afd4ca --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,5 @@ +require "rubygems" +require File.dirname(__FILE__) + "/../lib/redistat" + +Redistat.connect({:port => 8379, :db => 15}) +Redistat.flush \ No newline at end of file