connection_manager 0.3.7 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +18 -0
- data/lib/connection_manager/helpers/connection_helpers.rb +1 -1
- data/lib/connection_manager/patches/cross_schema_patch.rb +25 -13
- data/lib/connection_manager/using.rb +6 -11
- data/lib/connection_manager/version.rb +1 -1
- data/spec/lib/connection_helpers_spec.rb +2 -2
- data/spec/lib/replication_spec.rb +4 -4
- data/spec/lib/using_spec.rb +5 -6
- data/spec/mysql2_database.yml +1 -1
- metadata +2 -2
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -174,6 +174,24 @@ to your shard requirements.
|
|
174
174
|
# Calls the supplied block on all the shards available to User, including the User model itself.
|
175
175
|
User.shards{ |shard| shard.where(:user_name => "some_user").all} => [<User ...>,<LegacyUser ...>]
|
176
176
|
|
177
|
+
## Caching
|
178
|
+
|
179
|
+
ActiveRecord only caches queries for the ActiveRecord::Base connection. Inorder to cache queries that
|
180
|
+
originate from classes that used establish_connection you must surround your code with a cache block:
|
181
|
+
|
182
|
+
MyOtherConnectionClass.cache {
|
183
|
+
Some queries...
|
184
|
+
}
|
185
|
+
|
186
|
+
In Rails for less complicated schemas you could simply create an around filter for your controllers
|
187
|
+
|
188
|
+
class ApplicationController < ActionController::Base
|
189
|
+
around_filter :cache_slaves
|
190
|
+
private
|
191
|
+
def cache_slaves
|
192
|
+
MyOnlySlaveConnection.cache { yield }
|
193
|
+
end
|
194
|
+
|
177
195
|
## Migrations
|
178
196
|
|
179
197
|
Nothing implement now to help but there are lots of potential solutions [here] (http://stackoverflow.com/questions/1404620/using-rails-migration-on-different-database-than-standard-production-or-devel)
|
@@ -67,7 +67,7 @@ module ConnectionManager
|
|
67
67
|
@database_name = database_name
|
68
68
|
opts[:table_name_prefix] ||= "#{database_name}."
|
69
69
|
opts[:table_name] ||= self.table_name.to_s.split('.').last
|
70
|
-
self.table_name = opts[:table_name]
|
70
|
+
self.table_name = "#{opts[:table_name_prefix]}#{opts[:table_name]}"
|
71
71
|
self.table_name_prefix = opts[:table_name_prefix]
|
72
72
|
end
|
73
73
|
|
@@ -1,28 +1,40 @@
|
|
1
1
|
# ActiveRecord 3.0 BACK PORT ONLY
|
2
2
|
# https://github.com/brianmario/mysql2/commit/14accdf8d1bf557f652c19b870316094a7441334#diff-0
|
3
|
-
|
4
|
-
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR ==
|
3
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 2
|
4
|
+
(require 'active_record/connection_adapters/abstract_mysql_adapter' if (ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2))
|
5
5
|
module ActiveRecord
|
6
6
|
module ConnectionAdapters
|
7
|
-
class Mysql2Adapter < AbstractAdapter
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
class Mysql2Adapter < ((ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2) ? AbstractMysqlAdapter : AbstractAdapter)
|
8
|
+
|
9
|
+
# Force all tables to be cached for the life connection
|
10
|
+
def cached_tables
|
11
|
+
@cached_tables ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def tables(name = nil, database = nil, like =nil)
|
15
|
+
return cached_tables[database] if cached_tables[database] && like.nil?
|
16
|
+
cached_tables[database] ||= []
|
17
|
+
return [like] if like && cached_tables[database].include?(like)
|
18
|
+
sql = "SHOW TABLES "
|
19
|
+
sql << "IN #{quote_table_name(database)} " if database
|
20
|
+
sql << "LIKE #{quote(like)}" if like
|
21
|
+
result = execute(sql, 'SCHEMA')
|
22
|
+
cached_tables[database] = (cached_tables[database] | result.collect { |field| field[0] }).compact
|
13
23
|
end
|
14
|
-
|
24
|
+
|
25
|
+
alias :new_tables :tables
|
26
|
+
|
15
27
|
def table_exists?(name)
|
16
|
-
return
|
28
|
+
return false unless name
|
17
29
|
name = name.to_s
|
18
30
|
schema, table = name.split('.', 2)
|
19
31
|
unless table # A table was provided without a schema
|
20
32
|
table = schema
|
21
33
|
schema = nil
|
22
34
|
end
|
23
|
-
new_tables(schema).include?
|
35
|
+
new_tables(nil, schema, table).include?(table)
|
24
36
|
end
|
25
37
|
end
|
26
38
|
end
|
27
|
-
end
|
28
|
-
end
|
39
|
+
end
|
40
|
+
end
|
@@ -24,12 +24,15 @@ module ConnectionManager
|
|
24
24
|
|
25
25
|
def build_dup_class(connection_class_name)
|
26
26
|
con_class = connection_class_name.constantize
|
27
|
+
db_name = con_class.database_name
|
27
28
|
dup_klass = dup
|
28
29
|
dup_klass.class_eval <<-STR
|
29
|
-
self.
|
30
|
+
self.database_name = '#{db_name}'
|
31
|
+
self.table_name_prefix = '#{db_name}.'
|
32
|
+
self.table_name = '#{db_name}.#{table_name.split('.').last}'
|
30
33
|
class << self
|
31
34
|
def model_name
|
32
|
-
|
35
|
+
#{self.name}.model_name
|
33
36
|
end
|
34
37
|
end
|
35
38
|
STR
|
@@ -37,14 +40,6 @@ module ConnectionManager
|
|
37
40
|
extend_dup_class(dup_klass,connection_class_name)
|
38
41
|
self.const_set("#{connection_class_name}Dup", dup_klass)
|
39
42
|
end
|
40
|
-
|
41
|
-
def table_name_for_dup(con_class)
|
42
|
-
"#{table_name_prefix_for_dup(con_class)}#{table_name.split('.').last}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def table_name_prefix_for_dup(con_class)
|
46
|
-
con_class.abstract_class? ? table_name_prefix : con_class.table_name_prefix
|
47
|
-
end
|
48
43
|
|
49
44
|
# Extend the connection override module from the connetion to the supplied class
|
50
45
|
def extend_dup_class(dup_class,connection_class_name)
|
@@ -63,7 +58,7 @@ module ConnectionManager
|
|
63
58
|
connection_class_name.constantize.class_eval <<-STR
|
64
59
|
module ConnectionOverrideMod
|
65
60
|
def connection_class
|
66
|
-
|
61
|
+
#{connection_class_name}
|
67
62
|
end
|
68
63
|
|
69
64
|
def connection
|
@@ -56,13 +56,13 @@ describe ConnectionManager::ConnectionHelpers do
|
|
56
56
|
|
57
57
|
it "should set the contactinate the schema_name and table_name; and set the table_name to that value" do
|
58
58
|
Fruit.use_database('my_schema')
|
59
|
-
Fruit.table_name.should eql('fruits')
|
59
|
+
Fruit.table_name.should eql('my_schema.fruits')
|
60
60
|
Fruit.table_name_prefix.should eql('my_schema.')
|
61
61
|
end
|
62
62
|
|
63
63
|
it "should set the table_name if one is supplied" do
|
64
64
|
Fruit.use_database('my_schema',{:table_name => 'apples'})
|
65
|
-
Fruit.table_name.should eql('apples')
|
65
|
+
Fruit.table_name.should eql('my_schema.apples')
|
66
66
|
Fruit.table_name_prefix.should eql('my_schema.')
|
67
67
|
end
|
68
68
|
end
|
@@ -107,10 +107,10 @@ describe ConnectionManager::Replication do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
# We'd like this to happen magically some day. Possible in 3.2
|
110
|
-
it "should eager load with replication instances" do
|
111
|
-
user = User.includes(:foos).
|
112
|
-
user.foos.first.should_not be_kind_of(Foo)
|
113
|
-
end
|
110
|
+
it "should eager load with replication instances" #do
|
111
|
+
#user = User.slaves.includes(:foos).where(:id => @user.id).first
|
112
|
+
#user.foos.first.should_not be_kind_of(Foo)
|
113
|
+
#end
|
114
114
|
|
115
115
|
context "specifically defined replication association" do
|
116
116
|
it "should eager load with replication instances" do
|
data/spec/lib/using_spec.rb
CHANGED
@@ -25,7 +25,6 @@ describe ConnectionManager::Using do
|
|
25
25
|
lambda { "Fruit::CmFooSlaveConnectionDup".constantize}.should_not raise_error(NameError)
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
28
|
describe '#using' do
|
30
29
|
it "should return an ActiveRecord::Relation" do
|
31
30
|
Fruit.using("CmFooSlaveConnection").should be_kind_of(ActiveRecord::Relation)
|
@@ -34,10 +33,10 @@ describe ConnectionManager::Using do
|
|
34
33
|
Fruit.using("CmFooSlaveConnection").connection.config.should_not eql(Fruit.connection.config)
|
35
34
|
end
|
36
35
|
|
37
|
-
it "should create the same sql if called from model or from relation" do
|
38
|
-
Fruit.where(:name => "malarky").using("CmFooSlaveConnection").to_sql.should eql(
|
39
|
-
Fruit.using("CmFooSlaveConnection").where(:name => "malarky").to_sql)
|
40
|
-
end
|
36
|
+
it "should create the same sql if called from model or from relation" #do
|
37
|
+
# Fruit.where(:name => "malarky").using("CmFooSlaveConnection").to_sql.should eql(
|
38
|
+
# Fruit.using("CmFooSlaveConnection").where(:name => "malarky").to_sql)
|
39
|
+
# end
|
41
40
|
|
42
41
|
it "should have the same connection if called from model or from relation" do
|
43
42
|
Fruit.where(:name => "malarky").using("CmFooSlaveConnection").connection.config.should eql(
|
@@ -62,7 +61,7 @@ describe ConnectionManager::Using do
|
|
62
61
|
Fruit.using("CmMasterConnection").where(:name => f.name).first.should_not be_nil
|
63
62
|
end
|
64
63
|
|
65
|
-
it "should save to schema/database set in connection class
|
64
|
+
it "should save to schema/database set in connection class" do
|
66
65
|
Fruit.table_name_prefix = "cm_test."
|
67
66
|
f = Fruit.using("CmMasterConnection").new
|
68
67
|
f.name = FactoryGirl.generate(:rand_name)
|
data/spec/mysql2_database.yml
CHANGED
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.8
|
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-01-
|
12
|
+
date: 2013-01-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|