Permalink
Browse files

Add ability to pull version history out of SQL

  • Loading branch information...
1 parent 5438426 commit 1312f809fe745368d0dfef41252730796bb4bd6b @evanphx evanphx committed Sep 15, 2012
View
@@ -54,22 +54,48 @@ def self.most_downloaded_all_time(n=5)
def self.counts_by_day_for_versions(versions, days)
dates = (days.days.ago.to_date...Time.zone.today).map(&:to_s)
- versions.inject({}) do |downloads, version|
- $redis.hmget(self.history_key(version), *dates).each_with_index do |count, idx|
- downloads["#{version.id}-#{dates[idx]}"] = count.to_i
+ downloads = {}
+ versions.each do |version|
+ key = history_key(version)
+
+ $redis.hmget(key, *dates).zip(dates).each do |count, date|
+ if count
+ count = count.to_i
+ else
+ vh = VersionHistory.where(:version_id => version.id,
+ :day => date).first
+
+ count = vh ? vh.count : 0
+ end
+
+ downloads["#{version.id}-#{date}"] = count
end
downloads["#{version.id}-#{Time.zone.today}"] = self.today(version)
- downloads
end
+
+ downloads
end
def self.counts_by_day_for_version_in_date_range(version, start, stop)
downloads = ActiveSupport::OrderedHash.new
dates = (start..stop).map(&:to_s)
- $redis.hmget(self.history_key(version), *dates).each_with_index do |count, idx|
- downloads["#{dates[idx]}"] = count.to_i
+ $redis.hmget(history_key(version), *dates).zip(dates).each do |count, date|
+ if count
+ count = count.to_i
+ else
+ vh = VersionHistory.where(:version_id => version.id,
+ :day => date).first
+
+ if vh
+ count = vh.count
+ else
+ count = 0
+ end
+ end
+
+ downloads[date] = count
end
if stop == Time.zone.today
@@ -90,6 +116,8 @@ def self.key(what)
version_key(what.full_name)
when Rubygem
rubygem_key(what.name)
+ else
+ raise TypeError, "Unknown type for key - #{what.class}"
end
end
@@ -99,6 +127,8 @@ def self.history_key(what)
version_history_key(what.full_name)
when Rubygem
rubygem_history_key(what.name)
+ else
+ raise TypeError, "Unknown type for history_key - #{what.class}"
end
end
@@ -0,0 +1,4 @@
+class VersionHistory < ActiveRecord::Base
+ attr_accessible :count, :day, :version_id
+ belongs_to :version
+end
@@ -0,0 +1,11 @@
+class CreateVersionHistories < ActiveRecord::Migration
+ def change
+ create_table :version_histories do |t|
+ t.integer :version_id
+ t.date :day
+ t.integer :count
+
+ t.timestamps
+ end
+ end
+end
@@ -0,0 +1,9 @@
+class AddVersionHistoryIndexes < ActiveRecord::Migration
+ def up
+ add_index :version_histories, [:version_id, :day], :unique => true
+ end
+
+ def down
+ remove_index :version_histories, :column => [:version_id, :day]
+ end
+end
View
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120118194729) do
+ActiveRecord::Schema.define(:version => 20120915212528) do
create_table "announcements", :force => true do |t|
t.text "body"
@@ -119,6 +119,16 @@
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
add_index "users", ["token"], :name => "index_users_on_token"
+ create_table "version_histories", :force => true do |t|
+ t.integer "version_id"
+ t.date "day"
+ t.integer "count"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ add_index "version_histories", ["version_id", "day"], :name => "index_version_histories_on_version_id_and_day", :unique => true
+
create_table "versions", :force => true do |t|
t.text "authors"
t.text "description"
View
@@ -83,6 +83,11 @@
rubygem
end
+ factory :version_history do
+ day { Time.zone.today.to_s }
+ count 1
+ end
+
sequence :url do |n|
"http://example#{n}.com"
end
View
@@ -132,6 +132,60 @@ class DownloadTest < ActiveSupport::TestCase
assert_equal downloads, Download.counts_by_day_for_versions([@version_1, @version_2, @version_3], 2)
end
+ should "find counts per day for versions when in DB also" do
+ @rubygem_1 = create(:rubygem)
+ @version_1 = create(:version, :rubygem => @rubygem_1)
+ @version_2 = create(:version, :rubygem => @rubygem_1)
+
+ @rubygem_2 = create(:rubygem)
+ @version_3 = create(:version, :rubygem => @rubygem_2)
+
+ @rubygem_3 = create(:rubygem)
+ @version_4 = create(:version, :rubygem => @rubygem_3)
+
+ Timecop.freeze(1.day.ago) do
+ create :version_history, :version => @version_1, :count => 5
+ create :version_history, :version => @version_2
+ create :version_history, :version => @version_3
+ end
+
+ Download.incr(@rubygem_2, @version_3.full_name)
+ Download.incr(@rubygem_1, @version_1.full_name)
+ Download.incr(@rubygem_2, @version_3.full_name)
+ Download.incr(@rubygem_2, @version_3.full_name)
+ Download.incr(@rubygem_1, @version_2.full_name)
+
+ downloads = {
+ "#{@version_1.id}-#{2.days.ago.to_date}" => 0, "#{@version_1.id}-#{Date.yesterday}" => 5, "#{@version_1.id}-#{Time.zone.today}" => 1,
+ "#{@version_2.id}-#{2.days.ago.to_date}" => 0, "#{@version_2.id}-#{Date.yesterday}" => 1, "#{@version_2.id}-#{Time.zone.today}" => 1,
+ "#{@version_3.id}-#{2.days.ago.to_date}" => 0, "#{@version_3.id}-#{Date.yesterday}" => 1, "#{@version_3.id}-#{Time.zone.today}" => 3 }
+
+ assert_equal downloads.size, 9
+ assert_equal downloads, Download.counts_by_day_for_versions([@version_1, @version_2, @version_3], 2)
+ end
+
+ should "find counts per day for versions in range" do
+ @rubygem_1 = create(:rubygem)
+ @version_1 = create(:version, :rubygem => @rubygem_1)
+
+ Timecop.freeze(1.day.ago) do
+ create :version_history, :version => @version_1, :count => 5
+ end
+
+ Download.incr(@rubygem_1, @version_1.full_name)
+
+ start = 2.days.ago.to_date.to_s
+ fin = Time.zone.today.to_s
+
+ downloads = ActiveSupport::OrderedHash.new.tap do |d|
+ d[start] = 0
+ d["#{Date.yesterday}"] = 5
+ d[fin] = 1
+ end
+
+ assert_equal downloads, Download.counts_by_day_for_version_in_date_range(@version_1, start, fin)
+ end
+
should "find download count by gem name" do
rubygem = create(:rubygem)
version1 = create(:version, :rubygem => rubygem)

0 comments on commit 1312f80

Please sign in to comment.