18 Commits

Author SHA1 Message Date
ecbd15ef1e Merge branch 'release/v0.2.4' 2011-03-14 11:14:01 +00:00
2b2461dd9f started release v0.2.4 2011-03-14 11:13:50 +00:00
3e177c9ae4 changed json dependency back to '>= 1.4.0' for backwards compatibility with certain older projects/gems, make sure you're using 1.5.0 or later of the json gem for JRuby support 2011-03-14 11:13:06 +00:00
d4cd5402bc create Label#join method for easily joining Labels 2011-03-14 11:10:24 +00:00
d560a7deff killed an old line of commented out code 2011-03-14 10:38:16 +00:00
3df6666704 additions to specs 2011-03-14 10:37:56 +00:00
80fd63059b updated time_ext dependency to ensure there's no loading issues within Rails applications 2011-03-13 23:47:02 +00:00
d0b7f097a8 updated json dependency to '>= 1.5.0' to ensure JRuby compatability 2011-03-13 23:46:00 +00:00
875d16b01c Merge branch 'release/v0.2.3' into dev 2011-03-13 20:30:21 +00:00
00791d36d8 Merge branch 'release/v0.2.3' 2011-03-13 20:30:17 +00:00
94b589c5e6 started release v0.2.3 2011-03-13 20:30:11 +00:00
cdf52869d6 added #find_event method to Model 2011-03-13 20:28:17 +00:00
8b711d4d9c fixed a bug with Event#find 2011-03-13 20:24:06 +00:00
e4aaedfe58 made Key#scope return Scope object instead of Scope#to_s 2011-03-13 20:23:41 +00:00
ea820d44f4 fixed typo in Finder spec 2011-03-13 19:52:30 +00:00
acedf071d1 improved options passed into Finder object, :depth option is not needed if :interval is set to a depth value instead of true 2011-03-13 19:51:04 +00:00
108b6ab02e Finder's options methods now set the option when an argument is supplied and returns self for method chaining. When no argument is supplied it returns the option value itself.
Example:

    finder = Redistat::Finder.new
    finder.scope("Foo") #=> Finder object
    finder.scope        #=> Scope object
    finder.scope.to_s   #=> "Foo"
2011-03-13 19:46:52 +00:00
9920c0dc2f Merge branch 'release/v0.2.2' into dev 2011-03-12 22:26:58 +00:00
15 changed files with 94 additions and 36 deletions

View File

@@ -91,7 +91,7 @@ module Redistat
event = db.hgetall "#{scope}#{KEY_EVENT}#{id}" event = db.hgetall "#{scope}#{KEY_EVENT}#{id}"
return nil if event.size == 0 return nil if event.size == 0
self.new( event["scope"], event["label"], event["date"], JSON.parse(event["stats"]), self.new( event["scope"], event["label"], event["date"], JSON.parse(event["stats"]),
JSON.parse(event["meta"]), JSON.parse(event["options"]), false ) JSON.parse(event["options"]), JSON.parse(event["meta"]), false )
end end
end end

View File

@@ -81,49 +81,56 @@ module Redistat
} }
end end
def connection_ref(ref) def connection_ref(ref = nil)
return options[:connection_ref] if ref.nil?
reset! if options[:connection_ref] != ref reset! if options[:connection_ref] != ref
options[:connection_ref] = ref options[:connection_ref] = ref
self self
end end
def scope(scope) def scope(input = nil)
reset! if !options[:scope].nil? && options[:scope].to_s != scope return options[:scope] if input.nil?
options[:scope] = Scope.new(scope) reset! if !options[:scope].nil? && options[:scope].to_s != input.to_s
options[:scope] = Scope.new(input)
self self
end end
def label(label) def label(input = nil)
reset! if options.has_key?(:label) && options[:label].to_s != label.to_s return options[:label] if input.nil?
options[:label] = (!label.nil?) ? Label.new(label) : nil reset! if options.has_key?(:label) && options[:label].to_s != input.to_s
options[:label] = (!input.nil?) ? Label.new(input) : nil
self self
end end
def dates(from, till) def dates(start, finish)
from(from).till(till) from(start).till(finish)
end end
alias :date :dates alias :date :dates
def from(date) def from(date = nil)
return options[:from] if date.nil?
reset! if options[:from] != date reset! if options[:from] != date
options[:from] = date options[:from] = date
self self
end end
def till(date) def till(date = nil)
return options[:till] if date.nil?
reset! if options[:till] != date reset! if options[:till] != date
options[:till] = date options[:till] = date
self self
end end
alias :until :till alias :until :till
def depth(unit) def depth(unit = nil)
return options[:depth] if unit.nil?
reset! if options[:depth] != unit reset! if options[:depth] != unit
options[:depth] = unit options[:depth] = unit
self self
end end
def interval(unit) def interval(unit = nil)
return options[:interval] if unit.nil?
reset! if options[:interval] != unit reset! if options[:interval] != unit
options[:interval] = unit options[:interval] = unit
self self

