switchman 1.5.6 → 1.5.7

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: 9f89b4901f87f3beb95a7714ad526cb67907068d
4
- data.tar.gz: b16ba8ab6429b604f83a5a6cdc45f5c4a4322e06
3
+ metadata.gz: 9a061d43139c6beef4a69af819d1797a7d14650d
4
+ data.tar.gz: 4efbe1614848d2d2ba0e23d8bc8b993ff44a9fc9
5
5
  SHA512:
6
- metadata.gz: ccc0efa41d2ecc1b2d7eacda7bb6cf9574156fb4d4fda8c57affb3c115086574a8f500369f9eaf10e59362016f964babad253c68bcdc6f079143a722f23c244d
7
- data.tar.gz: 203bbd2ed5c185f4e737d292c5b9c16640500811035bc7b21f84b5a10372db1fd466124ed737e063b417c4819a6f8075c338164818ffce551d7748d59ba51bd0
6
+ metadata.gz: 423e156b64348617b371ff59e042db181a69eda6a64bae54c5823b4e8e6e4f35b0ed748c4ee2f6e4d462bd17501f6bd417c881d3edb6c21266f7421650716d15
7
+ data.tar.gz: 8ced56c4ab5bf0327b98d8fa4d25b228b02badb181866f722d79cce44eece0148f1b0dd328ec93a91181d7802a65123cd1c3e33d2811a35115bdae95a18eb83b
File without changes
@@ -91,6 +91,7 @@ module Switchman
91
91
  end
92
92
  end
93
93
 
94
+
94
95
  private
95
96
 
96
97
  [:where, :having].each do |type|
@@ -222,6 +223,22 @@ module Switchman
222
223
  super.tap { |factory| factory.scope = self }
223
224
  end
224
225
 
226
+ def arel_columns(columns)
227
+ columns.map do |field|
228
+ if (Symbol === field || String === field) && ::Rails.version >= '5' && (klass.has_attribute?(field) || klass.attribute_alias?(field)) && !from_clause.value
229
+ klass.arel_attribute(field, table)
230
+ elsif (Symbol === field || String === field) && ::Rails.version < '5' && columns_hash.key?(field.to_s) && !from_value
231
+ arel_table[field]
232
+ elsif Symbol === field
233
+ # the rest of this is pulled from AR - the only change is from quote_table_name to quote_column_name here
234
+ # otherwise qualified names will add the schema to a column
235
+ connection.quote_column_name(field.to_s)
236
+ else
237
+ field
238
+ end
239
+ end
240
+ end
241
+
225
242
  # semi-private
226
243
  public
227
244
  def transpose_predicates(predicates, source_shard, target_shard, remove_nonlocal_primary_keys = false, binds = nil)
@@ -1,6 +1,22 @@
1
1
  module Switchman
2
2
  module ActiveRecord
3
3
  module StatementCache
4
+ module ClassMethods
5
+ def create(connection, block = Proc.new)
6
+ relation = block.call ::ActiveRecord::StatementCache::Params.new
7
+
8
+ binds = ::Rails.version >= '5' ? relation.bound_attributes : relation.bind_values
9
+ bind_map = ::ActiveRecord::StatementCache::BindMap.new(binds)
10
+ new relation.arel, bind_map
11
+ end
12
+ end
13
+
14
+ def initialize(arel, bind_map)
15
+ @arel = arel
16
+ @bind_map = bind_map
17
+ @qualified_query_builders = {}
18
+ end
19
+
4
20
  # since the StatememtCache is only implemented
5
21
  # for basic relations in AR::Base#find, AR::Base#find_by and AR::Association#get_records,
6
22
  # we can make some assumptions about the shard source
@@ -17,12 +33,25 @@ module Switchman
17
33
 
18
34
  bind_values = bind_map.bind(params, current_shard, target_shard)
19
35
 
20
- sql = query_builder.sql_for(bind_values, connection)
21
36
  target_shard.activate(klass.shard_category) do
