switchman 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 657642d7cee67361f96f71c662754e3045797d54
4
- data.tar.gz: b812153caf29c4699863e85c3fd65f1146b1ba83
3
+ metadata.gz: afbf29688ae3158c8e0a6e02d5dd27355d33fcc9
4
+ data.tar.gz: 104a872cbf73ba12f5a9bdc74d25db7d25d68c59
5
5
  SHA512:
6
- metadata.gz: 85b96aae81f8939ab5625d582ede7a46e795db85b6fc60c04207dde636701ff8dca25d1517ceb794c232f39309a45df8f3e00a812e91c63776471883da53eea0
7
- data.tar.gz: 081fd47e581206a4b628ff13d3eff837c8a4fbc9f143b08ae32cabfeff53153a78d733eb904048bcf4f23bd7aab6dfbb8fa1e2049388882e7cb060e6af9eea5f
6
+ metadata.gz: 453bb244bc91a04501f5952f629a964ebcb338629a6ba4e3530954a71325bb268acbc514619e1ca06d68c6d56d333e24575dc6eb053c8c86a22506462882c0ca
7
+ data.tar.gz: 9f39e116166e29ce9bfaf22aff35d84821f8d8ccbd2ff93032cb8dfbabd77c695e4a4a1aaf4608ca5171b31b17a66325357f16a85b9b6aeb83bb1aa9c8f84941
@@ -470,6 +470,7 @@ module Switchman
470
470
  end
471
471
 
472
472
  def shard_for(any_id, source_shard = nil)
473
+ return any_id.shard if any_id.is_a?(::ActiveRecord::Base)
473
474
  _, shard = local_id_for(any_id)
474
475
  shard || source_shard || Shard.current
475
476
  end
@@ -103,7 +103,7 @@ module Switchman
103
103
  # for belongs_to, it's the shard of the foreign_key
104
104
  partition_proc = ->(owner) do
105
105
  if owner.class.sharded_column?(owner_key_name)
106
- Shard.shard_for(owner, owner[owner_key_name])
106
+ Shard.shard_for(owner[owner_key_name], owner.shard)
107
107
  else
108
108
  Shard.current
109
109
  end
@@ -1,3 +1,5 @@
1
+ require 'switchman/errors'
2
+
1
3
  module Switchman
2
4
  module ActiveRecord
3
5
  module ConnectionPool
@@ -26,6 +28,7 @@ module Switchman
26
28
 
27
29
  def connection
28
30
  conn = super
31
+ raise NonExistentShardError if shard.new_record?
29
32
  switch_database(conn) if conn.shard != self.shard
30
33
  conn
31
34
  end
@@ -11,6 +11,7 @@ module Switchman
11
11
  def global_id_for(local_id); local_id; end
12
12
  def database_server_id; nil; end
13
13
  def database_server; DatabaseServer.find(nil); end
14
+ def new_record?; false; end
14
15
  def name
15
16
  unless instance_variable_defined?(:@name)
16
17
  @name = nil # prevent taking this branch on recursion
@@ -0,0 +1,203 @@
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
@@ -0,0 +1,3 @@
1
+ module Switchman
2
+ class NonExistentShardError < RuntimeError; end
3
+ end
@@ -1,3 +1,3 @@
1
1
  module Switchman
2
- VERSION = "1.5.3"
2
+ VERSION = "1.5.4"
3
3
  end
@@ -225,6 +225,20 @@ module Switchman
225
225
  run_cmd('pg_dump', args, 'dumping')
226
226
  File.open(filename, "a") { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
227
227
  end
228
+
229
+ if ::Rails.version < '4.2.5'
230
+ # These methods are backported from rails 4.2.5 to work with the above
231
+ def run_cmd(cmd, args, action)
232
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
233
+ end
234
+
235
+ def run_cmd_error(cmd, args, action)
236
+ msg = "failed to execute:\n"
237
+ msg << "#{cmd} #{args.join(' ')}\n\n"
238
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
239
+ msg
240
+ end
241
+ end
228
242
  end
229
243
  end
230
244
  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.3
4
+ version: 1.5.4
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-03-28 00:00:00.000000000 Z
13
+ date: 2016-05-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: railties
@@ -192,7 +192,9 @@ files:
192
192
  - lib/switchman/database_server.rb
193
193
  - lib/switchman/default_shard.rb
194
194
  - lib/switchman/engine.rb
195
+ - lib/switchman/engine.rb~
195
196
  - lib/switchman/environment.rb
197
+ - lib/switchman/errors.rb
196
198
  - lib/switchman/r_spec_helper.rb
197
199
  - lib/switchman/rails.rb
198
200
  - lib/switchman/schema_cache.rb
@@ -222,9 +224,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
224
  version: '0'
223
225
  requirements: []
224
226
  rubyforge_project:
225
- rubygems_version: 2.5.1
227
+ rubygems_version: 2.6.4
226
228
  signing_key:
227
229
  specification_version: 4
228
230
  summary: Rails 4 sharding magic
229
231
  test_files: []
230
- has_rdoc: