magic_multi_connections 1.0.0 → 1.2.1
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/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
|
+
|