View File

@@ -9,6 +9,10 @@ module Redistat
end end
def find_date_sets(start_date, end_date, depth = nil, interval = false) def find_date_sets(start_date, end_date, depth = nil, interval = false)
if depth.nil? && interval.is_a?(Symbol)
depth = interval
interval = true
end
start_date = start_date.to_time if start_date.is_a?(::Date) start_date = start_date.to_time if start_date.is_a?(::Date)
end_date = end_date.to_time if end_date.is_a?(::Date) end_date = end_date.to_time if end_date.is_a?(::Date)
if !interval if !interval

View File

@@ -30,13 +30,14 @@ module Redistat
options[:depth] options[:depth]
end end
def scope # def scope
@scope.to_s # @scope.to_s
end # end
def scope=(input) def scope=(input)
@scope = (input.instance_of?(Redistat::Scope)) ? input : Scope.new(input) @scope = (input.instance_of?(Redistat::Scope)) ? input : Scope.new(input)
end end
attr_reader :scope
def label=(input) def label=(input)
@label = (input.instance_of?(Redistat::Label)) ? input : Label.create(input, @options) @label = (input.instance_of?(Redistat::Label)) ? input : Label.create(input, @options)
@@ -60,7 +61,6 @@ module Redistat
def update_index def update_index
@label.groups.each do |label| @label.groups.each do |label|
# break if label.parent.nil?
parent = (label.parent || "") parent = (label.parent || "")
db.sadd("#{scope}#{LABEL_INDEX}#{parent}", label.me) db.sadd("#{scope}#{LABEL_INDEX}#{parent}", label.me)
end end

View File

@@ -11,6 +11,11 @@ module Redistat
self.new(name, opts).save self.new(name, opts).save
end end
def self.join(*args)
args = args.map {|i| i.to_s}
self.new(args.reject {|i| i.blank? }.join(GROUP_SEPARATOR))
end
def initialize(str, opts = {}) def initialize(str, opts = {})
parse_options(opts) parse_options(opts)
@raw = str.to_s @raw = str.to_s

View File

@@ -13,7 +13,7 @@ module Redistat
# #
def store(label, stats = {}, date = nil, opts = {}, meta = {}) def store(label, stats = {}, date = nil, opts = {}, meta = {})
Event.new(name, label, date, stats, options.merge(opts), meta).save Event.new(self.name, label, date, stats, options.merge(opts), meta).save
end end
alias :event :store alias :event :store
@@ -29,6 +29,10 @@ module Redistat
:till => till }.merge(options.merge(opts)) ) :till => till }.merge(options.merge(opts)) )
end end
def find_event(event_id)
Event.find(self.name, event_id)
end
# #
# options methods # options methods

View File

@@ -1,3 +1,3 @@
module Redistat module Redistat
VERSION = "0.2.2" VERSION = "0.2.4"
end end

View File

@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'activesupport', '>= 2.3.6' s.add_runtime_dependency 'activesupport', '>= 2.3.6'
s.add_runtime_dependency 'json', '>= 1.4.0' s.add_runtime_dependency 'json', '>= 1.4.0'
s.add_runtime_dependency 'redis', '>= 2.1.0' s.add_runtime_dependency 'redis', '>= 2.1.0'
s.add_runtime_dependency 'time_ext', '>= 0.2.8' s.add_runtime_dependency 'time_ext', '>= 0.2.9'
s.add_development_dependency 'rspec', '>= 2.1.0' s.add_development_dependency 'rspec', '>= 2.1.0'
s.add_development_dependency 'rcov', '>= 0.9.9' s.add_development_dependency 'rcov', '>= 0.9.9'

View File