22
- klass.find_by_sql(sql, bind_values)
37
+ if connection.use_qualified_names?
38
+ sql = qualified_query_builder(target_shard, klass).sql_for(bind_values, connection)
39
+ klass.find_by_sql(sql, bind_values)
40
+ else
41
+ sql = generic_query_builder(connection).sql_for(bind_values, connection)
42
+ klass.find_by_sql(sql, bind_values)
43
+ end
23
44
  end
24
45
  end
25
46
 
47
+ def generic_query_builder(connection)
48
+ @query_builder ||= connection.cacheable_query(@arel)
49
+ end
50
+
51
+ def qualified_query_builder(shard, klass)
52
+ @qualified_query_builders[shard.id] ||= klass.connection.cacheable_query(@arel)
53
+ end
54
+
26
55
  module BindMap
27
56
  # performs id transposition here instead of query_methods.rb
28
57
  def bind(values, current_shard, target_shard)
@@ -94,11 +94,10 @@ module Switchman
94
94
 
95
95
  if ::Rails.version > '4.2'
96
96
  require "switchman/active_record/statement_cache"
97
- require "switchman/active_record/core"
98
97
  ::ActiveRecord::StatementCache.prepend(ActiveRecord::StatementCache)
98
+ ::ActiveRecord::StatementCache.singleton_class.prepend(ActiveRecord::StatementCache::ClassMethods)
99
99
  ::ActiveRecord::StatementCache::BindMap.prepend(ActiveRecord::StatementCache::BindMap)
100
100
  ::ActiveRecord::StatementCache::Substitute.send(:attr_accessor, :primary, :sharded)
101
- singleton_class.prepend ActiveRecord::Core
102
101
 
103
102
  ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::CollectionAssociation)
104
103
  end
@@ -1,3 +1,3 @@
1
1
  module Switchman
2
- VERSION = "1.5.6"
2
+ VERSION = "1.5.7"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: switchman
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.6
4
+ version: 1.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-06-07 00:00:00.000000000 Z
13
+ date: 2016-06-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: railties
@@ -162,6 +162,7 @@ files:
162
162
  - app/models/switchman/shard_internal.rb
163
163
  - db/migrate/20130328212039_create_switchman_shards.rb
164
164
  - db/migrate/20130328224244_create_default_shard.rb
165
+ - db/shard_1708.sqlite3
165
166
  - lib/switchman.rb
166
167
  - lib/switchman/action_controller/caching.rb
167
168
  - lib/switchman/active_record/abstract_adapter.rb
@@ -172,7 +173,6 @@ files:
172
173
  - lib/switchman/active_record/calculations.rb
173
174
  - lib/switchman/active_record/connection_handler.rb
174
175
  - lib/switchman/active_record/connection_pool.rb
175
- - lib/switchman/active_record/core.rb
176
176
  - lib/switchman/active_record/finder_methods.rb
177
177
  - lib/switchman/active_record/log_subscriber.rb
178
178
  - lib/switchman/active_record/model_schema.rb
@@ -194,7 +194,6 @@ files:
194
194
  - lib/switchman/database_server.rb
195
195
  - lib/switchman/default_shard.rb
196
196
  - lib/switchman/engine.rb
197
- - lib/switchman/engine.rb~
198
197
  - lib/switchman/environment.rb
199
198
  - lib/switchman/errors.rb
200
199
  - lib/switchman/r_spec_helper.rb
@@ -202,7 +201,6 @@ files:
202
201
  - lib/switchman/schema_cache.rb
203
202
  - lib/switchman/shackles.rb
204
203
  - lib/switchman/shackles/relation.rb
205
- - lib/switchman/shard_aware_statement_cache.rb
206
204
  - lib/switchman/sharded_instrumenter.rb
207
205
  - lib/switchman/test_helper.rb
208
206
  - lib/switchman/version.rb
@@ -227,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
225
  version: '0'
228
226
  requirements: []
229
227
  rubyforge_project:
