redhillonrails_core 1.0.9.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,103 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module MysqlAdapter
3
- def self.included(base)
4
- base.class_eval do
5
- alias_method_chain :remove_column, :redhillonrails_core
6
- alias_method_chain :connect, :redhillonrails_core
7
- end
8
- end
9
-
10
- def connect_with_redhillonrails_core(*args)
11
- result = connect_without_redhillonrails_core(*args)
12
- if version[0] < 5
13
- self.class.send(:include, Mysql4Adapter) unless self.class.include?(Mysql4Adapter)
14
- else
15
- self.class.send(:include, Mysql5Adapter) unless self.class.include?(Mysql5Adapter)
16
- end
17
- result
18
- end
19
-
20
- def set_table_comment(table_name, comment)
21
- execute "ALTER TABLE #{quote_table_name(table_name)} COMMENT='#{quote_string(comment)}'"
22
- end
23
-
24
- def clear_table_comment(table_name)
25
- execute "ALTER TABLE #{quote_table_name(table_name)} COMMENT=''"
26
- end
27
-
28
- def remove_foreign_key(table_name, foreign_key_name, options = {})
29
- execute "ALTER TABLE #{quote_table_name(table_name)} DROP FOREIGN KEY #{foreign_key_name}"
30
- end
31
-
32
- def remove_column_with_redhillonrails_core(table_name, column_name)
33
- foreign_keys(table_name).select { |foreign_key| foreign_key.column_names.include?(column_name.to_s) }.each do |foreign_key|
34
- remove_foreign_key(table_name, foreign_key.name)
35
- end
36
- remove_column_without_redhillonrails_core(table_name, column_name)
37
- end
38
-
39
- def foreign_keys(table_name, name = nil)
40
- results = execute("SHOW CREATE TABLE #{quote_table_name(table_name)}", name)
41
-
42
- foreign_keys = []
43
-
44
- results.each do |row|
45
- row[1].lines.each do |line|
46
- if line =~ /^ CONSTRAINT [`"](.+?)[`"] FOREIGN KEY \([`"](.+?)[`"]\) REFERENCES [`"](.+?)[`"] \((.+?)\)( ON DELETE (.+?))?( ON UPDATE (.+?))?,?$/
47
- name = $1
48
- column_names = $2
49
- references_table_name = $3
50
- references_column_names = $4
51
- on_update = $8
52
- on_delete = $6
53
- on_update = on_update.downcase.gsub(' ', '_').to_sym if on_update
54
- on_delete = on_delete.downcase.gsub(' ', '_').to_sym if on_delete
55
-
56
- foreign_keys << ForeignKeyDefinition.new(name,
57
- table_name, column_names.gsub('`', '').split(', '),
58
- references_table_name, references_column_names.gsub('`', '').split(', '),
59
- on_update, on_delete)
60
- end
61
- end
62
- end
63
-
64
- foreign_keys
65
- end
66
-
67
- def reverse_foreign_keys(table_name, name = nil)
68
- @@schema ||= nil
69
- @@schema_version ||= 0
70
- current_version = ActiveRecord::Migrator.current_version
71
- if @@schema.nil? || @@schema_version != current_version
72
- @@schema_version = current_version
73
- ans = execute(<<-SQL, name)
74
- SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name
75
- FROM information_schema.key_column_usage
76
- WHERE table_schema = SCHEMA()
77
- AND referenced_table_schema = table_schema
78
- ORDER BY constraint_name, ordinal_position;
79
- SQL
80
- @@schema = []
81
- ans.each do | row |
82
- @@schema << [row[0], row[1], row[2], row[3], row[4]]
83
- end
84
- end
85
- results = @@schema
86
- current_foreign_key = nil
87
- foreign_keys = []
88
-
89
- results.each do |row|
90
- next if row[3] != table_name
91
- if current_foreign_key != row[0]
92
- foreign_keys << ForeignKeyDefinition.new(row[0], row[1], [], row[3], [])
93
- current_foreign_key = row[0]
94
- end
95
-
96
- foreign_keys.last.column_names << row[2]
97
- foreign_keys.last.references_column_names << row[4]
98
- end
99
-
100
- foreign_keys
101
- end
102
- end
103
- end
@@ -1,8 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module MysqlColumn
3
- def initialize(name, default, sql_type = nil, null = true)
4
- default = nil if !null && default.blank?
5
- super
6
- end
7
- end
8
- end
@@ -1,178 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module PostgresqlAdapter
3
- def self.included(base)
4
- base.class_eval do
5
- alias_method_chain :indexes, :redhillonrails_core
6
- end
7
- end
8
-
9
- def set_table_comment(table_name, comment)
10
- execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS '#{quote_string(comment)}'"
11
- end
12
-
13
- def clear_table_comment(table_name)
14
- execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS NULL"
15
- end
16
-
17
- def add_index(table_name, column_name, options = {})
18
- column_name, options = [], column_name if column_name.is_a?(Hash)
19
- column_names = Array(column_name)
20
- if column_names.empty?
21
- raise ArgumentError, "No columns and :expression missing from options - cannot create index" if options[:expression].blank?
22
- raise ArgumentError, "Index name not given. Pass :name option" if options[:name].blank?
23
- end
24
-
25
- index_type = options[:unique] ? "UNIQUE" : ""
26
- index_name = options[:name] || index_name(table_name, column_names)
27
- conditions = options[:conditions]
28
-
29
- if column_names.empty? then
30
- sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{options[:expression]}"
31
- else
32
- quoted_column_names = column_names.map { |e| options[:case_sensitive] == false && e.to_s !~ /_id$/ ? "LOWER(#{quote_column_name(e)})" : quote_column_name(e) }
33
-
34
- sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names.join(", ")})"
35
- sql += " WHERE (#{ ActiveRecord::Base.send(:sanitize_sql, conditions, quote_table_name(table_name)) })" if conditions
36
- end
37
- execute sql
38
- end
39
-
40
- def supports_partial_indexes?
41
- true
42
- end
43
-
44
- INDEX_CASE_INSENSITIVE_REGEX = /\((.*LOWER\([^:]+(::text)?\).*)\)/i
45
- INDEX_PARTIAL_REGEX = /\((.*)\)\s+WHERE (.*)$/i
46
- INDEX_NON_BTREE_REGEX = /((?:gin|gist|hash).*)$/i
47
-
48
- def indexes_with_redhillonrails_core(table_name, name = nil)
49
- indexes = indexes_without_redhillonrails_core(table_name, name)
50
- # Process indexes containg expressions and partial indexes
51
- # Ie. consider
52
- result = query(<<-SQL, name)
53
- SELECT c2.relname, i.indisunique, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)
54
- FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
55
- WHERE c.relname = '#{table_name}'
56
- AND c.oid = i.indrelid AND i.indexrelid = c2.oid
57
- AND i.indisprimary = 'f'
58
- AND (i.indexprs IS NOT NULL OR i.indpred IS NOT NULL)
59
- ORDER BY 1
60
- SQL
61
-
62
-
63
- # Correctly process complex indexes, ie:
64
- # CREATE INDEX test_index ON custom_pages USING btree (lower(title::text), created_at) WHERE kind = 1 AND author_id = 3
65
- result.each do |(index_name, unique, index_def)|
66
- case_sensitive_match = INDEX_CASE_INSENSITIVE_REGEX.match(index_def)
67
- partial_index_match = INDEX_PARTIAL_REGEX.match(index_def)
68
- if non_btree_match = INDEX_NON_BTREE_REGEX.match(index_def) || (case_sensitive_match && partial_index_match) then
69
- # If we have both types of indexes simultaneously, we don't try to parse it all: simply assume it's an expression index
70
- indexes.delete_if { |index| index.name == index_name } # prevent duplicated indexes
71
-
72
- index = ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, false, nil)
73
- index.expression = if case_sensitive_match then
74
- index_def.split(/using/i, 2).last.strip
75
- else
76
- non_btree_match[1]
77
- end
78
- indexes << index
79
- elsif case_sensitive_match || partial_index_match then
80
- # column_definitions may be ie. 'LOWER(lower)' or 'login, deleted_at' or LOWER(login), deleted_at
81
- column_definitions = case_sensitive_match ? case_sensitive_match[1] : partial_index_match[1]
82
-
83
- indexes.delete_if { |index| index.name == index_name } # prevent duplicated indexes
84
- column_names = determine_index_column_names(column_definitions)
85
-
86
- index = ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique == "t", column_names)
87
- index.case_sensitive = !case_sensitive_match
88
- # conditions may be ie. active = true AND deleted_at IS NULL.
89
- index.conditions = partial_index_match[2] if partial_index_match
90
- indexes << index
91
-
92
- end
93
- end
94
-
95
- indexes
96
- end
97
-
98
- def foreign_keys(table_name, name = nil)
99
- load_foreign_keys(<<-SQL, name)
100
- SELECT f.conname, pg_get_constraintdef(f.oid), t.relname
101
- FROM pg_class t, pg_constraint f
102
- WHERE f.conrelid = t.oid
103
- AND f.contype = 'f'
104
- AND t.relname = '#{table_name}'
105
- SQL
106
- end
107
-
108
- def reverse_foreign_keys(table_name, name = nil)
109
- load_foreign_keys(<<-SQL, name)
110
- SELECT f.conname, pg_get_constraintdef(f.oid), t2.relname
111
- FROM pg_class t, pg_class t2, pg_constraint f
112
- WHERE f.confrelid = t.oid
113
- AND f.conrelid = t2.oid
114
- AND f.contype = 'f'
115
- AND t.relname = '#{table_name}'
116
- SQL
117
- end
118
-
119
- def views(name = nil)
120
- schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
121
- query(<<-SQL, name).map { |row| row[0] }
122
- SELECT viewname
123
- FROM pg_views
124
- WHERE schemaname IN (#{schemas})
125
- SQL
126
- end
127
-
128
- def view_definition(view_name, name = nil)
129
- result = query(<<-SQL, name)
130
- SELECT pg_get_viewdef(oid)
131
- FROM pg_class
132
- WHERE relkind = 'v'
133
- AND relname = '#{view_name}'
134
- SQL
135
- row = result.first
136
- row.first unless row.nil?
137
- end
138
-
139
- private
140
-
141
- def load_foreign_keys(sql, name = nil)
142
- foreign_keys = []
143
-
144
- query(sql, name).each do |row|
145
- if row[1] =~ /^FOREIGN KEY \((.+?)\) REFERENCES (.+?)\((.+?)\)( ON UPDATE (.+?))?( ON DELETE (.+?))?( (DEFERRABLE|NOT DEFERRABLE))?$/
146
- name = row[0]
147
- from_table_name = row[2]
148
- column_names = $1
149
- references_table_name = $2
150
- references_column_names = $3
151
- on_update = $5
152
- on_delete = $7
153
- deferrable = $9 == "DEFERRABLE"
154
- on_update = on_update.downcase.gsub(' ', '_').to_sym if on_update
155
- on_delete = on_delete.downcase.gsub(' ', '_').to_sym if on_delete
156
-
157
- foreign_keys << ForeignKeyDefinition.new(name,
158
- from_table_name, column_names.split(', '),
159
- references_table_name.sub(/^"(.*)"$/, '\1'), references_column_names.split(', '),
160
- on_update, on_delete, deferrable)
161
- end
162
- end
163
-
164
- foreign_keys
165
- end
166
-
167
- # Converts form like: column1, LOWER(column2)
168
- # to: column1, column2
169
- def determine_index_column_names(column_definitions)
170
- column_definitions.split(", ").map do |name|
171
- name = $1 if name =~ /^LOWER\(([^:]+)(::text)?\)$/i
172
- name = $1 if name =~ /^"(.*)"$/
173
- name
174
- end
175
- end
176
-
177
- end
178
- end
@@ -1,23 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module SchemaStatements
3
- def self.included(base)
4
- base.module_eval do
5
- alias_method_chain :create_table, :redhillonrails_core
6
- end
7
- end
8
-
9
- def create_table_with_redhillonrails_core(name, options = {})
10
- if options.include?(:comment)
11
- options = options.dup
12
- comment = options.delete(:comment)
13
- end
14
-
15
- create_table_without_redhillonrails_core(name, options) do |table_defintion|
16
- table_defintion.name = name
17
- yield table_defintion if block_given?
18
- end
19
-
20
- set_table_comment(name, comment) if comment
21
- end
22
- end
23
- end
@@ -1,109 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module Sqlite3Adapter
3
- def self.included(base)
4
- base.class_eval do
5
- alias_method_chain :tables, :redhillonrails_core
6
- end
7
- end
8
-
9
- def move_table(from, to, options = {}, &block) #:nodoc:
10
- copy_table(from, to, options, &block)
11
- drop_table(from, options)
12
- end
13
-
14
- def add_foreign_key(from_table_name, from_column_names, to_table_name, to_column_names, options = {})
15
- initialize_sqlite3_foreign_key_table
16
- from_column_names = Array(from_column_names)
17
- to_column_names = Array(to_column_names)
18
- fk_name = options[:name] || ["fk", from_table_name, *to_column_names].join("_")
19
-
20
- columns = %w(name from_table_name from_column_names to_table_name to_column_names)
21
- values = [fk_name, from_table_name, from_column_names.join(","), to_table_name, to_column_names.join(",")]
22
-
23
- quoted_values = values.map { |x| quote(x.to_s) }.join(",")
24
-
25
- # TODO: support options
26
-
27
- insert <<-SQL
28
- INSERT INTO #{sqlite3_foreign_key_table}(#{quoted_columns(columns)})
29
- VALUES (#{quoted_values})
30
- SQL
31
- end
32
-
33
- def remove_foreign_key(table_name, foreign_key_name, options = {})
34
- return if options[:temporary] == true
35
- initialize_sqlite3_foreign_key_table
36
-
37
- rows_deleted = delete <<-SQL
38
- DELETE FROM #{sqlite3_foreign_key_table}
39
- WHERE #{quote_column_name("name")} = #{quote(foreign_key_name.to_s)}
40
- AND #{quote_column_name("from_table_name")} = #{quote(table_name.to_s)}
41
- SQL
42
-
43
- if rows_deleted != 1
44
- raise ActiveRecord::ActiveRecordError, "Foreign-key '#{foreign_key_name}' on table '#{table_name}' not found"
45
- end
46
- end
47
-
48
- def tables_with_redhillonrails_core(name=nil)
49
- tables_without_redhillonrails_core.reject{ |name| name == sqlite3_foreign_key_table }
50
- end
51
-
52
- def foreign_keys(table_name, name = nil)
53
- load_foreign_keys("from_table_name", table_name, name)
54
- end
55
-
56
- def reverse_foreign_keys(table_name, name = nil)
57
- load_foreign_keys("to_table_name", table_name, name)
58
- end
59
-
60
- # TODO: tests!
61
-
62
- private
63
-
64
- def quoted_columns(columns)
65
- columns.map { |x| quote_column_name(x) }.join(",")
66
- end
67
-
68
- def sqlite3_foreign_key_table
69
- "sqlite3_foreign_keys"
70
- end
71
-
72
- def initialize_sqlite3_foreign_key_table
73
- unless sqlite3_foreign_key_table_exists?
74
- create_table(sqlite3_foreign_key_table, :id => false) do |t|
75
- t.string "name", :null => false
76
- t.string "from_table_name", :null => false
77
- t.string "from_column_names", :null => false
78
- t.string "to_table_name", :null => false
79
- t.string "to_column_names", :null => false
80
- end
81
- add_index(sqlite3_foreign_key_table, "name", :unique => true)
82
- add_index(sqlite3_foreign_key_table, "from_table_name", :unique => false)
83
- add_index(sqlite3_foreign_key_table, "to_table_name", :unique => false)
84
- end
85
- end
86
-
87
- def sqlite3_foreign_key_table_exists?
88
- tables_without_redhillonrails_core.detect { |name| name == sqlite3_foreign_key_table }
89
- end
90
-
91
- def load_foreign_keys(discriminating_column, table_name, name = nil)
92
- rows = select_all(<<-SQL, name)
93
- SELECT *
94
- FROM #{sqlite3_foreign_key_table}
95
- WHERE #{quote_column_name(discriminating_column)} = #{quote(table_name.to_s)}
96
- SQL
97
-
98
- rows.map do |row|
99
- ForeignKeyDefinition.new(
100
- row["name"],
101
- row["from_table_name"], row["from_column_names"].split(","),
102
- row["to_table_name"], row["to_column_names"].split(",")
103
- )
104
- end
105
- end
106
-
107
- end
108
-
109
- end
@@ -1,27 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
2
- module TableDefinition
3
- def self.included(base)
4
- base.class_eval do
5
- attr_accessor :name
6
- alias_method_chain :initialize, :redhillonrails_core
7
- alias_method_chain :to_sql, :redhillonrails_core
8
- end
9
- end
10
-
11
- def initialize_with_redhillonrails_core(*args)
12
- initialize_without_redhillonrails_core(*args)
13
- @foreign_keys = []
14
- end
15
-
16
- def foreign_key(column_names, references_table_name, references_column_names, options = {})
17
- @foreign_keys << ForeignKeyDefinition.new(options[:name], nil, column_names, ActiveRecord::Migrator.proper_table_name(references_table_name), references_column_names, options[:on_update], options[:on_delete], options[:deferrable])
18
- self
19
- end
20
-
21
- def to_sql_with_redhillonrails_core
22
- sql = to_sql_without_redhillonrails_core
23
- sql << ', ' << @foreign_keys * ', ' unless @foreign_keys.empty? || ActiveRecord::Schema.defining?
24
- sql
25
- end
26
- end
27
- end
@@ -1,25 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord
2
- module Schema
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- class << base
10
- attr_accessor :defining
11
- alias :defining? :defining
12
-
13
- alias_method_chain :define, :redhillonrails_core
14
- end
15
- end
16
-
17
- def define_with_redhillonrails_core(info={}, &block)
18
- self.defining = true
19
- define_without_redhillonrails_core(info, &block)
20
- ensure
21
- self.defining = false
22
- end
23
- end
24
- end
25
- end
@@ -1,66 +0,0 @@
1
- module RedHillConsulting::Core::ActiveRecord
2
- module SchemaDumper
3
- def self.included(base)
4
- base.class_eval do
5
- private
6
- alias_method_chain :tables, :redhillonrails_core
7
- alias_method_chain :indexes, :redhillonrails_core
8
- end
9
- end
10
-
11
- private
12
-
13
- def tables_with_redhillonrails_core(stream)
14
- @foreign_keys = StringIO.new
15
- begin
16
- tables_without_redhillonrails_core(stream)
17
- @foreign_keys.rewind
18
- stream.print @foreign_keys.read
19
- views(stream)
20
- ensure
21
- @foreign_keys = nil
22
- end
23
- end
24
-
25
- def indexes_with_redhillonrails_core(table, stream)
26
- indexes = @connection.indexes(table)
27
- indexes.each do |index|
28
- if index.expression.blank? then
29
- stream.print " add_index #{index.table.inspect}, #{index.columns.inspect}, :name => #{index.name.inspect}"
30
- stream.print ", :unique => true" if index.unique
31
- stream.print ", :case_sensitive => false" unless index.case_sensitive?
32
- stream.print ", :conditions => #{index.conditions.inspect}" unless index.conditions.blank?
33
- else
34
- stream.print " add_index #{index.table.inspect}"
35
- stream.print ", :expression => #{index.expression.inspect}"
36
- stream.print ", :name => #{index.name.inspect}"
37
- end
38
-
39
- stream.puts
40
- end
41
- stream.puts unless indexes.empty?
42
-
43
- foreign_keys(table, @foreign_keys)
44
- end
45
-
46
- def foreign_keys(table, stream)
47
- foreign_keys = @connection.foreign_keys(table)
48
- foreign_keys.each do |foreign_key|
49
- stream.print " "
50
- stream.print foreign_key.to_dump
51
- stream.puts
52
- end
53
- stream.puts unless foreign_keys.empty?
54
- end
55
-
56
- def views(stream)
57
- views = @connection.views
58
- views.each do |view_name|
59
- definition = @connection.view_definition(view_name)
60
- stream.print " create_view #{view_name.inspect}, #{definition.inspect}"
61
- stream.puts
62
- end
63
- stream.puts unless views.empty?
64
- end
65
- end
66
- end
@@ -1,4 +0,0 @@
1
- module RedHillConsulting::Core
2
- module ActiveRecord
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module RedHillConsulting
2
- module Core
3
- end
4
- end
@@ -1,9 +0,0 @@
1
- namespace :db do
2
- desc "Describe all the tables in the database by reading the table comments"
3
- task :comments => :environment do
4
- ActiveRecord::Base.connection.tables.sort.each do |table_name|
5
- comment = ActiveRecord::Base.connection.table_comment(table_name)
6
- puts "#{table_name} - #{comment}"
7
- end
8
- end
9
- end