product on schema 1 (1 row) set search_path = schema2; select * from products; name --------------------- product on schema 2 (1 row) PostgreSQL Schemas
|h,k| h[k] = ThreadSafe::Cache.new(:initial_capacity => 2) end @class_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k| h[k] = ThreadSafe::Cache.new end end def connection_pool_list owner_to_pool.values.compact end def connection_pools ActiveSupport::Deprecation.warn(<<-MSG.squish) In the next release, this will return the same as `#connection_pool_list`. (An array of pools, rather than a hash mapping specs to pools.) MSG Hash[connection_pool_list.map { |pool| [pool.spec, pool] }] end def establish_connection(owner, spec) @class_to_pool.clear raise RuntimeError, "Anonymous class is not allowed." unless owner.name owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec) end def active_connections? connection_pool_list.any?(&:active_connection?) end def clear_active_connections! connection_pool_list.each(&:release_connection) end def clear_reloadable_connections! connection_pool_list.each(&:clear_reloadable_connections!) end def clear_all_connections! connection_pool_list.each(&:disconnect!) end def retrieve_connection(klass) pool = retrieve_connection_pool(klass) raise ConnectionNotEstablished, "No connection pool for #{klass}" unless pool conn = pool.connection raise ConnectionNotEstablished, "No connection for #{klass} in connection pool" unless conn conn end def connected?(klass) conn = retrieve_connection_pool(klass) conn && conn.connected? end def remove_connection(owner) if pool = owner_to_pool.delete(owner.name) @class_to_pool.clear pool.automatic_reconnect = false pool.disconnect! pool.spec.config end end def retrieve_connection_pool(klass) class_to_pool[klass.name] ||= begin until pool = pool_for(klass) klass = klass.superclass break unless klass <= Base end class_to_pool[klass.name] = pool end end private def owner_to_pool @owner_to_pool[Process.pid] end def class_to_pool @class_to_pool[Process.pid] end def pool_for(owner) owner_to_pool.fetch(owner.name) { if ancestor_pool = pool_from_any_process_for(owner) establish_connection owner, ancestor_pool.spec else owner_to_pool[owner.name] = nil end } end def pool_from_any_process_for(owner) owner_to_pool = @owner_to_pool.values.find { |v| v[owner.name] } owner_to_pool && owner_to_pool[owner.name] end end Connection Handler (Rails 4.2)
class Book < ActiveRecord::Base establish_connection 'library_db' end Connection Handler (Rails 4.2) connection pool do ActiveRecord::Base connection pool da classe Book
_| name = name.to_sym handler = ConnectionHandler.new handler.establish_connection(self, spec(name)) @cache[name] = handler end end def connection_handler_for(name) @cache.fetch(name.to_sym) end end Connection Switcher
yield ensure clear_active_connections! ThreadRegistry.current_shard = old_shard end def connection_handler return super if use_master_connection? handler.connection_handler_for(current_shard) end end Connection Switcher
Contact.find_by(email: '[email protected]') end end request identificação da conta troca do database execução da ação restaura p/ schema anterior restaura p/ database anterior resposta
using('master', 'public') do ActiveRecord::Migrator.migrate('db/public') end Account.all.each do |acc| using(acc.shard_name, acc.schema_name) do ActiveRecord::Migrator.migrate('db/accounts') end end end Rails Tasks
|h,k| h[k] = Concurrent::Map.new(:initial_capacity => 2) end end def connection_pool_list owner_to_pool.values.compact end alias :connection_pools :connection_pool_list def establish_connection(spec) owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec) end def active_connections? connection_pool_list.any?(&:active_connection?) end def clear_active_connections! connection_pool_list.each(&:release_connection) end def clear_reloadable_connections! connection_pool_list.each(&:clear_reloadable_connections!) end def clear_all_connections! connection_pool_list.each(&:disconnect!) end def retrieve_connection(spec_name) pool = retrieve_connection_pool(spec_name) raise ConnectionNotEstablished, "No connection pool with id #{spec_name} found." unless pool conn = pool.connection raise ConnectionNotEstablished, "No connection for #{spec_name} in connection pool" unless conn conn end def connected?(spec_name) conn = retrieve_connection_pool(spec_name) conn && conn.connected? end def remove_connection(spec_name) if pool = owner_to_pool.delete(spec_name) pool.automatic_reconnect = false pool.disconnect! pool.spec.config end end def retrieve_connection_pool(spec_name) owner_to_pool.fetch(spec_name) do if ancestor_pool = pool_from_any_process_for(spec_name) establish_connection(ancestor_pool.spec).tap do |pool| pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache end else owner_to_pool[spec_name] = nil end end end private def owner_to_pool @owner_to_pool[Process.pid] end def pool_from_any_process_for(spec_name) owner_to_pool = @owner_to_pool.values.find { |v| v[spec_name] } owner_to_pool && owner_to_pool[spec_name] end end Connection Handler (Rails 5)
|pool| pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache end else owner_to_pool[spec_name] = nil end end end Connection Handler (Rails 5)