activerecord-turntable 2.0.6 → 2.1.0.beta1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d82829564262382156d47ab48a5331ee39507e2b
4
- data.tar.gz: 2046ebf2f59a336a20d91df727c98da717a1b4f5
3
+ metadata.gz: bd8da73b8e0ac2f22797a0eb070c3624038b2ea3
4
+ data.tar.gz: 57b762fbd0ef0d06c5f7562c4cf68d5cc3c8f8bb
5
5
  SHA512:
6
- metadata.gz: a29ef422e6cbe7494c67c9480e541469ebbfc2773f48a0ef606c130ca7b6c791a6a8502cb23ce46f8fb739899b4ea4c438a46d348e3ca4d4e42b6cd93e9117ce
7
- data.tar.gz: befc1adb93081acf2d9ba91c5cad860039b37530e484198334cec82935dc608719e8845dd83fe326d8da0c9add919222edfb5493033a2f8c69a256e712292a34
6
+ metadata.gz: 74cb71bdcd32cca8731ce965b5fd7d0e8b8dd9d7bde6484abb6aa83021d530c3a54ac22d33c73bc2bb8d7c491a0401562b827e78eef3e56eb3bb5e6a56121f8e
7
+ data.tar.gz: 8ffc60cb0b0dd8e4428f4b3d76690a6135eeb2c60bf5bb0a7ffb0c8655e0be7a835c72bfa8580841c46b0a44bb60d57f88b04d7a48ae7b54ea620cc44f5bc909
data/.travis.yml CHANGED
@@ -2,7 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.2
5
+ - 2.1
6
6
  - 2.2
7
7
  - ruby-head
8
8
  gemfile:
@@ -14,6 +14,4 @@ before_script:
14
14
  script: bundle exec rake spec
15
15
  matrix:
16
16
  allow_failures:
17
- - rvm: 2.2
18
17
  - rvm: ruby-head
19
- - gemfile: gemfiles/rails4_2.gemfile
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## activerecord-turntable 2.1.0 (unreleased) ##
2
+
3
+ Support activerecord 4.2.0
4
+
5
+ ### Bugfixes
6
+
7
+ * Fix cluster helper methods(i.e xxxx_cluster_transaction helper) on lazy load environments(development, test)
8
+
1
9
  ## activerecord-turntable 2.0.6 ##
2
10
 
3
11
  ### Bugfixes
data/Rakefile CHANGED
@@ -85,6 +85,7 @@ namespace :turntable do
85
85
  ActiveRecord::Base.connection.create_table :cards_users do |t|
86
86
  t.belongs_to :card, :null => false
87
87
  t.belongs_to :user, :null => false
88
+ t.integer :num, :default => 1, :null => false
88
89
  t.timestamps
89
90
  end
90
91
  ActiveRecord::Base.connection.create_sequence_for :cards_users
@@ -43,6 +43,9 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency "faker"
44
44
  spec.add_development_dependency "webmock"
45
45
  spec.add_development_dependency "pry"
46
+ if RUBY_VERSION > "2.0"
47
+ spec.add_development_dependency "pry-byebug"
48
+ end
46
49
  spec.add_development_dependency "guard-rspec"
47
50
  spec.add_development_dependency "coveralls"
48
51
 
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'activerecord', "= 4.2.0.rc1"
4
- gem 'activesupport', "= 4.2.0.rc1"
3
+ gem 'activerecord', "~> 4.2.0"
4
+ gem 'activesupport', "~> 4.2.0"
5
5
 
6
6
  gemspec :path => '../'
@@ -11,33 +11,58 @@ module ActiveRecord::Turntable
11
11
  ActiveRecord::Associations::Builder::Association.valid_options += [:foreign_shard_key]
12
12
  end
13
13
 
14
+ private
15
+
16
+ def turntable_scope(scope, bind = nil)
17
+ if should_use_shard_key?
18
+ scope = scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
19
+ end
20
+ scope
21
+ end
22
+
14
23
  module SingularAssociationExt
15
24
  extend ActiveSupport::Concern
16
25
 
17
26
  included do
18
- alias_method_chain :find_target, :turntable
27
+ if ActiveRecord::Turntable.rails42_later?
28
+ alias_method_chain :get_records, :turntable
29
+ else
30
+ alias_method_chain :find_target, :turntable
31
+ end
19
32
  end
20
33
 
21
- private
22
-
23
34
  # @note Override to add sharding condition for singular association
24
- if ActiveRecord::Turntable.rails41_later?
25
- def find_target_with_turntable
26
- current_scope = scope
27
- if should_use_shard_key?
28
- current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
35
+ if ActiveRecord::Turntable.rails42_later?
36
+ def get_records_with_turntable
37
+ if reflection.scope_chain.any?(&:any?) ||
38
+ scope.eager_loading? ||
39
+ klass.current_scope ||
40
+ klass.default_scopes.any? ||
41
+ should_use_shard_key? # OPTIMIZE: Use bind values if cachable scope
42
+
43
+ return turntable_scope(scope).limit(1).to_a
29
44
  end
30
- if record = current_scope.take
45
+
46
+ conn = klass.connection
47
+ sc = reflection.association_scope_cache(conn, owner) do
48
+ ActiveRecord::StatementCache.create(conn) { |params|
49
+ as = ActiveRecord::Associations::AssociationScope.create { params.bind }
50
+ target_scope.merge(as.scope(self, conn)).limit(1)
51
+ }
52
+ end
53
+
54
+ binds = ActiveRecord::Associations::AssociationScope.get_bind_values(owner, reflection.chain)
55
+ sc.execute binds, klass, klass.connection
56
+ end
57
+ elsif ActiveRecord::Turntable.rails41_later?
58
+ def find_target_with_turntable
59
+ if record = turntable_scope(scope).take
31
60
  set_inverse_instance record
32
61
  end
33
62
  end
34
63
  else
35
64
  def find_target_with_turntable
36
- current_scope = scope
37
- if should_use_shard_key?
38
- current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
39
- end
40
- current_scope.take.tap { |record| set_inverse_instance(record) }
65
+ turntable_scope(scope).take.tap { |record| set_inverse_instance(record) }
41
66
  end
42
67
  end
43
68
  end
