oracle_enhanced 1.2.5
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/.gitignore +10 -0
- data/History.txt +182 -0
- data/License.txt +20 -0
- data/Manifest.txt +32 -0
- data/README.rdoc +77 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced.rake +51 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1661 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +121 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +64 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +39 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +393 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +389 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +163 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_reserved_words.rb +126 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +168 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +213 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +224 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +11 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +477 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_structure_dumper_spec.rb +267 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +206 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +40 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +107 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +984 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +67 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +93 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +25 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +370 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +203 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_spec.rb +784 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +114 -0
- metadata +140 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedReservedWords #:nodoc:
|
4
|
+
|
5
|
+
RESERVED_WORDS = {
|
6
|
+
"ACCESS" => true,
|
7
|
+
"ADD" => true,
|
8
|
+
"ALL" => true,
|
9
|
+
"ALTER" => true,
|
10
|
+
"AND" => true,
|
11
|
+
"ANY" => true,
|
12
|
+
"AS" => true,
|
13
|
+
"ASC" => true,
|
14
|
+
"AUDIT" => true,
|
15
|
+
"BETWEEN" => true,
|
16
|
+
"BY" => true,
|
17
|
+
"CHAR" => true,
|
18
|
+
"CHECK" => true,
|
19
|
+
"CLUSTER" => true,
|
20
|
+
"COLUMN" => true,
|
21
|
+
"COMMENT" => true,
|
22
|
+
"COMPRESS" => true,
|
23
|
+
"CONNECT" => true,
|
24
|
+
"CREATE" => true,
|
25
|
+
"CURRENT" => true,
|
26
|
+
"DATE" => true,
|
27
|
+
"DECIMAL" => true,
|
28
|
+
"DEFAULT" => true,
|
29
|
+
"DELETE" => true,
|
30
|
+
"DESC" => true,
|
31
|
+
"DISTINCT" => true,
|
32
|
+
"DROP" => true,
|
33
|
+
"ELSE" => true,
|
34
|
+
"EXCLUSIVE" => true,
|
35
|
+
"EXISTS" => true,
|
36
|
+
"FILE" => true,
|
37
|
+
"FLOAT" => true,
|
38
|
+
"FOR" => true,
|
39
|
+
"FROM" => true,
|
40
|
+
"GRANT" => true,
|
41
|
+
"GROUP" => true,
|
42
|
+
"HAVING" => true,
|
43
|
+
"IDENTIFIED" => true,
|
44
|
+
"IMMEDIATE" => true,
|
45
|
+
"IN" => true,
|
46
|
+
"INCREMENT" => true,
|
47
|
+
"INDEX" => true,
|
48
|
+
"INITIAL" => true,
|
49
|
+
"INSERT" => true,
|
50
|
+
"INTEGER" => true,
|
51
|
+
"INTERSECT" => true,
|
52
|
+
"INTO" => true,
|
53
|
+
"IS" => true,
|
54
|
+
"LEVEL" => true,
|
55
|
+
"LIKE" => true,
|
56
|
+
"LOCK" => true,
|
57
|
+
"LONG" => true,
|
58
|
+
"MAXEXTENTS" => true,
|
59
|
+
"MINUS" => true,
|
60
|
+
"MLSLABEL" => true,
|
61
|
+
"MODE" => true,
|
62
|
+
"MODIFY" => true,
|
63
|
+
"NOAUDIT" => true,
|
64
|
+
"NOCOMPRESS" => true,
|
65
|
+
"NOT" => true,
|
66
|
+
"NOWAIT" => true,
|
67
|
+
"NULL" => true,
|
68
|
+
"NUMBER" => true,
|
69
|
+
"OF" => true,
|
70
|
+
"OFFLINE" => true,
|
71
|
+
"ON" => true,
|
72
|
+
"ONLINE" => true,
|
73
|
+
"OPTION" => true,
|
74
|
+
"OR" => true,
|
75
|
+
"ORDER" => true,
|
76
|
+
"PCTFREE" => true,
|
77
|
+
"PRIOR" => true,
|
78
|
+
"PRIVILEGES" => true,
|
79
|
+
"PUBLIC" => true,
|
80
|
+
"RAW" => true,
|
81
|
+
"RENAME" => true,
|
82
|
+
"RESOURCE" => true,
|
83
|
+
"REVOKE" => true,
|
84
|
+
"ROW" => true,
|
85
|
+
"ROWID" => true,
|
86
|
+
"ROWNUM" => true,
|
87
|
+
"ROWS" => true,
|
88
|
+
"SELECT" => true,
|
89
|
+
"SESSION" => true,
|
90
|
+
"SET" => true,
|
91
|
+
"SHARE" => true,
|
92
|
+
"SIZE" => true,
|
93
|
+
"SMALLINT" => true,
|
94
|
+
"START" => true,
|
95
|
+
"SUCCESSFUL" => true,
|
96
|
+
"SYNONYM" => true,
|
97
|
+
"SYSDATE" => true,
|
98
|
+
"TABLE" => true,
|
99
|
+
"THEN" => true,
|
100
|
+
"TO" => true,
|
101
|
+
"TRIGGER" => true,
|
102
|
+
"UID" => true,
|
103
|
+
"UNION" => true,
|
104
|
+
"UNIQUE" => true,
|
105
|
+
"UPDATE" => true,
|
106
|
+
"USER" => true,
|
107
|
+
"VALIDATE" => true,
|
108
|
+
"VALUES" => true,
|
109
|
+
"VARCHAR" => true,
|
110
|
+
"VARCHAR2" => true,
|
111
|
+
"VIEW" => true,
|
112
|
+
"WHENEVER" => true,
|
113
|
+
"WHERE" => true,
|
114
|
+
"WITH" => true
|
115
|
+
}
|
116
|
+
|
117
|
+
def quote_oracle_reserved_words(name)
|
118
|
+
RESERVED_WORDS[name.to_s.upcase].nil? ? name : "\"#{name}\""
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
125
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedReservedWords
|
126
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class OracleEnhancedForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
class OracleEnhancedSynonymDefinition < Struct.new(:name, :table_owner, :table_name, :db_link) #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class OracleEnhancedIndexDefinition < Struct.new(:table, :name, :unique, :tablespace, :columns) #:nodoc:
|
10
|
+
end
|
11
|
+
|
12
|
+
module OracleEnhancedSchemaDefinitions #:nodoc:
|
13
|
+
def self.included(base)
|
14
|
+
base::TableDefinition.class_eval do
|
15
|
+
include OracleEnhancedTableDefinition
|
16
|
+
end
|
17
|
+
|
18
|
+
# Available starting from ActiveRecord 2.1
|
19
|
+
base::Table.class_eval do
|
20
|
+
include OracleEnhancedTable
|
21
|
+
end if defined?(base::Table)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module OracleEnhancedTableDefinition
|
26
|
+
class ForeignKey < Struct.new(:base, :to_table, :options) #:nodoc:
|
27
|
+
def to_sql
|
28
|
+
base.foreign_key_definition(to_table, options)
|
29
|
+
end
|
30
|
+
alias to_s :to_sql
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.included(base) #:nodoc:
|
34
|
+
base.class_eval do
|
35
|
+
alias_method_chain :references, :foreign_keys
|
36
|
+
alias_method_chain :to_sql, :foreign_keys
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds a :foreign_key option to TableDefinition.references.
|
41
|
+
# If :foreign_key is true, a foreign key constraint is added to the table.
|
42
|
+
# You can also specify a hash, which is passed as foreign key options.
|
43
|
+
#
|
44
|
+
# ===== Examples
|
45
|
+
# ====== Add goat_id column and a foreign key to the goats table.
|
46
|
+
# t.references(:goat, :foreign_key => true)
|
47
|
+
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
48
|
+
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
49
|
+
#
|
50
|
+
# Note: No foreign key is created if :polymorphic => true is used.
|
51
|
+
# Note: If no name is specified, the database driver creates one for you!
|
52
|
+
def references_with_foreign_keys(*args)
|
53
|
+
options = args.extract_options!
|
54
|
+
fk_options = options.delete(:foreign_key)
|
55
|
+
|
56
|
+
if fk_options && !options[:polymorphic]
|
57
|
+
fk_options = {} if fk_options == true
|
58
|
+
args.each { |to_table| foreign_key(to_table, fk_options) }
|
59
|
+
end
|
60
|
+
|
61
|
+
references_without_foreign_keys(*(args << options))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Defines a foreign key for the table. +to_table+ can be a single Symbol, or
|
65
|
+
# an Array of Symbols. See SchemaStatements#add_foreign_key
|
66
|
+
#
|
67
|
+
# ===== Examples
|
68
|
+
# ====== Creating a simple foreign key
|
69
|
+
# t.foreign_key(:people)
|
70
|
+
# ====== Defining the column
|
71
|
+
# t.foreign_key(:people, :column => :sender_id)
|
72
|
+
# ====== Creating a named foreign key
|
73
|
+
# t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
|
74
|
+
# ====== Defining the column of the +to_table+.
|
75
|
+
# t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
|
76
|
+
def foreign_key(to_table, options = {})
|
77
|
+
if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
|
78
|
+
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
79
|
+
foreign_keys << ForeignKey.new(@base, to_table, options)
|
80
|
+
else
|
81
|
+
raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_sql_with_foreign_keys #:nodoc:
|
86
|
+
sql = to_sql_without_foreign_keys
|
87
|
+
sql << ', ' << (foreign_keys * ', ') unless foreign_keys.blank?
|
88
|
+
sql
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def foreign_keys
|
93
|
+
@foreign_keys ||= []
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
module OracleEnhancedTable
|
98
|
+
def self.included(base) #:nodoc:
|
99
|
+
base.class_eval do
|
100
|
+
alias_method_chain :references, :foreign_keys
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
|
105
|
+
# an Array of Symbols. See SchemaStatements#add_foreign_key
|
106
|
+
#
|
107
|
+
# ===== Examples
|
108
|
+
# ====== Creating a simple foreign key
|
109
|
+
# t.foreign_key(:people)
|
110
|
+
# ====== Defining the column
|
111
|
+
# t.foreign_key(:people, :column => :sender_id)
|
112
|
+
# ====== Creating a named foreign key
|
113
|
+
# t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
|
114
|
+
# ====== Defining the column of the +to_table+.
|
115
|
+
# t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
|
116
|
+
def foreign_key(to_table, options = {})
|
117
|
+
if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
|
118
|
+
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
119
|
+
@base.add_foreign_key(@table_name, to_table, options)
|
120
|
+
else
|
121
|
+
raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Remove the given foreign key from the table.
|
126
|
+
#
|
127
|
+
# ===== Examples
|
128
|
+
# ====== Remove the suppliers_company_id_fk in the suppliers table.
|
129
|
+
# t.remove_foreign_key :companies
|
130
|
+
# ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
|
131
|
+
# remove_foreign_key :column => :branch_id
|
132
|
+
# ====== Remove the foreign key named party_foreign_key in the accounts table.
|
133
|
+
# remove_index :name => :party_foreign_key
|
134
|
+
def remove_foreign_key(options = {})
|
135
|
+
@base.remove_foreign_key(@table_name, options)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Adds a :foreign_key option to TableDefinition.references.
|
139
|
+
# If :foreign_key is true, a foreign key constraint is added to the table.
|
140
|
+
# You can also specify a hash, which is passed as foreign key options.
|
141
|
+
#
|
142
|
+
# ===== Examples
|
143
|
+
# ====== Add goat_id column and a foreign key to the goats table.
|
144
|
+
# t.references(:goat, :foreign_key => true)
|
145
|
+
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
146
|
+
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
147
|
+
#
|
148
|
+
# Note: No foreign key is created if :polymorphic => true is used.
|
149
|
+
def references_with_foreign_keys(*args)
|
150
|
+
options = args.extract_options!
|
151
|
+
polymorphic = options[:polymorphic]
|
152
|
+
fk_options = options.delete(:foreign_key)
|
153
|
+
|
154
|
+
references_without_foreign_keys(*(args << options))
|
155
|
+
# references_without_foreign_keys adds {:type => :integer}
|
156
|
+
args.extract_options!
|
157
|
+
if fk_options && !polymorphic
|
158
|
+
fk_options = {} if fk_options == true
|
159
|
+
args.each { |to_table| foreign_key(to_table, fk_options) }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
ActiveRecord::ConnectionAdapters.class_eval do
|
167
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaDefinitions
|
168
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedSchemaDumper #:nodoc:
|
4
|
+
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.class_eval do
|
7
|
+
private
|
8
|
+
alias_method_chain :tables, :oracle_enhanced
|
9
|
+
alias_method_chain :indexes, :oracle_enhanced
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def tables_with_oracle_enhanced(stream)
|
16
|
+
sorted_tables = @connection.tables.sort
|
17
|
+
sorted_tables.each do |tbl|
|
18
|
+
# add table prefix or suffix for schema_migrations
|
19
|
+
next if [ActiveRecord::Migrator.proper_table_name('schema_migrations'), ignore_tables].flatten.any? do |ignored|
|
20
|
+
case ignored
|
21
|
+
when String; tbl == ignored
|
22
|
+
when Regexp; tbl =~ ignored
|
23
|
+
else
|
24
|
+
raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# change table name inspect method
|
28
|
+
tbl.extend TableInspect
|
29
|
+
oracle_enhanced_table(tbl, stream)
|
30
|
+
# add primary key trigger if table has it
|
31
|
+
primary_key_trigger(tbl, stream)
|
32
|
+
end
|
33
|
+
sorted_tables.each do |tbl|
|
34
|
+
# add foreign keys if table has them
|
35
|
+
foreign_keys(tbl, stream)
|
36
|
+
end
|
37
|
+
# add synonyms in local schema
|
38
|
+
synonyms(stream)
|
39
|
+
end
|
40
|
+
|
41
|
+
def primary_key_trigger(table_name, stream)
|
42
|
+
if @connection.respond_to?(:has_primary_key_trigger?) && @connection.has_primary_key_trigger?(table_name)
|
43
|
+
pk, pk_seq = @connection.pk_and_sequence_for(table_name)
|
44
|
+
stream.print " add_primary_key_trigger #{table_name.inspect}"
|
45
|
+
stream.print ", :primary_key => \"#{pk}\"" if pk != 'id'
|
46
|
+
stream.print "\n\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def foreign_keys(table_name, stream)
|
51
|
+
if @connection.respond_to?(:foreign_keys) && (foreign_keys = @connection.foreign_keys(table_name)).any?
|
52
|
+
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
53
|
+
statement_parts = [ ('add_foreign_key ' + foreign_key.from_table.inspect) ]
|
54
|
+
statement_parts << foreign_key.to_table.inspect
|
55
|
+
statement_parts << (':name => ' + foreign_key.options[:name].inspect)
|
56
|
+
|
57
|
+
if foreign_key.options[:column] != "#{foreign_key.to_table.singularize}_id"
|
58
|
+
statement_parts << (':column => ' + foreign_key.options[:column].inspect)
|
59
|
+
end
|
60
|
+
if foreign_key.options[:primary_key] != 'id'
|
61
|
+
statement_parts << (':primary_key => ' + foreign_key.options[:primary_key].inspect)
|
62
|
+
end
|
63
|
+
unless foreign_key.options[:dependent].blank?
|
64
|
+
statement_parts << (':dependent => ' + foreign_key.options[:dependent].inspect)
|
65
|
+
end
|
66
|
+
|
67
|
+
' ' + statement_parts.join(', ')
|
68
|
+
end
|
69
|
+
|
70
|
+
stream.puts add_foreign_key_statements.sort.join("\n")
|
71
|
+
stream.puts
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def synonyms(stream)
|
76
|
+
if @connection.respond_to?(:synonyms)
|
77
|
+
syns = @connection.synonyms
|
78
|
+
syns.each do |syn|
|
79
|
+
table_name = syn.table_name
|
80
|
+
table_name = "#{syn.table_owner}.#{table_name}" if syn.table_owner
|
81
|
+
table_name = "#{table_name}@#{syn.db_link}" if syn.db_link
|
82
|
+
stream.print " add_synonym #{syn.name.inspect}, #{table_name.inspect}, :force => true"
|
83
|
+
stream.puts
|
84
|
+
end
|
85
|
+
stream.puts unless syns.empty?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def indexes_with_oracle_enhanced(table, stream)
|
90
|
+
if (indexes = @connection.indexes(table)).any?
|
91
|
+
add_index_statements = indexes.map do |index|
|
92
|
+
# use table.inspect as it will remove prefix and suffix
|
93
|
+
statment_parts = [ ('add_index ' + table.inspect) ]
|
94
|
+
statment_parts << index.columns.inspect
|
95
|
+
statment_parts << (':name => ' + index.name.inspect)
|
96
|
+
statment_parts << ':unique => true' if index.unique
|
97
|
+
statment_parts << ':tablespace => ' + index.tablespace.inspect if index.tablespace
|
98
|
+
|
99
|
+
' ' + statment_parts.join(', ')
|
100
|
+
end
|
101
|
+
|
102
|
+
stream.puts add_index_statements.sort.join("\n")
|
103
|
+
stream.puts
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def oracle_enhanced_table(table, stream)
|
108
|
+
columns = @connection.columns(table)
|
109
|
+
begin
|
110
|
+
tbl = StringIO.new
|
111
|
+
|
112
|
+
# first dump primary key column
|
113
|
+
if @connection.respond_to?(:pk_and_sequence_for)
|
114
|
+
pk, pk_seq = @connection.pk_and_sequence_for(table)
|
115
|
+
elsif @connection.respond_to?(:primary_key)
|
116
|
+
pk = @connection.primary_key(table)
|
117
|
+
end
|
118
|
+
|
119
|
+
tbl.print " create_table #{table.inspect}"
|
120
|
+
|
121
|
+
# addition to make temporary option work
|
122
|
+
tbl.print ", :temporary => true" if @connection.temporary_table?(table)
|
123
|
+
|
124
|
+
if columns.detect { |c| c.name == pk }
|
125
|
+
if pk != 'id'
|
126
|
+
tbl.print %Q(, :primary_key => "#{pk}")
|
127
|
+
end
|
128
|
+
else
|
129
|
+
tbl.print ", :id => false"
|
130
|
+
end
|
131
|
+
tbl.print ", :force => true"
|
132
|
+
tbl.puts " do |t|"
|
133
|
+
|
134
|
+
# then dump all non-primary key columns
|
135
|
+
column_specs = columns.map do |column|
|
136
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
|
137
|
+
next if column.name == pk
|
138
|
+
spec = {}
|
139
|
+
spec[:name] = column.name.inspect
|
140
|
+
spec[:type] = column.type.to_s
|
141
|
+
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal
|
142
|
+
spec[:precision] = column.precision.inspect if !column.precision.nil?
|
143
|
+
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
144
|
+
spec[:null] = 'false' if !column.null
|
145
|
+
spec[:default] = default_string(column.default) if column.has_default?
|
146
|
+
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
|
147
|
+
spec
|
148
|
+
end.compact
|
149
|
+
|
150
|
+
# find all migration keys used in this table
|
151
|
+
keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map(&:keys).flatten
|
152
|
+
|
153
|
+
# figure out the lengths for each column based on above keys
|
154
|
+
lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
|
155
|
+
|
156
|
+
# the string we're going to sprintf our values against, with standardized column widths
|
157
|
+
format_string = lengths.map{ |len| "%-#{len}s" }
|
158
|
+
|
159
|
+
# find the max length for the 'type' column, which is special
|
160
|
+
type_length = column_specs.map{ |column| column[:type].length }.max
|
161
|
+
|
162
|
+
# add column type definition to our format string
|
163
|
+
format_string.unshift " t.%-#{type_length}s "
|
164
|
+
|
165
|
+
format_string *= ''
|
166
|
+
|
167
|
+
column_specs.each do |colspec|
|
168
|
+
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
169
|
+
values.unshift colspec[:type]
|
170
|
+
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
171
|
+
tbl.puts
|
172
|
+
end
|
173
|
+
|
174
|
+
tbl.puts " end"
|
175
|
+
tbl.puts
|
176
|
+
|
177
|
+
indexes(table, tbl)
|
178
|
+
|
179
|
+
tbl.rewind
|
180
|
+
stream.print tbl.read
|
181
|
+
rescue => e
|
182
|
+
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
183
|
+
stream.puts "# #{e.message}"
|
184
|
+
stream.puts
|
185
|
+
end
|
186
|
+
|
187
|
+
stream
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
# remove table name prefix and suffix when doing #inspect (which is used in tables method)
|
192
|
+
module TableInspect #:nodoc:
|
193
|
+
def inspect
|
194
|
+
remove_prefix_and_suffix(self)
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
198
|
+
def remove_prefix_and_suffix(table_name)
|
199
|
+
if table_name =~ /\A#{ActiveRecord::Base.table_name_prefix}(.*)#{ActiveRecord::Base.table_name_suffix}\Z/
|
200
|
+
"\"#{$1}\""
|
201
|
+
else
|
202
|
+
"\"#{table_name}\""
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
ActiveRecord::SchemaDumper.class_eval do
|
212
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaDumper
|
213
|
+
end
|