activerecord-turntable 3.0.0.alpha3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/.rubocop.yml +18 -0
  4. data/.rubocop_todo.yml +153 -0
  5. data/.travis.yml +20 -4
  6. data/CHANGELOG.md +32 -0
  7. data/Guardfile +2 -2
  8. data/README.md +68 -14
  9. data/Rakefile +42 -0
  10. data/activerecord-turntable.gemspec +13 -3
  11. data/gemfiles/rails_edge.gemfile +8 -0
  12. data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +3 -1
  13. data/lib/active_record/turntable/active_record_ext/activerecord_import_ext.rb +5 -7
  14. data/lib/active_record/turntable/active_record_ext/acts_as_archive_extension.rb +2 -2
  15. data/lib/active_record/turntable/active_record_ext/association.rb +3 -3
  16. data/lib/active_record/turntable/active_record_ext/clever_load.rb +2 -2
  17. data/lib/active_record/turntable/active_record_ext/database_tasks.rb +10 -8
  18. data/lib/active_record/turntable/active_record_ext/fixtures.rb +15 -13
  19. data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +6 -0
  20. data/lib/active_record/turntable/active_record_ext/persistence.rb +25 -23
  21. data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +8 -75
  22. data/lib/active_record/turntable/algorithm/range_algorithm.rb +6 -7
  23. data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +6 -7
  24. data/lib/active_record/turntable/base.rb +2 -17
  25. data/lib/active_record/turntable/cluster_helper_methods.rb +7 -4
  26. data/lib/active_record/turntable/connection_proxy.rb +4 -2
  27. data/lib/active_record/turntable/migration.rb +3 -5
  28. data/lib/active_record/turntable/mixer.rb +20 -19
  29. data/lib/active_record/turntable/pool_proxy.rb +20 -14
  30. data/lib/active_record/turntable/query_cache.rb +1 -1
  31. data/lib/active_record/turntable/railties/databases.rake +12 -12
  32. data/lib/active_record/turntable/seq_shard.rb +1 -1
  33. data/lib/active_record/turntable/sequencer/barrage.rb +3 -2
  34. data/lib/active_record/turntable/sequencer.rb +33 -29
  35. data/lib/active_record/turntable/shard.rb +8 -8
  36. data/lib/active_record/turntable/sharding_condition.rb +14 -14
  37. data/lib/active_record/turntable/sql_tree_patch.rb +7 -3
  38. data/lib/active_record/turntable/util.rb +4 -2
  39. data/lib/active_record/turntable/version.rb +1 -1
  40. data/lib/active_record/turntable.rb +6 -5
  41. data/lib/activerecord-turntable.rb +1 -0
  42. metadata +120 -101
  43. data/lib/active_record/turntable/helpers/test_helper.rb +0 -25
  44. data/lib/active_record/turntable/helpers.rb +0 -9
  45. data/spec/active_record/turntable/active_record_ext/association_preloader_spec.rb +0 -78
  46. data/spec/active_record/turntable/active_record_ext/association_spec.rb +0 -81
  47. data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +0 -72
  48. data/spec/active_record/turntable/active_record_ext/fixture_set_spec.rb +0 -27
  49. data/spec/active_record/turntable/active_record_ext/locking_optimistic_spec.rb +0 -28
  50. data/spec/active_record/turntable/active_record_ext/migration_spec.rb +0 -38
  51. data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +0 -211
  52. data/spec/active_record/turntable/active_record_ext/sequencer_spec.rb +0 -22
  53. data/spec/active_record/turntable/active_record_ext/test_fixtures_spec.rb +0 -34
  54. data/spec/active_record/turntable/algorithm/modulo_algorithm_spec.rb +0 -34
  55. data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +0 -34
  56. data/spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb +0 -34
  57. data/spec/active_record/turntable/algorithm_spec.rb +0 -100
  58. data/spec/active_record/turntable/base_spec.rb +0 -13
  59. data/spec/active_record/turntable/cluster_spec.rb +0 -48
  60. data/spec/active_record/turntable/config_spec.rb +0 -17
  61. data/spec/active_record/turntable/connection_proxy_spec.rb +0 -252
  62. data/spec/active_record/turntable/finder_spec.rb +0 -40
  63. data/spec/active_record/turntable/mixer/fader_spec.rb +0 -4
  64. data/spec/active_record/turntable/mixer_spec.rb +0 -112
  65. data/spec/active_record/turntable/query_cache_spec.rb +0 -28
  66. data/spec/active_record/turntable/sequencer/api_spec.rb +0 -38
  67. data/spec/active_record/turntable/sequencer/barrage_spec.rb +0 -22
  68. data/spec/active_record/turntable/sequencer/mysql_spec.rb +0 -22
  69. data/spec/active_record/turntable/shard_spec.rb +0 -21
  70. data/spec/active_record/turntable/sql_tree_patch_spec.rb +0 -34
  71. data/spec/active_record/turntable/transaction_spec.rb +0 -35
  72. data/spec/active_record/turntable_spec.rb +0 -30
  73. data/spec/config/database.yml +0 -35
  74. data/spec/config/turntable.yml +0 -56
  75. data/spec/fabricators/.gitkeep +0 -0
  76. data/spec/fabricators/turntable_fabricator.rb +0 -12
  77. data/spec/fixtures/cards.yml +0 -11
  78. data/spec/migrations/.gitkeep +0 -0
  79. data/spec/migrations/001_create_users.rb +0 -17
  80. data/spec/migrations/002_create_user_statuses.rb +0 -16
  81. data/spec/migrations/003_create_cards.rb +0 -14
  82. data/spec/migrations/004_create_cards_users.rb +0 -15
  83. data/spec/models/card.rb +0 -3
  84. data/spec/models/cards_user.rb +0 -10
  85. data/spec/models/cards_users_histories.rb +0 -7
  86. data/spec/models/events_users_history.rb +0 -7
  87. data/spec/models/user.rb +0 -7
  88. data/spec/models/user_status.rb +0 -6
  89. data/spec/spec_helper.rb +0 -38
  90. data/spec/support/matchers/be_saved_to.rb +0 -6
  91. data/spec/support/turntable_helper.rb +0 -30
