kovyrin-db-charmer 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +42 -5
- data/VERSION +1 -1
- data/db-charmer.gemspec +3 -2
- data/init.rb +1 -4
- data/lib/db_charmer/active_record_extensions.rb +8 -8
- data/lib/db_charmer/association_proxy.rb +17 -0
- data/lib/db_charmer/connection_factory.rb +4 -4
- data/lib/db_charmer/connection_proxy.rb +0 -1
- data/lib/db_charmer/multi_db_migrations.rb +1 -1
- data/lib/db_charmer/multi_db_proxy.rb +9 -7
- data/lib/db_charmer.rb +16 -4
- metadata +5 -3
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
5. Adds multiple databases migrations to ActiveRecord
|
10
10
|
|
11
11
|
|
12
|
-
== Installation
|
12
|
+
== Installation
|
13
13
|
|
14
14
|
There are two options when approaching db-charmer installation:
|
15
15
|
* using gem (recommended)
|
@@ -57,6 +57,11 @@ change would happen. This is really useful when in development mode or in tests
|
|
57
57
|
create many different databases on your local machine and just want to put all your tables in one
|
58
58
|
database.
|
59
59
|
|
60
|
+
Warning: All the connection switching calls would switch connection *only* for those classes the
|
61
|
+
method called on. You can't call the +switch_connection_to+ method and switch connection for a
|
62
|
+
base class in some hierarchy (for example, you can't switch AR::Base connection and see all your
|
63
|
+
models switched to the new connection, use classic +establish_connection+ instead).
|
64
|
+
|
60
65
|
|
61
66
|
== Multiple DB Migrations
|
62
67
|
|
@@ -190,19 +195,51 @@ well: block and proxy.
|
|
190
195
|
3) <tt>on_db(connection)</tt> - this method is what makes two previous methods possible.
|
191
196
|
It is used to switch a model's connection to some db for a short block of code
|
192
197
|
or even for one statement (two forms). It accepts the same range of values as
|
193
|
-
the +switch_connection_to+ method does.
|
198
|
+
the +switch_connection_to+ method does. Example:
|
199
|
+
|
200
|
+
Comment.on_db(:olap).count
|
201
|
+
Post.on_db(:foo).find(:first)
|
202
|
+
|
203
|
+
|
204
|
+
=== Associations Connection Management
|
205
|
+
|
206
|
+
ActiveRecord models can have associations and with their own connections and it becomes
|
207
|
+
pretty hard to manage connections in chained calls like <tt>User.posts.count</tt>. With
|
208
|
+
class-only connection switching methods this call would look like the following if we'd
|
209
|
+
want to count posts on a separate database:
|
210
|
+
|
211
|
+
Post.on_db(:olap) { User.posts.count }
|
212
|
+
|
213
|
+
Apparently this is not the best way to write the code and we've implemented <tt>on_*</tt>
|
214
|
+
methods on associations as well so you could do things like this:
|
215
|
+
|
216
|
+
@user.posts.on_db(:olap).count
|
217
|
+
@user.posts.on_slave.find(:title => 'Hello, world!')
|
218
|
+
|
219
|
+
Notice: Since ActiveRecord associations implemented as proxies for resulting
|
220
|
+
objects/collections, it is possible to use our connection switching methods even without
|
221
|
+
chained methods:
|
222
|
+
|
223
|
+
@post.user.on_slave - would return post's author
|
224
|
+
@photo.owner.on_slave - would return photo's owner
|
194
225
|
|
195
226
|
|
196
227
|
== Documentation
|
197
228
|
|
198
|
-
For more information on the plugin internals, please check out the source code. All the plugin's
|
229
|
+
For more information on the plugin internals, please check out the source code. All the plugin's
|
230
|
+
code is covered with tests that were placed in a separate staging rails project located at
|
231
|
+
http://github.com/kovyrin/db-charmer-sandbox. The project has unit tests for all or at least the
|
232
|
+
most of the parts of plugin's code.
|
199
233
|
|
200
234
|
|
201
235
|
== What Ruby and Rails implementations does it work for?
|
202
236
|
|
203
|
-
We've tested the plugin on MRI 1.8.6 with Rails 2.
|
237
|
+
We've tested the plugin on MRI 1.8.6 with Rails 2.2 and 2.3. We use it in production on Scribd.com
|
238
|
+
with MRI 1.8.6 and Rails 2.2.
|
204
239
|
|
205
240
|
|
206
241
|
== Who are the authors?
|
207
242
|
|
208
|
-
This plugin has been created in Scribd.com for our internal use and then the sources were opened for
|
243
|
+
This plugin has been created in Scribd.com for our internal use and then the sources were opened for
|
244
|
+
other people to use. All the code in this package has been developed by Alexey Kovyrin for Scribd.com
|
245
|
+
and is released under the GPLv2 license. For more details, see the LICENSE file.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/db-charmer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{db-charmer}
|
8
|
-
s.version = "1.0
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alexey Kovyrin"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-09-18}
|
13
13
|
s.description = %q{ActiveRecord Connections Magic (slaves, multiple connections, etc)}
|
14
14
|
s.email = %q{alexey@kovyrin.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
"init.rb",
|
28
28
|
"lib/db_charmer.rb",
|
29
29
|
"lib/db_charmer/active_record_extensions.rb",
|
30
|
+
"lib/db_charmer/association_proxy.rb",
|
30
31
|
"lib/db_charmer/connection_factory.rb",
|
31
32
|
"lib/db_charmer/connection_proxy.rb",
|
32
33
|
"lib/db_charmer/connection_switch.rb",
|
data/init.rb
CHANGED
@@ -13,31 +13,31 @@ module DbCharmer
|
|
13
13
|
#-----------------------------------------------------------------------------
|
14
14
|
@@db_charmer_opts = {}
|
15
15
|
def db_charmer_opts=(opts)
|
16
|
-
@@db_charmer_opts[self.
|
16
|
+
@@db_charmer_opts[self.name] = opts
|
17
17
|
end
|
18
18
|
|
19
19
|
def db_charmer_opts
|
20
|
-
@@db_charmer_opts[self.
|
20
|
+
@@db_charmer_opts[self.name] || {}
|
21
21
|
end
|
22
22
|
|
23
23
|
#-----------------------------------------------------------------------------
|
24
24
|
@@db_charmer_connection_proxies = {}
|
25
25
|
def db_charmer_connection_proxy=(proxy)
|
26
|
-
@@db_charmer_connection_proxies[self.
|
26
|
+
@@db_charmer_connection_proxies[self.name] = proxy
|
27
27
|
end
|
28
28
|
|
29
29
|
def db_charmer_connection_proxy
|
30
|
-
@@db_charmer_connection_proxies[self.
|
30
|
+
@@db_charmer_connection_proxies[self.name]
|
31
31
|
end
|
32
32
|
|
33
33
|
#-----------------------------------------------------------------------------
|
34
34
|
@@db_charmer_slaves = {}
|
35
35
|
def db_charmer_slaves=(slaves)
|
36
|
-
@@db_charmer_slaves[self.
|
36
|
+
@@db_charmer_slaves[self.name] = slaves
|
37
37
|
end
|
38
38
|
|
39
39
|
def db_charmer_slaves
|
40
|
-
@@db_charmer_slaves[self.
|
40
|
+
@@db_charmer_slaves[self.name] || []
|
41
41
|
end
|
42
42
|
|
43
43
|
def db_charmer_random_slave
|
@@ -48,11 +48,11 @@ module DbCharmer
|
|
48
48
|
#-----------------------------------------------------------------------------
|
49
49
|
@@db_charmer_connection_levels = Hash.new(0)
|
50
50
|
def db_charmer_connection_level=(level)
|
51
|
-
@@db_charmer_connection_levels[self.
|
51
|
+
@@db_charmer_connection_levels[self.name] = level
|
52
52
|
end
|
53
53
|
|
54
54
|
def db_charmer_connection_level
|
55
|
-
@@db_charmer_connection_levels[self.
|
55
|
+
@@db_charmer_connection_levels[self.name] || 0
|
56
56
|
end
|
57
57
|
|
58
58
|
def db_charmer_top_level_connection?
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DbCharmer
|
2
|
+
module AssociationProxy
|
3
|
+
module InstanceMethods
|
4
|
+
def on_db(con, &block)
|
5
|
+
@reflection.klass.on_db(con, self, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def on_slave(con = nil, &block)
|
9
|
+
@reflection.klass.on_slave(con, self, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_master(&block)
|
13
|
+
@reflection.klass.on_master(self, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -8,18 +8,18 @@ module DbCharmer
|
|
8
8
|
|
9
9
|
def self.connect(db_name, should_exist = false)
|
10
10
|
@@connection_classes[db_name.to_s] ||= establish_connection(db_name.to_s, should_exist)
|
11
|
-
DbCharmer.logger.warn("ConnectionFactory.connect(#{db_name}) = #{@@connection_classes[db_name.to_s]}")
|
12
|
-
return @@connection_classes[db_name.to_s]
|
11
|
+
# DbCharmer.logger.warn("ConnectionFactory.connect(#{db_name}) = #{@@connection_classes[db_name.to_s]}")
|
12
|
+
# return @@connection_classes[db_name.to_s]
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.establish_connection(db_name, should_exist = false)
|
16
|
-
DbCharmer.logger.debug("Creating a connection proxy for #{db_name}")
|
16
|
+
# DbCharmer.logger.debug("Creating a connection proxy for #{db_name}")
|
17
17
|
abstract_class = generate_abstract_class(db_name, should_exist)
|
18
18
|
DbCharmer::ConnectionProxy.new(abstract_class)
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.generate_abstract_class(db_name, should_exist = false)
|
22
|
-
DbCharmer.logger.info("Generating abstract connection class for #{db_name}: #{abstract_connection_class_name db_name}")
|
22
|
+
# DbCharmer.logger.info("Generating abstract connection class for #{db_name}: #{abstract_connection_class_name db_name}")
|
23
23
|
|
24
24
|
module_eval <<-EOF, __FILE__, __LINE__ + 1
|
25
25
|
class #{abstract_connection_class_name db_name} < ActiveRecord::Base
|
@@ -16,16 +16,18 @@ module DbCharmer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module ClassMethods
|
19
|
-
def on_db(con)
|
19
|
+
def on_db(con, proxy_target = nil)
|
20
|
+
proxy_target ||= self
|
21
|
+
|
20
22
|
# Chain call
|
21
|
-
return OnDbProxy.new(
|
23
|
+
return OnDbProxy.new(proxy_target, con) unless block_given?
|
22
24
|
|
23
25
|
# Block call
|
24
26
|
begin
|
25
27
|
self.db_charmer_connection_level += 1
|
26
28
|
old_proxy = db_charmer_connection_proxy
|
27
29
|
switch_connection_to(con, DbCharmer.migration_connections_should_exist?)
|
28
|
-
yield(
|
30
|
+
yield(proxy_target)
|
29
31
|
ensure
|
30
32
|
switch_connection_to(old_proxy)
|
31
33
|
self.db_charmer_connection_level -= 1
|
@@ -34,14 +36,14 @@ module DbCharmer
|
|
34
36
|
end
|
35
37
|
|
36
38
|
module MasterSlaveClassMethods
|
37
|
-
def on_slave(con = nil, &block)
|
39
|
+
def on_slave(con = nil, proxy_target = nil, &block)
|
38
40
|
con ||= db_charmer_random_slave
|
39
41
|
raise ArgumentError, "No slaves found in the class and no slave connection given" unless con
|
40
|
-
on_db(con, &block)
|
42
|
+
on_db(con, proxy_target, &block)
|
41
43
|
end
|
42
44
|
|
43
|
-
def on_master(&block)
|
44
|
-
on_db(nil, &block)
|
45
|
+
def on_master(proxy_target = nil, &block)
|
46
|
+
on_db(nil, proxy_target, &block)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
data/lib/db_charmer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
puts "Loading DbCharmer..."
|
2
|
+
|
1
3
|
module DbCharmer
|
2
4
|
@@migration_connections_should_exist = Rails.env.production?
|
3
5
|
mattr_accessor :migration_connections_should_exist
|
@@ -19,14 +21,13 @@ module DbCharmer
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
24
|
+
puts "Extending AR..."
|
25
|
+
|
22
26
|
require 'db_charmer/active_record_extensions'
|
23
27
|
require 'db_charmer/connection_factory'
|
24
28
|
require 'db_charmer/connection_proxy'
|
25
29
|
require 'db_charmer/connection_switch'
|
26
|
-
require 'db_charmer/
|
27
|
-
require 'db_charmer/finder_overrides'
|
28
|
-
require 'db_charmer/multi_db_migrations'
|
29
|
-
require 'db_charmer/multi_db_proxy'
|
30
|
+
require 'db_charmer/association_proxy'
|
30
31
|
|
31
32
|
# Enable misc AR extensions
|
32
33
|
ActiveRecord::Base.extend(DbCharmer::ActiveRecordExtensions::ClassMethods)
|
@@ -36,6 +37,17 @@ ActiveRecord::Base.extend(DbCharmer::ConnectionSwitch::ClassMethods)
|
|
36
37
|
|
37
38
|
# Enable connection proxy in AR
|
38
39
|
ActiveRecord::Base.extend(DbCharmer::MultiDbProxy::ClassMethods)
|
40
|
+
#ActiveRecord::Base.send(:include, DbCharmer::MultiDbProxy::InstanceMethods)
|
41
|
+
|
42
|
+
# Enable connection proxy for associations
|
43
|
+
ActiveRecord::Associations::AssociationProxy.send(:include, DbCharmer::AssociationProxy::InstanceMethods)
|
44
|
+
|
45
|
+
puts "Doing the magic..."
|
46
|
+
|
47
|
+
require 'db_charmer/db_magic'
|
48
|
+
require 'db_charmer/finder_overrides'
|
49
|
+
require 'db_charmer/multi_db_migrations'
|
50
|
+
require 'db_charmer/multi_db_proxy'
|
39
51
|
|
40
52
|
# Enable multi-db migrations
|
41
53
|
ActiveRecord::Migration.extend(DbCharmer::MultiDbMigrations::ClassMethods)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kovyrin-db-charmer
|
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
|
- Alexey Kovyrin
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-18 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- init.rb
|
43
43
|
- lib/db_charmer.rb
|
44
44
|
- lib/db_charmer/active_record_extensions.rb
|
45
|
+
- lib/db_charmer/association_proxy.rb
|
45
46
|
- lib/db_charmer/connection_factory.rb
|
46
47
|
- lib/db_charmer/connection_proxy.rb
|
47
48
|
- lib/db_charmer/connection_switch.rb
|
@@ -51,6 +52,7 @@ files:
|
|
51
52
|
- lib/db_charmer/multi_db_proxy.rb
|
52
53
|
has_rdoc: false
|
53
54
|
homepage: http://github.com/kovyrin/db-charmer
|
55
|
+
licenses:
|
54
56
|
post_install_message:
|
55
57
|
rdoc_options:
|
56
58
|
- --charset=UTF-8
|
@@ -71,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
73
|
requirements: []
|
72
74
|
|
73
75
|
rubyforge_project:
|
74
|
-
rubygems_version: 1.
|
76
|
+
rubygems_version: 1.3.5
|
75
77
|
signing_key:
|
76
78
|
specification_version: 3
|
77
79
|
summary: db-charmer 1.0.1
|