@@ -8,8 +8,8 @@ describe Redistat::Event do
@scope = "PageViews" @scope = "PageViews"
@label = "about_us" @label = "about_us"
@label_hash = Digest::SHA1.hexdigest(@label) @label_hash = Digest::SHA1.hexdigest(@label)
@stats = {:views => 1} @stats = {'views' => 1}
@meta = {:user_id => 239} @meta = {'user_id' => 239}
@options = {:depth => :hour} @options = {:depth => :hour}
@date = Time.now @date = Time.now
@event = Redistat::Event.new(@scope, @label, @date, @stats, @options, @meta) @event = Redistat::Event.new(@scope, @label, @date, @stats, @options, @meta)
@@ -17,7 +17,7 @@ describe Redistat::Event do
it "should initialize properly" do it "should initialize properly" do
@event.id.should be_nil @event.id.should be_nil
@event.scope.should == @scope @event.scope.to_s.should == @scope
@event.label.to_s.should == @label @event.label.to_s.should == @label
@event.label_hash.should == @label_hash @event.label_hash.should == @label_hash
@event.date.to_time.to_s.should == @date.to_s @event.date.to_time.to_s.should == @date.to_s
@@ -63,9 +63,11 @@ describe Redistat::Event do
it "should find event by id" do it "should find event by id" do
@event = Redistat::Event.new(@scope, @label, @date, @stats, @options.merge({:store_event => true}), @meta).save @event = Redistat::Event.new(@scope, @label, @date, @stats, @options.merge({:store_event => true}), @meta).save
fetched = Redistat::Event.find(@scope, @event.id) fetched = Redistat::Event.find(@scope, @event.id)
@event.scope.should == fetched.scope @event.scope.to_s.should == fetched.scope.to_s
@event.label.to_s.should == fetched.label.to_s @event.label.to_s.should == fetched.label.to_s
@event.date.to_s.should == fetched.date.to_s @event.date.to_s.should == fetched.date.to_s
@event.stats.should == fetched.stats
@event.meta.should == fetched.meta
end end
it "should store summarized statistics" do it "should store summarized statistics" do

View File

@@ -28,11 +28,13 @@ describe Redistat::Finder::DateSet do
result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :hour, true) result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :hour, true)
result[0][:add].should == ["2010082818", "2010082819", "2010082820", "2010082821", "2010082822"] result[0][:add].should == ["2010082818", "2010082819", "2010082820", "2010082821", "2010082822"]
result[0][:rem].should == [] result[0][:rem].should == []
result.should == Redistat::Finder::DateSet.new(t_start, t_end, nil, :hour)
t_end = t_start + 4.days t_end = t_start + 4.days
result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :day, true) result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :day, true)
result[0][:add].should == ["20100828", "20100829", "20100830", "20100831", "20100901"] result[0][:add].should == ["20100828", "20100829", "20100830", "20100831", "20100901"]
result[0][:rem].should == [] result[0][:rem].should == []
result.should == Redistat::Finder::DateSet.new(t_start, t_end, nil, :day)
end end
it "should find start keys properly" do it "should find start keys properly" do

View File

@@ -25,31 +25,36 @@ describe Redistat::Finder do
finder.options[:label].to_s.should == options[:label] finder.options[:label].to_s.should == options[:label]
finder.options.should == options.merge(:scope => finder.options[:scope], :label => finder.options[:label]) finder.options.should == options.merge(:scope => finder.options[:scope], :label => finder.options[:label])
finder = Redistat::Finder.scope("hello")
finder.options[:scope].to_s.should == "hello"
finder.scope.to_s.should == "hello"
finder = Redistat::Finder.label("hello")
finder.options[:label].to_s.should == "hello"
finder.label.to_s.should == "hello"
finder = Redistat::Finder.dates(@two_hours_ago, @one_hour_ago) finder = Redistat::Finder.dates(@two_hours_ago, @one_hour_ago)
finder.options[:from].should == @two_hours_ago finder.options[:from].should == @two_hours_ago
finder.options[:till].should == @one_hour_ago finder.options[:till].should == @one_hour_ago
finder = Redistat::Finder.scope("hello")
finder.options[:scope].to_s.should == "hello"
finder = Redistat::Finder.label("hello")
finder.options[:label].to_s.should == "hello"
finder = Redistat::Finder.from(@two_hours_ago) finder = Redistat::Finder.from(@two_hours_ago)
finder.options[:from].should == @two_hours_ago finder.options[:from].should == @two_hours_ago
finder.from.should == @two_hours_ago
finder = Redistat::Finder.till(@one_hour_ago) finder = Redistat::Finder.till(@one_hour_ago)
finder.options[:till].should == @one_hour_ago finder.options[:till].should == @one_hour_ago
finder.till.should == @one_hour_ago
finder = Redistat::Finder.depth(:hour) finder = Redistat::Finder.depth(:hour)
finder.options[:depth].should == :hour finder.options[:depth].should == :hour
finder.depth.should == :hour
finder = Redistat::Finder.interval(true) finder = Redistat::Finder.interval(true)
finder.options[:interval].should be_true finder.options[:interval].should be_true
finder.interval.should be_true
finder = Redistat::Finder.interval(false) finder = Redistat::Finder.interval(false)
finder.options[:interval].should be_false finder.options[:interval].should be_false
finder.interval.should be_false
end end
it "should fetch stats properly" do it "should fetch stats properly" do

