activerecord-turntable 1.1.2 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.travis.yml +3 -5
- data/CHANGELOG.md +70 -0
- data/Guardfile +7 -5
- data/README.md +490 -0
- data/Rakefile +37 -22
- data/activerecord-turntable.gemspec +37 -34
- data/gemfiles/rails4_0.gemfile +6 -0
- data/gemfiles/rails4_1.gemfile +6 -0
- data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +14 -29
- data/lib/active_record/turntable/active_record_ext/activerecord_import_ext.rb +45 -0
- data/lib/active_record/turntable/active_record_ext/acts_as_archive_extension.rb +21 -0
- data/lib/active_record/turntable/active_record_ext/association.rb +85 -0
- data/lib/active_record/turntable/active_record_ext/association_preloader.rb +37 -0
- data/lib/active_record/turntable/active_record_ext/clever_load.rb +33 -76
- data/lib/active_record/turntable/active_record_ext/connection_handler_extension.rb +31 -0
- data/lib/active_record/turntable/active_record_ext/database_tasks.rb +81 -0
- data/lib/active_record/turntable/active_record_ext/fixtures.rb +54 -42
- data/lib/active_record/turntable/active_record_ext/locking_optimistic.rb +101 -0
- data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +28 -46
- data/lib/active_record/turntable/active_record_ext/migration_proxy.rb +7 -0
- data/lib/active_record/turntable/active_record_ext/persistence.rb +96 -94
- data/lib/active_record/turntable/active_record_ext/relation.rb +31 -0
- data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +18 -28
- data/lib/active_record/turntable/active_record_ext/transactions.rb +9 -3
- data/lib/active_record/turntable/active_record_ext.rb +26 -11
- data/lib/active_record/turntable/algorithm/base.rb +1 -1
- data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +1 -1
- data/lib/active_record/turntable/algorithm.rb +7 -3
- data/lib/active_record/turntable/base.rb +67 -14
- data/lib/active_record/turntable/cluster.rb +46 -2
- data/lib/active_record/turntable/config.rb +1 -1
- data/lib/active_record/turntable/connection_proxy/mixable.rb +7 -29
- data/lib/active_record/turntable/connection_proxy.rb +61 -72
- data/lib/active_record/turntable/error.rb +5 -6
- data/lib/active_record/turntable/helpers.rb +5 -1
- data/lib/active_record/turntable/migration.rb +9 -49
- data/lib/active_record/turntable/mixer/fader/calculate_shards_sum_result.rb +13 -2
- data/lib/active_record/turntable/mixer/fader/select_shards_merge_result.rb +17 -6
- data/lib/active_record/turntable/mixer/fader/specified_shard.rb +3 -1
- data/lib/active_record/turntable/mixer/fader.rb +12 -10
- data/lib/active_record/turntable/mixer.rb +59 -29
- data/lib/active_record/turntable/plugin.rb +6 -0
- data/lib/active_record/turntable/pool_proxy.rb +12 -19
- data/lib/active_record/turntable/rack/query_cache.rb +20 -23
- data/lib/active_record/turntable/rack.rb +4 -2
- data/lib/active_record/turntable/railtie.rb +4 -3
- data/lib/active_record/turntable/railties/databases.rake +81 -122
- data/lib/active_record/turntable/seq_shard.rb +1 -1
- data/lib/active_record/turntable/sequencer/api.rb +1 -1
- data/lib/active_record/turntable/sequencer/barrage.rb +28 -0
- data/lib/active_record/turntable/sequencer.rb +27 -9
- data/lib/active_record/turntable/shard.rb +2 -2
- data/lib/active_record/turntable/sql_tree_patch.rb +1 -1
- data/lib/active_record/turntable/version.rb +1 -1
- data/lib/active_record/turntable.rb +26 -16
- data/lib/generators/templates/turntable.yml +9 -7
- data/spec/active_record/turntable/active_record_ext/association_preloader_spec.rb +78 -0
- data/spec/active_record/turntable/active_record_ext/association_spec.rb +72 -0
- data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +25 -46
- data/spec/active_record/turntable/active_record_ext/locking_optimistic_spec.rb +28 -0
- data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +46 -25
- data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +4 -4
- data/spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb +35 -0
- data/spec/active_record/turntable/algorithm_spec.rb +28 -12
- data/spec/active_record/turntable/base_spec.rb +1 -1
- data/spec/active_record/turntable/cluster_spec.rb +27 -5
- data/spec/active_record/turntable/config_spec.rb +2 -2
- data/spec/active_record/turntable/connection_proxy_spec.rb +112 -45
- data/spec/active_record/turntable/finder_spec.rb +24 -11
- data/spec/active_record/turntable/mixer_spec.rb +21 -21
- data/spec/active_record/turntable/rack/query_cache_spec.rb +19 -0
- data/spec/active_record/turntable/sequencer/api_spec.rb +38 -0
- data/spec/active_record/turntable/sequencer/barrage_spec.rb +22 -0
- data/spec/active_record/turntable/sequencer/mysql_spec.rb +22 -0
- data/spec/active_record/turntable/shard_spec.rb +1 -1
- data/spec/active_record/turntable/transaction_spec.rb +35 -0
- data/spec/active_record/turntable_spec.rb +4 -4
- data/spec/config/database.yml +24 -34
- data/spec/config/turntable.yml +18 -1
- data/spec/fabricators/turntable_fabricator.rb +0 -2
- data/spec/models/card.rb +3 -0
- data/spec/models/cards_user.rb +10 -0
- data/spec/models/cards_users_histories.rb +7 -0
- data/spec/models/events_users_history.rb +7 -0
- data/spec/models/user.rb +7 -0
- data/spec/models/user_status.rb +6 -0
- data/spec/spec_helper.rb +10 -4
- data/spec/support/matchers/be_saved_to.rb +6 -0
- data/spec/support/turntable_helper.rb +29 -0
- metadata +124 -74
- data/README.rdoc +0 -294
- data/gemfiles/rails3_0.gemfile +0 -7
- data/gemfiles/rails3_1.gemfile +0 -6
- data/gemfiles/rails3_2.gemfile +0 -6
- data/lib/active_record/turntable/compatible.rb +0 -19
- data/sample_app/.gitignore +0 -16
- data/sample_app/Gemfile +0 -41
- data/sample_app/README.rdoc +0 -261
- data/sample_app/Rakefile +0 -7
- data/sample_app/app/assets/images/rails.png +0 -0
- data/sample_app/app/assets/javascripts/application.js +0 -15
- data/sample_app/app/assets/stylesheets/application.css +0 -13
- data/sample_app/app/controllers/application_controller.rb +0 -3
- data/sample_app/app/helpers/application_helper.rb +0 -2
- data/sample_app/app/mailers/.gitkeep +0 -0
- data/sample_app/app/models/.gitkeep +0 -0
- data/sample_app/app/models/user.rb +0 -4
- data/sample_app/app/views/layouts/application.html.erb +0 -14
- data/sample_app/config/application.rb +0 -65
- data/sample_app/config/boot.rb +0 -6
- data/sample_app/config/database.yml +0 -70
- data/sample_app/config/environment.rb +0 -5
- data/sample_app/config/environments/development.rb +0 -37
- data/sample_app/config/environments/production.rb +0 -67
- data/sample_app/config/environments/test.rb +0 -37
- data/sample_app/config/initializers/backtrace_silencers.rb +0 -7
- data/sample_app/config/initializers/inflections.rb +0 -15
- data/sample_app/config/initializers/mime_types.rb +0 -5
- data/sample_app/config/initializers/secret_token.rb +0 -7
- data/sample_app/config/initializers/session_store.rb +0 -8
- data/sample_app/config/initializers/wrap_parameters.rb +0 -14
- data/sample_app/config/locales/en.yml +0 -5
- data/sample_app/config/routes.rb +0 -58
- data/sample_app/config/turntable.yml +0 -64
- data/sample_app/config.ru +0 -4
- data/sample_app/db/migrate/20120316073058_create_users.rb +0 -11
- data/sample_app/db/seeds.rb +0 -7
- data/sample_app/lib/assets/.gitkeep +0 -0
- data/sample_app/lib/tasks/.gitkeep +0 -0
- data/sample_app/log/.gitkeep +0 -0
- data/sample_app/public/404.html +0 -26
- data/sample_app/public/422.html +0 -26
- data/sample_app/public/500.html +0 -25
- data/sample_app/public/favicon.ico +0 -0
- data/sample_app/public/index.html +0 -241
- data/sample_app/public/robots.txt +0 -5
- data/sample_app/script/rails +0 -6
- data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
- data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/sample_app/vendor/plugins/.gitkeep +0 -0
- data/spec/test_models.rb +0 -27
- data/spec/turntable_helper.rb +0 -29
data/Rakefile
CHANGED
@@ -7,6 +7,9 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
7
7
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
8
8
|
end
|
9
9
|
|
10
|
+
require 'active_record'
|
11
|
+
require "active_record/turntable/active_record_ext/database_tasks"
|
12
|
+
|
10
13
|
namespace :turntable do
|
11
14
|
namespace :db do
|
12
15
|
task :rails_env do
|
@@ -16,32 +19,34 @@ namespace :turntable do
|
|
16
19
|
end
|
17
20
|
|
18
21
|
task :load_config => :rails_env do
|
19
|
-
|
20
|
-
ActiveRecord::Base.configurations = YAML.
|
22
|
+
yaml_file = File.join(File.dirname(__FILE__), 'spec/config/database.yml')
|
23
|
+
ActiveRecord::Base.configurations = YAML.load ERB.new(IO.read(yaml_file)).result
|
21
24
|
end
|
22
25
|
|
23
26
|
desc "create turntable test database"
|
24
27
|
task :create => :load_config do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current(RAILS_ENV)
|
29
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current_turntable_cluster(RAILS_ENV)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "drop turntable test database"
|
33
|
+
task :drop => :load_config do
|
34
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current(RAILS_ENV)
|
35
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current_turntable_cluster(RAILS_ENV)
|
33
36
|
end
|
34
37
|
|
35
38
|
desc "migrate turntable test tables"
|
36
39
|
task :migrate => :load_config do
|
37
|
-
ActiveRecord::Base.establish_connection RAILS_ENV
|
40
|
+
ActiveRecord::Base.establish_connection RAILS_ENV.to_sym
|
38
41
|
require 'active_record/turntable'
|
39
42
|
ActiveRecord::Base.send(:include, ActiveRecord::Turntable)
|
40
43
|
ActiveRecord::ConnectionAdapters::SchemaStatements.send(:include, ActiveRecord::Turntable::Migration::SchemaStatementsExt)
|
41
|
-
database_configs = [ActiveRecord::Base.configurations[RAILS_ENV]] + ActiveRecord::Base.configurations[RAILS_ENV]["shards"].values + ActiveRecord::Base.configurations[RAILS_ENV]["seq"].values
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
+
configurations = [ActiveRecord::Base.configurations[RAILS_ENV]]
|
46
|
+
configurations += ActiveRecord::Tasks::DatabaseTasks.current_turntable_cluster_configurations(RAILS_ENV).map {|v| v[1]}.flatten.uniq
|
47
|
+
|
48
|
+
configurations.each do |configuration|
|
49
|
+
ActiveRecord::Base.establish_connection configuration
|
45
50
|
|
46
51
|
ActiveRecord::Base.connection.create_table :users do |t|
|
47
52
|
t.string :nickname
|
@@ -56,6 +61,7 @@ namespace :turntable do
|
|
56
61
|
t.belongs_to :user, :null => false
|
57
62
|
t.integer :hp, :null => false, :default => 0
|
58
63
|
t.integer :mp, :null => false, :default => 0
|
64
|
+
t.integer :lock_version, :null => false, :default => 0
|
59
65
|
t.datetime :deleted_at, :default => nil
|
60
66
|
t.timestamps
|
61
67
|
end
|
@@ -89,21 +95,30 @@ namespace :turntable do
|
|
89
95
|
t.datetime :deleted_at, :default => nil
|
90
96
|
end
|
91
97
|
ActiveRecord::Base.connection.create_sequence_for :archived_cards_users
|
98
|
+
|
99
|
+
ActiveRecord::Base.connection.create_table :cards_users_histories do |t|
|
100
|
+
t.belongs_to :cards_user, :null => false
|
101
|
+
t.belongs_to :user, :null => false
|
102
|
+
t.timestamps
|
103
|
+
end
|
104
|
+
ActiveRecord::Base.connection.create_sequence_for :cards_users_histories
|
105
|
+
|
106
|
+
ActiveRecord::Base.connection.create_table :events_users_histories do |t|
|
107
|
+
t.belongs_to :events_user, :null => false
|
108
|
+
t.belongs_to :cards_user, :null => false
|
109
|
+
t.belongs_to :user, :null => false
|
110
|
+
t.timestamps
|
111
|
+
end
|
112
|
+
ActiveRecord::Base.connection.create_sequence_for :events_users_histories
|
92
113
|
end
|
93
114
|
end
|
94
115
|
|
95
116
|
desc "drop turntable test database"
|
96
117
|
task :drop => :load_config do
|
97
|
-
|
98
|
-
database_configs.each do |dbconf|
|
99
|
-
command = "mysql "
|
100
|
-
command << "-u #{dbconf["username"]} " if dbconf["username"]
|
101
|
-
command << "-p#{dbconf["password"]} " if dbconf["password"]
|
102
|
-
command << "-h #{dbconf["host"]}" if dbconf["host"]
|
103
|
-
%x{ echo "DROP DATABASE #{dbconf["database"]}" | #{command} }
|
104
|
-
end
|
118
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current_turntable_cluster(RAILS_ENV)
|
105
119
|
end
|
106
120
|
|
121
|
+
desc "reset turntable test databases"
|
107
122
|
task :reset => ["turntable:db:drop", "turntable:db:create", "turntable:db:migrate"]
|
108
123
|
end
|
109
124
|
end
|
@@ -1,48 +1,51 @@
|
|
1
1
|
$:.push File.expand_path("../lib", __FILE__)
|
2
2
|
require "active_record/turntable/version"
|
3
3
|
|
4
|
-
Gem::Specification.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "activerecord-turntable"
|
6
|
+
spec.version = ActiveRecord::Turntable::VERSION
|
7
|
+
spec.authors = ["gussan", "sue445"]
|
8
|
+
spec.homepage = "https://github.com/drecom/activerecord-turntable"
|
9
|
+
spec.summary = %q{ActiveRecord sharding extension}
|
10
|
+
spec.description = %q{ActiveRecord sharding extension}
|
11
|
+
spec.license = "MIT"
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
spec.rubyforge_project = "activerecord-turntable"
|
14
|
+
spec.extra_rdoc_files = [
|
14
15
|
"LICENSE.txt",
|
15
|
-
"README.
|
16
|
+
"README.md",
|
16
17
|
"CHANGELOG.md"
|
17
18
|
]
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
s.licenses = ["MIT"]
|
24
|
-
s.rubygems_version = "1.8.16"
|
20
|
+
spec.files = `git ls-files`.split($/)
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
+
spec.require_paths = ["lib"]
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
s.add_runtime_dependency(%q<httpclient>, [">= 0"])
|
25
|
+
spec.add_dependency "activerecord", ">= 4.0.0"
|
26
|
+
spec.add_dependency "activesupport", ">= 4.0.0"
|
27
|
+
spec.add_dependency "sql_tree", "= 0.2.0"
|
28
|
+
spec.add_dependency "bsearch", "~> 1.5"
|
29
|
+
spec.add_dependency "httpclient", ">= 0"
|
32
30
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
# optional dependencies
|
32
|
+
spec.add_development_dependency "activerecord-import"
|
33
|
+
spec.add_development_dependency "barrage"
|
34
|
+
spec.add_development_dependency "mysql2"
|
35
|
+
|
36
|
+
spec.add_development_dependency "rake"
|
37
|
+
spec.add_development_dependency "rack"
|
38
|
+
spec.add_development_dependency "rspec", "~> 3.1.0"
|
39
|
+
spec.add_development_dependency "rspec-its"
|
40
|
+
spec.add_development_dependency "rspec-collection_matchers"
|
41
|
+
spec.add_development_dependency "fabrication"
|
42
|
+
spec.add_development_dependency "faker"
|
43
|
+
spec.add_development_dependency "webmock"
|
44
|
+
spec.add_development_dependency "pry"
|
45
|
+
spec.add_development_dependency "guard-rspec"
|
46
|
+
spec.add_development_dependency "coveralls"
|
44
47
|
|
45
48
|
if RUBY_PLATFORM =~ /darwin/
|
46
|
-
|
49
|
+
spec.add_development_dependency "growl"
|
47
50
|
end
|
48
51
|
end
|
@@ -6,35 +6,20 @@ module ActiveRecord::Turntable
|
|
6
6
|
included do
|
7
7
|
protected
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def log(sql, name = "SQL", binds = [])
|
24
|
-
@instrumenter.instrument(
|
25
|
-
"sql.active_record",
|
26
|
-
:sql => sql,
|
27
|
-
:name => name,
|
28
|
-
:connection_id => object_id,
|
29
|
-
:binds => binds,
|
30
|
-
:turntable_shard_name => turntable_shard_name) { yield }
|
31
|
-
rescue Exception => e
|
32
|
-
message = "#{e.class.name}: #{e.message}: #{sql} : #{turntable_shard_name}"
|
33
|
-
@logger.debug message if @logger
|
34
|
-
exception = translate_exception(e, message)
|
35
|
-
exception.set_backtrace e.backtrace
|
36
|
-
raise exception
|
37
|
-
end
|
9
|
+
def log(sql, name = "SQL", binds = [])
|
10
|
+
@instrumenter.instrument(
|
11
|
+
"sql.active_record",
|
12
|
+
:sql => sql,
|
13
|
+
:name => name,
|
14
|
+
:connection_id => object_id,
|
15
|
+
:binds => binds,
|
16
|
+
:turntable_shard_name => turntable_shard_name) { yield }
|
17
|
+
rescue Exception => e
|
18
|
+
message = "#{e.class.name}: #{e.message}: #{sql} : #{turntable_shard_name}"
|
19
|
+
@logger.debug message if @logger
|
20
|
+
exception = translate_exception(e, message)
|
21
|
+
exception.set_backtrace e.backtrace
|
22
|
+
raise exception
|
38
23
|
end
|
39
24
|
end
|
40
25
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveRecord::Turntable
|
2
|
+
module ActiveRecordExt
|
3
|
+
module ActiverecordImportExt
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
alias_method_chain :values_sql_for_columns_and_attributes, :turntable
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def values_sql_for_columns_and_attributes_with_turntable(columns, array_of_attributes)
|
13
|
+
connection_memo = connection
|
14
|
+
array_of_attributes.map do |arr|
|
15
|
+
my_values = arr.each_with_index.map do |val,j|
|
16
|
+
column = columns[j]
|
17
|
+
|
18
|
+
# be sure to query sequence_name *last*, only if cheaper tests fail, because it's costly
|
19
|
+
if val.nil? && column.name == primary_key && !sequence_name.blank?
|
20
|
+
if sequencer_enabled?
|
21
|
+
connection_memo.next_sequence_value(sequence_name)
|
22
|
+
else
|
23
|
+
connection_memo.next_value_for_sequence(sequence_name)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
if serialized_attributes.include?(column.name)
|
27
|
+
connection_memo.quote(serialized_attributes[column.name].dump(val), column)
|
28
|
+
else
|
29
|
+
connection_memo.quote(val, column)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
"(#{my_values.join(',')})"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
require 'activerecord-import'
|
40
|
+
require 'activerecord-import/base'
|
41
|
+
(class << ActiveRecord::Base; self; end).send(:include, ActiverecordImportExt)
|
42
|
+
rescue LoadError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'acts_as_archive'
|
3
|
+
|
4
|
+
class ActsAsArchive
|
5
|
+
class << self
|
6
|
+
def move_with_turntable(config, where, merge_options={})
|
7
|
+
if [config[:to], config[:from]].all? { |k| k.try(:turntable_enabled?) }
|
8
|
+
current_shard = config[:from].connection.current_shard.name.to_sym
|
9
|
+
config[:to].connection.with_shard(current_shard) {
|
10
|
+
move_without_turntable(config, where, merge_options)
|
11
|
+
}
|
12
|
+
else
|
13
|
+
move_without_turntable(config, where, merge_options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method_chain :move, :turntable
|
18
|
+
end
|
19
|
+
end
|
20
|
+
rescue LoadError
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'active_record/associations'
|
2
|
+
|
3
|
+
module ActiveRecord::Turntable
|
4
|
+
module ActiveRecordExt
|
5
|
+
module Association
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
ActiveRecord::Associations::SingularAssociation.send(:include, SingularAssociationExt)
|
10
|
+
ActiveRecord::Associations::CollectionAssociation.send(:include, CollectionAssociationExt)
|
11
|
+
ActiveRecord::Associations::Builder::Association.valid_options += [:foreign_shard_key]
|
12
|
+
end
|
13
|
+
|
14
|
+
module SingularAssociationExt
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
included do
|
18
|
+
alias_method_chain :find_target, :turntable
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
if ActiveRecord::Turntable.rails41_later?
|
24
|
+
def find_target_with_turntable
|
25
|
+
current_scope = scope
|
26
|
+
if should_use_shard_key?
|
27
|
+
current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
|
28
|
+
end
|
29
|
+
if record = current_scope.take
|
30
|
+
set_inverse_instance record
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
def find_target_with_turntable
|
35
|
+
current_scope = scope
|
36
|
+
if should_use_shard_key?
|
37
|
+
current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
|
38
|
+
end
|
39
|
+
current_scope.take.tap { |record| set_inverse_instance(record) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module CollectionAssociationExt
|
45
|
+
extend ActiveSupport::Concern
|
46
|
+
|
47
|
+
included do
|
48
|
+
alias_method_chain :find_target, :turntable
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def find_target_with_turntable
|
54
|
+
records =
|
55
|
+
if options[:finder_sql]
|
56
|
+
reflection.klass.find_by_sql(custom_finder_sql)
|
57
|
+
else
|
58
|
+
current_scope = scope
|
59
|
+
if should_use_shard_key?
|
60
|
+
current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
|
61
|
+
end
|
62
|
+
current_scope.to_a
|
63
|
+
end
|
64
|
+
records.each { |record| set_inverse_instance(record) }
|
65
|
+
records
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def foreign_shard_key
|
73
|
+
options[:foreign_shard_key] || owner.turntable_shard_key
|
74
|
+
end
|
75
|
+
|
76
|
+
def should_use_shard_key?
|
77
|
+
same_association_shard_key? || !!options[:foreign_shard_key]
|
78
|
+
end
|
79
|
+
|
80
|
+
def same_association_shard_key?
|
81
|
+
owner.class.turntable_enabled? && klass.turntable_enabled? && foreign_shard_key == klass.turntable_shard_key
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_record/associations/preloader/association'
|
2
|
+
|
3
|
+
module ActiveRecord::Turntable
|
4
|
+
module ActiveRecordExt
|
5
|
+
module AssociationPreloader
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
alias_method_chain :records_for, :turntable
|
10
|
+
end
|
11
|
+
|
12
|
+
def records_for_with_turntable(ids)
|
13
|
+
returning_scope = records_for_without_turntable(ids)
|
14
|
+
if should_use_shard_key?
|
15
|
+
returning_scope = returning_scope.where(klass.turntable_shard_key => owners.map(&foreign_shard_key.to_sym).uniq)
|
16
|
+
end
|
17
|
+
returning_scope
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def foreign_shard_key
|
23
|
+
options[:foreign_shard_key] || model.turntable_shard_key
|
24
|
+
end
|
25
|
+
|
26
|
+
def should_use_shard_key?
|
27
|
+
sharded_by_same_key? || !!options[:foreign_shard_key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def sharded_by_same_key?
|
31
|
+
model.turntable_enabled? &&
|
32
|
+
klass.turntable_enabled? &&
|
33
|
+
model.turntable_shard_key == klass.turntable_shard_key
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,88 +3,45 @@ module ActiveRecord::Turntable::ActiveRecordExt
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
ActiveRecord::VERSION::STRING < '3.1' ?
|
7
|
-
include(AR30):
|
8
|
-
include(AR31)
|
9
|
-
|
10
6
|
class << ActiveRecord::Base
|
11
|
-
delegate :clever_load!, :to => :
|
7
|
+
delegate :clever_load!, :to => :all
|
12
8
|
end
|
13
9
|
end
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
# association_proxy.send(:set_inverse_instance, matched_object, obj)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
records
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
module AR31
|
54
|
-
def clever_load!(association_name)
|
55
|
-
# load records
|
56
|
-
records = self.to_a
|
57
|
-
klass = records.first.class
|
58
|
-
reflection = klass.reflections[association_name]
|
59
|
-
|
60
|
-
if reflection
|
61
|
-
foreign_class = reflection.klass
|
62
|
-
foreign_objects = case reflection.macro
|
63
|
-
when :has_one
|
64
|
-
foreign_class.where(reflection.foreign_key => records.map(&reflection.association_primary_key.to_sym).uniq)
|
65
|
-
when :belongs_to
|
66
|
-
foreign_class.where(reflection.association_primary_key => records.map(&reflection.foreign_key.to_sym).uniq)
|
67
|
-
else
|
68
|
-
[]
|
69
|
-
end
|
70
|
-
|
71
|
-
self.each do |obj|
|
72
|
-
matched_object = case reflection.macro
|
73
|
-
when :has_one
|
74
|
-
foreign_objects.find {|fo|
|
75
|
-
obj.send(reflection.association_primary_key) == fo.send(reflection.foreign_key)
|
76
|
-
}
|
77
|
-
when :belongs_to
|
78
|
-
foreign_objects.find {|fo|
|
79
|
-
obj.send(reflection.foreign_key) == fo.send(reflection.association_primary_key)
|
80
|
-
}
|
81
|
-
end
|
82
|
-
obj.association(association_name).target = matched_object
|
83
|
-
obj.association(association_name).send(:set_inverse_instance, matched_object)
|
84
|
-
end
|
11
|
+
def clever_load!(association_name)
|
12
|
+
# load records
|
13
|
+
records = self.to_a
|
14
|
+
klass = records.first.class
|
15
|
+
reflection = klass.reflections[association_name]
|
16
|
+
|
17
|
+
if reflection
|
18
|
+
foreign_class = reflection.klass
|
19
|
+
foreign_objects = case reflection.macro
|
20
|
+
when :has_one
|
21
|
+
foreign_class.where(reflection.foreign_key => records.map(&reflection.association_primary_key.to_sym).uniq)
|
22
|
+
when :belongs_to
|
23
|
+
foreign_class.where(reflection.association_primary_key => records.map(&reflection.foreign_key.to_sym).uniq)
|
24
|
+
else
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
|
28
|
+
self.each do |obj|
|
29
|
+
matched_object = case reflection.macro
|
30
|
+
when :has_one
|
31
|
+
foreign_objects.find {|fo|
|
32
|
+
obj.send(reflection.association_primary_key) == fo.send(reflection.foreign_key)
|
33
|
+
}
|
34
|
+
when :belongs_to
|
35
|
+
foreign_objects.find {|fo|
|
36
|
+
obj.send(reflection.foreign_key) == fo.send(reflection.association_primary_key)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
obj.association(association_name).target = matched_object
|
40
|
+
obj.association(association_name).set_inverse_instance(matched_object) if matched_object
|
41
|
+
obj.association(association_name).loaded!
|
85
42
|
end
|
86
|
-
records
|
87
43
|
end
|
44
|
+
records
|
88
45
|
end
|
89
46
|
end
|
90
47
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveRecord::Turntable
|
2
|
+
module ActiveRecordExt
|
3
|
+
module ConnectionHandlerExtension
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
alias_method_chain :pool_for, :turntable
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def pool_for_with_turntable(owner)
|
13
|
+
owner_to_pool.fetch(owner.name) {
|
14
|
+
if ancestor_pool = pool_from_any_process_for(owner)
|
15
|
+
if ancestor_pool.is_a?(ActiveRecord::Turntable::PoolProxy)
|
16
|
+
# Use same PoolProxy object
|
17
|
+
owner_to_pool[owner.name] = ancestor_pool
|
18
|
+
else
|
19
|
+
# A connection was established in an ancestor process that must have
|
20
|
+
# subsequently forked. We can't reuse the connection, but we can copy
|
21
|
+
# the specification and establish a new connection with it.
|
22
|
+
establish_connection owner, ancestor_pool.spec
|
23
|
+
end
|
24
|
+
else
|
25
|
+
owner_to_pool[owner.name] = nil
|
26
|
+
end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|