redhillonrails_core 1.0.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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/CHANGELOG +2 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +154 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/red_hill_consulting/core/active_record/base.rb +60 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb +46 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/column.rb +21 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb +26 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb +11 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql4_adapter.rb +37 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql5_adapter.rb +40 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb +92 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb +8 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb +131 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb +23 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb +109 -0
- data/lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb +27 -0
- data/lib/red_hill_consulting/core/active_record/schema.rb +25 -0
- data/lib/red_hill_consulting/core/active_record/schema_dumper.rb +58 -0
- data/lib/redhillonrails_core.rb +39 -0
- data/redhillonrails_core.gemspec +69 -0
- data/tasks/db/comments.rake +9 -0
- metadata +88 -0
data/.document
ADDED
data/.gitignore
ADDED
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006 RedHill Consulting, Pty. Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
NOTE: This plugin was created by harukizaemon(http://github.com/harukizaemon) but is not supported currently by him.
|
2
|
+
|
3
|
+
= RedHill on Rails Core
|
4
|
+
|
5
|
+
RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins. Those features include:
|
6
|
+
|
7
|
+
* Creating and dropping views;
|
8
|
+
* Creating and removing foreign-keys;
|
9
|
+
* Obtaining indexes directly from a model class; and
|
10
|
+
* Determining when <code>Schema.define()</code> is running.
|
11
|
+
|
12
|
+
=== View Support
|
13
|
+
|
14
|
+
The plugin provides a mechanism for creating and dropping views as well as
|
15
|
+
preserving views when performing a schema dump:
|
16
|
+
|
17
|
+
create_view :normal_customers, "SELECT * FROM customers WHERE status = 'normal'"
|
18
|
+
drop_view :normal_customers
|
19
|
+
|
20
|
+
=== Foreign Key Support
|
21
|
+
|
22
|
+
The plugin provides two mechanisms for adding foreign keys as well as
|
23
|
+
preserving foreign keys when performing a schema dump. (Using SQL-92 syntax and
|
24
|
+
as such should be compatible with most databases that support foreign-key
|
25
|
+
constraints.)
|
26
|
+
|
27
|
+
The first mechanism for creating foreign-keys allows you to add a foreign key
|
28
|
+
when defining a table. For example:
|
29
|
+
|
30
|
+
create_table :orders do |t|
|
31
|
+
...
|
32
|
+
t.foreign_key :customer_id, :customers, :id
|
33
|
+
end
|
34
|
+
|
35
|
+
You also have the option of specifying what to do on delete/update using
|
36
|
+
<code>:on_delete</code>/<code>:on_update</code>, respectively to one of: <code>:cascade</code>; <code>:restrict</code>; and <code>:set_null</code>:
|
37
|
+
|
38
|
+
create_table :orders do |t|
|
39
|
+
...
|
40
|
+
t.foreign_key :customer_id, :customers, :id, :on_delete => :set_null, :on_update => :cascade
|
41
|
+
end
|
42
|
+
|
43
|
+
The second method allows you to create arbitrary foreign-keys at any time:
|
44
|
+
|
45
|
+
add_foreign_key(:orders, :customer_id, :customers, :id, :on_delete => :set_null, :on_update => :cascade)
|
46
|
+
|
47
|
+
In either case, if your database supports deferred foreign keys (for example PostgreSQL) you can specify this as well:
|
48
|
+
|
49
|
+
t.foreign_key :customer_id, :customers, :id, :deferrable => true
|
50
|
+
add_foreign_key(:orders, :customer_id, :customers, :id, :deferrable => true)
|
51
|
+
|
52
|
+
By default, the foreign key will be assigned a name by the underlying database. However, if this doesn't suit
|
53
|
+
your needs, you can override the default assignment using the <code>:name</code> option:
|
54
|
+
|
55
|
+
add_foreign_key(:orders, :customer_id, :customers, :id, :on_delete => :set_null, :on_update => :cascade, <strong>:name => :orders_customer_id_foreign_key<strong>)
|
56
|
+
|
57
|
+
You can also query the foreign keys for a model yourself by calling <code>foreign_keys()</code>:
|
58
|
+
|
59
|
+
Order.foreign_keys
|
60
|
+
|
61
|
+
Or for an arbitrary table by calling <code>foreign_keys(table_name)</code> on a database adapter.
|
62
|
+
|
63
|
+
Either method returns an array of the following meta-data:
|
64
|
+
|
65
|
+
* +name+ - The name of the foreign key constraint;
|
66
|
+
* +table_name+ - The table for which the foreign-key was generated;
|
67
|
+
* +column_names+ - The column names in the table;
|
68
|
+
* +references_table_name+ - The table referenced by the foreign-key; and
|
69
|
+
* +references_column_names+ - The columns names in the referenced table.
|
70
|
+
|
71
|
+
If you need to drop a foreign-key, use:
|
72
|
+
|
73
|
+
remove_foreign_key :orders, :orders_ordered_by_id_fkey
|
74
|
+
|
75
|
+
The plugin also ensures that all foreign keys are output when performing a
|
76
|
+
schema dump. This happens automatically when running <code>rake migrate</code> or
|
77
|
+
<code>rake db:schema:dump</code>. This has particular implications when running
|
78
|
+
unit tests that contain fixtures. To ensure the test data is correctly reset after
|
79
|
+
each test, you should list your fixtures in order of parent->child. For example:
|
80
|
+
|
81
|
+
fixtures :customers, :products, :orders, :order_lines
|
82
|
+
|
83
|
+
Rails will then set-up and tear-down the fixtures in the correct sequence.
|
84
|
+
|
85
|
+
Some databases (PostgreSQL and MySQL for example) allow you to set a comment for a
|
86
|
+
table. You can do this for existing tables by using:
|
87
|
+
|
88
|
+
set_table_comment :orders, "All pending and processed orders"
|
89
|
+
|
90
|
+
or even at the time of creation:
|
91
|
+
|
92
|
+
create_table :orders, :comment => "All pending and processed orders" do |t|
|
93
|
+
...
|
94
|
+
end
|
95
|
+
|
96
|
+
You can clear table comments using:
|
97
|
+
|
98
|
+
clear_table_comment :orders
|
99
|
+
|
100
|
+
There is also a rake tasks to show all database tables and their comments:
|
101
|
+
|
102
|
+
rake db:comments
|
103
|
+
|
104
|
+
The plugin fully supports and understands the following active-record
|
105
|
+
configuration properties:
|
106
|
+
|
107
|
+
* <code>config.active_record.pluralize_table_names</code>
|
108
|
+
* <code>config.active_record.table_name_prefix</code>
|
109
|
+
* <code>config.active_record.table_name_suffix</code>
|
110
|
+
|
111
|
+
=== Model Indexes
|
112
|
+
|
113
|
+
ActiveRecord::Base already provides a method on connection for obtaining the
|
114
|
+
indexes for a given table. This plugin now makes it possible to obtain the
|
115
|
+
indexes for a given model--<code>ActiveRecord::Base</code>--class. For example:
|
116
|
+
|
117
|
+
Invoice.indexes
|
118
|
+
|
119
|
+
Would return all the indexes for the +invoices+ table.
|
120
|
+
|
121
|
+
=== Schema Defining
|
122
|
+
|
123
|
+
The plugin also adds a method--<code>defining?()</code>--to
|
124
|
+
<code>ActiveRecord::Schema</code> to indicate when <code>define()</code> is running. This is necessary
|
125
|
+
as some migration plugins must change their behaviour accordingly.
|
126
|
+
|
127
|
+
=== Case-insensitive Indexes
|
128
|
+
|
129
|
+
For PostgreSQL, you can add an option <code>:case_sensitive => false</code> to <code>add_index</code>
|
130
|
+
which will generate an expression index of the form:
|
131
|
+
|
132
|
+
LOWER(column_name)
|
133
|
+
|
134
|
+
This means finder queries of the form:
|
135
|
+
|
136
|
+
WHERE LOWER(column_name) = LOWER(?)
|
137
|
+
|
138
|
+
are able to use the indexes rather require, in the worst case, full-table scans.
|
139
|
+
|
140
|
+
Note also that this ties in well with Rails built-in support for case-insensitive searching:
|
141
|
+
|
142
|
+
validates_uniqueness_of :name, :case_sensitive => false
|
143
|
+
|
144
|
+
=== See Also
|
145
|
+
|
146
|
+
* Foreign Key Associations (foreign_key_associations)
|
147
|
+
* Foreign Key Migrations (foreign_key_migrations)
|
148
|
+
* Row Version Migrations (row_version_migrations)
|
149
|
+
* Schema Validations (schema_validations)
|
150
|
+
|
151
|
+
=== License
|
152
|
+
|
153
|
+
This plugin is copyright 2006 by RedHill Consulting, Pty. Ltd. and is released
|
154
|
+
under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "redhillonrails_core"
|
8
|
+
gem.summary = %Q{RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins}
|
9
|
+
gem.description = %Q{
|
10
|
+
RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins. Those features include:
|
11
|
+
|
12
|
+
* Creating and dropping views;
|
13
|
+
* Creating and removing foreign-keys;
|
14
|
+
* Obtaining indexes directly from a model class; and
|
15
|
+
* Determining when <code>Schema.define()</code> is running.
|
16
|
+
}
|
17
|
+
gem.email = "michal.lomnicki@gmail.com"
|
18
|
+
gem.homepage = "http://github.com/mlomnicki/redhillonrails_core"
|
19
|
+
gem.authors = ["Michał Łomnicki"]
|
20
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
Rake::TestTask.new(:test) do |test|
|
29
|
+
test.libs << 'lib' << 'test'
|
30
|
+
test.pattern = 'test/**/test_*.rb'
|
31
|
+
test.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
end
|
41
|
+
rescue LoadError
|
42
|
+
task :rcov do
|
43
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
task :test => :check_dependencies
|
48
|
+
|
49
|
+
task :default => :test
|
50
|
+
|
51
|
+
require 'rake/rdoctask'
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
54
|
+
|
55
|
+
rdoc.rdoc_dir = 'rdoc'
|
56
|
+
rdoc.title = "redhillonrails_core #{version}"
|
57
|
+
rdoc.rdoc_files.include('README*')
|
58
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'redhillonrails_core' unless defined?(RedHillConsulting::Core)
|
@@ -0,0 +1,60 @@
|
|
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
|
+
column_name = index.columns.reverse.detect { |name| name !~ /_id$/ } || index.columns.last
|
30
|
+
column = cols[column_name]
|
31
|
+
column.case_sensitive = index.case_sensitive?
|
32
|
+
column.unique_scope = index.columns.reject { |name| name == column_name } if index.unique
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@columns
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset_column_information_with_redhillonrails_core
|
39
|
+
reset_column_information_without_redhillonrails_core
|
40
|
+
@indexes = @foreign_keys = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def pluralized_table_name(table_name)
|
44
|
+
ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def indexes
|
48
|
+
@indexes ||= connection.indexes(table_name, "#{name} Indexes")
|
49
|
+
end
|
50
|
+
|
51
|
+
def foreign_keys
|
52
|
+
@foreign_keys ||= connection.foreign_keys(table_name, "#{name} Foreign Keys")
|
53
|
+
end
|
54
|
+
|
55
|
+
def reverse_foreign_keys
|
56
|
+
connection.reverse_foreign_keys(table_name, "#{name} Reverse Foreign Keys")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
|
2
|
+
module AbstractAdapter
|
3
|
+
def self.included(base)
|
4
|
+
base.module_eval do
|
5
|
+
alias_method_chain :drop_table, :redhillonrails_core
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_view(view_name, definition)
|
10
|
+
execute "CREATE VIEW #{view_name} AS #{definition}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def drop_view(view_name)
|
14
|
+
execute "DROP VIEW #{view_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def views(name = nil)
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
|
21
|
+
def view_definition(view_name, name = nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
def foreign_keys(table_name, name = nil)
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
|
28
|
+
def reverse_foreign_keys(table_name, name = nil)
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {})
|
33
|
+
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])
|
34
|
+
execute "ALTER TABLE #{table_name} ADD #{foreign_key}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_foreign_key(table_name, foreign_key_name, options = {})
|
38
|
+
execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{foreign_key_name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def drop_table_with_redhillonrails_core(name, options = {})
|
42
|
+
reverse_foreign_keys(name).each { |foreign_key| remove_foreign_key(foreign_key.table_name, foreign_key.name, options) }
|
43
|
+
drop_table_without_redhillonrails_core(name, options)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
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
|
@@ -0,0 +1,26 @@
|
|
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
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RedHillConsulting::Core::ActiveRecord::ConnectionAdapters
|
2
|
+
module IndexDefinition
|
3
|
+
def case_sensitive?
|
4
|
+
@case_sensitive.nil? ? true : @case_sensitive
|
5
|
+
end
|
6
|
+
|
7
|
+
def case_sensitive=(case_sensitive)
|
8
|
+
@case_sensitive = case_sensitive
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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].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
|
@@ -0,0 +1,40 @@
|
|
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
|
@@ -0,0 +1,92 @@
|
|
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
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_table_comment(table_name, comment)
|
10
|
+
execute "ALTER TABLE #{table_name} COMMENT='#{quote_string(comment)}'"
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_table_comment(table_name)
|
14
|
+
execute "ALTER TABLE #{table_name} COMMENT=''"
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove_foreign_key(table_name, foreign_key_name, options = {})
|
18
|
+
execute "ALTER TABLE #{table_name} DROP FOREIGN KEY #{foreign_key_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_column_with_redhillonrails_core(table_name, column_name)
|
22
|
+
foreign_keys(table_name).select { |foreign_key| foreign_key.column_names.include?(column_name.to_s) }.each do |foreign_key|
|
23
|
+
remove_foreign_key(table_name, foreign_key.name)
|
24
|
+
end
|
25
|
+
remove_column_without_redhillonrails_core(table_name, column_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def foreign_keys(table_name, name = nil)
|
29
|
+
results = execute("SHOW CREATE TABLE `#{table_name}`", name)
|
30
|
+
|
31
|
+
foreign_keys = []
|
32
|
+
|
33
|
+
results.each do |row|
|
34
|
+
row[1].each do |line|
|
35
|
+
if line =~ /^ CONSTRAINT [`"](.+?)[`"] FOREIGN KEY \([`"](.+?)[`"]\) REFERENCES [`"](.+?)[`"] \((.+?)\)( ON DELETE (.+?))?( ON UPDATE (.+?))?,?$/
|
36
|
+
name = $1
|
37
|
+
column_names = $2
|
38
|
+
references_table_name = $3
|
39
|
+
references_column_names = $4
|
40
|
+
on_update = $8
|
41
|
+
on_delete = $6
|
42
|
+
on_update = on_update.downcase.gsub(' ', '_').to_sym if on_update
|
43
|
+
on_delete = on_delete.downcase.gsub(' ', '_').to_sym if on_delete
|
44
|
+
|
45
|
+
foreign_keys << ForeignKeyDefinition.new(name,
|
46
|
+
table_name, column_names.gsub('`', '').split(', '),
|
47
|
+
references_table_name, references_column_names.gsub('`', '').split(', '),
|
48
|
+
on_update, on_delete)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
foreign_keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def reverse_foreign_keys(table_name, name = nil)
|
57
|
+
@@schema ||= nil
|
58
|
+
@@schema_version ||= 0
|
59
|
+
current_version = ActiveRecord::Migrator.current_version
|
60
|
+
if @@schema.nil? || @@schema_version != current_version
|
61
|
+
@@schema_version = current_version
|
62
|
+
ans = execute(<<-SQL, name)
|
63
|
+
SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name
|
64
|
+
FROM information_schema.key_column_usage
|
65
|
+
WHERE table_schema = SCHEMA()
|
66
|
+
AND referenced_table_schema = table_schema
|
67
|
+
ORDER BY constraint_name, ordinal_position;
|
68
|
+
SQL
|
69
|
+
@@schema = []
|
70
|
+
ans.each do | row |
|
71
|
+
@@schema << [row[0], row[1], row[2], row[3], row[4]]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
results = @@schema
|
75
|
+
current_foreign_key = nil
|
76
|
+
foreign_keys = []
|
77
|
+
|
78
|
+
results.each do |row|
|
79
|
+
next if row[3] != table_name
|
80
|
+
if current_foreign_key != row[0]
|
81
|
+
foreign_keys << ForeignKeyDefinition.new(row[0], row[1], [], row[3], [])
|
82
|
+
current_foreign_key = row[0]
|
83
|
+
end
|
84
|
+
|
85
|
+
foreign_keys.last.column_names << row[2]
|
86
|
+
foreign_keys.last.references_column_names << row[4]
|
87
|
+
end
|
88
|
+
|
89
|
+
foreign_keys
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,131 @@
|
|
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 #{table_name} IS '#{quote_string(comment)}'"
|
11
|
+
end
|
12
|
+
|
13
|
+
def clear_table_comment(table_name)
|
14
|
+
execute "COMMENT ON TABLE #{table_name} IS NULL"
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_index(table_name, column_name, options = {})
|
18
|
+
column_names = Array(column_name)
|
19
|
+
index_name = index_name(table_name, :column => column_names)
|
20
|
+
|
21
|
+
if Hash === options # legacy support, since this param was a string
|
22
|
+
index_type = options[:unique] ? "UNIQUE" : ""
|
23
|
+
index_name = options[:name] || index_name
|
24
|
+
else
|
25
|
+
index_type = options
|
26
|
+
end
|
27
|
+
|
28
|
+
quoted_column_names = column_names.map { |e| options[:case_sensitive] == false && e.to_s !~ /_id$/ ? "LOWER(#{quote_column_name(e)})" : quote_column_name(e) }
|
29
|
+
|
30
|
+
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names.join(", ")})"
|
31
|
+
end
|
32
|
+
|
33
|
+
def indexes_with_redhillonrails_core(table_name, name = nil)
|
34
|
+
indexes = indexes_without_redhillonrails_core(table_name, name)
|
35
|
+
result = query(<<-SQL, name)
|
36
|
+
SELECT c2.relname, i.indisunique, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)
|
37
|
+
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
|
38
|
+
WHERE c.relname = '#{table_name}'
|
39
|
+
AND c.oid = i.indrelid AND i.indexrelid = c2.oid
|
40
|
+
AND i.indisprimary = 'f'
|
41
|
+
AND i.indexprs IS NOT NULL
|
42
|
+
ORDER BY 1
|
43
|
+
SQL
|
44
|
+
|
45
|
+
result.each do |row|
|
46
|
+
if row[2]=~ /\((.*LOWER\([^:]+(::text)?\).*)\)$/i
|
47
|
+
indexes.delete_if { |index| index.name == row[0] }
|
48
|
+
column_names = $1.split(", ").map do |name|
|
49
|
+
name = $1 if name =~ /^LOWER\(([^:]+)(::text)?\)$/i
|
50
|
+
name = $1 if name =~ /^"(.*)"$/
|
51
|
+
name
|
52
|
+
end
|
53
|
+
index = ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, row[0], row[1] == "t", column_names)
|
54
|
+
index.case_sensitive = false
|
55
|
+
indexes << index
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
indexes
|
60
|
+
end
|
61
|
+
|
62
|
+
def foreign_keys(table_name, name = nil)
|
63
|
+
load_foreign_keys(<<-SQL, name)
|
64
|
+
SELECT f.conname, pg_get_constraintdef(f.oid), t.relname
|
65
|
+
FROM pg_class t, pg_constraint f
|
66
|
+
WHERE f.conrelid = t.oid
|
67
|
+
AND f.contype = 'f'
|
68
|
+
AND t.relname = '#{table_name}'
|
69
|
+
SQL
|
70
|
+
end
|
71
|
+
|
72
|
+
def reverse_foreign_keys(table_name, name = nil)
|
73
|
+
load_foreign_keys(<<-SQL, name)
|
74
|
+
SELECT f.conname, pg_get_constraintdef(f.oid), t2.relname
|
75
|
+
FROM pg_class t, pg_class t2, pg_constraint f
|
76
|
+
WHERE f.confrelid = t.oid
|
77
|
+
AND f.conrelid = t2.oid
|
78
|
+
AND f.contype = 'f'
|
79
|
+
AND t.relname = '#{table_name}'
|
80
|
+
SQL
|
81
|
+
end
|
82
|
+
|
83
|
+
def views(name = nil)
|
84
|
+
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
|
85
|
+
query(<<-SQL, name).map { |row| row[0] }
|
86
|
+
SELECT viewname
|
87
|
+
FROM pg_views
|
88
|
+
WHERE schemaname IN (#{schemas})
|
89
|
+
SQL
|
90
|
+
end
|
91
|
+
|
92
|
+
def view_definition(view_name, name = nil)
|
93
|
+
result = query(<<-SQL, name)
|
94
|
+
SELECT pg_get_viewdef(oid)
|
95
|
+
FROM pg_class
|
96
|
+
WHERE relkind = 'v'
|
97
|
+
AND relname = '#{view_name}'
|
98
|
+
SQL
|
99
|
+
row = result.first
|
100
|
+
row.first unless row.nil?
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def load_foreign_keys(sql, name = nil)
|
106
|
+
foreign_keys = []
|
107
|
+
|
108
|
+
query(sql, name).each do |row|
|
109
|
+
if row[1] =~ /^FOREIGN KEY \((.+?)\) REFERENCES (.+?)\((.+?)\)( ON UPDATE (.+?))?( ON DELETE (.+?))?( (DEFERRABLE|NOT DEFERRABLE))?$/
|
110
|
+
name = row[0]
|
111
|
+
from_table_name = row[2]
|
112
|
+
column_names = $1
|
113
|
+
references_table_name = $2
|
114
|
+
references_column_names = $3
|
115
|
+
on_update = $5
|
116
|
+
on_delete = $7
|
117
|
+
deferrable = $9 == "DEFERRABLE"
|
118
|
+
on_update = on_update.downcase.gsub(' ', '_').to_sym if on_update
|
119
|
+
on_delete = on_delete.downcase.gsub(' ', '_').to_sym if on_delete
|
120
|
+
|
121
|
+
foreign_keys << ForeignKeyDefinition.new(name,
|
122
|
+
from_table_name, column_names.split(', '),
|
123
|
+
references_table_name.sub(/^"(.*)"$/, '\1'), references_column_names.split(', '),
|
124
|
+
on_update, on_delete, deferrable)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
foreign_keys
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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
|
@@ -0,0 +1,109 @@
|
|
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
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,25 @@
|
|
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
|
@@ -0,0 +1,58 @@
|
|
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
|
+
stream.print " add_index #{index.table.inspect}, #{index.columns.inspect}, :name => #{index.name.inspect}"
|
29
|
+
stream.print ", :unique => true" if index.unique
|
30
|
+
stream.print ", :case_sensitive => false" unless index.case_sensitive?
|
31
|
+
stream.puts
|
32
|
+
end
|
33
|
+
stream.puts unless indexes.empty?
|
34
|
+
|
35
|
+
foreign_keys(table, @foreign_keys)
|
36
|
+
end
|
37
|
+
|
38
|
+
def foreign_keys(table, stream)
|
39
|
+
foreign_keys = @connection.foreign_keys(table)
|
40
|
+
foreign_keys.each do |foreign_key|
|
41
|
+
stream.print " "
|
42
|
+
stream.print foreign_key.to_dump
|
43
|
+
stream.puts
|
44
|
+
end
|
45
|
+
stream.puts unless foreign_keys.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def views(stream)
|
49
|
+
views = @connection.views
|
50
|
+
views.each do |view_name|
|
51
|
+
definition = @connection.view_definition(view_name)
|
52
|
+
stream.print " create_view #{view_name.inspect}, #{definition.inspect}"
|
53
|
+
stream.puts
|
54
|
+
end
|
55
|
+
stream.puts unless views.empty?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'red_hill_consulting/core/active_record/base'
|
2
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/abstract_adapter'
|
3
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition'
|
4
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/column'
|
5
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/index_definition'
|
6
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/mysql_adapter'
|
7
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/mysql_column'
|
8
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter'
|
9
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/schema_statements'
|
10
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter'
|
11
|
+
require 'red_hill_consulting/core/active_record/connection_adapters/table_definition'
|
12
|
+
|
13
|
+
ActiveRecord::Base.send(:include, RedHillConsulting::Core::ActiveRecord::Base)
|
14
|
+
ActiveRecord::Schema.send(:include, RedHillConsulting::Core::ActiveRecord::Schema)
|
15
|
+
ActiveRecord::SchemaDumper.send(:include, RedHillConsulting::Core::ActiveRecord::SchemaDumper)
|
16
|
+
ActiveRecord::ConnectionAdapters::IndexDefinition.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::IndexDefinition)
|
17
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::TableDefinition)
|
18
|
+
ActiveRecord::ConnectionAdapters::Column.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::Column)
|
19
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
20
|
+
ActiveRecord::ConnectionAdapters::SchemaStatements.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::SchemaStatements)
|
21
|
+
|
22
|
+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) then
|
23
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::PostgresqlAdapter)
|
24
|
+
end
|
25
|
+
if defined?(ActiveRecord::ConnectionAdapters::MysqlAdapter) then
|
26
|
+
ActiveRecord::ConnectionAdapters::MysqlColumn.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::MysqlColumn)
|
27
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::MysqlAdapter)
|
28
|
+
if ActiveRecord::Base.connection.send(:version)[0] < 5
|
29
|
+
#include MySql4Adapter
|
30
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::Mysql4Adapter)
|
31
|
+
else
|
32
|
+
#include MySql5Adapter
|
33
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::Mysql5Adapter)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter) then
|
38
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.send(:include, RedHillConsulting::Core::ActiveRecord::ConnectionAdapters::Sqlite3Adapter)
|
39
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{redhillonrails_core}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Micha\305\202 \305\201omnicki"]
|
12
|
+
s.date = %q{2010-03-13}
|
13
|
+
s.description = %q{
|
14
|
+
RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins. Those features include:
|
15
|
+
|
16
|
+
* Creating and dropping views;
|
17
|
+
* Creating and removing foreign-keys;
|
18
|
+
* Obtaining indexes directly from a model class; and
|
19
|
+
* Determining when <code>Schema.define()</code> is running.
|
20
|
+
}
|
21
|
+
s.email = %q{michal.lomnicki@gmail.com}
|
22
|
+
s.extra_rdoc_files = [
|
23
|
+
"README.rdoc"
|
24
|
+
]
|
25
|
+
s.files = [
|
26
|
+
".document",
|
27
|
+
".gitignore",
|
28
|
+
"CHANGELOG",
|
29
|
+
"MIT-LICENSE",
|
30
|
+
"README.rdoc",
|
31
|
+
"Rakefile",
|
32
|
+
"VERSION",
|
33
|
+
"init.rb",
|
34
|
+
"lib/red_hill_consulting/core/active_record/base.rb",
|
35
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb",
|
36
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/column.rb",
|
37
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb",
|
38
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb",
|
39
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/mysql4_adapter.rb",
|
40
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/mysql5_adapter.rb",
|
41
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb",
|
42
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb",
|
43
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb",
|
44
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb",
|
45
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb",
|
46
|
+
"lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb",
|
47
|
+
"lib/red_hill_consulting/core/active_record/schema.rb",
|
48
|
+
"lib/red_hill_consulting/core/active_record/schema_dumper.rb",
|
49
|
+
"lib/redhillonrails_core.rb",
|
50
|
+
"redhillonrails_core.gemspec",
|
51
|
+
"tasks/db/comments.rake"
|
52
|
+
]
|
53
|
+
s.homepage = %q{http://github.com/mlomnicki/redhillonrails_core}
|
54
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
55
|
+
s.require_paths = ["lib"]
|
56
|
+
s.rubygems_version = %q{1.3.5}
|
57
|
+
s.summary = %q{RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins}
|
58
|
+
|
59
|
+
if s.respond_to? :specification_version then
|
60
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
61
|
+
s.specification_version = 3
|
62
|
+
|
63
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
64
|
+
else
|
65
|
+
end
|
66
|
+
else
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,9 @@
|
|
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
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redhillonrails_core
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Micha\xC5\x82 \xC5\x81omnicki"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-03-13 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: |
|
17
|
+
|
18
|
+
RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins. Those features include:
|
19
|
+
|
20
|
+
* Creating and dropping views;
|
21
|
+
* Creating and removing foreign-keys;
|
22
|
+
* Obtaining indexes directly from a model class; and
|
23
|
+
* Determining when <code>Schema.define()</code> is running.
|
24
|
+
|
25
|
+
email: michal.lomnicki@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README.rdoc
|
32
|
+
files:
|
33
|
+
- .document
|
34
|
+
- .gitignore
|
35
|
+
- CHANGELOG
|
36
|
+
- MIT-LICENSE
|
37
|
+
- README.rdoc
|
38
|
+
- Rakefile
|
39
|
+
- VERSION
|
40
|
+
- init.rb
|
41
|
+
- lib/red_hill_consulting/core/active_record/base.rb
|
42
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb
|
43
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/column.rb
|
44
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb
|
45
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb
|
46
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/mysql4_adapter.rb
|
47
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/mysql5_adapter.rb
|
48
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb
|
49
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb
|
50
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb
|
51
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb
|
52
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb
|
53
|
+
- lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb
|
54
|
+
- lib/red_hill_consulting/core/active_record/schema.rb
|
55
|
+
- lib/red_hill_consulting/core/active_record/schema_dumper.rb
|
56
|
+
- lib/redhillonrails_core.rb
|
57
|
+
- redhillonrails_core.gemspec
|
58
|
+
- tasks/db/comments.rake
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/mlomnicki/redhillonrails_core
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --charset=UTF-8
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: RedHill on Rails Core is a plugin that features to support other RedHill on Rails plugins
|
87
|
+
test_files: []
|
88
|
+
|