@@ -26,24 +26,30 @@ module ActiveRecord::Turntable
26
26
  end
27
27
  end
28
28
 
29
- %w(active_connection?).each do |name|
30
- define_method(name.to_sym) do |*_args|
31
- @proxy.master.connection_pool.send(name.to_sym) ||
32
- @proxy.seq.connection_pool.try(name.to_sym) if @proxy.respond_to?(:seq) ||
33
- @proxy.shards.values.any? do |pool|
34
- pool.connection_pool.send(name.to_sym)
35
- end
36
- end
29
+ def active_connection?
30
+ connection_pools_list.any?(&:active_connection?)
37
31
  end
38
32
 
39
- %w(disconnect! release_connection clear_all_connections! clear_active_connections! clear_reloadable_connections! clear_stale_cached_connections! verify_active_connections!).each do |name|
33
+ %w(disconnect!
34
+ release_connection
35
+ clear_all_connections!
36
+ clear_active_connections!
37
+ clear_reloadable_connections!
38
+ clear_stale_cached_connections!
39
+ verify_active_connections!).each do |name|
40
40
  define_method(name.to_sym) do
41
- @proxy.master.connection_pool.send(name.to_sym)
42
- @proxy.seq.connection_pool.try(name.to_sym) if @proxy.respond_to?(:seq)
43
- @proxy.shards.values.each do |pool|
44
- pool.connection_pool.send(name.to_sym)
45
- end
41
+ connection_pools_list.each { |cp| cp.public_send(name.to_sym) }
46
42
  end
47
43
  end
44
+
45
+ private
46
+
47
+ def connection_pools_list
48
+ pools = []
49
+ pools << proxy.master.connection_pool
50
+ pools << proxy.seq.try(:connection_pool) if proxy.respond_to?(:seq)
51
+ pools.concat(proxy.shards.values.map(&:connection_pool))
52
+ pools.compact
53
+ end
48
54
  end
49
55
  end
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  end
18
18
 
19
19
  def self.complete(enabled)
20
- klasses = ActiveRecord::Base.turntable_connections.values
20
+ klasses = ActiveRecord::Base.turntable_connections.values
21
21
  klasses.each do |k|
22
22
  k.connection.clear_query_cache
23
23
  k.connection.disable_query_cache! unless enabled
@@ -35,9 +35,9 @@ db_namespace = namespace :db do
35
35
  # TODO: implement schema:cache:xxxx
36
36
  task :dump do
37
37
  require "active_record/schema_dumper"
38
- config = ActiveRecord::Base.configurations[Rails.env]
39
- shard_configs = config["shards"]
40
- shard_configs.merge!(config["seq"]) if config["seq"]
38
+ current_config = ActiveRecord::Base.configurations[Rails.env]
39
+ shard_configs = current_config["shards"]
40
+ shard_configs.merge!(current_config["seq"]) if current_config["seq"]
41
41
  if shard_configs
42
42
  shard_configs.each do |name, config|
