activerecord-oracle_enhanced-adapter 8.1.0-java
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.
- checksums.yaml +7 -0
- data/History.md +1971 -0
- data/License.txt +20 -0
- data/README.md +947 -0
- data/VERSION +1 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +24 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +137 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +359 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +47 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +325 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +63 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +71 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +629 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +57 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +465 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +195 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +186 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +99 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +197 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +739 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +394 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +3 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +886 -0
- data/lib/active_record/type/oracle_enhanced/boolean.rb +19 -0
- data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/integer.rb +14 -0
- data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
- data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
- data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
- data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
- data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
- data/lib/activerecord-oracle_enhanced-adapter.rb +25 -0
- data/lib/arel/visitors/oracle.rb +216 -0
- data/lib/arel/visitors/oracle12.rb +121 -0
- data/lib/arel/visitors/oracle_common.rb +51 -0
- data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +24 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +40 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/composite_spec.rb +84 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +589 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/dbconsole_spec.rb +63 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1318 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +485 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
- data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
- data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
- data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
- data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
- data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
- data/spec/active_record/oracle_enhanced/type/integer_spec.rb +101 -0
- data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
- data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
- data/spec/active_record/oracle_enhanced/type/text_spec.rb +295 -0
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +107 -0
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +225 -0
- data/spec/support/alter_system_set_open_cursors.sql +1 -0
- data/spec/support/alter_system_user_password.sql +2 -0
- data/spec/support/create_oracle_enhanced_users.sql +31 -0
- metadata +181 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord # :nodoc:
|
|
4
|
+
module ConnectionAdapters # :nodoc:
|
|
5
|
+
module OracleEnhanced # :nodoc:
|
|
6
|
+
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
|
|
7
|
+
DEFAULT_PRIMARY_KEY_COLUMN_SPEC = { precision: "38", null: "false" }.freeze
|
|
8
|
+
private_constant :DEFAULT_PRIMARY_KEY_COLUMN_SPEC
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
def column_spec_for_primary_key(column)
|
|
12
|
+
spec = super
|
|
13
|
+
spec.except!(:precision) if prepare_column_options(column) == DEFAULT_PRIMARY_KEY_COLUMN_SPEC
|
|
14
|
+
spec
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def tables(stream)
|
|
18
|
+
# do not include materialized views in schema dump - they should be created separately after schema creation
|
|
19
|
+
sorted_tables = (@connection.tables - @connection.materialized_views).sort
|
|
20
|
+
sorted_tables.each do |tbl|
|
|
21
|
+
# add table prefix or suffix for schema_migrations
|
|
22
|
+
next if ignored? tbl
|
|
23
|
+
table(tbl, stream)
|
|
24
|
+
end
|
|
25
|
+
# following table definitions
|
|
26
|
+
# add foreign keys if table has them
|
|
27
|
+
sorted_tables.each do |tbl|
|
|
28
|
+
next if ignored? tbl
|
|
29
|
+
foreign_keys(tbl, stream)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# add synonyms in local schema
|
|
33
|
+
synonyms(stream)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def synonyms(stream)
|
|
37
|
+
syns = @connection.synonyms
|
|
38
|
+
syns.each do |syn|
|
|
39
|
+
next if ignored? syn.name
|
|
40
|
+
table_name = syn.table_name
|
|
41
|
+
table_name = "#{syn.table_owner}.#{table_name}" if syn.table_owner
|
|
42
|
+
stream.print " add_synonym #{syn.name.inspect}, #{table_name.inspect}, force: true"
|
|
43
|
+
stream.puts
|
|
44
|
+
end
|
|
45
|
+
stream.puts unless syns.empty?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def _indexes(table, stream)
|
|
49
|
+
if (indexes = @connection.indexes(table)).any?
|
|
50
|
+
add_index_statements = indexes.filter_map do |index|
|
|
51
|
+
case index.type
|
|
52
|
+
when nil
|
|
53
|
+
# do nothing here. see indexes_in_create
|
|
54
|
+
statement_parts = []
|
|
55
|
+
when "CTXSYS.CONTEXT"
|
|
56
|
+
if index.statement_parameters
|
|
57
|
+
statement_parts = [ ("add_context_index " + remove_prefix_and_suffix(table).inspect) ]
|
|
58
|
+
statement_parts << index.statement_parameters
|
|
59
|
+
else
|
|
60
|
+
statement_parts = [ ("add_context_index " + remove_prefix_and_suffix(table).inspect) ]
|
|
61
|
+
statement_parts << index.columns.inspect
|
|
62
|
+
statement_parts << ("sync: " + $1.inspect) if index.parameters =~ /SYNC\((.*?)\)/
|
|
63
|
+
statement_parts << ("name: " + index.name.inspect)
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
# unrecognized index type
|
|
67
|
+
statement_parts = ["# unrecognized index #{index.name.inspect} with type #{index.type.inspect}"]
|
|
68
|
+
end
|
|
69
|
+
" " + statement_parts.join(", ") unless statement_parts.empty?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
return if add_index_statements.empty?
|
|
73
|
+
|
|
74
|
+
stream.puts add_index_statements.sort.join("\n")
|
|
75
|
+
stream.puts
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def indexes_in_create(table, stream)
|
|
80
|
+
if (indexes = @connection.indexes(table)).any?
|
|
81
|
+
index_statements = indexes.map do |index|
|
|
82
|
+
" t.index #{index_parts(index).join(', ')}" unless index.type == "CTXSYS.CONTEXT"
|
|
83
|
+
end
|
|
84
|
+
stream.puts index_statements.compact.sort.join("\n")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def index_parts(index)
|
|
89
|
+
index_parts = super
|
|
90
|
+
index_parts << "tablespace: #{index.tablespace.inspect}" if index.tablespace
|
|
91
|
+
index_parts
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def table(table, stream)
|
|
95
|
+
columns = @connection.columns(table)
|
|
96
|
+
begin
|
|
97
|
+
self.table_name = table
|
|
98
|
+
|
|
99
|
+
tbl = StringIO.new
|
|
100
|
+
|
|
101
|
+
# first dump primary key column
|
|
102
|
+
if @connection.respond_to?(:primary_keys)
|
|
103
|
+
pk = @connection.primary_keys(table)
|
|
104
|
+
pk = pk.first unless pk.size > 1
|
|
105
|
+
else
|
|
106
|
+
pk = @connection.primary_key(table)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
|
110
|
+
|
|
111
|
+
# addition to make temporary option work
|
|
112
|
+
tbl.print ", temporary: true" if @connection.temporary_table?(table)
|
|
113
|
+
|
|
114
|
+
case pk
|
|
115
|
+
when String
|
|
116
|
+
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
|
|
117
|
+
pkcol = columns.detect { |c| c.name == pk }
|
|
118
|
+
pkcolspec = column_spec_for_primary_key(pkcol)
|
|
119
|
+
unless pkcolspec.empty?
|
|
120
|
+
if pkcolspec != pkcolspec.slice(:id, :default)
|
|
121
|
+
pkcolspec = { id: { type: pkcolspec.delete(:id), **pkcolspec }.compact }
|
|
122
|
+
end
|
|
123
|
+
tbl.print ", #{format_colspec(pkcolspec)}"
|
|
124
|
+
end
|
|
125
|
+
when Array
|
|
126
|
+
tbl.print ", primary_key: #{pk.inspect}"
|
|
127
|
+
else
|
|
128
|
+
tbl.print ", id: false"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
table_options = @connection.table_options(table)
|
|
132
|
+
if table_options.present?
|
|
133
|
+
tbl.print ", #{format_options(table_options)}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
tbl.puts ", force: :cascade do |t|"
|
|
137
|
+
|
|
138
|
+
# then dump all non-primary key columns
|
|
139
|
+
columns.each do |column|
|
|
140
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
|
141
|
+
next if column.name == pk
|
|
142
|
+
type, colspec = column_spec(column)
|
|
143
|
+
tbl.print " t.#{type} #{column.name.inspect}"
|
|
144
|
+
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
|
145
|
+
tbl.puts
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
indexes_in_create(table, tbl)
|
|
149
|
+
|
|
150
|
+
tbl.puts " end"
|
|
151
|
+
tbl.puts
|
|
152
|
+
|
|
153
|
+
_indexes(table, tbl)
|
|
154
|
+
|
|
155
|
+
tbl.rewind
|
|
156
|
+
stream.print tbl.read
|
|
157
|
+
rescue => e
|
|
158
|
+
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
|
159
|
+
stream.puts "# #{e.message}"
|
|
160
|
+
stream.puts
|
|
161
|
+
ensure
|
|
162
|
+
self.table_name = nil
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def prepare_column_options(column)
|
|
167
|
+
spec = super
|
|
168
|
+
|
|
169
|
+
if @connection.supports_virtual_columns? && column.virtual?
|
|
170
|
+
spec[:as] = extract_expression_for_virtual_column(column)
|
|
171
|
+
spec = { type: schema_type(column).inspect }.merge!(spec) unless column.type == :decimal
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
spec
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def default_primary_key?(column)
|
|
178
|
+
schema_type(column) == :integer
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def extract_expression_for_virtual_column(column)
|
|
182
|
+
column_name = column.name
|
|
183
|
+
@connection.select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
|
|
184
|
+
select data_default from all_tab_columns
|
|
185
|
+
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
|
186
|
+
and table_name = :table_name
|
|
187
|
+
and column_name = :column_name
|
|
188
|
+
SQL
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def bind_string(name, value)
|
|
192
|
+
ActiveRecord::Relation::QueryAttribute.new(name, value, Type::OracleEnhanced::String.new)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|