@@ -46,27 +71,54 @@ module ActiveRecord::Turntable
46
71
  extend ActiveSupport::Concern
47
72
 
48
73
  included do
49
- alias_method_chain :find_target, :turntable
74
+ if ActiveRecord::Turntable.rails42_later?
75
+ alias_method_chain :get_records, :turntable
76
+ else
77
+ alias_method_chain :find_target, :turntable
78
+ end
50
79
  end
51
80
 
52
81
  private
53
82
 
54
- # @note Override to add sharding condition for collection association
55
- def find_target_with_turntable
56
- records =
57
- if options[:finder_sql]
58
- reflection.klass.find_by_sql(custom_finder_sql)
59
- else
60
- current_scope = scope
61
- if should_use_shard_key?
62
- current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
63
- end
64
- current_scope.to_a
83
+ if ActiveRecord::Turntable.rails42_later?
84
+ def get_records_with_turntable
85
+ if reflection.scope_chain.any?(&:any?) ||
86
+ scope.eager_loading? ||
87
+ klass.current_scope ||
88
+ klass.default_scopes.any? ||
89
+ should_use_shard_key? # OPTIMIZE: Use bind values if cachable scope
90
+
91
+ return turntable_scope(scope).to_a
92
+ end
93
+
94
+ conn = klass.connection
95
+ sc = reflection.association_scope_cache(conn, owner) do
96
+ ActiveRecord::StatementCache.create(conn) { |params|
97
+ as = ActiveRecord::Associations::AssociationScope.create { params.bind }
98
+ target_scope.merge as.scope(self, conn)
99
+ }
65
100
  end
66
- records.each { |record| set_inverse_instance(record) }
67
- records
68
- end
69
101
 
102
+ binds = ActiveRecord::Associations::AssociationScope.get_bind_values(owner, reflection.chain)
103
+ sc.execute binds, klass, klass.connection
104
+ end
105
+ else
106
+ # @note Override to add sharding condition for collection association
107
+ def find_target_with_turntable
108
+ records =
109
+ if options[:finder_sql]
110
+ reflection.klass.find_by_sql(custom_finder_sql)
111
+ else
112
+ current_scope = scope
113
+ if should_use_shard_key?
114
+ current_scope = current_scope.where(klass.turntable_shard_key => owner.send(foreign_shard_key))
115
+ end
116
+ current_scope.to_a
117
+ end
118
+ records.each { |record| set_inverse_instance(record) }
119
+ records
120
+ end
121
+ end
70
122
  end
71
123
 
72
124
  private
@@ -12,7 +12,8 @@ module ActiveRecord::Turntable::ActiveRecordExt
12
12
  # load records
13
13
  records = self.to_a
14
14
  klass = records.first.class
15
- reflection = klass.reflections[association_name]
15
+ association_key = ActiveRecord::Turntable.rails42_later? ? association_name.to_s : association_name
16
+ reflection = klass.reflections[association_key]
16
17
 
17
18
  if reflection
18
19
  foreign_class = reflection.klass
@@ -29,7 +29,11 @@ module ActiveRecord::Turntable::ActiveRecordExt
29
29
  )
30
30
  )
31
31
  if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
32
- condition_scope = condition_scope.where(klass.turntable_shard_key => self.send(turntable_shard_key))
32
+ condition_scope = condition_scope.where(
33
+ relation.table[klass.turntable_shard_key].eq(
34
+ self.class.quote_value(self.send(turntable_shard_key), column_for_attribute(klass.turntable_shard_key))
35
+ )
36
+ )
33
37
  end
34
38
  stmt = condition_scope.arel.compile_update(arel_attributes_with_values_for_update(attribute_names))
35
39
 
@@ -48,7 +52,7 @@ module ActiveRecord::Turntable::ActiveRecordExt
48
52
  end
49
53
  end
50
54
  EOD
51
- else
55
+ elsif ar_version < "4.2"
52
56
  method_name = ar_version =~ /\A4\.1\.[01]\z/ ? "update_record" : "_update_record"
53
57
 
54
58
  class_eval <<-EOD
@@ -73,7 +77,11 @@ module ActiveRecord::Turntable::ActiveRecordExt
73
77
  )
74
78
  )
75
79
  if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
76
- condition_scope = condition_scope.where(klass.turntable_shard_key => self.send(turntable_shard_key))
80
+ condition_scope = condition_scope.where(
81
+ relation.table[klass.turntable_shard_key].eq(
82
+ self.class.quote_value(self.send(turntable_shard_key), column_for_attribute(klass.turntable_shard_key))
83
+ )
84
+ )
77
85
  end
