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.
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
+