magic_multi_connections 1.0.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +0 -0
- data/History.txt +0 -0
- data/Manifest.txt +43 -32
- data/README.txt +0 -0
- data/Rakefile +21 -15
- data/lib/ext_active_record/association_extensions.rb +90 -0
- data/lib/ext_active_record/connection_specification.rb +0 -0
- data/lib/magic_multi_connections.rb +22 -21
- data/lib/magic_multi_connections/connected.rb +91 -29
- data/lib/magic_multi_connections/module.rb +27 -26
- data/lib/magic_multi_connections/version.rb +9 -9
- data/scripts/txt2html +0 -0
- data/scripts/txt2js +1 -1
- data/setup.rb +0 -0
- data/test/connections/native_mysql/connection.rb +24 -0
- data/test/connections/native_postgresql/connection.rb +0 -0
- data/test/fixtures/address.rb +3 -0
- data/test/fixtures/addresses.yml +4 -0
- data/test/fixtures/assignment.rb +7 -0
- data/test/fixtures/classified.rb +5 -0
- data/test/fixtures/contact_repository.rb +2 -2
- data/test/fixtures/db_definitions/mysql.sql +19 -0
- data/test/fixtures/db_definitions/postgresql.sql +7 -1
- data/test/fixtures/habit.rb +3 -0
- data/test/fixtures/paycheck.rb +3 -0
- data/test/fixtures/people.yml +0 -0
- data/test/fixtures/person.rb +3 -1
- data/test/fixtures/soldier.rb +8 -0
- data/test/test_helper.rb +71 -71
- data/test/test_magic_multi_connections.rb +27 -26
- data/test/test_mmc_associations.rb +46 -0
- data/test/test_parent_module.rb +0 -0
- data/test/test_preexisting_module.rb +0 -0
- data/website/index.html +354 -340
- data/website/index.txt +286 -223
- data/website/javascripts/rounded_corners_lite.inc.js +0 -0
- data/website/stylesheets/screen.css +0 -0
- data/website/template.js +0 -0
- data/website/template.rhtml +0 -0
- data/website/version-raw.js +2 -2
- data/website/version-raw.txt +1 -1
- data/website/version.js +1 -1
- data/website/version.txt +0 -0
- metadata +63 -37
data/CHANGELOG.txt
CHANGED
File without changes
|
data/History.txt
CHANGED
File without changes
|
data/Manifest.txt
CHANGED
@@ -1,32 +1,43 @@
|
|
1
|
-
CHANGELOG.txt
|
2
|
-
History.txt
|
3
|
-
Manifest.txt
|
4
|
-
README.txt
|
5
|
-
Rakefile
|
6
|
-
lib/ext_active_record/
|
7
|
-
lib/
|
8
|
-
lib/magic_multi_connections
|
9
|
-
lib/magic_multi_connections/
|
10
|
-
lib/magic_multi_connections/
|
11
|
-
|
12
|
-
scripts/
|
13
|
-
|
14
|
-
|
15
|
-
test/
|
16
|
-
test/
|
17
|
-
test/fixtures/
|
18
|
-
test/fixtures/
|
19
|
-
test/
|
20
|
-
test/
|
21
|
-
test/
|
22
|
-
test/
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
1
|
+
CHANGELOG.txt
|
2
|
+
History.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
lib/ext_active_record/association_extensions.rb
|
7
|
+
lib/ext_active_record/connection_specification.rb
|
8
|
+
lib/magic_multi_connections.rb
|
9
|
+
lib/magic_multi_connections/connected.rb
|
10
|
+
lib/magic_multi_connections/module.rb
|
11
|
+
lib/magic_multi_connections/version.rb
|
12
|
+
scripts/txt2html
|
13
|
+
scripts/txt2js
|
14
|
+
setup.rb
|
15
|
+
test/connections/native_mysql/connection.rb
|
16
|
+
test/connections/native_postgresql/connection.rb
|
17
|
+
test/fixtures/address.rb
|
18
|
+
test/fixtures/addresses.yml
|
19
|
+
test/fixtures/assignment.rb
|
20
|
+
test/fixtures/classified.rb
|
21
|
+
test/fixtures/contact_repository.rb
|
22
|
+
test/fixtures/db_definitions/mysql.sql
|
23
|
+
test/fixtures/db_definitions/postgresql.sql
|
24
|
+
test/fixtures/habit.rb
|
25
|
+
test/fixtures/paycheck.rb
|
26
|
+
test/fixtures/people.yml
|
27
|
+
test/fixtures/person.rb
|
28
|
+
test/fixtures/soldier.rb
|
29
|
+
test/test_helper.rb
|
30
|
+
test/test_magic_multi_connections.rb
|
31
|
+
test/test_mmc_associations.rb
|
32
|
+
test/test_parent_module.rb
|
33
|
+
test/test_preexisting_module.rb
|
34
|
+
website/index.html
|
35
|
+
website/index.txt
|
36
|
+
website/javascripts/rounded_corners_lite.inc.js
|
37
|
+
website/stylesheets/screen.css
|
38
|
+
website/template.js
|
39
|
+
website/template.rhtml
|
40
|
+
website/version-raw.js
|
41
|
+
website/version-raw.txt
|
42
|
+
website/version.js
|
43
|
+
website/version.txt
|
data/README.txt
CHANGED
File without changes
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ require 'hoe'
|
|
11
11
|
include FileUtils
|
12
12
|
require File.join(File.dirname(__FILE__), 'lib', 'magic_multi_connections', 'version')
|
13
13
|
|
14
|
-
AUTHOR = "
|
14
|
+
AUTHOR = "Dr Nic Williams" # can also be an array of Authors
|
15
15
|
EMAIL = "drnicwilliams@gmail.com"
|
16
16
|
DESCRIPTION = "Your ActiveRecord classes can be accessed within multiple modules, each which targets a different DB connection"
|
17
17
|
GEM_NAME = "magic_multi_connections" # what ppl will type to install your gem
|
@@ -22,7 +22,7 @@ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
|
22
22
|
NAME = "magic_multi_connections"
|
23
23
|
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
24
|
VERS = ENV['VERSION'] || (MagicMultiConnection::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
25
|
-
|
25
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config', 'debug.log']
|
26
26
|
RDOC_OPTS = ['--quiet', '--title', "magic_multi_connections documentation",
|
27
27
|
"--opname", "index.html",
|
28
28
|
"--line-numbers",
|
@@ -64,24 +64,30 @@ end
|
|
64
64
|
SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions))
|
65
65
|
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
67
|
+
namespace :postgresql do
|
68
|
+
desc 'Build the PostgreSQL test databases'
|
69
|
+
task :build_databases do
|
70
|
+
sh %{ createdb "#{GEM_NAME}_unittest" }
|
71
|
+
sh %{ psql "#{GEM_NAME}_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} }
|
72
|
+
sh %{ createdb "#{GEM_NAME}_extra_unittest" }
|
73
|
+
sh %{ psql "#{GEM_NAME}_extra_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} }
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Drop the PostgreSQL test databases'
|
77
|
+
task :drop_databases do
|
78
|
+
sh %{ dropdb "#{GEM_NAME}_unittest" }
|
79
|
+
sh %{ dropdb "#{GEM_NAME}_extra_unittest" }
|
80
|
+
end
|
74
81
|
|
75
|
-
desc '
|
76
|
-
task :
|
77
|
-
sh %{ dropdb "#{GEM_NAME}_unittest" }
|
78
|
-
sh %{ dropdb "#{GEM_NAME}_extra_unittest" }
|
82
|
+
desc 'Rebuild the PostgreSQL test databases'
|
83
|
+
task :rebuild_databases => [:drop_databases, :build_databases]
|
79
84
|
end
|
80
85
|
|
81
|
-
desc '
|
86
|
+
desc 'Build the PostgreSQL test databases'
|
87
|
+
task :build_postgresql_databases => 'postgresql:build_databases'
|
88
|
+
task :drop_postgresql_databases => 'postgresql:drop_databases'
|
82
89
|
task :rebuild_postgresql_databases => [:drop_postgresql_databases, :build_postgresql_databases]
|
83
90
|
|
84
|
-
|
85
91
|
desc 'Generate website files'
|
86
92
|
task :website_generate do
|
87
93
|
sh %{ ruby scripts/txt2html website/index.txt > website/index.html }
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#raise "STOP"
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Reflection
|
5
|
+
|
6
|
+
# This will add the 'mirrors_owner_db_connection' property to
|
7
|
+
# the Association Reflection object.
|
8
|
+
class AssociationReflection
|
9
|
+
|
10
|
+
def mirror_db_connection
|
11
|
+
return :default unless self.options.key?(:mirror_db_connection)
|
12
|
+
self.options.key?(:mirror_db_connection)
|
13
|
+
end
|
14
|
+
|
15
|
+
def mirror_db_connection=(value)
|
16
|
+
self.options[:mirror_db_connection] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Associations
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def create_has_many_reflection(association_id, options, &extension)
|
26
|
+
options.assert_valid_keys(
|
27
|
+
:class_name, :table_name, :foreign_key,
|
28
|
+
:exclusively_dependent, :dependent,
|
29
|
+
:select, :conditions, :include, :order, :group, :limit, :offset,
|
30
|
+
:as, :through, :source, :source_type,
|
31
|
+
:uniq,
|
32
|
+
:finder_sql, :counter_sql,
|
33
|
+
:before_add, :after_add, :before_remove, :after_remove,
|
34
|
+
:extend,
|
35
|
+
:mirror_db_connection
|
36
|
+
)
|
37
|
+
|
38
|
+
options[:extend] = create_extension_module(association_id, extension) if block_given?
|
39
|
+
|
40
|
+
create_reflection(:has_many, association_id, options, self)
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_has_one_reflection(association_id, options)
|
44
|
+
options.assert_valid_keys(
|
45
|
+
:class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as,
|
46
|
+
:mirror_db_connection
|
47
|
+
)
|
48
|
+
|
49
|
+
create_reflection(:has_one, association_id, options, self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_belongs_to_reflection(association_id, options)
|
53
|
+
options.assert_valid_keys(
|
54
|
+
:class_name, :foreign_key, :foreign_type, :remote, :conditions, :order, :include, :dependent,
|
55
|
+
:counter_cache, :extend, :polymorphic,
|
56
|
+
:mirror_db_connection
|
57
|
+
)
|
58
|
+
|
59
|
+
reflection = create_reflection(:belongs_to, association_id, options, self)
|
60
|
+
|
61
|
+
if options[:polymorphic]
|
62
|
+
reflection.options[:foreign_type] ||= reflection.class_name.underscore + "_type"
|
63
|
+
end
|
64
|
+
|
65
|
+
reflection
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_has_and_belongs_to_many_reflection(association_id, options, &extension)
|
69
|
+
options.assert_valid_keys(
|
70
|
+
:class_name, :table_name, :join_table, :foreign_key, :association_foreign_key,
|
71
|
+
:select, :conditions, :include, :order, :group, :limit, :offset,
|
72
|
+
:uniq,
|
73
|
+
:finder_sql, :delete_sql, :insert_sql,
|
74
|
+
:before_add, :after_add, :before_remove, :after_remove,
|
75
|
+
:extend,
|
76
|
+
:mirror_db_connection
|
77
|
+
)
|
78
|
+
|
79
|
+
options[:extend] = create_extension_module(association_id, extension) if block_given?
|
80
|
+
|
81
|
+
reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self)
|
82
|
+
|
83
|
+
reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name))
|
84
|
+
|
85
|
+
reflection
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
File without changes
|
@@ -1,21 +1,22 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
-
|
4
|
-
unless defined?(ActiveSupport) && defined?(ActiveRecord)
|
5
|
-
begin
|
6
|
-
require 'active_support'
|
7
|
-
require 'active_record'
|
8
|
-
rescue LoadError
|
9
|
-
require 'rubygems'
|
10
|
-
require 'active_support'
|
11
|
-
require 'active_record'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module MagicMultiConnection
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'magic_multi_connections/version'
|
19
|
-
require 'magic_multi_connections/connected'
|
20
|
-
require 'magic_multi_connections/module'
|
21
|
-
require 'ext_active_record/connection_specification'
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
unless defined?(ActiveSupport) && defined?(ActiveRecord)
|
5
|
+
begin
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_record'
|
8
|
+
rescue LoadError
|
9
|
+
require 'rubygems'
|
10
|
+
require 'active_support'
|
11
|
+
require 'active_record'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module MagicMultiConnection
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'magic_multi_connections/version'
|
19
|
+
require 'magic_multi_connections/connected'
|
20
|
+
require 'magic_multi_connections/module'
|
21
|
+
require 'ext_active_record/connection_specification'
|
22
|
+
require 'ext_active_record/association_extensions'
|
@@ -1,29 +1,91 @@
|
|
1
|
-
module MagicMultiConnection::Connected
|
2
|
-
def self.included(base)
|
3
|
-
base.instance_eval
|
4
|
-
alias :pre_connected_const_missing :const_missing
|
5
|
-
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
1
|
+
module MagicMultiConnection::Connected
|
2
|
+
def self.included(base)
|
3
|
+
base.instance_eval do
|
4
|
+
alias :pre_connected_const_missing :const_missing
|
5
|
+
|
6
|
+
def namespace_reflections_mirror_db
|
7
|
+
@namespace_reflections_mirror_db
|
8
|
+
end
|
9
|
+
|
10
|
+
def namespace_reflections_mirror_db=(value)
|
11
|
+
if value
|
12
|
+
warn "DEPRACATION WARNING: Automatic namespace associations will be removed in the next major release of this gem. Please use explicit association statments."
|
13
|
+
end
|
14
|
+
@namespace_reflections_mirror_db = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def const_missing(const_id)
|
18
|
+
# return pre_connected_const_missing(const_id) rescue nil
|
19
|
+
target_class = "#{self.parent_module}::#{const_id}".constantize rescue nil
|
20
|
+
raise NameError.new("uninitialized constant \{const_id}") unless target_class
|
21
|
+
|
22
|
+
# The code below is used to solve an issue with the acts_as_versioned
|
23
|
+
# plugin. Because the acts_as_versioned plugin creates a 'Version' model
|
24
|
+
# in the namespace of the class itself, the mmc method const_missing() will
|
25
|
+
# never get called. To get around this issue I have modified the acts_as_versioned
|
26
|
+
# plugin so that it uses the inherited() method and forces a new ActiveRecord object
|
27
|
+
# to be created. That inheritance method relies on mmc_owner function created below.
|
28
|
+
mmc_owner = self
|
29
|
+
klass = create_class const_id, target_class do
|
30
|
+
@@mmc_owner = mmc_owner
|
31
|
+
def self.mmc_owner
|
32
|
+
@@mmc_owner
|
33
|
+
end
|
34
|
+
end
|
35
|
+
klass.establish_connection self.connection_spec
|
36
|
+
klass
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_class(class_name, superclass = Object, &block)
|
40
|
+
klass = Class.new superclass, &block
|
41
|
+
result = self.const_set(class_name, klass)
|
42
|
+
|
43
|
+
# Cycle through all reflections, and redefine those reflections
|
44
|
+
# for all relationships where the ActiveRecord Object follows one
|
45
|
+
# of the two following conditions:
|
46
|
+
# 1. The module is set to mirror relationships for the namespace, the reflection object is in
|
47
|
+
# the reflection owner's namespace and the mirror_db_connection object is not explicitly set
|
48
|
+
# 2. The reflections mirror_db_connection is explicitly set to true.
|
49
|
+
parent_mod = self.parent_module
|
50
|
+
superclass.reflections.each do |reflection_name, reflection|
|
51
|
+
|
52
|
+
# First do a check to see if code is using a depracated method
|
53
|
+
# of associations:
|
54
|
+
reflection_mirrors_db = false
|
55
|
+
if reflection.mirror_db_connection == true
|
56
|
+
reflection_mirrors_db = true
|
57
|
+
elsif (reflection.mirror_db_connection == :default &&
|
58
|
+
namespace_reflections_mirror_db &&
|
59
|
+
Regexp.new("(::|^)#{parent_mod.to_s}(::|$)") =~ reflection.klass.to_s)
|
60
|
+
warn "DEPRACATION WARNING: Automatic namespace associations will be removed in the next major release of this gem. Please use explicit association statments."
|
61
|
+
reflection_mirrors_db = true
|
62
|
+
end
|
63
|
+
|
64
|
+
if reflection_mirrors_db
|
65
|
+
# redefine the reflection
|
66
|
+
new_class_name = reflection.class_name.sub(parent_mod.to_s, "::#{self.name}").gsub("::::", "::")
|
67
|
+
new_options = reflection.options.dup
|
68
|
+
new_options[:class_name] = new_class_name
|
69
|
+
case reflection.macro
|
70
|
+
when :has_one, :has_many, :belongs_to
|
71
|
+
new_options[:foreign_key] ||= reflection.primary_key_name
|
72
|
+
when :has_and_belongs_to_many
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
klass.send reflection.macro, reflection_name, new_options
|
77
|
+
end
|
78
|
+
end
|
79
|
+
result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
base.extend(ClassMethods)
|
83
|
+
end
|
84
|
+
|
85
|
+
module ClassMethods
|
86
|
+
def establish_connection_on(klass)
|
87
|
+
klass.establish_connection self.connection_spec
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -1,26 +1,27 @@
|
|
1
|
-
class Module
|
2
|
-
attr_accessor :connection_spec
|
3
|
-
|
4
|
-
def establish_connection(connection_spec)
|
5
|
-
include MagicMultiConnection::Connected
|
6
|
-
instance_variable_set '@connection_spec', connection_spec
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
parent = '
|
13
|
-
parent.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
next unless c.
|
22
|
-
c.
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
1
|
+
class Module
|
2
|
+
attr_accessor :connection_spec
|
3
|
+
|
4
|
+
def establish_connection(connection_spec, namespace_reflections_mirror_db = true)
|
5
|
+
include MagicMultiConnection::Connected
|
6
|
+
instance_variable_set '@connection_spec', connection_spec
|
7
|
+
instance_variable_set '@namespace_reflections_mirror_db', namespace_reflections_mirror_db
|
8
|
+
update_active_records
|
9
|
+
end
|
10
|
+
|
11
|
+
def parent_module
|
12
|
+
parent = self.name.split('::')[0..-2].join('::')
|
13
|
+
parent = 'Object' if parent.blank?
|
14
|
+
parent.constantize
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def update_active_records
|
19
|
+
self.constants.each do |c_str|
|
20
|
+
c = "#{self.name}::#{c_str}".constantize
|
21
|
+
next unless c.is_a? Class
|
22
|
+
next unless c.new.is_a? ActiveRecord::Base
|
23
|
+
c.establish_connection connection_spec
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|