switchman 1.5.6 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/db/shard_1708.sqlite3 +0 -0
- data/lib/switchman/active_record/query_methods.rb +17 -0
- data/lib/switchman/active_record/statement_cache.rb +31 -2
- data/lib/switchman/engine.rb +1 -2
- data/lib/switchman/version.rb +1 -1
- metadata +4 -6
- data/lib/switchman/active_record/core.rb +0 -18
- data/lib/switchman/engine.rb~ +0 -203
- data/lib/switchman/shard_aware_statement_cache.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a061d43139c6beef4a69af819d1797a7d14650d
|
4
|
+
data.tar.gz: 4efbe1614848d2d2ba0e23d8bc8b993ff44a9fc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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)
|
data/lib/switchman/engine.rb
CHANGED
@@ -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
|
data/lib/switchman/version.rb
CHANGED
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.
|
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-
|
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.
|
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
|
data/lib/switchman/engine.rb~
DELETED
@@ -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
|