78
86
  stmt = condition_scope.arel.compile_update(
79
87
  arel_attributes_with_values_for_update(attribute_names),
@@ -88,6 +96,56 @@ module ActiveRecord::Turntable::ActiveRecordExt
88
96
 
89
97
  affected_rows
90
98
 
99
+ # If something went wrong, revert the version.
100
+ rescue Exception
101
+ send(lock_col + '=', previous_lock_value)
102
+ raise
103
+ end
104
+ end
105
+ EOD
106
+ else
107
+ class_eval <<-EOD
108
+ def _update_record(attribute_names = self.attribute_names) #:nodoc:
109
+ return super unless locking_enabled?
110
+ return 0 if attribute_names.empty?
111
+
112
+ klass = self.class
113
+ lock_col = self.class.locking_column
114
+ previous_lock_value = send(lock_col).to_i
115
+ increment_lock
116
+
117
+ attribute_names += [lock_col]
118
+ attribute_names.uniq!
119
+
120
+ begin
121
+ relation = self.class.unscoped
122
+
123
+ condition_scope = relation.where(
124
+ relation.table[self.class.primary_key].eq(id).and(
125
+ relation.table[lock_col].eq(self.class.quote_value(previous_lock_value, column_for_attribute(lock_col)))
126
+ )
127
+ )
128
+ if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
129
+ condition_scope = condition_scope.where(
130
+ relation.table[klass.turntable_shard_key].eq(
131
+ self.class.quote_value(self.send(turntable_shard_key), column_for_attribute(klass.turntable_shard_key))
132
+ )
133
+ )
134
+ end
135
+
136
+ stmt = condition_scope.arel.compile_update(
137
+ arel_attributes_with_values_for_update(attribute_names),
138
+ self.class.primary_key
139
+ )
140
+
141
+ affected_rows = self.class.connection.update stmt
142
+
143
+ unless affected_rows == 1
144
+ raise ActiveRecord::StaleObjectError.new(self, "update")
145
+ end
146
+
147
+ affected_rows
148
+
91
149
  # If something went wrong, revert the version.
92
150
  rescue Exception
93
151
  send(lock_col + '=', previous_lock_value)
@@ -21,11 +21,16 @@ module ActiveRecord::Turntable::ActiveRecordExt
21
21
  finder_scope.find(id)
22
22
  end
23
23
 
24
- @attributes.update(fresh_object.instance_variable_get('@attributes'))
25
-
26
- @column_types = self.class.column_types
27
- @column_types_override = fresh_object.instance_variable_get('@column_types_override')
28
- @attributes_cache = {}
24
+ if ActiveRecord::Turntable.rails42_later?
25
+ @attributes = fresh_object.instance_variable_get('@attributes')
26
+ else
27
+ @attributes.update(fresh_object.instance_variable_get('@attributes'))
28
+
29
+ @column_types = self.class.column_types
30
+ @column_types_override = fresh_object.instance_variable_get('@column_types_override')
31
+ @attributes_cache = {}
32
+ end
33
+ @new_record = false
29
34
  self
30
35
  end
31
36
 
@@ -57,6 +62,8 @@ module ActiveRecord::Turntable::ActiveRecordExt
57
62
  end
58
63
 
59
64
  finder_scope.where(primary_key => self[primary_key]).update_all(changes) == 1
65
+ else
66
+ true
60
67
  end
61
68
  end
62
69
 
@@ -85,26 +92,47 @@ module ActiveRecord::Turntable::ActiveRecordExt
85
92
 
86
93
  private
87
94
 
95
+ ar_version = ActiveRecord::VERSION::STRING
96
+
88
97
  # @note Override to add sharding scope on destroying
89
- def relation_for_destroy
90
- pk = self.class.primary_key
91
- column = self.class.columns_hash[pk]
92
- substitute = self.class.connection.substitute_at(column, 0)
93
- klass = self.class
94
-
95
- relation = self.class.unscoped.where(
96
- self.class.arel_table[pk].eq(substitute))
97
- if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
98
- relation = relation.where(klass.turntable_shard_key => self.send(turntable_shard_key))
98
+ if ActiveRecord::Turntable.rails42_later?
99
+ def relation_for_destroy
100
+ pk = self.class.primary_key
101
+ column = self.class.columns_hash[pk]
102
+ substitute = self.class.connection.substitute_at(column, 0)
103
+ klass = self.class
104
+
105
+ relation = self.class.unscoped.where(
106
+ self.class.arel_table[pk].eq(substitute))
107
+ relation.bind_values = [[column, id]]
108
+
109
+ if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
110
+ shard_key_column = klass.columns_hash[klass.turntable_shard_key]
111
+ shard_key_substitute = klass.connection.substitute_at(shard_key_column)
112
+
113
+ relation = relation.where(self.class.arel_table[klass.turntable_shard_key].eq(shard_key_substitute))
114
+ relation.bind_values << [shard_key_column, self[klass.turntable_shard_key]]
115
+ end
116
+ relation
117
+ end
118
+ else
119
+ def relation_for_destroy
120
+ pk = self.class.primary_key
121
+ column = self.class.columns_hash[pk]
122
+ substitute = self.class.connection.substitute_at(column, 0)
123
+ klass = self.class
124
+
125
+ relation = self.class.unscoped.where(
126
+ self.class.arel_table[pk].eq(substitute))
127
+ if klass.turntable_enabled? and klass.primary_key != klass.turntable_shard_key.to_s
128
+ relation = relation.where(klass.turntable_shard_key => self.send(turntable_shard_key))
129
+ end
130
+ relation.bind_values = [[column, id]]
131
+ relation
99
132
  end
100
-
101
- relation.bind_values = [[column, id]]
102
- relation
103
133
  end
104
134
 
105
-
106
135
  # @note Override to add sharding scope on updating
107
- ar_version = ActiveRecord::VERSION::STRING
108
136
  if ar_version < "4.1"
109
137
  method_name = ar_version =~ /\A4\.0\.[0-5]\z/ ? "update_record" : "_update_record"
110
138
  class_eval <<-EOD
@@ -16,16 +16,42 @@ module ActiveRecord::Turntable
16
16
  end
17
17
 
18
18
  # @note Override to add sharding scope on updating
19
- def _update_record_with_turntable(values, id, id_was, turntable_scope = nil) # :nodoc:
20
- substitutes, binds = substitute_values values
21
- condition_scope = @klass.unscoped.where(@klass.arel_table[@klass.primary_key].eq(id_was || id))
22
- condition_scope = condition_scope.merge(turntable_scope) if turntable_scope
23
- um = condition_scope.arel.compile_update(substitutes, @klass.primary_key)
24
-
25
- @klass.connection.update(
26
- um,
27
- 'SQL',
28
- binds)
19
+ if ActiveRecord::Turntable.rails42_later?
20
+ def _update_record_with_turntable(values, id, id_was, turntable_scope = nil) # :nodoc:
21
+ substitutes, binds = substitute_values values
22
+
23
+ scope = @klass.unscoped
24
+
25
+ if @klass.finder_needs_type_condition?
26
+ scope.unscope!(where: @klass.inheritance_column)
27
+ end
28
+
29
+ relation = scope.where(@klass.primary_key => (id_was || id))
30
+ relation = relation.merge(turntable_scope) if turntable_scope
31
+
32
+ bvs = binds + relation.bind_values
33
+ um = relation
34
+ .arel
35
+ .compile_update(substitutes, @klass.primary_key)
36
+
37
+ @klass.connection.update(
38
+ um,
39
+ 'SQL',
40
+ bvs,
41
+ )
42
+ end
43
+ else
44
+ def _update_record_with_turntable(values, id, id_was, turntable_scope = nil) # :nodoc:
45
+ substitutes, binds = substitute_values values
46
+ condition_scope = @klass.unscoped.where(@klass.arel_table[@klass.primary_key].eq(id_was || id))
47
+ condition_scope = condition_scope.merge(turntable_scope) if turntable_scope
48
+ um = condition_scope.arel.compile_update(substitutes, @klass.primary_key)
49
+
50
+ @klass.connection.update(
51
+ um,
52
+ 'SQL',
53
+ binds)
54
+ end
29
55
  end
30
56
  end
31
57
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/lazy_load_hooks'
2
+
1
3
  module ActiveRecord::Turntable
2
4
  module Base
3
5
  extend ActiveSupport::Concern
@@ -7,12 +9,17 @@ module ActiveRecord::Turntable
7
9
  :turntable_enabled, :turntable_sequencer_enabled
8
10
 
9
11
  self.turntable_connections = {}
10
- self.turntable_clusters = Hash.new {|h,k| h[k]={}}
12
+ self.turntable_clusters = {}.with_indifferent_access
11
13
  self.turntable_enabled = false
12
14
  self.turntable_sequencer_enabled = false
13
15
  class << self
14
16
  delegate :shards_transaction, :with_all, :to => :connection
15
17
  end
18
+
19
+ ActiveSupport.on_load(:turntable_config_loaded) do
20
+ self.initialize_clusters!
21
+ end
22
+ include ClusterHelperMethods
16
23
  end
17
24
 
18
25
  module ClassMethods
@@ -26,55 +33,29 @@ module ActiveRecord::Turntable
26
33
  self.turntable_enabled = true
27
34
  self.turntable_cluster_name = cluster_name
28
35
  self.turntable_shard_key = shard_key_name
29
- self.turntable_cluster = Cluster.new(
30
- self,
31
- turntable_config[:clusters][cluster_name],
32
- options
33
- )
34
- self.turntable_clusters[cluster_name][self] = turntable_cluster
35
-
36
+ self.turntable_cluster =
37
+ self.turntable_clusters[cluster_name] ||= Cluster.new(
38
+ turntable_config[:clusters][cluster_name],
39
+ options
40
+ )
36
41
  turntable_replace_connection_pool
37
- turntable_define_cluster_methods(cluster_name)
38
- end
39
-
40
- #
41
- def force_transaction_all_shards!(options={}, &block)
42
- force_connect_all_shards!
43
- shards = turntable_connections.values
44
- shards += [ActiveRecord::Base.connection_pool]
45
- recursive_transaction(shards, options, &block)
46
42
  end
47
43
 
48
- def recursive_transaction(pools, options, &block)
49
- pool = pools.shift
50
- if pools.present?
51
- pool.connection.transaction(options) do
52
- recursive_transaction(pools, options, &block)
53
- end
54
- else
55
- pool.connection.transaction(options, &block)
56
- end
57
- end
58
-
59
- def force_connect_all_shards!
60
- conf = configurations[Rails.env]
61
- shards = {}
62
- shards = shards.merge(conf["shards"]) if conf["shards"]
63
- shards = shards.merge(conf["seq"]) if conf["seq"]
64
- shards.each do |name, config|
65
- turntable_connections[name] ||=
66
- ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec_for(config))
67
- end
68
- end
69
44
 
