redhillonrails_core 1.0.9.1 → 1.1.0

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 (58) hide show
  1. data/CHANGELOG +7 -0
  2. data/README.rdoc +31 -47
  3. data/lib/redhillonrails_core/active_record/base.rb +63 -0
  4. data/lib/redhillonrails_core/active_record/connection_adapters/abstract_adapter.rb +75 -0
  5. data/lib/redhillonrails_core/active_record/connection_adapters/column.rb +25 -0
  6. data/lib/redhillonrails_core/active_record/connection_adapters/foreign_key_definition.rb +30 -0
  7. data/lib/redhillonrails_core/active_record/connection_adapters/index_definition.rb +17 -0
  8. data/lib/redhillonrails_core/active_record/connection_adapters/mysql_adapter.rb +78 -0
  9. data/lib/redhillonrails_core/active_record/connection_adapters/mysql_column.rb +12 -0
  10. data/lib/redhillonrails_core/active_record/connection_adapters/postgresql_adapter.rb +160 -0
  11. data/lib/redhillonrails_core/active_record/connection_adapters/sqlite3_adapter.rb +111 -0
  12. data/lib/redhillonrails_core/active_record/connection_adapters/table_definition.rb +31 -0
  13. data/lib/redhillonrails_core/active_record/schema.rb +27 -0
  14. data/lib/redhillonrails_core/active_record/schema_dumper.rb +70 -0
  15. data/lib/redhillonrails_core.rb +20 -26
  16. data/redhillonrails_core.gemspec +34 -40
  17. data/spec/connections/mysql/connection.rb +18 -0
  18. data/spec/connections/mysql2/connection.rb +18 -0
  19. data/spec/connections/postgresql/connection.rb +15 -0
  20. data/spec/connections/sqlite3/connection.rb +14 -0
  21. data/spec/foreign_key_spec.rb +100 -0
  22. data/spec/index_definition_spec.rb +145 -0
  23. data/spec/index_spec.rb +67 -0
  24. data/spec/models/comment.rb +5 -0
  25. data/spec/models/post.rb +6 -0
  26. data/spec/models/user.rb +5 -0
  27. data/spec/schema/schema.rb +21 -0
  28. data/spec/schema_dumper_spec.rb +117 -0
  29. data/spec/spec_helper.rb +16 -0
  30. data/spec/support/reference.rb +66 -0
  31. metadata +32 -57
  32. data/.document +0 -5
  33. data/.gitignore +0 -23
  34. data/.rvmrc +0 -1
  35. data/Gemfile +0 -20
  36. data/Gemfile.lock +0 -50
  37. data/Rakefile +0 -76
  38. data/VERSION +0 -1
  39. data/examples/example_helper.rb +0 -44
  40. data/examples/postgresql_index_parser_example.rb +0 -198
  41. data/lib/red_hill_consulting/core/active_record/base.rb +0 -61
  42. data/lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb +0 -71
  43. data/lib/red_hill_consulting/core/active_record/connection_adapters/column.rb +0 -21
  44. data/lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb +0 -26
  45. data/lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb +0 -13
  46. data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql4_adapter.rb +0 -37
  47. data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql5_adapter.rb +0 -40
  48. data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb +0 -103
  49. data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb +0 -8
  50. data/lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb +0 -178
  51. data/lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb +0 -23
  52. data/lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb +0 -109
  53. data/lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb +0 -27
  54. data/lib/red_hill_consulting/core/active_record/schema.rb +0 -25
  55. data/lib/red_hill_consulting/core/active_record/schema_dumper.rb +0 -66
  56. data/lib/red_hill_consulting/core/active_record.rb +0 -4
  57. data/lib/red_hill_consulting/core.rb +0 -4
  58. data/tasks/db/comments.rake +0 -9
