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.
Files changed (44) hide show
  1. data/CHANGELOG.txt +0 -0
  2. data/History.txt +0 -0
  3. data/Manifest.txt +43 -32
  4. data/README.txt +0 -0
  5. data/Rakefile +21 -15
  6. data/lib/ext_active_record/association_extensions.rb +90 -0
  7. data/lib/ext_active_record/connection_specification.rb +0 -0
  8. data/lib/magic_multi_connections.rb +22 -21
  9. data/lib/magic_multi_connections/connected.rb +91 -29
  10. data/lib/magic_multi_connections/module.rb +27 -26
  11. data/lib/magic_multi_connections/version.rb +9 -9
  12. data/scripts/txt2html +0 -0
  13. data/scripts/txt2js +1 -1
  14. data/setup.rb +0 -0
  15. data/test/connections/native_mysql/connection.rb +24 -0
  16. data/test/connections/native_postgresql/connection.rb +0 -0
  17. data/test/fixtures/address.rb +3 -0
  18. data/test/fixtures/addresses.yml +4 -0
  19. data/test/fixtures/assignment.rb +7 -0
  20. data/test/fixtures/classified.rb +5 -0
  21. data/test/fixtures/contact_repository.rb +2 -2
  22. data/test/fixtures/db_definitions/mysql.sql +19 -0
  23. data/test/fixtures/db_definitions/postgresql.sql +7 -1
  24. data/test/fixtures/habit.rb +3 -0
  25. data/test/fixtures/paycheck.rb +3 -0
  26. data/test/fixtures/people.yml +0 -0
  27. data/test/fixtures/person.rb +3 -1
  28. data/test/fixtures/soldier.rb +8 -0
  29. data/test/test_helper.rb +71 -71
  30. data/test/test_magic_multi_connections.rb +27 -26
  31. data/test/test_mmc_associations.rb +46 -0
  32. data/test/test_parent_module.rb +0 -0
  33. data/test/test_preexisting_module.rb +0 -0
  34. data/website/index.html +354 -340
  35. data/website/index.txt +286 -223
  36. data/website/javascripts/rounded_corners_lite.inc.js +0 -0
  37. data/website/stylesheets/screen.css +0 -0
  38. data/website/template.js +0 -0
  39. data/website/template.rhtml +0 -0
  40. data/website/version-raw.js +2 -2
  41. data/website/version-raw.txt +1 -1
  42. data/website/version.js +1 -1
  43. data/website/version.txt +0 -0
  44. metadata +63 -37
File without changes
File without changes
@@ -1,32 +1,43 @@
1
- CHANGELOG.txt
2
- History.txt
3
- Manifest.txt
4
- README.txt
5
- Rakefile
6
- lib/ext_active_record/connection_specification.rb
7
- lib/magic_multi_connections.rb
8
- lib/magic_multi_connections/connected.rb
9
- lib/magic_multi_connections/module.rb
10
- lib/magic_multi_connections/version.rb
11
- scripts/txt2html
12
- scripts/txt2js
13
- setup.rb
14
- test/connections/native_postgresql/connection.rb
15
- test/fixtures/contact_repository.rb
16
- test/fixtures/db_definitions/postgresql.sql
17
- test/fixtures/people.yml
18
- test/fixtures/person.rb
19
- test/test_helper.rb
20
- test/test_magic_multi_connections.rb
21
- test/test_parent_module.rb
22
- test/test_preexisting_module.rb
23
- website/index.html
24
- website/index.txt
25
- website/javascripts/rounded_corners_lite.inc.js
26
- website/stylesheets/screen.css
27
- website/template.js
28
- website/template.rhtml
29
- website/version-raw.js
30
- website/version-raw.txt
31
- website/version.js
32
- website/version.txt
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 = "nicwilliams" # can also be an array of Authors
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
- CLEAN.include ['**/.*.sw?', '*.gem', '.config']
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
- desc 'Build the PostgreSQL test databases'
68
- task :build_postgresql_databases do
69
- sh %{ createdb "#{GEM_NAME}_unittest" }
70
- sh %{ psql "#{GEM_NAME}_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} }
71
- sh %{ createdb "#{GEM_NAME}_extra_unittest" }
72
- sh %{ psql "#{GEM_NAME}_extra_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} }
73
- end
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 'Drop the PostgreSQL test databases'
76
- task :drop_postgresql_databases do
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 'Rebuild the PostgreSQL test databases'
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
@@ -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 <<-EOS
4
- alias :pre_connected_const_missing :const_missing
5
-
6
- def const_missing(const_id)
7
- return pre_connected_const_missing(const_id) rescue nil
8
- target_class = "::\#{const_id}".constantize rescue nil
9
- raise NameError.new("uninitialized constant \#{const_id}") unless target_class
10
- klass = create_class const_id, target_class
11
- klass.establish_connection self.connection_spec
12
- klass
13
- end
14
-
15
- def create_class(class_name, superclass = Object, &block)
16
- klass = Class.new superclass, &block
17
- self.const_set class_name, klass
18
- end
19
- EOS
20
- base.extend(ClassMethods)
21
- end
22
-
23
- module ClassMethods
24
- def establish_connection_on(klass)
25
- klass.establish_connection self.connection_spec
26
- end
27
- end
28
- end
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
- update_active_records
8
- end
9
-
10
- def parent_module
11
- parent = self.name.split('::')[0..-2].join('::')
12
- parent = 'Object' if parent.blank?
13
- parent.constantize
14
- end
15
-
16
- private
17
- def update_active_records
18
- self.constants.each do |c_str|
19
- c = "#{self.name}::#{c_str}".constantize
20
- next unless c.is_a? Class
21
- next unless c.new.is_a? ActiveRecord::Base
22
- c.establish_connection connection_spec
23
- end
24
- end
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
+