70
45
  def turntable_replace_connection_pool
71
46
  ch = connection_handler
72
- cp = turntable_cluster.connection_proxy
47
+ cp = ConnectionProxy.new(self, turntable_cluster)
73
48
  pp = PoolProxy.new(cp)
74
49
  ch.class_to_pool.clear if defined?(ch.class_to_pool)
75
50
  ch.send(:class_to_pool)[name] = ch.send(:owner_to_pool)[name] = pp
76
51
  end
77
52
 
53
+ def initialize_clusters!
54
+ turntable_config[:clusters].each do |name, spec|
55
+ self.turntable_clusters[name] ||= Cluster.new(spec, {})
56
+ end
57
+ end
58
+
78
59
  def spec_for(config)
79
60
  begin
80
61
  require "active_record/connection_adapters/#{config['adapter']}_adapter"
@@ -114,16 +95,6 @@ module ActiveRecord::Turntable
114
95
  turntable_cluster.select_shard(current_sequence) if sequencer_enabled?
115
96
  end
116
97
 
117
- def weighted_random_shard_with(*klasses, &block)
118
- shards_weight = self.turntable_cluster.weighted_shards
119
- sum = shards_weight.values.inject(&:+)
120
- idx = rand(sum)
121
- shard, weight = shards_weight.find {|k,v|
122
- (idx -= v) < 0
123
- }
124
- self.connection.with_recursive_shards(shard.name, *klasses, &block)
125
- end
126
-
127
98
  def with_shard(any_shard)
128
99
  shard = case any_shard
129
100
  when Numeric
@@ -135,41 +106,6 @@ module ActiveRecord::Turntable
135
106
  end
136
107
  connection.with_shard(shard) { yield }
137
108
  end