43
43
  next unless config["database"]
@@ -48,15 +48,15 @@ db_namespace = namespace :db do
48
48
  end
49
49
  end
50
50
  end
51
- ActiveRecord::Base.establish_connection(config)
51
+ ActiveRecord::Base.establish_connection(current_config)
52
52
  turntable_namespace["schema:dump"].reenable
53
53
  end
54
54
 
55
55
  desc "Load a schema.rb file into the database"
56
56
  task :load do
57
- config = ActiveRecord::Base.configurations[Rails.env]
58
- shard_configs = config["shards"]
59
- shard_configs.merge!(config["seq"]) if config["seq"]
57
+ current_config = ActiveRecord::Base.configurations[Rails.env]
58
+ shard_configs = current_config["shards"]
59
+ shard_configs.merge!(current_config["seq"]) if current_config["seq"]
60
60
  if shard_configs
61
61
  shard_configs.each do |name, config|
62
62
  next unless config["database"]
@@ -69,7 +69,7 @@ db_namespace = namespace :db do
69
69
  end
70
70
  end
71
71
  end
72
- ActiveRecord::Base.establish_connection(config)
72
+ ActiveRecord::Base.establish_connection(current_config)
73
73
  end
74
74
  end
75
75
 
@@ -116,16 +116,16 @@ db_namespace = namespace :db do
116
116
  namespace :test do
117
117
  # desc "Empty the test database"
118
118
  task :purge do
119
- config = ActiveRecord::Base.configurations[Rails.env]
120
- shard_configs = config["shards"]
121
- shard_configs.merge!(config["seq"]) if config["seq"]
119
+ current_config = ActiveRecord::Base.configurations[Rails.env]
120
+ shard_configs = current_config["shards"]
121
+ shard_configs.merge!(current_config["seq"]) if current_config["seq"]
122
122
  if shard_configs
123
123
  shard_configs.each do |_name, config|
124
124
  next unless config["database"]
125
125
  ActiveRecord::Tasks::DatabaseTasks.purge config
126
126
  end
127
127
  end
128
- ActiveRecord::Base.establish_connection(config)
128
+ ActiveRecord::Base.establish_connection(current_config)
129
129
  end
130
130
  end
131
131
  end
@@ -3,7 +3,7 @@ module ActiveRecord::Turntable
3
3
  private
4
4
 
5
5
  def create_connection_class
6
- klass = get_or_set_connection_class
6
+ klass = connection_class_instance
7
7
  klass.remove_connection
8
8
  klass.establish_connection ActiveRecord::Base.connection_pool.spec.config[:seq][name].with_indifferent_access
9
9
  klass
@@ -1,7 +1,8 @@
1
1
  module ActiveRecord::Turntable
2
2
  class Sequencer
3
3
  class Barrage < Sequencer
4
- @@unique_barrage_instance = {}
4
+ class_attribute :unique_barrage_instance
5
+ self.unique_barrage_instance = {}
5
6
 
6
7
  def initialize(klass, options = {})
7
8
  require "barrage"
@@ -20,7 +21,7 @@ module ActiveRecord::Turntable
20
21
  private
21
22
 
22
23
  def barrage
23
- @@unique_barrage_instance[@options] ||= ::Barrage.new(@options)
24
+ self.unique_barrage_instance[@options] ||= ::Barrage.new(@options)
24
25
  end
25
26
  end
26
27
  end
@@ -13,33 +13,48 @@ module ActiveRecord::Turntable
13
13
  autoload :Barrage
14
14
  end
15
15
 
