fixed tests, implemented sql based partitioning for favorites
This commit is contained in:
@@ -4,7 +4,7 @@ module PostSets
|
|||||||
|
|
||||||
def initialize(user_id, page = 1)
|
def initialize(user_id, page = 1)
|
||||||
@user = ::User.find(user_id)
|
@user = ::User.find(user_id)
|
||||||
@favorites = ::Favorite.model_for(user.id).for_user(user.id).paginate(page)
|
@favorites = ::Favorite.for_user(user.id).paginate(page)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_array
|
def tag_array
|
||||||
@@ -16,7 +16,7 @@ module PostSets
|
|||||||
end
|
end
|
||||||
|
|
||||||
def posts
|
def posts
|
||||||
favorites.map(&:post)
|
favorites.order("favorites.id desc").includes(:post).map(&:post)
|
||||||
end
|
end
|
||||||
|
|
||||||
def presenter
|
def presenter
|
||||||
|
|||||||
@@ -1,22 +1,4 @@
|
|||||||
class Favorite < ActiveRecord::Base
|
class Favorite < ActiveRecord::Base
|
||||||
TABLE_COUNT = 100
|
|
||||||
belongs_to :post
|
belongs_to :post
|
||||||
|
|
||||||
scope :for_user, lambda {|user_id| where("user_id = ?", user_id)}
|
scope :for_user, lambda {|user_id| where("user_id = ?", user_id)}
|
||||||
|
|
||||||
def self.model_for(user_id)
|
|
||||||
mod = user_id.to_i % TABLE_COUNT
|
|
||||||
Object.const_get("Favorite#{mod}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.delete_post(post_id)
|
|
||||||
0.upto(TABLE_COUNT - 1) do |i|
|
|
||||||
model_for(i).destroy_all(:post_id => post_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
0.upto(Favorite::TABLE_COUNT - 1) do |i|
|
|
||||||
Object.const_set("Favorite#{i}", Class.new(Favorite))
|
|
||||||
Object.const_get("Favorite#{i}").set_table_name("favorites_#{i}")
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ class Post < ActiveRecord::Base
|
|||||||
|
|
||||||
module FavoriteMethods
|
module FavoriteMethods
|
||||||
def delete_favorites
|
def delete_favorites
|
||||||
Favorite.delete_post(id)
|
Favorite.delete_all(:post_id => id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def favorited_by?(user_id)
|
def favorited_by?(user_id)
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ class User < ActiveRecord::Base
|
|||||||
class PrivilegeError < Exception ; end
|
class PrivilegeError < Exception ; end
|
||||||
|
|
||||||
module Levels
|
module Levels
|
||||||
MEMBER = 0
|
MEMBER = 20
|
||||||
PRIVILEGED = 100
|
PRIVILEGED = 30
|
||||||
CONTRIBUTOR = 200
|
CONTRIBUTOR = 33
|
||||||
JANITOR = 300
|
JANITOR = 35
|
||||||
MODERATOR = 400
|
MODERATOR = 40
|
||||||
ADMIN = 500
|
ADMIN = 50
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :password, :old_password
|
attr_accessor :password, :old_password
|
||||||
@@ -128,18 +128,18 @@ class User < ActiveRecord::Base
|
|||||||
|
|
||||||
module FavoriteMethods
|
module FavoriteMethods
|
||||||
def favorites
|
def favorites
|
||||||
Favorite.model_for(id).where("user_id = ?", id).order("id desc")
|
Favorite.where("user_id = ?", id).order("id desc")
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_favorite!(post)
|
def add_favorite!(post)
|
||||||
return if Favorite.model_for(id).exists?(:user_id => id, :post_id => post.id)
|
return if Favorite.exists?(:user_id => id, :post_id => post.id)
|
||||||
Favorite.model_for(id).create(:user_id => id, :post_id => post.id)
|
Favorite.create(:user_id => id, :post_id => post.id)
|
||||||
post.add_favorite!(self)
|
post.add_favorite!(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_favorite!(post)
|
def remove_favorite!(post)
|
||||||
return unless Favorite.model_for(id).exists?(:user_id => id, :post_id => post.id)
|
return unless Favorite.exists?(:user_id => id, :post_id => post.id)
|
||||||
Favorite.model_for(id).destroy_all(:user_id => id, :post_id => post.id)
|
Favorite.destroy_all(:user_id => id, :post_id => post.id)
|
||||||
post.remove_favorite!(self)
|
post.remove_favorite!(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ Bundler.require(:default, Rails.env) if defined?(Bundler)
|
|||||||
|
|
||||||
module Danbooru
|
module Danbooru
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
|
config.active_record.schema_format = :sql
|
||||||
config.encoding = "utf-8"
|
config.encoding = "utf-8"
|
||||||
config.filter_parameters += [:password]
|
config.filter_parameters += [:password]
|
||||||
config.assets.enabled = true
|
config.assets.enabled = true
|
||||||
config.autoload_paths += %W(#{config.root}/app/presenters #{config.root}/app/logical)
|
config.autoload_paths += %W(#{config.root}/app/presenters #{config.root}/app/logical)
|
||||||
config.plugins = [:all]
|
config.plugins = [:all]
|
||||||
config.time_zone = 'Eastern Time (US & Canada)'
|
config.time_zone = 'Eastern Time (US & Canada)'
|
||||||
config.active_record.schema_format = :sql
|
|
||||||
# config.action_view.javascript_expansions[:defaults] = [
|
# config.action_view.javascript_expansions[:defaults] = [
|
||||||
# "src/lib/jquery-1.6.0.min.js",
|
# "src/lib/jquery-1.6.0.min.js",
|
||||||
# "src/lib/jquery-ui-1.8.9.custom.min.js",
|
# "src/lib/jquery-ui-1.8.9.custom.min.js",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,14 +9,44 @@ class CreateFavorites < ActiveRecord::Migration
|
|||||||
end
|
end
|
||||||
|
|
||||||
0.upto(TABLE_COUNT - 1) do |i|
|
0.upto(TABLE_COUNT - 1) do |i|
|
||||||
create_table "favorites_#{i}" do |t|
|
execute <<-EOS
|
||||||
t.column :user_id, :integer
|
create table favorites_#{i} (
|
||||||
t.column :post_id, :integer
|
check (user_id % 100 = #{i})
|
||||||
end
|
) inherits (favorites)
|
||||||
|
EOS
|
||||||
|
|
||||||
add_index "favorites_#{i}", :user_id
|
add_index "favorites_#{i}", :user_id
|
||||||
add_index "favorites_#{i}", :post_id
|
add_index "favorites_#{i}", :post_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fragment = []
|
||||||
|
|
||||||
|
1.upto(TABLE_COUNT - 1) do |i|
|
||||||
|
fragment << <<-EOS
|
||||||
|
elsif (NEW.user_id % 100 = #{i}) then
|
||||||
|
insert into favorites_#{i} values (NEW.*);
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
execute <<-EOS
|
||||||
|
create or replace function favorites_insert_trigger()
|
||||||
|
returns trigger as $$
|
||||||
|
begin
|
||||||
|
if (NEW.user_id % 100 = 0) then
|
||||||
|
insert into favorites_0 values (NEW.*);
|
||||||
|
#{fragment.join("\n")}
|
||||||
|
end if;
|
||||||
|
return NULL;
|
||||||
|
end;
|
||||||
|
$$
|
||||||
|
language plpgsql
|
||||||
|
EOS
|
||||||
|
|
||||||
|
execute <<-EOS
|
||||||
|
create trigger insert_favorites_trigger
|
||||||
|
before insert on favorites
|
||||||
|
for each row execute procedure favorites_insert_trigger()
|
||||||
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def self.down
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace :db do
|
|
||||||
namespace :test do
|
|
||||||
task :reset => [:environment, "db:drop", "db:create", "db:migrate", "db:structure:dump", "db:test:clone_structure"] do
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -24,8 +24,8 @@ module PostSets
|
|||||||
|
|
||||||
context "a favorite set for before the most recent post" do
|
context "a favorite set for before the most recent post" do
|
||||||
setup do
|
setup do
|
||||||
id = ::Favorite.model_for(@user.id).where(:user_id => @user.id, :post_id => @post_3.id).first.id
|
id = ::Favorite.where(:user_id => @user.id, :post_id => @post_3.id).first.id
|
||||||
::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1)
|
::Favorite.stubs(:records_per_page).returns(1)
|
||||||
@set = PostSets::Favorite.new(@user.id, "b#{id}")
|
@set = PostSets::Favorite.new(@user.id, "b#{id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ module PostSets
|
|||||||
|
|
||||||
context "a favorite set for after the second most recent post" do
|
context "a favorite set for after the second most recent post" do
|
||||||
setup do
|
setup do
|
||||||
id = ::Favorite.model_for(@user.id).where(:user_id => @user.id, :post_id => @post_2.id).first.id
|
id = ::Favorite.where(:user_id => @user.id, :post_id => @post_2.id).first.id
|
||||||
::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1)
|
::Favorite.stubs(:records_per_page).returns(1)
|
||||||
@set = PostSets::Favorite.new(@user.id, "a#{id}")
|
@set = PostSets::Favorite.new(@user.id, "a#{id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ module PostSets
|
|||||||
|
|
||||||
context "a favorite set for page 2" do
|
context "a favorite set for page 2" do
|
||||||
setup do
|
setup do
|
||||||
::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1)
|
::Favorite.stubs(:records_per_page).returns(1)
|
||||||
@set = PostSets::Favorite.new(@user.id, 2)
|
@set = PostSets::Favorite.new(@user.id, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ module PostSets
|
|||||||
|
|
||||||
context "a favorite set with no page specified" do
|
context "a favorite set with no page specified" do
|
||||||
setup do
|
setup do
|
||||||
::Favorite.model_for(@user.id).stubs(:records_per_page).returns(1)
|
::Favorite.stubs(:records_per_page).returns(1)
|
||||||
@set = PostSets::Favorite.new(@user.id)
|
@set = PostSets::Favorite.new(@user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
c1.add_favorite!(user)
|
c1.add_favorite!(user)
|
||||||
c1.delete!
|
c1.delete!
|
||||||
p1.reload
|
p1.reload
|
||||||
assert(!Favorite.model_for(user.id).exists?(:post_id => c1.id, :user_id => user.id))
|
assert(!Favorite.exists?(:post_id => c1.id, :user_id => user.id))
|
||||||
assert(Favorite.model_for(user.id).exists?(:post_id => p1.id, :user_id => user.id))
|
assert(Favorite.exists?(:post_id => p1.id, :user_id => user.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
should "update the parent's has_children flag" do
|
should "update the parent's has_children flag" do
|
||||||
@@ -335,22 +335,22 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
post.add_favorite!(user)
|
post.add_favorite!(user)
|
||||||
post.reload
|
post.reload
|
||||||
assert_equal("fav:#{user.id}", post.fav_string)
|
assert_equal("fav:#{user.id}", post.fav_string)
|
||||||
assert(Favorite.model_for(user.id).exists?(:user_id => user.id, :post_id => post.id))
|
assert(Favorite.exists?(:user_id => user.id, :post_id => post.id))
|
||||||
|
|
||||||
post.add_favorite!(user)
|
post.add_favorite!(user)
|
||||||
post.reload
|
post.reload
|
||||||
assert_equal("fav:#{user.id}", post.fav_string)
|
assert_equal("fav:#{user.id}", post.fav_string)
|
||||||
assert(Favorite.model_for(user.id).exists?(:user_id => user.id, :post_id => post.id))
|
assert(Favorite.exists?(:user_id => user.id, :post_id => post.id))
|
||||||
|
|
||||||
post.remove_favorite!(user)
|
post.remove_favorite!(user)
|
||||||
post.reload
|
post.reload
|
||||||
assert_equal("", post.fav_string)
|
assert_equal("", post.fav_string)
|
||||||
assert(!Favorite.model_for(user.id).exists?(:user_id => user.id, :post_id => post.id))
|
assert(!Favorite.exists?(:user_id => user.id, :post_id => post.id))
|
||||||
|
|
||||||
post.remove_favorite!(user)
|
post.remove_favorite!(user)
|
||||||
post.reload
|
post.reload
|
||||||
assert_equal("", post.fav_string)
|
assert_equal("", post.fav_string)
|
||||||
assert(!Favorite.model_for(user.id).exists?(:user_id => user.id, :post_id => post.id))
|
assert(!Favorite.exists?(:user_id => user.id, :post_id => post.id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user