138
-
139
- private
140
-
141
- def turntable_define_cluster_methods(cluster_name)
142
- turntable_define_cluster_class_methods(cluster_name)
143
- end
144
-
145
- def turntable_define_cluster_class_methods(cluster_name)
146
- (class << ActiveRecord::Base; self; end).class_eval <<-EOD
147
- unless respond_to?(:#{cluster_name}_transaction)
148
- def #{cluster_name}_transaction(shards = [], options = {})
149
- cluster = turntable_clusters[#{cluster_name.inspect}].values.first
150
- cluster.shards_transaction(shards, options) { yield }
151
- end
152
- end
153
-
154
- unless respond_to?(:all_cluster_transaction)
155
- def all_cluster_transaction(options = {})
156
- clusters = turntable_clusters.values.map { |v| v.values.first }
157
- recursive_cluster_transaction(clusters) { yield }
158
- end
159
-
160
- def recursive_cluster_transaction(clusters, options = {}, &block)
161
- current_cluster = clusters.shift
162
- current_cluster.shards_transaction do
163
- if clusters.present?
164
- recursive_cluster_transaction(clusters, options, &block)
165
- else
166
- yield
167
- end
168
- end
169
- end
170
- end
171
- EOD
172
- end
173
109
  end
174
110
 
175
111
  def shards_transaction(options = {}, &block)
@@ -8,15 +8,11 @@ module ActiveRecord::Turntable
8
8
  "algorithm" => "range",
9
9
  }.with_indifferent_access
10
10
 
11
- def initialize(klass, cluster_spec, options = {})
12
- @klass = klass
11
+ def initialize(cluster_spec, options = {})
13
12
  @config = DEFAULT_CONFIG.merge(cluster_spec)
14
13
  @options = options.with_indifferent_access
15
14
  @shards = {}.with_indifferent_access
16
15
 
17
- # setup master shard
18
- @master_shard = MasterShard.new(klass)
19
-
20
16
  # setup sequencer
21
17
  if (seq = (@options[:seq] || @config[:seq])) && seq[:type] == :mysql
22
18
  @seq_shard = SeqShard.new(seq)
@@ -30,36 +26,21 @@ module ActiveRecord::Turntable
30
26
  # setup algorithm
31
27
  alg_name = "ActiveRecord::Turntable::Algorithm::#{@config["algorithm"].camelize}Algorithm"
32
28
  @algorithm = alg_name.constantize.new(@config)
33
-
34
- # setup proxy
35
- @connection_proxy = ConnectionProxy.new(self, cluster_spec)
36
- end
37
-
38
- def klass
39
- @klass
40
- end
41
-
42
- def master
43
- @master_shard
44
29
  end
45
30
 
46
31
  def seq
47
- @seq_shard || @master_shard
32
+ @seq_shard
48
33
  end
49
34
 
50
35
  def shards
51
36
  @shards
52
37
  end
53
38
 
54
- def connection_proxy
55
- @connection_proxy
56
- end
57
-
58
39
  def shard_for(key)
59
40
  @shards[@algorithm.calculate(key)]
60
41
  rescue
61
42
  raise ActiveRecord::Turntable::CannotSpecifyShardError,
62
- "[#{klass}] cannot select_shard for key:#{key}"
43
+ "cannot select_shard for key:#{key}"
63
44
  end
64
45
 
65
46
  def select_shard(key)
@@ -74,8 +55,7 @@ module ActiveRecord::Turntable
74
55
  shards = @shards.values.dup
75
56
  end
76
57
  end
77
- shard_or_object = shards.shift
78
- shard = to_shard(shard_or_object)
58
+ shard = to_shard(shards.shift)
79
59
  if shards.present?
80
60
  shard.connection.transaction(options) do
81
61
  shards_transaction(shards, options, true, &block)
@@ -98,14 +78,12 @@ module ActiveRecord::Turntable
98
78
  when Symbol
99
79
  shards[shard_or_object]
100
80
  else
101
- binding.pry
102
81
  raise ActiveRecord::Turntable::TurntableError,
103
82
  "transaction cannot call to object: #{shard_or_object}"
104
83
  end
105
84
  end
106
85
 
107
86
  def weighted_shards(key = nil)
108
- key ||= @klass.current_sequence
109
87
  Hash[@algorithm.calculate_used_shards_with_weight(key).map do |k,v|
110
88
  [@shards[k], v]
111
89
  end]
@@ -0,0 +1,85 @@
1
+ module ActiveRecord::Turntable
2
+ module ClusterHelperMethods
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ ActiveSupport.on_load(:turntable_config_loaded) do
7
+ turntable_clusters.each do |name, cluster|
8
+ turntable_define_cluster_methods(name)
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def force_transaction_all_shards!(options={}, &block)
15
+ force_connect_all_shards!
16
+ shards = turntable_connections.values
17
+ shards += [ActiveRecord::Base.connection_pool]
18
+ recursive_transaction(shards, options, &block)
19
+ end
20
+
21
+ def recursive_transaction(pools, options, &block)
22
+ pool = pools.shift
23
+ if pools.present?
24
+ pool.connection.transaction(options) do
25
+ recursive_transaction(pools, options, &block)
26
+ end
27
+ else
28
+ pool.connection.transaction(options, &block)
29
+ end
30
+ end
31
+
32
+ def force_connect_all_shards!
33
+ conf = configurations[Rails.env]
34
+ shards = {}
35
+ shards = shards.merge(conf["shards"]) if conf["shards"]
36
+ shards = shards.merge(conf["seq"]) if conf["seq"]
37
+ shards.each do |name, config|
38
+ turntable_connections[name] ||=
39
+ ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec_for(config))
40
+ end
41
+ end
42
+
43
+ def weighted_random_shard_with(*klasses, &block)
44
+ shards_weight = self.turntable_cluster.weighted_shards(self.current_sequence)
45
+ sum = shards_weight.values.inject(&:+)
46
+ idx = rand(sum)
47
+ shard, weight = shards_weight.find {|k,v|
48
+ (idx -= v) < 0
49
+ }
50
+ self.connection.with_recursive_shards(shard.name, *klasses, &block)
51
+ end
52
+
53
+ def all_cluster_transaction(options = {})
54
+ clusters = turntable_clusters.values
55
+ recursive_cluster_transaction(clusters) { yield }
56
+ end
57
+
58
+ def recursive_cluster_transaction(clusters, options = {}, &block)
59
+ current_cluster = clusters.shift
60
+ current_cluster.shards_transaction do
61
+ if clusters.present?
62
+ recursive_cluster_transaction(clusters, options, &block)
63
+ else
64
+ yield
65
+ end
66
+ end
67
+ end
68
+
69
+ def turntable_define_cluster_methods(cluster_name)
70
+ turntable_define_cluster_class_methods(cluster_name)
71
+ end
72
+
73
+ def turntable_define_cluster_class_methods(cluster_name)
74
+ (class << ActiveRecord::Base; self; end).class_eval <<-EOD
75
+ unless respond_to?(:#{cluster_name}_transaction)
76
+ def #{cluster_name}_transaction(shards = [], options = {})
77
+ cluster = turntable_clusters[#{cluster_name.inspect}]
78
+ cluster.shards_transaction(shards, options) { yield }
79
+ end
80
+ end
81
+ EOD
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,3 +1,4 @@
1
+ require 'active_support/lazy_load_hooks'
1
2
  require 'active_support/core_ext/hash/indifferent_access'
2
3
 
3
4
  module ActiveRecord::Turntable
@@ -13,12 +14,13 @@ module ActiveRecord::Turntable
13
14
  @config[key]
14
15
  end
15
16
 
16
- def self.load!(config_file, env = (defined?(Rails) ? Rails.env : 'development'))
17
+ def self.load!(config_file = ActiveRecord::Base.turntable_config_file, env = (defined?(Rails) ? Rails.env : 'development'))
17
18
  instance.load!(config_file, env)
18
19
  end
19
20
 
20
21
  def load!(config_file, env)
21
22
  @config = YAML.load(ERB.new(IO.read(config_file)).result).with_indifferent_access[env]
23
+ ActiveSupport.run_load_hooks(:turntable_config_loaded, ActiveRecord::Base)
22
24
  end
23
25
  end
24
26
  end
@@ -6,12 +6,14 @@ module ActiveRecord::Turntable
6
6
  # for expiring query cache
7
7
  CLEAR_CACHE_METHODS = [:update, :insert, :delete, :exec_insert, :exec_update, :exec_delete, :insert_many]
8
8
 
9
+ attr_reader :klass
9
10
  attr_writer :spec
10
11
 
11
- def initialize(cluster, options = {})
12
- @cluster = cluster
13
- @model_class = cluster.klass
14
- @default_current_shard = (cluster.master || cluster.shards.first[1])
12
+ def initialize(klass, cluster, options = {})
13
+ @klass = klass
14
+ @cluster = cluster
15
+ @master_shard = MasterShard.new(klass)
16
+ @default_current_shard = @master_shard
15
17
  @mixer = ActiveRecord::Turntable::Mixer.new(self)
16
18
  end
17
19
 
@@ -36,7 +38,7 @@ module ActiveRecord::Turntable
36
38
  end
37
39
 
38
40
  def enable_query_cache!
39
- @model_class.turntable_connections.each do |k,v|
41
+ klass.turntable_connections.each do |k,v|
40
42
  v.connection.enable_query_cache!
41
43
  end
42
44
  end
@@ -46,7 +48,7 @@ module ActiveRecord::Turntable
46
48
  end
47
49
 
48
50
  def clear_query_cache
49
- @model_class.turntable_connections.each do |k,v|
51
+ klass.turntable_connections.each do |k,v|
50
52
  v.connection.clear_query_cache
51
53
  end
52
54
  end
@@ -91,7 +93,7 @@ module ActiveRecord::Turntable
91
93
  end
92
94
 
93
95
  def master
94
- @cluster.master
96
+ @master_shard
95
97
  end
96
98
 
97
99
  def master_connection
@@ -99,7 +101,7 @@ module ActiveRecord::Turntable
99
101
  end
100
102
 
101
103
  def seq
102
- @cluster.seq
104
+ @cluster.seq || master
103
105
  end
104
106
 
105
107
  def current_shard
@@ -107,7 +109,7 @@ module ActiveRecord::Turntable
107
109
  end
108
110
 
109
111
  def current_shard=(shard)
110
- logger.debug { "Changing #{@model_class}'s shard to #{shard.name}"}
112
+ logger.debug { "Changing #{klass}'s shard to #{shard.name}"}
111
113
  current_shard_entry[object_id] = shard
112
114
  end
113
115
 
@@ -170,7 +172,7 @@ module ActiveRecord::Turntable
170
172
  # Send queries to master connection and all shards in this cluster
171
173
  # @param [Boolean] continue_on_error when a shard raises error, ignore exception and continue
172
174
  def with_master_and_all(continue_on_error = false)
173
- ([@cluster.master] + @cluster.shards.values).map do |shard|
175
+ ([master] + @cluster.shards.values).map do |shard|
174
176
  begin
175
177
  with_shard(shard) {
176
178
  yield
@@ -185,7 +187,7 @@ module ActiveRecord::Turntable
185
187
  end
186
188
 
187
189
  def with_master(&block)
188
- with_shard(@cluster.master) do
190
+ with_shard(master) do
189
191
  yield
190
192
  end
191
193
  end
@@ -126,12 +126,12 @@ module ActiveRecord::Turntable
126
126
  def build_select_fader(tree, method, query, *args, &block)
127
127
  shard_keys = if !tree.where and tree.from.size == 1 and SQLTree::Node::SubQuery === tree.from.first.table_reference.table
128
128
  find_shard_keys(tree.from.first.table_reference.table.where,
129
- @proxy.cluster.klass.table_name,
130
- @proxy.cluster.klass.turntable_shard_key.to_s)
129
+ @proxy.klass.table_name,
130
+ @proxy.klass.turntable_shard_key.to_s)
131
131
  else
132
132
  find_shard_keys(tree.where,
133
- @proxy.cluster.klass.table_name,
134
- @proxy.cluster.klass.turntable_shard_key.to_s)
133
+ @proxy.klass.table_name,
134
+ @proxy.klass.turntable_shard_key.to_s)
135
135
  end
136
136
 
137
137
  if shard_keys.size == 1 # shard
@@ -186,7 +186,7 @@ module ActiveRecord::Turntable
186
186
  end
187
187
 
188
188
  def build_update_fader(tree, method, query, *args, &block)
189
- shard_keys = find_shard_keys(tree.where, @proxy.cluster.klass.table_name, @proxy.cluster.klass.turntable_shard_key.to_s)
189
+ shard_keys = find_shard_keys(tree.where, @proxy.klass.table_name, @proxy.klass.turntable_shard_key.to_s)
190
190
  shards_with_query = if shard_keys.present?
191
191
  build_shards_with_same_query(shard_keys.map {|k| @proxy.cluster.shard_for(k) }, query)
192
192
  else
@@ -208,7 +208,7 @@ module ActiveRecord::Turntable
208
208
  end
209
209
 
210
210
  def build_insert_fader(tree, method, query, *args, &block)
211
- values_hash = divide_insert_values(tree, @proxy.cluster.klass.turntable_shard_key)
211
+ values_hash = divide_insert_values(tree, @proxy.klass.turntable_shard_key)
212
212
  shards_with_query = {}
213
213
  values_hash.each do |k,vs|
214
214
  tree.values = [[SQLTree::Node::Expression::Variable.new("\\0")]]
@@ -12,6 +12,13 @@ module ActiveRecord::Turntable
12
12
  end
13
13
  end
14
14
 
15
+ # initialize
16
+ initializer "turntable.initialize_clusters" do
17
+ ActiveSupport.on_load(:active_record) do
18
+ ActiveRecord::Turntable::Config.load!
19
+ end
20
+ end
21
+
15
22
  # QueryCache Middleware for turntable shards
16
23
  initializer "turntable.insert_query_cache_middleware" do |app|
17
24
  app.middleware.insert_after ActiveRecord::QueryCache, ActiveRecord::Turntable::Rack::QueryCache
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "2.0.6"
3
+ VERSION = "2.1.0.beta1"
4
4
  end
5
5
  end
@@ -20,6 +20,7 @@ module ActiveRecord::Turntable
20
20
  autoload :Algorithm
21
21
  autoload :Base
22
22
  autoload :Cluster
23
+ autoload :ClusterHelperMethods
23
24
  autoload :Config
24
25
  autoload :ConnectionProxy
25
26
  autoload :MasterShard
@@ -64,5 +65,9 @@ module ActiveRecord::Turntable
64
65
  rails4? && ActiveRecord::VERSION::MINOR >= 1
65
66
  end
66
67
 
68
+ def self.rails42_later?
69
+ rails4? && ActiveRecord::VERSION::MINOR >= 2
70
+ end
71
+
67
72
  require "active_record/turntable/railtie" if defined?(Rails)
68
73
  end
@@ -49,14 +49,14 @@ describe ActiveRecord::Turntable::ActiveRecordExt::Association do
49
49
  let(:cards_user) { CardsUser.where(user: user).first }
50
50
 
51
51
  context "associated objects has same turntable_key" do
52
- subject { cards_user.cards_users_histories }
52
+ subject { cards_user.cards_users_histories.to_a }
53
53
  it { expect { subject }.to_not raise_error }
54
54
  it { is_expected.to include(*cards_users_histories.select { |history| history.cards_user_id == cards_user.id }) }
55
55
  end
56
56
 
57
57
  context "associated objects has different turntable_key" do
58
58
  context "when foreign_shard_key option passed" do
59
- subject { cards_user.events_users_histories_with_foreign_shard_key }
59
+ subject { cards_user.events_users_histories_with_foreign_shard_key.to_a }
60
60
 
61
61
  it { expect { subject }.to_not raise_error }
62
62
  it { is_expected.to include(*events_users_histories.select { |history| history.cards_user_id == cards_user.id }) }
@@ -34,7 +34,9 @@ describe ActiveRecord::Turntable::ActiveRecordExt::Persistence do
34
34
  let(:card){
35
35
  Card.create!(:name => 'foobar')
36
36
  }
37
-
37
+ let(:cards_user){
38
+ user.cards_users.create(card: card)
39
+ }
38
40
  context "When creating record" do
39
41
  context "with blob column" do
40
42
  let(:blob_value) { "\123\123\123" }
@@ -108,31 +110,31 @@ describe ActiveRecord::Turntable::ActiveRecordExt::Persistence do
108
110
 
109
111
  context "When the model is sharded by other key" do
110
112
  it "should send shard_key condition when updating" do
111
- user_status.hp = 20
113
+ cards_user.num = 10
112
114
 
113
115
  strio = StringIO.new
114
116
  ActiveRecord::Base.logger = Logger.new(strio)
115
117
  expect {
116
- user_status.save!
118
+ cards_user.save!
117
119
  }.to_not raise_error
118
- expect(strio.string).to match(/`user_statuses`\.`user_id` = #{user_status.user_id}[^\s]*($|\s)/)
120
+ expect(strio.string).to match(/`cards_users`\.`user_id` = #{cards_user.user_id}[^\s]*($|\s)/)
119
121
  end
120
122
 
121
123
  it "should change updated_at when updating" do
122
- user_status.hp = 20
124
+ cards_user.num = 2
123
125
 
124
126
  expect {
125
- user_status.save!
126
- }.to change(user_status, :updated_at)
127
+ cards_user.save!
128
+ }.to change(cards_user, :updated_at)
127
129
  end
128
130
 
129
131
  it "should send shard_key condition when destroying" do
130
132
  strio = StringIO.new
131
133
  ActiveRecord::Base.logger = Logger.new(strio)
132
134
  expect {
133
- user_status.destroy
135
+ cards_user.destroy
134
136
  }.to_not raise_error
135
- expect(strio.string).to match(/`user_statuses`\.`user_id` = #{user_status.user_id}[^\s]*($|\s)/)
137
+ expect(strio.string).to match(/`cards_users`\.`user_id` = #{cards_user.user_id}[^\s]*($|\s)/)
136
138
  end
137
139
 
138
140
  it "should warn when creating without shard_key" do
@@ -140,39 +142,39 @@ describe ActiveRecord::Turntable::ActiveRecordExt::Persistence do
140
142
  end
141
143
 
142
144
  it "should execute one query when reloading" do
143
- user; user_status
145
+ user; cards_user
144
146
  strio = StringIO.new
145
147
  ActiveRecord::Base.logger = Logger.new(strio)
146
148
 
147
- expect { user_status.reload }.to_not raise_error
149
+ expect { cards_user.reload }.to_not raise_error
148
150
 
149
151
  expect(strio.string.split("\n").select {|stmt| stmt =~ /SELECT/ and stmt !~ /Turntable/ }).to have(1).items
150
152
  end
151
153
 
152
154
  it "should execute one query when touching" do
153
- user; user_status
155
+ user; cards_user
154
156
  strio = StringIO.new
155
157
  ActiveRecord::Base.logger = Logger.new(strio)
156
158
 
157
- expect { user_status.touch }.to_not raise_error
159
+ expect { cards_user.touch }.to_not raise_error
158
160
  expect(strio.string.split("\n").select {|stmt| stmt =~ /UPDATE/ and stmt !~ /Turntable/ }).to have(1).items
159
161
  end
160
162
 
161
163
  it "should execute one query when locking" do
162
- user; user_status
164
+ user; cards_user
163
165
  strio = StringIO.new
164
166
  ActiveRecord::Base.logger = Logger.new(strio)
165
167
 
166
- expect { user_status.lock! }.to_not raise_error
168
+ expect { cards_user.lock! }.to_not raise_error
167
169
  expect(strio.string.split("\n").select {|stmt| stmt =~ /SELECT/ and stmt !~ /Turntable/ }).to have(1).items
168
170
  end
169
171
 
170
172
  it "should execute one query when update_columns" do
171
- user; user_status
173
+ user; cards_user
172
174
  strio = StringIO.new
173
175
  ActiveRecord::Base.logger = Logger.new(strio)
174
176
 
175
- expect { user_status.update_columns(hp: 10) }.to_not raise_error
177
+ expect { cards_user.update_columns(num: 10) }.to_not raise_error
176
178
  expect(strio.string.split("\n").select {|stmt| stmt =~ /UPDATE/ and stmt !~ /Turntable/ }).to have(1).items
177
179
  end
178
180
  end
@@ -199,9 +201,9 @@ describe ActiveRecord::Turntable::ActiveRecordExt::Persistence do
199
201
  end
200
202
 
201
203
  context "When call reload" do
202
- subject { user_status.reload }
203
- it { is_expected.to be_instance_of(UserStatus)}
204
- it { is_expected.to eq(user_status) }
204
+ subject { cards_user.reload }
205
+ it { is_expected.to be_instance_of(CardsUser) }
206
+ it { is_expected.to eq(cards_user) }
205
207
  end
206
208
 
207
209
  end
@@ -10,14 +10,13 @@ describe ActiveRecord::Turntable::Cluster do
10
10
  truncate_shard
11
11
  end
12
12
  let(:cluster_config) { ActiveRecord::Base.turntable_config[:clusters][:user_cluster] }
13
- let(:cluster) { ActiveRecord::Turntable::Cluster.new(User, cluster_config) }
13
+ let(:cluster) { ActiveRecord::Turntable::Cluster.new(cluster_config) }
14
14
  let(:in_range_shard_key_value) { cluster_config[:shards].last[:less_than] - 1 }
15
15
  let(:out_of_range_shard_key_value) { cluster_config[:shards].last[:less_than] }
16
16
 
17
17
  context "When initialized" do
18
18
  subject { cluster }
19
19
 
20
- its(:klass) { should == User }
21
20
  its(:shards) { should have(3).items }
22
21
  end
23
22
 
@@ -11,8 +11,8 @@ describe ActiveRecord::Turntable::ConnectionProxy do
11
11
  truncate_shard
12
12
  end
13
13
 
14
- let(:cluster) { ActiveRecord::Turntable::Cluster.new(User, ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
15
- subject { ActiveRecord::Turntable::ConnectionProxy.new(cluster) }
14
+ let(:cluster) { ActiveRecord::Turntable::Cluster.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
15
+ subject { ActiveRecord::Turntable::ConnectionProxy.new(User, cluster) }
16
16
 
17
17
  its(:master_connection) { is_expected.to eql(ActiveRecord::Base.connection) }
18
18
  end
@@ -8,8 +8,8 @@ describe ActiveRecord::Turntable::Mixer do
8
8
  before do
9
9
  establish_connection_to(:test)
10
10
  truncate_shard
11
- @cluster = ActiveRecord::Turntable::Cluster.new(User, ActiveRecord::Base.turntable_config[:clusters][:user_cluster])
12
- @connection_proxy = ActiveRecord::Turntable::ConnectionProxy.new(@cluster)
11
+ @cluster = ActiveRecord::Turntable::Cluster.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster])
12
+ @connection_proxy = ActiveRecord::Turntable::ConnectionProxy.new(User, @cluster)
13
13
  end
14
14
 
15
15
  context "When initialized" do
@@ -12,7 +12,7 @@ describe "transaction" do
12
12
  let(:clusters) { ActiveRecord::Base.turntable_clusters }
13
13
 
14
14
  describe "all_cluster_transaction" do
15
- let(:all_clusters) { clusters.values.map { |v| v.values.first } }
15
+ let(:all_clusters) { clusters.values }
16
16
  let(:shards) { all_clusters.map { |c| c.shards.values }.flatten(1) }
17
17
 
18
18
  it "all shards should begin transaction" do
@@ -23,7 +23,7 @@ describe "transaction" do
23
23
  end
24
24
 
25
25
  describe "cluster_transaction" do
26
- let(:cluster) { clusters[:user_cluster].values.first }
26
+ let(:cluster) { clusters[:user_cluster] }
27
27
  let(:shards) { cluster.shards.values }
28
28
 
29
29
  it "all shards in the cluster should begin transaction" do
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,11 @@ require 'bundler/setup'
5
5
  require 'rspec/its'
6
6
  require 'rspec/collection_matchers'
7
7
  require 'webmock/rspec'
8
+ require 'pry'
9
+ begin
10
+ require 'pry-byebug'
11
+ rescue LoadError
12
+ end
8
13
 
9
14
  require 'activerecord-turntable'
10
15
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-turntable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.6
4
+ version: 2.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - gussan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-08 00:00:00.000000000 Z
12
+ date: 2015-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -261,6 +261,20 @@ dependencies:
261
261
  - - ">="
262
262
  - !ruby/object:Gem::Version
263
263
  version: '0'
264
+ - !ruby/object:Gem::Dependency
265
+ name: pry-byebug
266
+ requirement: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - ">="
269
+ - !ruby/object:Gem::Version
270
+ version: '0'
271
+ type: :development
272
+ prerelease: false
273
+ version_requirements: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
264
278
  - !ruby/object:Gem::Dependency
265
279
  name: guard-rspec
266
280
  requirement: !ruby/object:Gem::Requirement
@@ -354,6 +368,7 @@ files:
354
368
  - lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb
355
369
  - lib/active_record/turntable/base.rb
356
370
  - lib/active_record/turntable/cluster.rb
371
+ - lib/active_record/turntable/cluster_helper_methods.rb
357
372
  - lib/active_record/turntable/config.rb
358
373
  - lib/active_record/turntable/connection_proxy.rb
359
374
  - lib/active_record/turntable/connection_proxy/mixable.rb
@@ -445,9 +460,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
445
460
  version: 1.9.3
446
461
  required_rubygems_version: !ruby/object:Gem::Requirement
447
462
  requirements:
448
- - - ">="
463
+ - - ">"
449
464
  - !ruby/object:Gem::Version
450
- version: '0'
465
+ version: 1.3.1
451
466
  requirements: []
452
467
  rubyforge_project: activerecord-turntable
453
468
  rubygems_version: 2.4.4