connection_manager 0.3.9 → 0.3.10
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.
- data/lib/connection_manager/connection_builder.rb +3 -3
- data/lib/connection_manager/helpers/abstract_adapter_helper.rb +6 -0
- data/lib/connection_manager/helpers/connection_helpers.rb +11 -23
- data/lib/connection_manager/patches/cross_schema_patch.rb +22 -0
- data/lib/connection_manager/replication.rb +16 -28
- data/lib/connection_manager/using.rb +1 -3
- data/lib/connection_manager/version.rb +1 -1
- data/spec/lib/using_spec.rb +3 -3
- metadata +2 -2
@@ -11,7 +11,7 @@ module ConnectionManager
|
|
11
11
|
"development"
|
12
12
|
end
|
13
13
|
|
14
|
-
# Grab only
|
14
|
+
# Grab only those connections that correspond to the current env. If env
|
15
15
|
# is blank it grabs all the connection keys
|
16
16
|
#
|
17
17
|
# If you current environment valid database keys can be:
|
@@ -27,7 +27,7 @@ module ConnectionManager
|
|
27
27
|
ActiveRecord::Base.configurations[name_from_yml].symbolize_keys if found
|
28
28
|
end
|
29
29
|
|
30
|
-
# Returns currently loaded
|
30
|
+
# Returns currently loaded configurations where :build_connection is true
|
31
31
|
def database_keys_for_auto_build
|
32
32
|
ab_configs = []
|
33
33
|
configuration_keys.each do |key|
|
@@ -71,7 +71,7 @@ module ConnectionManager
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# Given an connection key name from the database.yml, returns the string
|
74
|
-
#
|
74
|
+
# equivalent of the class name for that entry.
|
75
75
|
def connection_class_name(name_from_yml)
|
76
76
|
new_class_name = clean_yml_key(name_from_yml)
|
77
77
|
new_class_name = new_class_name.gsub(/\_/,' ').titleize.gsub(/ /,'')
|
@@ -4,6 +4,12 @@ module ConnectionManager
|
|
4
4
|
@config
|
5
5
|
end
|
6
6
|
|
7
|
+
# Determines if connection supports cross database queries
|
8
|
+
def cross_database_support?
|
9
|
+
(@config[:cross_database_support] || @config[:adapter].match(/(mysql)|(postgres)|(sqlserver)/i))
|
10
|
+
end
|
11
|
+
alias :cross_schema_support? :cross_database_support?
|
12
|
+
|
7
13
|
def using_em_adapter?
|
8
14
|
(@config[:adapter].match(/^em\_/) && defined?(EM) && EM::reactor_running?)
|
9
15
|
end
|
@@ -3,18 +3,6 @@ module ConnectionManager
|
|
3
3
|
module ConnectionHelpers
|
4
4
|
@@managed_connections = HashWithIndifferentAccess.new
|
5
5
|
|
6
|
-
# Returns the database_name of the connection unless set otherwise
|
7
|
-
def database_name
|
8
|
-
@database_name = "#{connection.config[:database].to_s}" if @database_name.blank?
|
9
|
-
@database_name
|
10
|
-
end
|
11
|
-
|
12
|
-
def database_name=database_name
|
13
|
-
@database_name = database_name
|
14
|
-
end
|
15
|
-
|
16
|
-
alias :schema_name :database_name
|
17
|
-
|
18
6
|
# Returns true if this is a readonly only a readonly model
|
19
7
|
# If the connection.readonly? then the model that uses the connection
|
20
8
|
# must be readonly.
|
@@ -52,7 +40,7 @@ module ConnectionManager
|
|
52
40
|
#
|
53
41
|
# Options:
|
54
42
|
# * :table_name_prefix - the prefix required for making cross database/schema
|
55
|
-
# joins for you database
|
43
|
+
# joins for you database management system. By default table_name_prefix is the
|
56
44
|
# database/schema name followed by a period EX: "my_database."
|
57
45
|
# * :table_name - the table name for the model if it does not match ActiveRecord
|
58
46
|
# naming conventions
|
@@ -64,21 +52,21 @@ module ConnectionManager
|
|
64
52
|
# LegacyUser.limit(1).to_sql => "SELECT * FROM `BDUser`.`UserData` LIMIT 1
|
65
53
|
#
|
66
54
|
def use_database(database_name,opts={})
|
67
|
-
|
68
|
-
opts[:table_name_prefix] ||= "#{database_name}."
|
69
|
-
opts[:
|
70
|
-
|
71
|
-
|
55
|
+
self.database_name = database_name
|
56
|
+
opts[:table_name_prefix] ||= "#{database_name}." if self.connection.cross_database_support?
|
57
|
+
self.table_name_prefix = opts[:table_name_prefix] unless opts[:table_name_prefix].blank?
|
58
|
+
opts[:table_name] ||= self.table_name
|
59
|
+
opts[:table_name] = opts[:table_name].to_s.split('.').last if self.connection.cross_database_support?
|
60
|
+
self.table_name = "#{opts[:table_name_prefix]}#{opts[:table_name]}" unless self.abstract_class? || opts[:table_name].blank?
|
72
61
|
end
|
73
|
-
|
74
62
|
alias :use_schema :use_database
|
75
|
-
|
76
|
-
# Establishes and checks in a connection,
|
63
|
+
|
64
|
+
# Establishes and checks in a connection, normally for abstract classes AKA connection classes.
|
77
65
|
#
|
78
66
|
# Options:
|
79
67
|
# * :abstract_class - used the set #abstract_class, default is true
|
80
68
|
# * :readonly - force all instances to readonly
|
81
|
-
# * :class_name - name of connection class name, default is current class
|
69
|
+
# * :class_name - name of connection class name, default is current class name
|
82
70
|
# * :table_name_prefix - prefix to append to table name for cross database joins,
|
83
71
|
# default is the "#{self.database_name}."
|
84
72
|
# EX:
|
@@ -94,7 +82,7 @@ module ConnectionManager
|
|
94
82
|
self.abstract_class = opts[:abstract_class]
|
95
83
|
set_to_readonly if (readonly? || opts[:readonly] || self.connection.readonly?)
|
96
84
|
add_managed_connections(yml_key,opts[:class_name])
|
97
|
-
use_database(self.database_name,opts)
|
85
|
+
use_database(self.database_name,opts)
|
98
86
|
end
|
99
87
|
|
100
88
|
# Override ActiveRecord::Base instance method readonly? to force
|
@@ -38,3 +38,25 @@ if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 2
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
# We need to make sure we override existing database_name name methods
|
43
|
+
module ActiveRecord
|
44
|
+
class Base
|
45
|
+
class << self
|
46
|
+
# Returns the database_name of the connection unless set otherwise
|
47
|
+
def database_name
|
48
|
+
@database_name = "#{connection.config[:database].to_s}" if @database_name.blank?
|
49
|
+
@database_name
|
50
|
+
end
|
51
|
+
alias :schema_name :database_name
|
52
|
+
|
53
|
+
# Sometimes we need to manually set the database name, like when the connection
|
54
|
+
# has a database but our table is in a different database/schema but on the
|
55
|
+
# same DMS.
|
56
|
+
def database_name=database_name
|
57
|
+
@database_name = database_name
|
58
|
+
end
|
59
|
+
alias :schema_name= :database_name=
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext/hash/indifferent_access'
|
2
2
|
module ConnectionManager
|
3
3
|
module Replication
|
4
|
-
|
5
4
|
# Replication methods (replication_method_name, which is the option[:name] for the
|
6
|
-
# #replication method) and all
|
5
|
+
# #replication method) and all their associated connections. The key is the
|
7
6
|
# replication_method_name and the value is an array of all the replication_classes
|
8
7
|
# the replication_method has access to.
|
9
8
|
#
|
@@ -34,33 +33,22 @@ module ConnectionManager
|
|
34
33
|
# * :name - name of class method to call to access replication, default to slaves
|
35
34
|
# * :readonly - forces all results to readonly
|
36
35
|
# * :type - the type of replication; :slave or :master, defaults to :slave
|
37
|
-
# * :using - list of connections to use; can be database.yml key or the name of the connection class --- DEPRECIATED
|
38
|
-
# * A Block may be passed that will be called on each of the newly created child classes
|
39
36
|
def replicated(*connections)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
connections = options[:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
connections = connection.replication_keys(options[:type]) if connections.blank?
|
53
|
-
set_replications_to_method(connections,options[:name])
|
54
|
-
build_repliciation_class_method(options)
|
55
|
-
build_replication_association_class(options)
|
56
|
-
build_query_method_alias_method(options[:name])
|
57
|
-
build_repliciation_instance_method(options[:name])
|
58
|
-
options[:name]
|
37
|
+
@replicated = true
|
38
|
+
options = {:name => "slaves"}.merge!(connections.extract_options!)
|
39
|
+
options[:type] ||= :slaves
|
40
|
+
options[:build_replicants] = true if (options[:build_replicants].blank? && options[:type] == :masters)
|
41
|
+
self.use_database(self.database_name,{:table_name => self.table_name}) if self.connection.cross_database_support?
|
42
|
+
connections = connection.replication_keys(options[:type]) if connections.blank?
|
43
|
+
set_replications_to_method(connections,options[:name])
|
44
|
+
build_repliciation_class_method(options)
|
45
|
+
build_replication_association_class(options)
|
46
|
+
build_query_method_alias_method(options[:name])
|
47
|
+
build_repliciation_instance_method(options[:name])
|
48
|
+
options[:name]
|
59
49
|
end
|
60
50
|
|
61
|
-
|
62
|
-
# Get a connection class name from out replication_methods pool
|
63
|
-
# could add mutex but not sure blocking is with it.
|
51
|
+
# Get a connection class name from out replication_methods pool.
|
64
52
|
def fetch_replication_method(method_name)
|
65
53
|
available_connections = @replication_methods[method_name]
|
66
54
|
raise ArgumentError, "No connections found for #{method_name}." if available_connections.blank?
|
@@ -112,7 +100,7 @@ module ConnectionManager
|
|
112
100
|
end
|
113
101
|
|
114
102
|
# Builds a class within the model with the name of replication method. Use this
|
115
|
-
# class as the :class_name options for associations when it is
|
103
|
+
# class as the :class_name options for associations when it is necessary to
|
116
104
|
# ensure eager loading uses a replication connection.
|
117
105
|
#
|
118
106
|
# EX:
|
@@ -142,7 +130,7 @@ module ConnectionManager
|
|
142
130
|
STR
|
143
131
|
end
|
144
132
|
|
145
|
-
# Build a query method with the name of our
|
133
|
+
# Build a query method with the name of our replication method. This method
|
146
134
|
# uses the relation.klass to fetch the appropriate connection, ensuring the
|
147
135
|
# correct connection is used even if the method is already defined by another class.
|
148
136
|
# We want to make sure we don't override existing methods in ActiveRecord::QueryMethods
|
@@ -32,9 +32,7 @@ module ConnectionManager
|
|
32
32
|
db_name = con_class.database_name
|
33
33
|
dup_klass = dup
|
34
34
|
dup_klass.class_eval <<-STR
|
35
|
-
self.
|
36
|
-
self.table_name_prefix = '#{db_name}.'
|
37
|
-
self.table_name = '#{db_name}.#{table_name.split('.').last}'
|
35
|
+
self.use_database('#{db_name}',{:table_name => '#{table_name}'})
|
38
36
|
class << self
|
39
37
|
def model_name
|
40
38
|
#{self.name}.model_name
|
data/spec/lib/using_spec.rb
CHANGED
@@ -22,9 +22,9 @@ describe ConnectionManager::Using do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should create the exact same sql if called from model or from relation" #do
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
25
|
+
#Fruit.where(:name => "malarky").using("CmFooSlaveConnection").to_sql.should eql(
|
26
|
+
#Fruit.using("CmFooSlaveConnection").where(:name => "malarky").to_sql)
|
27
|
+
#end
|
28
28
|
|
29
29
|
it "should have the same connection if called from model or from relation" do
|
30
30
|
Fruit.where(:name => "malarky").using("CmFooSlaveConnection").connection.config.should eql(
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: connection_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|