data/Gemfile.lock DELETED
@@ -1,50 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activerecord (2.3.10)
5
- activesupport (= 2.3.10)
6
- activesupport (2.3.10)
7
- archive-tar-minitar (0.5.2)
8
- columnize (0.3.1)
9
- gemcutter (0.6.1)
10
- git (1.2.5)
11
- jeweler (1.4.0)
12
- gemcutter (>= 0.1.0)
13
- git (>= 1.2.5)
14
- rubyforge (>= 2.0.0)
15
- json_pure (1.4.6)
16
- linecache (0.43)
17
- linecache19 (0.5.11)
18
- ruby_core_source (>= 0.1.4)
19
- micronaut (0.3.0)
20
- pg (0.9.0)
21
- rake (0.8.7)
22
- ruby-debug (0.10.3)
23
- columnize (>= 0.1)
24
- ruby-debug-base (~> 0.10.3.0)
25
- ruby-debug-base (0.10.3)
26
- linecache (>= 0.3)
27
- ruby-debug-base19 (0.11.24)
28
- columnize (>= 0.3.1)
29
- linecache19 (>= 0.5.11)
30
- ruby_core_source (>= 0.1.4)
31
- ruby-debug19 (0.11.6)
32
- columnize (>= 0.3.1)
33
- linecache19 (>= 0.5.11)
34
- ruby-debug-base19 (>= 0.11.19)
35
- ruby_core_source (0.1.4)
36
- archive-tar-minitar (>= 0.5.2)
37
- rubyforge (2.0.4)
38
- json_pure (>= 1.1.7)
39
-
40
- PLATFORMS
41
- ruby
42
-
43
- DEPENDENCIES
44
- activerecord (< 3.0.0)
45
- jeweler
46
- micronaut
47
- pg
48
- rake
49
- ruby-debug
50
- ruby-debug19
data/Rakefile DELETED
@@ -1,76 +0,0 @@
1
- # encoding: utf-8
2
- require 'rubygems'
3
- require 'rake'
4
-
5
- begin
6
- require 'jeweler'
7
- Jeweler::Tasks.new do |gem|
8
- gem.name = "redhillonrails_core"
9
- gem.summary = %Q{RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins}
10
- gem.description = %Q{RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins. It creates and drops views and foreign-keys or obtains indexes directly from a model class.}
11
- gem.email = "michal.lomnicki@gmail.com"
12
- gem.homepage = "http://github.com/mlomnicki/redhillonrails_core"
13
- gem.authors = ["Michał Łomnicki"]
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
-
16
- gem.add_dependency "activerecord"
17
-
18
- gem.add_development_dependency "micronaut"
19
- end
20
- Jeweler::GemcutterTasks.new
21
- rescue LoadError
22
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
- end
24
-
25
- require 'rake/testtask'
26
- Rake::TestTask.new(:test) do |test|
27
- test.libs << 'lib' << 'test'
28
- test.pattern = 'test/**/test_*.rb'
29
- test.verbose = true
30
- end
31
-
32
- begin
33
- require 'rcov/rcovtask'
34
- Rcov::RcovTask.new do |test|
35
- test.libs << 'test'
36
- test.pattern = 'test/**/test_*.rb'
37
- test.verbose = true
38
- end
39
- rescue LoadError
40
- task :rcov do
41
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
- end
43
- end
44
-
45
- require 'rake/rdoctask'
46
- Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "redhillonrails_core #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
54
-
55
- require "micronaut/rake_task"
56
- Micronaut::RakeTask.new(:examples) do |examples|
57
- examples.pattern = "examples/**/*_example.rb"
58
- examples.ruby_opts << "-Ilib -Iexamples"
59
- end
60
-
61
- Micronaut::RakeTask.new(:rcov) do |examples|
62
- examples.pattern = "examples/**/*_example.rb"
63
- examples.rcov_opts = "-Ilib -Iexamples"
64
- examples.rcov = true
65
- end
66
-
67
- task :examples => :check_dependencies
68
-
69
- task :default => :examples
70
-
71
- namespace :postgresql do
72
- task :examples do
73
- ENV["ADAPTER"] = "postgresql"
74
- Rake::Task["examples"].invoke
75
- end
76
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.9.1
@@ -1,44 +0,0 @@
1
- require "micronaut"
2
- require "active_record"
3
- require "redhillonrails_core"
4
- require "fileutils"
5
-
6
- begin
7
- require "ruby-debug"
8
- rescue LoadError
9
- # Don't care - debugging won't be available
10
- end
11
-
12
- # Log data somewhere interesting
13
- FileUtils.mkdir_p("log") rescue nil
14
- ActiveRecord::Base.logger = Logger.new("log/test.log")
15
-
16
- # The model we'll be playing along with. Nothing ActiveRecord-like is expected or required here.
17
- class User < ActiveRecord::Base
18
- end
19
-
20
- # We drop and reload the schema on all specs, to make it easier to know what'll be in the DB
21
- case ENV["ADAPTER"]
22
- when "postgresql"
23
- ActiveRecord::Base.establish_connection :adapter => "postgresql", :database => "redhillonrails_core_test", :min_messages => "warning"
24
- else
25
- raise ArgumentError, "ADAPTER environment variable left unset: run tests and set ADAPTER to a known value. Valid values are: postgresql"
26
- end
27
-
28
- Micronaut.configure do |c|
29
- c.before :each do
30
- @migrator.suppress_messages do
31
- @migrator.up
32
- end
33
- end
34
-
35
- c.before :each do
36
- User.reset_column_information
37
- end
38
-
39
- c.after :each do
40
- @migrator.suppress_messages do
41
- @migrator.down
42
- end
43
- end
44
- end
@@ -1,198 +0,0 @@
1
- require "example_helper"
2
- require "red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter"
3
-
4
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "simple indexes" do
5
-
6
- before :all do
7
- @migrator = Class.new(ActiveRecord::Migration) do
8
- def self.up
9
- create_table :users do |t|
10
- t.string :username
11
- end
12
-
13
- add_index :users, :username
14
- end
15
-
16
- def self.down
17
- drop_table :users
18
- end
19
- end
20
- end
21
-
22
- it "should parse the index and return appropriate information" do
23
- indexes = User.indexes
24
- indexes.length.should == 1
25
-
26
- index = indexes.first
27
- index.name.should == "index_users_on_username"
28
- index.columns.should == ["username"]
29
- index.unique.should == false
30
- index.should be_case_sensitive
31
- index.expression.should be_nil
32
- end
33
-
34
- end
35
-
36
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "unique indexes" do
37
-
38
- before :all do
39
- @migrator = Class.new(ActiveRecord::Migration) do
40
- def self.up
41
- create_table :users do |t|
42
- t.string :username
43
- end
44
-
45
- add_index :users, :username, :unique => true, :case_sensitive => true
46
- end
47
-
48
- def self.down
49
- drop_table :users
50
- end
51
- end
52
- end
53
-
54
- it "should parse the index and return appropriate information" do
55
- indexes = User.indexes
56
- indexes.length.should == 1
57
-
58
- index = indexes.first
59
- index.name.should == "index_users_on_username"
60
- index.columns.should == ["username"]
61
- index.unique.should == true
62
- index.should be_case_sensitive
63
- index.expression.should be_nil
64
- end
65
-
66
- end
67
-
68
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "case-insensitive indexes" do
69
-
70
- before :all do
71
- @migrator = Class.new(ActiveRecord::Migration) do
72
- def self.up
73
- create_table :users do |t|
74
- t.string :username
75
- end
76
-
77
- add_index :users, :username, :case_sensitive => false
78
- end
79
-
80
- def self.down
81
- drop_table :users
82
- end
83
- end
84
- end
85
-
86
- it "should parse the index and return appropriate information" do
87
- indexes = User.indexes
88
- indexes.length.should == 1
89
-
90
- index = indexes.first
91
- index.name.should == "index_users_on_username"
92
- index.columns.should == ["username"]
93
- index.unique.should == false
94
- index.should_not be_case_sensitive
95
- index.expression.should be_nil
96
- end
97
-
98
- end
99
-
100
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "partial indexes" do
101
-
102
- before :all do
103
- @migrator = Class.new(ActiveRecord::Migration) do
104
- def self.up
105
- create_table :users do |t|
106
- t.string :username, :state
107
- end
108
-
109
- add_index :users, :username, :unique => true, :name => "index_users_on_active_usernames", :conditions => {:state => "active"}
110
- end
111
-
112
- def self.down
113
- drop_table :users
114
- end
115
- end
116
- end
117
-
118
- it "should parse conditional index and report conditions" do
119
- indexes = User.indexes
120
- indexes.length.should == 1
121
-
122
- index = indexes.first
123
- index.should be_case_sensitive
124
- index.columns.should == ["username"]
125
-
126
- # FIXME: This is subject to change depending on the PostgreSQL version
127
- index.conditions.should == "state::text = 'active'::text"
128
- end
129
-
130
- end
131
-
132
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "expression indexes" do
133
-
134
- before :all do
135
- @migrator = Class.new(ActiveRecord::Migration) do
136
- def self.up
137
- create_table :users do |t|
138
- t.string :username, :state
139
- end
140
-
141
- add_index :users, :expression => "USING gin (to_tsvector('english', username))", :name => "index_users_full_text"
142
- end
143
-
144
- def self.down
145
- drop_table :users
146
- end
147
- end
148
- end
149
-
150
- it "should parse conditional index and report conditions" do
151
- indexes = User.indexes
152
- indexes.length.should == 1
153
-
154
- index = indexes.first
155
- index.unique.should == false
156
- index.should be_case_sensitive
157
- index.columns.should be_nil
158
-
159
- # FIXME: This is subject to change depending on the PostgreSQL version
160
- index.conditions.should be_nil
161
- index.expression.should == "gin (to_tsvector('english'::regconfig, username::text))"
162
- end
163
-
164
- end
165
-
166
- describe RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter, "case insensitive + partial index" do
167
-
168
- before :all do
169
- @migrator = Class.new(ActiveRecord::Migration) do
170
- def self.up
171
- create_table :users do |t|
172
- t.string :username, :state
173
- end
174
-
175
- add_index :users, :username, :unique => true, :case_sensitive => false, :conditions => {:state => %w(active suspended invited)}
176
- end
177
-
178
- def self.down
179
- drop_table :users
180
- end
181
- end
182
- end
183
-
184
- it "should parse as an expression index" do
185
- indexes = User.indexes
186
- indexes.length.should == 1
187
-
188
- index = indexes.first
189
- index.unique.should == false # We don't attempt to determine if this is true/false when it's an expression index
190
- index.should be_case_sensitive # Same here: return the default value - expression trumps all other values
191
- index.columns.should be_nil # And we know the columns aren't specified when it's an expression
192
-
193
- # FIXME: This is subject to change depending on the PostgreSQL version
194
- index.conditions.should be_nil
195
- index.expression.should == "btree (lower(username::text)) WHERE state::text = ANY (ARRAY['active'::character varying, 'suspended'::character varying, 'invited'::character varying]::text[])"
196
- end
197
-
198
- end
@@ -1,61 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord
2
- module Base
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- class << base
10
- alias_method_chain :columns, :redhillonrails_core
11
- alias_method_chain :abstract_class?, :redhillonrails_core
12
- alias_method_chain :reset_column_information, :redhillonrails_core
13
- end
14
- end
15
-
16
- def base_class?
17
- self == base_class
18
- end
19
-
20
- def abstract_class_with_redhillonrails_core?
21
- abstract_class_without_redhillonrails_core? || !(name =~ /^Abstract/).nil?
22
- end
23
-
24
- def columns_with_redhillonrails_core
25
- unless @columns
26
- columns_without_redhillonrails_core
27
- cols = columns_hash
28
- indexes.each do |index|
29
- next if index.columns.blank?
30
- column_name = index.columns.reverse.detect { |name| name !~ /_id$/ } || index.columns.last
31
- column = cols[column_name]
32
- column.case_sensitive = index.case_sensitive?
33
- column.unique_scope = index.columns.reject { |name| name == column_name } if index.unique
34
- end
35
- end
36
- @columns
37
- end
38
-
39
- def reset_column_information_with_redhillonrails_core
40
- reset_column_information_without_redhillonrails_core
41
- @indexes = @foreign_keys = nil
42
- end
43
-
44
- def pluralized_table_name(table_name)
45
- ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
46
- end
47
-
48
- def indexes
49
- @indexes ||= connection.indexes(table_name, "#{name} Indexes")
50
- end
51
-
52
- def foreign_keys
53
- @foreign_keys ||= connection.foreign_keys(table_name, "#{name} Foreign Keys")
54
- end
55
-
56
- def reverse_foreign_keys
57
- connection.reverse_foreign_keys(table_name, "#{name} Reverse Foreign Keys")
58
- end
59
- end
60
- end
61
- end
@@ -1,71 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module AbstractAdapter
3
- def self.included(base)
4
- base.alias_method_chain :initialize, :redhillonrails_core
5
- base.alias_method_chain :drop_table, :redhillonrails_core
6
- end
7
-
8
- def initialize_with_redhillonrails_core(*args)
9
- initialize_without_redhillonrails_core(*args)
10
- adapter = nil
11
- case adapter_name
12
- # name of MySQL adapter depends on mysql gem
13
- # * with mysql gem adapter is named MySQL
14
- # * with mysql2 gem adapter is named Mysql2
15
- # Here we handle this and hopefully futher adapter names
16
- when /^MySQL/i
17
- adapter = 'MysqlAdapter'
18
- when 'PostgreSQL'
19
- adapter = 'PostgresqlAdapter'
20
- when 'SQLite'
21
- adapter = 'SqliteAdapter'
22
- end
23
- if adapter
24
- adapter_module = RedHillConsulting::Core::ActiveRecord::ConnectionAdapters.const_get(adapter)
25
- self.class.send(:include, adapter_module) unless self.class.include?(adapter_module)
26
- end
27
- end
28
-
29
- def create_view(view_name, definition)
30
- execute "CREATE VIEW #{view_name} AS #{definition}"
31
- end
32
-
33
- def drop_view(view_name)
34
- execute "DROP VIEW #{view_name}"
35
- end
36
-
37
- def views(name = nil)
38
- []
39
- end
40
-
41
- def view_definition(view_name, name = nil)
42
- end
43
-
44
- def foreign_keys(table_name, name = nil)
45
- []
46
- end
47
-
48
- def reverse_foreign_keys(table_name, name = nil)
49
- []
50
- end
51
-
52
- def add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {})
53
- foreign_key = ForeignKeyDefinition.new(options[:name], table_name, column_names, ActiveRecord::Migrator.proper_table_name(references_table_name), references_column_names, options[:on_update], options[:on_delete], options[:deferrable])
54
- execute "ALTER TABLE #{table_name} ADD #{foreign_key}"
55
- end
56
-
57
- def remove_foreign_key(table_name, foreign_key_name, options = {})
58
- execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{foreign_key_name}"
59
- end
60
-
61
- def drop_table_with_redhillonrails_core(name, options = {})
62
- reverse_foreign_keys(name).each { |foreign_key| remove_foreign_key(foreign_key.table_name, foreign_key.name, options) }
63
- drop_table_without_redhillonrails_core(name, options)
64
- end
65
-
66
- def supports_partial_indexes?
67
- false
68
- end
69
-
70
- end
71
- end
@@ -1,21 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module Column
3
- attr_accessor :unique_scope
4
- attr_accessor :case_sensitive
5
- alias case_sensitive? case_sensitive
6
-
7
- def unique?
8
- !unique_scope.nil?
9
- end
10
-
11
- def required_on
12
- if null
13
- nil
14
- elsif default.nil?
15
- :save
16
- else
17
- :update
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- class ForeignKeyDefinition < Struct.new(:name, :table_name, :column_names, :references_table_name, :references_column_names, :on_update, :on_delete, :deferrable)
3
- ACTIONS = { :cascade => "CASCADE", :restrict => "RESTRICT", :set_null => "SET NULL", :set_default => "SET DEFAULT", :no_action => "NO ACTION" }.freeze
4
-
5
- def to_dump
6
- dump = "add_foreign_key"
7
- dump << " #{table_name.inspect}, [#{Array(column_names).collect{ |name| name.inspect }.join(', ')}]"
8
- dump << ", #{references_table_name.inspect}, [#{Array(references_column_names).collect{ |name| name.inspect }.join(', ')}]"
9
- dump << ", :on_update => :#{on_update}" if on_update
10
- dump << ", :on_delete => :#{on_delete}" if on_delete
11
- dump << ", :deferrable => #{deferrable}" if deferrable
12
- dump << ", :name => #{name.inspect}" if name
13
- dump
14
- end
15
-
16
- def to_sql
17
- sql = name ? "CONSTRAINT #{name} " : ""
18
- sql << "FOREIGN KEY (#{Array(column_names).join(", ")}) REFERENCES #{references_table_name} (#{Array(references_column_names).join(", ")})"
19
- sql << " ON UPDATE #{ACTIONS[on_update]}" if on_update
20
- sql << " ON DELETE #{ACTIONS[on_delete]}" if on_delete
21
- sql << " DEFERRABLE" if deferrable
22
- sql
23
- end
24
- alias :to_s :to_sql
25
- end
26
- end
@@ -1,13 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module IndexDefinition
3
- attr_accessor :conditions, :expression
4
-
5
- def case_sensitive?
6
- @case_sensitive.nil? ? true : @case_sensitive
7
- end
8
-
9
- def case_sensitive=(case_sensitive)
10
- @case_sensitive = case_sensitive
11
- end
12
- end
13
- end
@@ -1,37 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- # MySQL4-specific behaviors
3
- module Mysql4Adapter
4
- def reverse_foreign_keys(table_name, name = nil)
5
- tables = execute("SHOW TABLES")
6
-
7
- foreign_keys = []
8
-
9
- tables.each do |table|
10
- results = execute("SHOW CREATE TABLE #{table}")
11
- results.each do |row|
12
- row[1].lines.each do |line|
13
- if line =~ /^ CONSTRAINT [`"](.+?)[`"] FOREIGN KEY \([`"](.+?)[`"]\) REFERENCES [`"](.+?)[`"] \((.+?)\)( ON DELETE (.+?))?( ON UPDATE (.+?))?,?$/
14
- name = $1
15
- column_names = $2
16
- references_table_name = $3
17
- references_column_names = $4
18
- on_update = $8
19
- on_delete = $6
20
- on_update = on_update.downcase.gsub(' ', '_').to_sym if on_update
21
- on_delete = on_delete.downcase.gsub(' ', '_').to_sym if on_delete
22
-
23
- if references_table_name == table_name
24
- foreign_keys << ForeignKeyDefinition.new(name,
25
- table, column_names.gsub('`', '').split(', '),
26
- references_table_name, references_column_names.gsub('`', '').split(', '),
27
- on_update, on_delete)
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- foreign_keys
35
- end
36
- end
37
- end
@@ -1,40 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- # MySQL5-specific behaviors
3
- module Mysql5Adapter
4
- def reverse_foreign_keys(table_name, name = nil)
5
- @@schema ||= nil
6
- @@schema_version ||= 0
7
- current_version = ActiveRecord::Migrator.current_version
8
- if @@schema.nil? || @@schema_version != current_version
9
- @@schema_version = current_version
10
- ans = execute(<<-SQL, name)
11
- SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name
12
- FROM information_schema.key_column_usage
13
- WHERE table_schema = SCHEMA()
14
- AND referenced_table_schema = table_schema
15
- ORDER BY constraint_name, ordinal_position;
16
- SQL
17
- @@schema = []
18
- ans.each do | row |
19
- @@schema << [row[0], row[1], row[2], row[3], row[4]]
20
- end
21
- end
22
- results = @@schema
23
- current_foreign_key = nil
24
- foreign_keys = []
25
-
26
- results.each do |row|
27
- next unless table_name.casecmp(row[3]) == 0
28
- if current_foreign_key != row[0]
29
- foreign_keys << ForeignKeyDefinition.new(row[0], row[1], [], row[3], [])
30
- current_foreign_key = row[0]
31
- end
32
-
33
- foreign_keys.last.column_names << row[2]
34
- foreign_keys.last.references_column_names << row[4]
35
- end
36
-
37
- foreign_keys
38
- end
39
- end
40
- end