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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +1971 -0
  3. data/License.txt +20 -0
  4. data/README.md +947 -0
  5. data/VERSION +1 -0
  6. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +7 -0
  7. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +24 -0
  8. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +137 -0
  9. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +359 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +47 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +325 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +63 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +71 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +629 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +57 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +465 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +195 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +186 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +99 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +197 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +739 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +394 -0
  26. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +34 -0
  27. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +3 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +886 -0
  29. data/lib/active_record/type/oracle_enhanced/boolean.rb +19 -0
  30. data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
  31. data/lib/active_record/type/oracle_enhanced/integer.rb +14 -0
  32. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  33. data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
  34. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  35. data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
  36. data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
  37. data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
  38. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  39. data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
  40. data/lib/activerecord-oracle_enhanced-adapter.rb +25 -0
  41. data/lib/arel/visitors/oracle.rb +216 -0
  42. data/lib/arel/visitors/oracle12.rb +121 -0
  43. data/lib/arel/visitors/oracle_common.rb +51 -0
  44. data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +24 -0
  45. data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +40 -0
  46. data/spec/active_record/connection_adapters/oracle_enhanced/composite_spec.rb +84 -0
  47. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +589 -0
  48. data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
  49. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
  50. data/spec/active_record/connection_adapters/oracle_enhanced/dbconsole_spec.rb +63 -0
  51. data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
  52. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
  53. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
  54. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
  55. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1318 -0
  56. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +485 -0
  57. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
  58. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
  59. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  60. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
  61. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
  62. data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
  63. data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
  64. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
  65. data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
  66. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +101 -0
  67. data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
  68. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
  69. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
  70. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
  71. data/spec/active_record/oracle_enhanced/type/text_spec.rb +295 -0
  72. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +107 -0
  73. data/spec/spec_config.yaml.template +11 -0
  74. data/spec/spec_helper.rb +225 -0
  75. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  76. data/spec/support/alter_system_user_password.sql +2 -0
  77. data/spec/support/create_oracle_enhanced_users.sql +31 -0
  78. 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