230
- rubygems_version: 2.6.4
228
+ rubygems_version: 2.4.5
231
229
  signing_key:
232
230
  specification_version: 4
233
231
  summary: Rails 4 sharding magic
@@ -1,18 +0,0 @@
1
- require "switchman/shard_aware_statement_cache"
2
-
3
- module Switchman
4
- module ActiveRecord
5
- module Core
6
- def initialize_find_by_cache
7
- if ::Rails.version < '5'
8
- self.find_by_statement_cache = ShardAwareStatementCache.new(shard_category)
9
- else
10
- # note that this will not work beyond ActiveRecord 5.0.0.beta3 since
11
- # as of beta4 this has been replaced with a hash containing two separate caches:
12
- # one for prepared statements, and one for unprepared ones
13
- @find_by_statement_cache = ShardAwareStatementCache.new(shard_category)
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,203 +0,0 @@
1
- module Switchman
2
- class Engine < ::Rails::Engine
3
- require 'byebug'
4
- debugger
5
- isolate_namespace Switchman
6
-
7
- config.autoload_once_paths << File.expand_path(File.join(__FILE__, "../../../app/models"))
8
-
9
- def self.lookup_stores(cache_store_config)
10
- result = {}
11
- cache_store_config.each do |key, value|
12
- next if value.is_a?(String)
13
- result[key] = ::ActiveSupport::Cache.lookup_store(value)
14
- end
15
-
16
- cache_store_config.each do |key, value|
17
- next unless value.is_a?(String)
18
- result[key] = result[value]
19
- end
20
- result
21
- end
22
-
23
- initializer 'switchman.initialize_cache', :before => 'initialize_cache' do
24
- require "switchman/active_support/cache"
25
- ::ActiveSupport::Cache.singleton_class.prepend(ActiveSupport::Cache::ClassMethods)
26
-
27
- # if we haven't already setup our cache map out-of-band, set it up from
28
- # config.cache_store now. behaves similarly to Rails' default
29
- # initialize_cache initializer, but for each value in the map, rather
30
- # than just Rails.cache. if config.cache_store is a flat value, uses it
31
- # to fill just the Rails.env entry in the cache map.
32
- unless Switchman.config[:cache_map].present?
33
- cache_store_config = ::Rails.configuration.cache_store
34
- unless cache_store_config.is_a?(Hash)
35
- cache_store_config = {::Rails.env => cache_store_config}
36
- end
37
-
38
- Switchman.config[:cache_map] = Engine.lookup_stores(cache_store_config)
39
- end
40
-
41
- # if the configured cache map (either from before, or as populated from
42
- # config.cache_store) didn't have an entry for Rails.env, add one using
43
- # lookup_store(nil); matches the behavior of Rails' default
44
- # initialize_cache initializer when config.cache_store is nil.
45
- unless Switchman.config[:cache_map].has_key?(::Rails.env)
46
- value = ::ActiveSupport::Cache.lookup_store(nil)
47
- Switchman.config[:cache_map][::Rails.env] = value
48
- end
49
-
50
- middlewares = Switchman.config[:cache_map].values.map do |store|
51
- store.middleware if store.respond_to?(:middleware)
52
- end.compact.uniq
53
- middlewares.each do |middleware|
54
- config.middleware.insert_before("Rack::Runtime", middleware)
55
- end
56
-
57
- # prevent :initialize_cache from trying to (or needing to) set
58
- # Rails.cache. once our switchman.extend_ar initializer (below) runs
59
- # Rails.cache will be overridden to pull appropriate values from the
60
- # cache map, but between now and then, Rails.cache should return the
61
- # Rails.env entry in the cache map.
62
- ::Rails.cache = Switchman.config[:cache_map][::Rails.env]
63
-
64
- require "switchman/rails"
65
- ::Rails.singleton_class.prepend(Rails::ClassMethods)
66
- end
67
-
68
- initializer 'switchman.asplode', :after => "active_record.initialize_database" do
69
- ::Rails.cache
70
- end
71
-
72
- initializer 'switchman.extend_ar', :before => "active_record.initialize_database" do
73
- ::ActiveSupport.on_load(:active_record) do
74
- require 'byebug'
75
- debugger
76
- require "switchman/active_record/abstract_adapter"
77
- require "switchman/active_record/association"
78
- require "switchman/active_record/attribute_methods"
79
- require "switchman/active_record/base"
80
- require "switchman/active_record/calculations"
81
- require "switchman/active_record/connection_handler"
82
- require "switchman/active_record/connection_pool"
83
- require "switchman/active_record/finder_methods"
84
- require "switchman/active_record/log_subscriber"
85
- require "switchman/active_record/model_schema"
86
- require "switchman/active_record/persistence"
87
- require "switchman/active_record/predicate_builder"
88
- require "switchman/active_record/query_cache"
89
- require "switchman/active_record/query_methods"
90
- require "switchman/active_record/reflection"
91
- require "switchman/active_record/relation"
92
- require "switchman/active_record/spawn_methods"
93
- require "switchman/active_record/where_clause_factory"
94
- require "switchman/active_record/type_caster"
95
- require "switchman/arel"
96
- require "switchman/shackles/relation"
97
-
98
- include ActiveRecord::Base
99
- include ActiveRecord::AttributeMethods
100
- include ActiveRecord::Persistence
101
- singleton_class.prepend ActiveRecord::ModelSchema::ClassMethods
102
-
103
- if ::Rails.version > '4.2'
104
- require "switchman/active_record/statement_cache"
105
- ::ActiveRecord::StatementCache.prepend(ActiveRecord::StatementCache)
106
- ::ActiveRecord::StatementCache::BindMap.prepend(ActiveRecord::StatementCache::BindMap)
107
- ::ActiveRecord::StatementCache::Substitute.send(:attr_accessor, :primary, :sharded)
108
-
109
- ::ActiveRecord::Associations::CollectionAssociation.prepend(ActiveRecord::CollectionAssociation)
110
- ::ActiveRecord::PredicateBuilder.singleton_class.prepend(ActiveRecord::PredicateBuilder)
111
- end
112
-
113
- if ::Rails.version > '4.1'
114
- prepend(ActiveRecord::AutosaveAssociation)
115
- end
116
-
117
- ::ActiveRecord::Associations::Association.prepend(ActiveRecord::Association)
118
- ::ActiveRecord::Associations::BelongsToAssociation.prepend(ActiveRecord::BelongsToAssociation)
119
- ::ActiveRecord::Associations::CollectionProxy.include(ActiveRecord::CollectionProxy)
120
- if ::Rails.version < '5'
121
- ::ActiveRecord::Associations::Builder::CollectionAssociation.include(ActiveRecord::Builder::CollectionAssociation)
122
- end
123
-
124
- ::ActiveRecord::Associations::Preloader::Association.prepend(ActiveRecord::Preloader::Association)
125
- ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::AbstractAdapter)
126
- ::ActiveRecord::ConnectionAdapters::ConnectionHandler.prepend(ActiveRecord::ConnectionHandler)
127
- ::ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ActiveRecord::ConnectionPool)
128
- ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(ActiveRecord::QueryCache)
129
- # when we call super in Switchman::ActiveRecord::QueryCache#select_all,
130
- # we want it to find the definition from
131
- # ActiveRecord::ConnectionAdapters::DatabaseStatements, not
132
- # ActiveRecord::ConnectionAdapters::QueryCache
133
- ::ActiveRecord::ConnectionAdapters::QueryCache.send(:remove_method, :select_all)
134
-
135
- ::ActiveRecord::LogSubscriber.prepend(ActiveRecord::LogSubscriber)
136
- ::ActiveRecord::Reflection::AssociationReflection.prepend(ActiveRecord::Reflection::AssociationReflection)
137
- ::ActiveRecord::Relation.prepend(ActiveRecord::Calculations)
138
- ::ActiveRecord::Relation.include(ActiveRecord::FinderMethods)
139
- ::ActiveRecord::Relation.include(ActiveRecord::QueryMethods)
140
- ::ActiveRecord::Relation.prepend(ActiveRecord::Relation)
141
- ::ActiveRecord::Relation.include(ActiveRecord::SpawnMethods)
142
- ::ActiveRecord::Relation.prepend(Shackles::Relation)
143
-
144
- if ::Rails.version >= '5'
145
- ::ActiveRecord::Relation::WhereClauseFactory.prepend(ActiveRecord::WhereClauseFactory)
146
- ::ActiveRecord::PredicateBuilder::AssociationQueryValue.prepend(ActiveRecord::PredicateBuilder::AssociationQueryValue)
147
- ::ActiveRecord::TypeCaster::Map.include(ActiveRecord::TypeCaster::Map)
148
- ::ActiveRecord::TypeCaster::Connection.include(ActiveRecord::TypeCaster::Connection)
149
- end
150
-
151
- ::Arel::Table.prepend(Arel::Table)
152
- ::Arel::Visitors::ToSql.prepend(Arel::Visitors::ToSql)
153
- ::Arel::Visitors::PostgreSQL.include(Arel::Visitors::PostgreSQL) if ::Rails.version < '4.2'
154
- end
155
- end
156
-
157
- def self.foreign_key_check(name, type, options)
158
- if name.to_s =~ /_id\z/ && type.to_s == 'integer' && options[:limit].to_i < 8
159
- puts "WARNING: All foreign keys need to be 8-byte integers. #{name} looks like a foreign key. If so, please add the option: `:limit => 8`"
160
- end
161
- end
162
-
163
- initializer 'switchman.extend_connection_adapters', :after => "active_record.initialize_database" do
164
- ::ActiveSupport.on_load(:active_record) do
165
- ::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |klass|
166
- klass.prepend(ActiveRecord::AbstractAdapter::ForeignKeyCheck)
167
- end
168
-
169
- require 'switchman/active_record/table_definition'
170
- ::ActiveRecord::ConnectionAdapters::TableDefinition.prepend(ActiveRecord::TableDefinition)
171
-
172
- if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
173
- require "switchman/active_record/postgresql_adapter"
174
- ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecord::PostgreSQLAdapter)
175
- end
176
- end
177
- end
178
-
179
- initializer 'switchman.eager_load' do
180
- ::ActiveSupport.on_load(:before_eager_load) do
181
- # This needs to be loaded before Switchman::Shard, otherwise it won't autoload it correctly
182
- require 'active_record/base'
183
- end
184
- end
185
-
186
- initializer 'switchman.extend_shackles', :before => "switchman.extend_ar" do
187
- ::ActiveSupport.on_load(:active_record) do
188
- require "switchman/shackles"
189
-
190
- ::Shackles.singleton_class.prepend(Shackles::ClassMethods)
191
- end
192
- end
193
-
194
- initializer 'switchman.extend_controller', :after => "shackles.extend_ar" do
195
- ::ActiveSupport.on_load(:action_controller) do
196
- require "switchman/action_controller/caching"
197
-
198
- ::ActionController::Base.include(ActionController::Caching)
199
- end
200
- end
201
-
202
- end
203
- end
@@ -1,21 +0,0 @@
1
- module Switchman
2
- class ShardAwareStatementCache
3
-
4
- attr_accessor :__cache, :shard_category
5
- private :__cache, :shard_category
6
-
7
- def initialize(shard_category)
8
- self.extend Mutex_m
9
- self.__cache = {}
10
- self.shard_category = shard_category
11
- end
12
-
13
- def [](key)
14
- __cache[[key, Shard.current(shard_category).id]]
15
- end
16
-
17
- def []=(key, value)
18
- __cache[[key, Shard.current(shard_category).id]] = value
19
- end
20
- end
21
- end