View File

@@ -13,7 +13,7 @@ describe Redistat::Key do
end end
it "should initialize properly" do it "should initialize properly" do
@key.scope.should == @scope @key.scope.to_s.should == @scope
@key.label.to_s.should == @label @key.label.to_s.should == @label
@key.label_hash.should == @label_hash @key.label_hash.should == @label_hash
@key.groups.map { |k| k.instance_variable_get("@label") }.should == @key.instance_variable_get("@label").groups @key.groups.map { |k| k.instance_variable_get("@label") }.should == @key.instance_variable_get("@label").groups
@@ -28,6 +28,8 @@ describe Redistat::Key do
@key.to_s(props.last).should == "#{@scope}/#{@label}:#{@key.date.to_s(props.last)}" @key.to_s(props.last).should == "#{@scope}/#{@label}:#{@key.date.to_s(props.last)}"
props.pop props.pop
end end
key = Redistat::Key.new(@scope, nil, @date, {:depth => :hour})
key.to_s.should == "#{@scope}:#{key.date.to_s(:hour)}"
end end
it "should abide to hashed_label option" do it "should abide to hashed_label option" do
@@ -44,10 +46,10 @@ describe Redistat::Key do
it "should allow changing attributes" do it "should allow changing attributes" do
# scope # scope
@key.scope.should == @scope @key.scope.to_s.should == @scope
@scope = "VisitorCount" @scope = "VisitorCount"
@key.scope = @scope @key.scope = @scope
@key.scope.should == @scope @key.scope.to_s.should == @scope
# date # date
@key.date.to_time.to_s.should == @date.to_s @key.date.to_time.to_s.should == @date.to_s
@date = Time.now @date = Time.now

View File

@@ -25,6 +25,19 @@ describe Redistat::Label do
db.hget(Redistat::KEY_LABELS, label.hash).should == name db.hget(Redistat::KEY_LABELS, label.hash).should == name
end end
it "should join labels" do
include Redistat
label = Label.join('email', 'message', 'public')
label.should be_a(Label)
label.to_s.should == 'email/message/public'
label = Label.join(Label.new('email'), Label.new('message'), Label.new('public'))
label.should be_a(Label)
label.to_s.should == 'email/message/public'
label = Label.join('email', '', 'message', nil, 'public')
label.should be_a(Label)
label.to_s.should == 'email/message/public'
end
describe "Grouping" do describe "Grouping" do
before(:each) do before(:each) do
@name = "message/public/offensive" @name = "message/public/offensive"

View File

@@ -28,6 +28,11 @@ describe Redistat::Model do
finder.options[:till].should == one_hour_ago finder.options[:till].should == one_hour_ago
end end
it "should #find_event" do
Redistat::Event.should_receive(:find).with('ModelHelper1', 1)
ModelHelper1.find_event(1)
end
it "should listen to model-defined options" do it "should listen to model-defined options" do
ModelHelper2.depth.should == :day ModelHelper2.depth.should == :day
ModelHelper2.store_event.should == true ModelHelper2.store_event.should == true

View File

@@ -46,6 +46,15 @@ describe Redistat::Summary do
end end
end end
it "should update summaries even if no label is set" do
key = Redistat::Key.new(@scope, nil, @date, {:depth => :day})
Redistat::Summary.update(key, @stats, :hour)
summary = db.hgetall(key.to_s(:hour))
summary.should have(2).items
summary["views"].should == "3"
summary["visitors"].should == "2"
end
it "should inject stats key grouping summaries" do it "should inject stats key grouping summaries" do
hash = { "count/hello" => 3, "count/world" => 7, hash = { "count/hello" => 3, "count/world" => 7,
"death/bomb" => 4, "death/unicorn" => 3, "death/bomb" => 4, "death/unicorn" => 3,