16
- @@sequence_types = {
16
+ class_attribute :sequence_types
17
+ class_attribute :sequences
18
+ class_attribute :tables
19
+
20
+ self.sequence_types = {
17
21
  api: Api,
18
22
  mysql: Mysql,
19
23
  barrage: Barrage,
20
24
  }
25
+ self.sequences = {}
26
+ self.tables = {}
21
27
 
22
- @@sequences = {}
23
- @@tables = {}
24
- cattr_reader :sequences, :tables
28
+ class << self
29
+ def build(klass, sequence_name = nil, cluster_name = nil)
30
+ sequence_name ||= current_cluster_config_for(cluster_name || klass)[:seq].keys.first
31
+ seq_config = current_cluster_config_for(cluster_name || klass)[:seq][sequence_name]
32
+ seq_type = (seq_config[:seq_type] ? seq_config[:seq_type].to_sym : :mysql)
33
+ tables[klass.table_name] ||= (sequences[sequence_name(klass.table_name, klass.primary_key)] ||= sequence_types[seq_type].new(klass, seq_config))
34
+ end
25
35
 
26
- def self.build(klass, sequence_name = nil, cluster_name = nil)
27
- sequence_name ||= current_cluster_config_for(cluster_name || klass)[:seq].keys.first
28
- seq_config = current_cluster_config_for(cluster_name || klass)[:seq][sequence_name]
29
- seq_type = (seq_config[:seq_type] ? seq_config[:seq_type].to_sym : :mysql)
30
- @@tables[klass.table_name] ||= (@@sequences[sequence_name(klass.table_name, klass.primary_key)] ||= @@sequence_types[seq_type].new(klass, seq_config))
31
- end
36
+ def has_sequencer?(table_name)
37
+ !!tables[table_name]
38
+ end
32
39
 
33
- def self.has_sequencer?(table_name)
34
- !!@@tables[table_name]
35
- end
40
+ def sequence_name(table_name, pk)
41
+ "#{table_name}_#{pk || 'id'}_seq"
42
+ end
36
43
 
37
- def self.sequence_name(table_name, pk)
38
- "#{table_name}_#{pk || 'id'}_seq"
39
- end
44
+ def table_name(seq_name)
45
+ seq_name.split("_").first
46
+ end
47
+
48
+ private
40
49
 
41
- def self.table_name(seq_name)
42
- seq_name.split("_").first
50
+ def current_cluster_config_for(klass_or_name)
51
+ cluster_name = if klass_or_name.is_a?(Symbol)
52
+ klass_or_name
53
+ else
54
+ klass_or_name.turntable_cluster_name.to_s
55
+ end
56
+ ActiveRecord::Base.turntable_config[:clusters][cluster_name]
57
+ end
43
58
  end
44
59
 
45
60
  def next_sequence_value
@@ -49,16 +64,5 @@ module ActiveRecord::Turntable
49
64
  def current_sequence_value
50
65
  raise NotImplementedError
51
66
  end
52
-
53
- private
54
-
55
- def self.current_cluster_config_for(klass_or_name)
56
- cluster_name = if klass_or_name.is_a?(Symbol)
57
- klass_or_name
58
- else
59
- klass_or_name.turntable_cluster_name.to_s
60
- end
61
- ActiveRecord::Base.turntable_config[:clusters][cluster_name]
62
- end
63
67
  end
64
68
  end
@@ -33,7 +33,14 @@ module ActiveRecord::Turntable
33
33
  @connection_klass ||= create_connection_class
34
34
  end
35
35
 
36
- def get_or_set_connection_class
36
+ def create_connection_class
37
+ klass = connection_class_instance
38
+ klass.remove_connection
39
+ klass.establish_connection ActiveRecord::Base.connection_pool.spec.config[:shards][name].with_indifferent_access
40
+ klass
41
+ end
42
+
43
+ def connection_class_instance
37
44
  if Connections.const_defined?(name.classify)
38
45
  klass = Connections.const_get(name.classify)
39
46
  else
@@ -43,12 +50,5 @@ module ActiveRecord::Turntable
43
50
  end
44
51
  klass
45
52
  end
46
-
47
- def create_connection_class
48
- klass = get_or_set_connection_class
49
- klass.remove_connection
50
- klass.establish_connection ActiveRecord::Base.connection_pool.spec.config[:shards][name].with_indifferent_access
51
- klass
52
- end
53
53
  end
54
54
  end
@@ -2,22 +2,22 @@ module ActiveRecord::Turntable
2
2
  module ShardingCondition
3
3
  private
4
4
 
5
- def foreign_shard_key
6
- options[:foreign_shard_key] || foreign_target_model.turntable_shard_key
7
- end
5
+ def foreign_shard_key
6
+ options[:foreign_shard_key] || foreign_target_model.turntable_shard_key
7
+ end
8
8
 
9
- def foreign_target_model
10
- respond_to?(:model) ? model : owner
11
- end
9
+ def foreign_target_model
10
+ respond_to?(:model) ? model : owner
11
+ end
12
12
 
13
- def should_use_shard_key?
14
- sharded_by_same_key? || !!options[:foreign_shard_key]
15
- end
13
+ def should_use_shard_key?
14
+ sharded_by_same_key? || !!options[:foreign_shard_key]
15
+ end
16
16
 
17
- def sharded_by_same_key?
18
- foreign_target_model.turntable_enabled? &&
19
- klass.turntable_enabled? &&
20
- foreign_shard_key == klass.turntable_shard_key
21
- end
17
+ def sharded_by_same_key?
18
+ foreign_target_model.turntable_enabled? &&
19
+ klass.turntable_enabled? &&
20
+ foreign_shard_key == klass.turntable_shard_key
21
+ end
22
22
  end
23
23
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:disable Style/CaseEquality
1
2
  require "sql_tree"
2
3
  require "active_support/core_ext/kernel/reporting"
3
4
 
@@ -37,6 +38,7 @@ class SQLTree::Tokenizer
37
38
  end
38
39
 
39
40
  # @note Override to handle x'..' binary string
41
+ # rubocop:disable Lint/EmptyWhen:
40
42
  def each_token(&block) # :yields: SQLTree::Token
41
43
  while next_char
42
44
  case current_char
@@ -47,7 +49,7 @@ class SQLTree::Tokenizer
47
49
  when "," then handle_token(SQLTree::Token::COMMA, &block)
48
50
  when /\d/ then tokenize_number(&block)
49
51
  when "'" then tokenize_quoted_string(&block)
50
- when "E", "x", 'X' then tokenize_possible_escaped_string(&block)
52
+ when "E", "x", "X" then tokenize_possible_escaped_string(&block)
51
53
  when /\w/ then tokenize_keyword(&block)
52
54
  when OPERATOR_CHARS then tokenize_operator(&block)
53
55
  when SQLTree.identifier_quote_char then tokenize_quoted_identifier(&block)
@@ -57,6 +59,7 @@ class SQLTree::Tokenizer
57
59
  # Make sure to yield any tokens that are still stashed on the queue.
58
60
  empty_keyword_queue!(&block)
59
61
  end
62
+ # rubocop:enable Lint/EmptyWhen:
60
63
  alias_method :each, :each_token
61
64
 
62
65
  def tokenize_possible_escaped_string(&block)
@@ -184,7 +187,7 @@ module SQLTree::Node
184
187
  end
185
188
  table_reference
186
189
  else
187
- raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
190
+ raise SQLTree::Parser::UnexpectedToken, tokens.current
188
191
  end
189
192
  end
190
193
  end
@@ -215,7 +218,7 @@ module SQLTree::Node
215
218
  tokens.consume(SQLTree::Token::RPAREN)
216
219
  self.new(hint_method, hint_key, index_list)
217
220
  else
218
- raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
221
+ raise SQLTree::Parser::UnexpectedToken, tokens.current
219
222
  end
220
223
  end
221
224
  end
@@ -350,3 +353,4 @@ module SQLTree::Node
350
353
  end
351
354
  end
352
355
  end
356
+ # rubocop:enable Style/CaseEquality
@@ -1,7 +1,5 @@
1
1
  module ActiveRecord::Turntable
2
2
  module Util
3
- extend self
4
-
5
3
  def ar_version_equals_or_later?(version)
6
4
  ar_version >= Gem::Version.new(version)
7
5
  end
@@ -13,5 +11,9 @@ module ActiveRecord::Turntable
13
11
  def ar_version
14
12
  ActiveRecord.gem_version
15
13
  end
14
+
15
+ module_function :ar_version_equals_or_later?,
16
+ :ar_version_earlier_than?,
17
+ :ar_version
16
18
  end
17
19
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "3.0.0.alpha3".freeze
3
+ VERSION = "3.0.0".freeze
4
4
  end
5
5
  end
@@ -34,7 +34,6 @@ module ActiveRecord::Turntable
34
34
  autoload :SeqShard
35
35
  autoload :Sequencer
36
36
  end
37
- autoload :Helpers
38
37
 
39
38
  included do
40
39
  include ActiveRecordExt
@@ -45,13 +44,15 @@ module ActiveRecord::Turntable
45
44
  DEFAULT_PATH = File.dirname(File.dirname(__FILE__))
46
45
 
47
46
  def turntable_config_file
48
- @@turntable_config_file ||=
49
- File.join(defined?(::Rails) ?
50
- ::Rails.root.to_s : DEFAULT_PATH, "config/turntable.yml")
47
+ @turntable_config_file ||= File.join(turntable_app_root_path, "config/turntable.yml")
51
48
  end
52
49
 
53
50
  def turntable_config_file=(filename)
54
- @@turntable_config_file = filename
51
+ @turntable_config_file = filename
52
+ end
53
+
54
+ def turntable_app_root_path
55
+ defined?(::Rails.root) ? ::Rails.root.to_s : DEFAULT_PATH
55
56
  end
56
57
 
57
58
  def turntable_config
@@ -1,2 +1,3 @@
1
+ # rubocop:disable Style/FileName
1
2
  require "active_record"
2
3
  require "active_record/turntable"