connection_manager 1.0.4 → 1.1.0
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 +8 -8
- data/CHANGE.md +12 -1
- data/README.md +99 -82
- data/connection_manager.gemspec +7 -11
- data/lib/connection_manager/builder.rb +56 -0
- data/lib/connection_manager/connection_adapters/abstract_adapter.rb +50 -0
- data/lib/connection_manager/connection_adapters/mysql_adapter.rb +39 -0
- data/lib/connection_manager/connection_handling.rb +91 -0
- data/lib/connection_manager/core.rb +24 -0
- data/lib/connection_manager/querying.rb +13 -0
- data/lib/connection_manager/railtie.rb +10 -0
- data/lib/connection_manager/relation.rb +21 -0
- data/lib/connection_manager/replication.rb +56 -85
- data/lib/connection_manager/shards.rb +2 -1
- data/lib/connection_manager/using.rb +30 -24
- data/lib/connection_manager/version.rb +1 -1
- data/lib/connection_manager.rb +26 -16
- data/spec/{mysql2_database.yml → database.yml} +30 -26
- data/spec/factories.rb +1 -1
- data/spec/helpers/database_spec_helper.rb +91 -62
- data/spec/helpers/models_spec_helper.rb +23 -12
- data/spec/lib/builder_spec.rb +31 -0
- data/spec/lib/connection_adapters/abstract_adapter_spec.rb +48 -0
- data/spec/lib/connection_adapters/mysql_adapter_spec.rb +13 -0
- data/spec/lib/connection_handling_spec.rb +65 -0
- data/spec/lib/core_spec.rb +10 -0
- data/spec/lib/integration/cross_schema_spec.rb +35 -0
- data/spec/lib/querying_spec.rb +19 -0
- data/spec/lib/relation_spec.rb +21 -0
- data/spec/lib/replication_spec.rb +19 -57
- data/spec/lib/shards_spec.rb +3 -3
- data/spec/lib/using_proxy_spec.rb +27 -0
- data/spec/lib/using_spec.rb +28 -15
- data/spec/spec_helper.rb +2 -10
- metadata +73 -35
- data/lib/connection_manager/connection_builder.rb +0 -82
- data/lib/connection_manager/connection_manager_railtie.rb +0 -8
- data/lib/connection_manager/helpers/abstract_adapter_helper.rb +0 -95
- data/lib/connection_manager/helpers/connection_helpers.rb +0 -119
- data/lib/connection_manager/patches/cross_schema_patch.rb +0 -67
- data/spec/jdbcmysql_database.yml +0 -50
- data/spec/lib/connection_builder_spec.rb +0 -28
- data/spec/lib/connection_helpers_spec.rb +0 -79
- data/spec/lib/patches/cross_schema_path_spec.rb +0 -74
- data/spec/sqlite_database.yml +0 -26
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: connection_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Mckinney
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -31,19 +31,53 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '4.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.0'
|
40
|
+
- - <=
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '4.1'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.0'
|
50
|
+
- - <=
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '4.1'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: thread_safe
|
35
55
|
requirement: !ruby/object:Gem::Requirement
|
36
56
|
requirements:
|
37
57
|
- - ! '>='
|
38
58
|
- !ruby/object:Gem::Version
|
39
59
|
version: '0'
|
40
|
-
type: :
|
60
|
+
type: :runtime
|
41
61
|
prerelease: false
|
42
62
|
version_requirements: !ruby/object:Gem::Requirement
|
43
63
|
requirements:
|
44
64
|
- - ! '>='
|
45
65
|
- !ruby/object:Gem::Version
|
46
66
|
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '2.0'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '2.0'
|
47
81
|
- !ruby/object:Gem::Dependency
|
48
82
|
name: autotest
|
49
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,27 +121,21 @@ dependencies:
|
|
87
121
|
- !ruby/object:Gem::Version
|
88
122
|
version: '0'
|
89
123
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
124
|
+
name: mysql2
|
91
125
|
requirement: !ruby/object:Gem::Requirement
|
92
126
|
requirements:
|
93
127
|
- - ! '>='
|
94
128
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
96
|
-
- - <=
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version: '4.1'
|
129
|
+
version: '0'
|
99
130
|
type: :development
|
100
131
|
prerelease: false
|
101
132
|
version_requirements: !ruby/object:Gem::Requirement
|
102
133
|
requirements:
|
103
134
|
- - ! '>='
|
104
135
|
- !ruby/object:Gem::Version
|
105
|
-
version: '
|
106
|
-
- - <=
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '4.1'
|
136
|
+
version: '0'
|
109
137
|
- !ruby/object:Gem::Dependency
|
110
|
-
name:
|
138
|
+
name: pg
|
111
139
|
requirement: !ruby/object:Gem::Requirement
|
112
140
|
requirements:
|
113
141
|
- - ! '>='
|
@@ -120,8 +148,8 @@ dependencies:
|
|
120
148
|
- - ! '>='
|
121
149
|
- !ruby/object:Gem::Version
|
122
150
|
version: '0'
|
123
|
-
description:
|
124
|
-
|
151
|
+
description: Improves support for cross-schema, replication and mutli-DMS applications
|
152
|
+
using ActiveRecord.
|
125
153
|
email:
|
126
154
|
- joshmckin@gmail.com
|
127
155
|
executables: []
|
@@ -137,29 +165,36 @@ files:
|
|
137
165
|
- Rakefile
|
138
166
|
- connection_manager.gemspec
|
139
167
|
- lib/connection_manager.rb
|
140
|
-
- lib/connection_manager/
|
141
|
-
- lib/connection_manager/
|
142
|
-
- lib/connection_manager/
|
143
|
-
- lib/connection_manager/
|
144
|
-
- lib/connection_manager/
|
168
|
+
- lib/connection_manager/builder.rb
|
169
|
+
- lib/connection_manager/connection_adapters/abstract_adapter.rb
|
170
|
+
- lib/connection_manager/connection_adapters/mysql_adapter.rb
|
171
|
+
- lib/connection_manager/connection_handling.rb
|
172
|
+
- lib/connection_manager/core.rb
|
173
|
+
- lib/connection_manager/querying.rb
|
174
|
+
- lib/connection_manager/railtie.rb
|
175
|
+
- lib/connection_manager/relation.rb
|
145
176
|
- lib/connection_manager/replication.rb
|
146
177
|
- lib/connection_manager/shards.rb
|
147
178
|
- lib/connection_manager/using.rb
|
148
179
|
- lib/connection_manager/version.rb
|
180
|
+
- spec/database.yml
|
149
181
|
- spec/factories.rb
|
150
182
|
- spec/helpers/database_spec_helper.rb
|
151
183
|
- spec/helpers/models_spec_helper.rb
|
152
|
-
- spec/
|
153
|
-
- spec/lib/
|
154
|
-
- spec/lib/
|
155
|
-
- spec/lib/
|
184
|
+
- spec/lib/builder_spec.rb
|
185
|
+
- spec/lib/connection_adapters/abstract_adapter_spec.rb
|
186
|
+
- spec/lib/connection_adapters/mysql_adapter_spec.rb
|
187
|
+
- spec/lib/connection_handling_spec.rb
|
188
|
+
- spec/lib/core_spec.rb
|
189
|
+
- spec/lib/integration/cross_schema_spec.rb
|
190
|
+
- spec/lib/querying_spec.rb
|
191
|
+
- spec/lib/relation_spec.rb
|
156
192
|
- spec/lib/replication_spec.rb
|
157
193
|
- spec/lib/shards_spec.rb
|
194
|
+
- spec/lib/using_proxy_spec.rb
|
158
195
|
- spec/lib/using_spec.rb
|
159
|
-
- spec/mysql2_database.yml
|
160
196
|
- spec/spec.opts
|
161
197
|
- spec/spec_helper.rb
|
162
|
-
- spec/sqlite_database.yml
|
163
198
|
homepage: ''
|
164
199
|
licenses: []
|
165
200
|
metadata: {}
|
@@ -182,20 +217,23 @@ rubyforge_project: connection_manager
|
|
182
217
|
rubygems_version: 2.2.2
|
183
218
|
signing_key:
|
184
219
|
specification_version: 4
|
185
|
-
summary:
|
186
|
-
active_record
|
220
|
+
summary: Cross-schema, replication and mutli-DMS gem for ActiveRecord.
|
187
221
|
test_files:
|
222
|
+
- spec/database.yml
|
188
223
|
- spec/factories.rb
|
189
224
|
- spec/helpers/database_spec_helper.rb
|
190
225
|
- spec/helpers/models_spec_helper.rb
|
191
|
-
- spec/
|
192
|
-
- spec/lib/
|
193
|
-
- spec/lib/
|
194
|
-
- spec/lib/
|
226
|
+
- spec/lib/builder_spec.rb
|
227
|
+
- spec/lib/connection_adapters/abstract_adapter_spec.rb
|
228
|
+
- spec/lib/connection_adapters/mysql_adapter_spec.rb
|
229
|
+
- spec/lib/connection_handling_spec.rb
|
230
|
+
- spec/lib/core_spec.rb
|
231
|
+
- spec/lib/integration/cross_schema_spec.rb
|
232
|
+
- spec/lib/querying_spec.rb
|
233
|
+
- spec/lib/relation_spec.rb
|
195
234
|
- spec/lib/replication_spec.rb
|
196
235
|
- spec/lib/shards_spec.rb
|
236
|
+
- spec/lib/using_proxy_spec.rb
|
197
237
|
- spec/lib/using_spec.rb
|
198
|
-
- spec/mysql2_database.yml
|
199
238
|
- spec/spec.opts
|
200
239
|
- spec/spec_helper.rb
|
201
|
-
- spec/sqlite_database.yml
|
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
-
module ConnectionManager
|
3
|
-
module ConnectionBuilder
|
4
|
-
|
5
|
-
# Get the current environment if defined
|
6
|
-
# Check for Rails, check for RACK_ENV, default to 'development'
|
7
|
-
def ar_env
|
8
|
-
return Rails.env if defined?(Rails)
|
9
|
-
return RACK_ENV if defined?(RACK_ENV)
|
10
|
-
return ENV["AR_ENV"] if ENV["AR_ENV"]
|
11
|
-
"development"
|
12
|
-
end
|
13
|
-
|
14
|
-
# Grab only those connections that correspond to the current env. If env
|
15
|
-
# is blank it grabs all the connection keys
|
16
|
-
#
|
17
|
-
# If you current environment valid database keys can be:
|
18
|
-
# * development
|
19
|
-
# * other_database_development
|
20
|
-
# * slave_database_development
|
21
|
-
def configuration_keys
|
22
|
-
ActiveRecord::Base.configurations.keys.select{|n| n.match(ar_env_regex)}
|
23
|
-
end
|
24
|
-
|
25
|
-
def database_yml_attributes(name_from_yml)
|
26
|
-
found = ActiveRecord::Base.configurations[name_from_yml]
|
27
|
-
ActiveRecord::Base.configurations[name_from_yml].symbolize_keys if found
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns currently loaded configurations where :build_connection is true
|
31
|
-
def database_keys_for_auto_build
|
32
|
-
ab_configs = []
|
33
|
-
configuration_keys.each do |key|
|
34
|
-
ab_configs << key if (database_yml_attributes(key)[:build_connection_class] == true)
|
35
|
-
end
|
36
|
-
ab_configs
|
37
|
-
end
|
38
|
-
|
39
|
-
# Builds connection classes using the database keys provided; expects an array.
|
40
|
-
def build_connection_classes(database_keys_to_use=database_keys_for_auto_build)
|
41
|
-
database_keys_to_use.each do |key|
|
42
|
-
build_connection_class(connection_class_name(key),key)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Build connection classes base on the supplied class name and connection
|
47
|
-
# key from database.yml
|
48
|
-
def build_connection_class(class_name,connection_key)
|
49
|
-
begin
|
50
|
-
class_name.constantize
|
51
|
-
rescue NameError
|
52
|
-
klass = Class.new(ActiveRecord::Base)
|
53
|
-
new_connection_class = Object.const_set(class_name, klass)
|
54
|
-
new_connection_class.establish_managed_connection(connection_key)
|
55
|
-
new_connection_class.use_database(new_connection_class.current_database_name)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
def ar_env_regex
|
61
|
-
return @ar_env_regex if @ar_env_regex
|
62
|
-
s = "#{ar_env}$"
|
63
|
-
@ar_env_regex = Regexp.new("(#{s})")
|
64
|
-
end
|
65
|
-
|
66
|
-
# Creates a string to be used for the class name. Removes the current env.
|
67
|
-
def clean_yml_key(name)
|
68
|
-
new_name = "#{name}".gsub(ar_env_regex,'')
|
69
|
-
new_name = "Base"if new_name.blank?
|
70
|
-
new_name.gsub(/\_$/,'')
|
71
|
-
end
|
72
|
-
|
73
|
-
# Given an connection key name from the database.yml, returns the string
|
74
|
-
# equivalent of the class name for that entry.
|
75
|
-
def connection_class_name(name_from_yml)
|
76
|
-
new_class_name = clean_yml_key(name_from_yml)
|
77
|
-
new_class_name = new_class_name.gsub(/\_/,' ').titleize.gsub(/ /,'')
|
78
|
-
new_class_name << "Connection"
|
79
|
-
new_class_name
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
module ConnectionManager
|
2
|
-
module AbstractAdapterHelper
|
3
|
-
def config
|
4
|
-
@config
|
5
|
-
end
|
6
|
-
|
7
|
-
# Determines if connection supports cross database queries
|
8
|
-
def cross_database_support?
|
9
|
-
@cross_database_support ||= (@config[:cross_database_support] || @config[:adapter].match(/(mysql)|(postgres)|(sqlserver)/i))
|
10
|
-
end
|
11
|
-
alias :cross_schema_support? :cross_database_support?
|
12
|
-
|
13
|
-
def using_em_adapter?
|
14
|
-
(@config[:adapter].match(/^em\_/) && defined?(EM) && EM::reactor_running?)
|
15
|
-
end
|
16
|
-
|
17
|
-
def readonly?
|
18
|
-
(@config[:readonly] == true)
|
19
|
-
end
|
20
|
-
|
21
|
-
def replicated?
|
22
|
-
(!slave_keys.blank? || !master_keys.blank?)
|
23
|
-
end
|
24
|
-
|
25
|
-
def database_name
|
26
|
-
@config[:database]
|
27
|
-
end
|
28
|
-
|
29
|
-
def replication_keys(type=:slaves)
|
30
|
-
return slave_keys if type == :slaves
|
31
|
-
master_keys
|
32
|
-
end
|
33
|
-
|
34
|
-
def slave_keys
|
35
|
-
@slave_keys ||= (@config[:slaves] ? @config[:slaves].collect{|r| r.to_sym} : [] )
|
36
|
-
end
|
37
|
-
|
38
|
-
def master_keys
|
39
|
-
@master_keys ||= (@config[:masters] ? @config[:masters].collect{|r| r.to_sym} : [])
|
40
|
-
end
|
41
|
-
|
42
|
-
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 1
|
43
|
-
|
44
|
-
# Returns the schema for a give table. Returns nil of multiple matches are found
|
45
|
-
def fetch_table_schema(table_name)
|
46
|
-
return nil unless cross_database_support?
|
47
|
-
sql = "SELECT table_schema FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
|
48
|
-
results = execute(sql, 'SCHEMA')
|
49
|
-
found = results.to_a
|
50
|
-
return found[0][0] if (found.length == 1)
|
51
|
-
nil
|
52
|
-
end
|
53
|
-
|
54
|
-
# Returns table_schema.table_name for the given table. Returns nil if multiple matches are found
|
55
|
-
def fetch_full_table_name(table_name)
|
56
|
-
return nil unless cross_database_support?
|
57
|
-
return table_name if (table_name.to_s.match(/(^$)|(\.)/))
|
58
|
-
sql = "SELECT CONCAT(table_schema,'.',table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
|
59
|
-
found = nil
|
60
|
-
results = execute(sql, 'SCHEMA')
|
61
|
-
found = results.to_a
|
62
|
-
if (found.length == 1)
|
63
|
-
found = found[0][0]
|
64
|
-
else
|
65
|
-
found = table_name
|
66
|
-
end
|
67
|
-
found
|
68
|
-
end
|
69
|
-
else
|
70
|
-
|
71
|
-
# Returns the schema for a give table. Returns nil of multiple matches are found
|
72
|
-
def fetch_table_schema(table_name)
|
73
|
-
return nil unless cross_database_support?
|
74
|
-
sql = "SELECT table_schema FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
|
75
|
-
execute_and_free(sql, 'SCHEMA') do |result|
|
76
|
-
found = result.to_a
|
77
|
-
return nil unless (found.length == 1)
|
78
|
-
found[0][0]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns table_schema.table_name for the given table. Returns nil if multiple matches are found
|
83
|
-
def fetch_full_table_name(table_name)
|
84
|
-
return nil unless cross_database_support?
|
85
|
-
return table_name if (table_name.to_s.match(/(^$)|(\.)/))
|
86
|
-
sql = "SELECT CONCAT(table_schema,'.',table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '#{table_name}'"
|
87
|
-
execute_and_free(sql, 'SCHEMA') do |result|
|
88
|
-
found = result.to_a
|
89
|
-
return table_name unless (found.length == 1)
|
90
|
-
found[0][0]
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
-
module ConnectionManager
|
3
|
-
module ConnectionHelpers
|
4
|
-
@@managed_connections = HashWithIndifferentAccess.new
|
5
|
-
|
6
|
-
# Returns the database_name of the connection unless set otherwise
|
7
|
-
def current_database_name
|
8
|
-
return "#{connection.config[:database].to_s}" if @current_database_name.blank?
|
9
|
-
@current_database_name
|
10
|
-
end
|
11
|
-
alias :database_name :current_database_name
|
12
|
-
alias :current_schema_name :current_database_name
|
13
|
-
alias :schema_name :current_database_name
|
14
|
-
|
15
|
-
|
16
|
-
# Sometimes we need to manually set the database name, like when the connection
|
17
|
-
# has a database but our table is in a different database/schema but on the
|
18
|
-
# same DMS.
|
19
|
-
def current_database_name=current_database_name
|
20
|
-
@current_database_name= current_database_name
|
21
|
-
end
|
22
|
-
alias :database_name= :current_database_name=
|
23
|
-
alias :current_schema_name= :current_database_name=
|
24
|
-
alias :schema_name= :current_database_name=
|
25
|
-
|
26
|
-
# Returns true if this is a readonly only a readonly model
|
27
|
-
# If the connection.readonly? then the model that uses the connection
|
28
|
-
# must be readonly.
|
29
|
-
def readonly?
|
30
|
-
((@readonly == true)||connection.readonly?)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Allow setting of readonly at the model level
|
34
|
-
def readonly=readonly
|
35
|
-
@readonly = readonly
|
36
|
-
end
|
37
|
-
|
38
|
-
# A place to store managed connections
|
39
|
-
def managed_connections
|
40
|
-
@@managed_connections
|
41
|
-
end
|
42
|
-
|
43
|
-
def add_managed_connections(yml_key,value)
|
44
|
-
@@managed_connections[yml_key] ||= []
|
45
|
-
@@managed_connections[yml_key] << value unless @@managed_connections[yml_key].include?(value)
|
46
|
-
@@managed_connections
|
47
|
-
end
|
48
|
-
|
49
|
-
def managed_connection_classes
|
50
|
-
managed_connections.values.flatten
|
51
|
-
end
|
52
|
-
|
53
|
-
def yml_key
|
54
|
-
@yml_key
|
55
|
-
end
|
56
|
-
|
57
|
-
# Tell Active Record to use a different database/schema on this model.
|
58
|
-
# You may call #use_database when your schemas reside on the same database server
|
59
|
-
# and you do not want to create extra connection class and database.yml entries.
|
60
|
-
#
|
61
|
-
# Options:
|
62
|
-
# * :table_name_prefix - the prefix required for making cross database/schema
|
63
|
-
# joins for you database management system. By default table_name_prefix is the
|
64
|
-
# database/schema name followed by a period EX: "my_database."
|
65
|
-
# * :table_name - the table name for the model if it does not match ActiveRecord
|
66
|
-
# naming conventions
|
67
|
-
#
|
68
|
-
# EX: class LegacyUser < ActiveRecord::Base
|
69
|
-
# use_database('DBUser', :table_name => 'UserData')
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
# LegacyUser.limit(1).to_sql => "SELECT * FROM `BDUser`.`UserData` LIMIT 1
|
73
|
-
#
|
74
|
-
def use_database(database_name=nil,opts={})
|
75
|
-
self.current_database_name = database_name if database_name
|
76
|
-
opts[:table_name_prefix] = "#{self.current_database_name}." if opts[:table_name_prefix].blank? && self.connection.cross_database_support?
|
77
|
-
unless self.abstract_class? || self.name == "ActiveRecord::Base"
|
78
|
-
opts[:table_name] = self.table_name if opts[:table_name].blank?
|
79
|
-
opts[:table_name].gsub!(self.table_name_prefix,'') unless self.table_name_prefix.blank?
|
80
|
-
self.table_name = "#{opts[:table_name_prefix]}#{opts[:table_name]}"
|
81
|
-
end
|
82
|
-
self.table_name_prefix = opts[:table_name_prefix] unless opts[:table_name_prefix].blank?
|
83
|
-
end
|
84
|
-
alias :use_schema :use_database
|
85
|
-
|
86
|
-
# Establishes and checks in a connection, normally for abstract classes AKA connection classes.
|
87
|
-
#
|
88
|
-
# Options:
|
89
|
-
# * :abstract_class - used the set #abstract_class, default is true
|
90
|
-
# * :readonly - force all instances to readonly
|
91
|
-
# * :class_name - name of connection class name, default is current class name
|
92
|
-
# * :table_name_prefix - prefix to append to table name for cross database joins,
|
93
|
-
# default is the "#{self.database_name}."
|
94
|
-
# EX:
|
95
|
-
# class MyConnection < ActiveRecord::Base
|
96
|
-
# establish_managed_connection :key_from_db_yml,{:readonly => true}
|
97
|
-
# end
|
98
|
-
#
|
99
|
-
def establish_managed_connection(yml_key,opts={})
|
100
|
-
@yml_key = yml_key
|
101
|
-
opts = {:class_name => self.name,
|
102
|
-
:abstract_class => true}.merge(opts)
|
103
|
-
establish_connection(yml_key)
|
104
|
-
self.abstract_class = opts[:abstract_class]
|
105
|
-
set_to_readonly if (readonly? || opts[:readonly] || self.connection.readonly?)
|
106
|
-
add_managed_connections(yml_key,opts[:class_name])
|
107
|
-
use_database(self.current_database_name,opts)
|
108
|
-
end
|
109
|
-
|
110
|
-
# Override ActiveRecord::Base instance method readonly? to force
|
111
|
-
# readonly connections.
|
112
|
-
def set_to_readonly
|
113
|
-
self.readonly = true
|
114
|
-
define_method(:readonly?) do
|
115
|
-
true
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class Base
|
3
|
-
class << self
|
4
|
-
# We want to make sure we get the full table name with schema
|
5
|
-
def arel_table # :nodoc:
|
6
|
-
begin
|
7
|
-
@arel_table ||= Arel::Table.new(quoted_table_name.to_s.gsub('`',''), arel_engine)
|
8
|
-
rescue ActiveRecord::ConnectionNotEstablished
|
9
|
-
Arel::Table.new(table_name, arel_engine)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
# In a schema schema environment we want to set table name prefix
|
16
|
-
# to the schema_name + . if its not set already
|
17
|
-
alias :base_compute_table_name :compute_table_name
|
18
|
-
def compute_table_name
|
19
|
-
result = base_compute_table_name
|
20
|
-
if result.match(/^[^.]*$/) && connection.cross_schema_support?
|
21
|
-
t_schema = connection.fetch_table_schema(undecorated_table_name(name))
|
22
|
-
self.table_name_prefix = "#{t_schema}." if t_schema
|
23
|
-
result = base_compute_table_name
|
24
|
-
end
|
25
|
-
result
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 1
|
32
|
-
require 'active_record/connection_adapters/mysql2_adapter'
|
33
|
-
module ActiveRecord
|
34
|
-
module ConnectionAdapters
|
35
|
-
class Mysql2Adapter < AbstractAdapter
|
36
|
-
|
37
|
-
# Force all tables to be cached for the life connection
|
38
|
-
def cached_tables
|
39
|
-
@cached_tables ||= {}
|
40
|
-
end
|
41
|
-
|
42
|
-
def tables(name = nil, database = nil, like =nil)
|
43
|
-
return cached_tables[database] if cached_tables[database] && like.nil?
|
44
|
-
cached_tables[database] ||= []
|
45
|
-
return [like] if like && cached_tables[database].include?(like)
|
46
|
-
sql = "SHOW TABLES "
|
47
|
-
sql << "IN #{database} " if database
|
48
|
-
sql << "LIKE #{quote(like)}" if like
|
49
|
-
result = execute(sql, 'SCHEMA')
|
50
|
-
cached_tables[database] = (cached_tables[database] | result.collect { |field| field[0] }).compact
|
51
|
-
end
|
52
|
-
|
53
|
-
# We have to clean the name of '`' and fetch table name with schema
|
54
|
-
def table_exists?(name)
|
55
|
-
return false unless name
|
56
|
-
name = name.to_s
|
57
|
-
schema, table = name.split('.', 2)
|
58
|
-
unless table # A table was provided without a schema
|
59
|
-
table = schema
|
60
|
-
schema = nil
|
61
|
-
end
|
62
|
-
tables(nil, schema, table).include?(table)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/spec/jdbcmysql_database.yml
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# Warning: The database defined as "test" will be erased and
|
2
|
-
# re-generated from your development database when you run "rake".
|
3
|
-
# Do not set this db to the same as development or production.
|
4
|
-
common: &common
|
5
|
-
adapter: jdbcmysql
|
6
|
-
username: root
|
7
|
-
password: omegared
|
8
|
-
pool: 100
|
9
|
-
timeout: 5000
|
10
|
-
build_connection_class: true
|
11
|
-
|
12
|
-
master: &master
|
13
|
-
username: root
|
14
|
-
password: omegared
|
15
|
-
|
16
|
-
readonly: &readonly
|
17
|
-
username: readonly
|
18
|
-
password: omegared
|
19
|
-
|
20
|
-
test:
|
21
|
-
<<: *common
|
22
|
-
<<: *master
|
23
|
-
database: cm_test
|
24
|
-
slaves: [slave_1_cm_test, slave_2_cm_test]
|
25
|
-
|
26
|
-
cm_user_test:
|
27
|
-
<<: *common
|
28
|
-
<<: *master
|
29
|
-
database: cm_user_test
|
30
|
-
slaves: [slave_1_cm_user_test]
|
31
|
-
|
32
|
-
slave_1_cm_test:
|
33
|
-
<<: *common
|
34
|
-
<<: *readonly
|
35
|
-
database: cm_test
|
36
|
-
|
37
|
-
slave_2_cm_test:
|
38
|
-
<<: *common
|
39
|
-
<<: *readonly
|
40
|
-
database: cm_test
|
41
|
-
|
42
|
-
shard_1_cm_test:
|
43
|
-
<<: *common
|
44
|
-
<<: *master
|
45
|
-
database: legacy_cm_test
|
46
|
-
|
47
|
-
slave_1_cm_user_test:
|
48
|
-
<<: *common
|
49
|
-
<<: *readonly
|
50
|
-
database: cm_user_test
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
describe ConnectionManager::ConnectionBuilder do
|
3
|
-
|
4
|
-
describe '#connection_class_name' do
|
5
|
-
it "should return a string for a class name appended with 'Connection' " do
|
6
|
-
ActiveRecord::Base.send(:connection_class_name,"my_database").should eql("MyDatabaseConnection")
|
7
|
-
end
|
8
|
-
it "should return remove the appended rails env" do
|
9
|
-
ActiveRecord::Base.send(:connection_class_name,"my_database_test").should eql("MyDatabaseConnection")
|
10
|
-
end
|
11
|
-
it "should use the database name from the database.yml if supplied string is only is only the Rails.env" do
|
12
|
-
ActiveRecord::Base.send(:connection_class_name,"test").should eql("BaseConnection")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#build_connection_class' do
|
17
|
-
before(:all) do
|
18
|
-
ActiveRecord::Base.build_connection_class("MyConnectionClass", :test)
|
19
|
-
end
|
20
|
-
it "should add a class with supplied class name to ConnectionManager::ConnectionBuilder" do
|
21
|
-
defined?(MyConnectionClass).should be_true
|
22
|
-
MyConnectionClass.is_a?(Class).should be_true
|
23
|
-
end
|
24
|
-
it "should have a super class of ActiveRecord::Base" do
|
25
|
-
MyConnectionClass.superclass.should eql(ActiveRecord::Base)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|