activerecord-oracle_enhanced-adapter 1.4.3 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +1162 -2
  3. data/README.md +567 -155
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +3 -1
  6. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +19 -0
  7. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +132 -0
  8. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +345 -0
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +52 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +280 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +64 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +59 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +538 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +46 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +435 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +196 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +164 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +79 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +194 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +709 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +28 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +353 -0
  26. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +33 -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 +385 -1083
  29. data/lib/active_record/type/oracle_enhanced/boolean.rb +20 -0
  30. data/lib/active_record/type/oracle_enhanced/integer.rb +15 -0
  31. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  32. data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
  33. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  34. data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
  35. data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
  36. data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
  37. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  38. data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
  39. data/lib/activerecord-oracle_enhanced-adapter.rb +5 -13
  40. data/spec/active_record/connection_adapters/{oracle_enhanced_emulate_oracle_adapter_spec.rb → emulation/oracle_adapter_spec.rb} +5 -4
  41. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +469 -0
  42. data/spec/active_record/connection_adapters/{oracle_enhanced_context_index_spec.rb → oracle_enhanced/context_index_spec.rb} +140 -128
  43. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +112 -0
  44. data/spec/active_record/connection_adapters/{oracle_enhanced_dbms_output_spec.rb → oracle_enhanced/dbms_output_spec.rb} +13 -13
  45. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +365 -0
  46. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +196 -0
  47. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
  48. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1433 -0
  49. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +478 -0
  50. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +385 -550
  51. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +92 -1249
  52. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  53. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +208 -0
  54. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +139 -0
  55. data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
  56. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +91 -0
  57. data/spec/active_record/oracle_enhanced/type/json_spec.rb +57 -0
  58. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
  59. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
  60. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +122 -0
  61. data/spec/active_record/oracle_enhanced/type/text_spec.rb +229 -0
  62. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +75 -0
  63. data/spec/spec_config.yaml.template +11 -0
  64. data/spec/spec_helper.rb +100 -93
  65. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  66. data/spec/support/alter_system_user_password.sql +2 -0
  67. data/spec/support/create_oracle_enhanced_users.sql +31 -0
  68. metadata +105 -152
  69. data/.rspec +0 -2
  70. data/Gemfile +0 -52
  71. data/RUNNING_TESTS.md +0 -45
  72. data/Rakefile +0 -59
  73. data/activerecord-oracle_enhanced-adapter.gemspec +0 -130
  74. data/lib/active_record/connection_adapters/oracle_enhanced.rake +0 -105
  75. data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +0 -41
  76. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +0 -121
  77. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +0 -151
  78. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +0 -119
  79. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +0 -359
  80. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +0 -25
  81. data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +0 -21
  82. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +0 -46
  83. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +0 -572
  84. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +0 -497
  85. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +0 -260
  86. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +0 -227
  87. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +0 -260
  88. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +0 -428
  89. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +0 -258
  90. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +0 -294
  91. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +0 -17
  92. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +0 -1
  93. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +0 -334
  94. data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +0 -19
  95. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +0 -113
  96. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +0 -141
  97. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +0 -378
  98. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +0 -440
  99. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +0 -1400
  100. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +0 -339
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe "OracleEnhancedAdapter quoting" do
4
+ include LoggerSpecHelper
5
+ include SchemaSpecHelper
6
+
7
+ before(:all) do
8
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
9
+ end
10
+
11
+ describe "reserved words column quoting" do
12
+
13
+ before(:all) do
14
+ schema_define do
15
+ create_table :test_reserved_words do |t|
16
+ t.string :varchar2
17
+ t.integer :integer
18
+ t.text :comment
19
+ end
20
+ end
21
+ class ::TestReservedWord < ActiveRecord::Base; end
22
+ end
23
+
24
+ after(:all) do
25
+ schema_define do
26
+ drop_table :test_reserved_words
27
+ end
28
+ Object.send(:remove_const, "TestReservedWord")
29
+ ActiveRecord::Base.table_name_prefix = nil
30
+ ActiveRecord::Base.clear_cache!
31
+ end
32
+
33
+ before(:each) do
34
+ set_logger
35
+ end
36
+
37
+ after(:each) do
38
+ clear_logger
39
+ end
40
+
41
+ it "should create table" do
42
+ [:varchar2, :integer, :comment].each do |attr|
43
+ expect(TestReservedWord.columns_hash[attr.to_s].name).to eq(attr.to_s)
44
+ end
45
+ end
46
+
47
+ it "should create record" do
48
+ attrs = {
49
+ varchar2: "dummy",
50
+ integer: 1,
51
+ comment: "dummy"
52
+ }
53
+ record = TestReservedWord.create!(attrs)
54
+ record.reload
55
+ attrs.each do |k, v|
56
+ expect(record.send(k)).to eq(v)
57
+ end
58
+ end
59
+
60
+ it "should remove double quotes in column quoting" do
61
+ expect(ActiveRecord::Base.connection.quote_column_name('aaa "bbb" ccc')).to eq('"aaa bbb ccc"')
62
+ end
63
+
64
+ end
65
+
66
+ describe "valid table names" do
67
+ before(:all) do
68
+ @adapter = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting
69
+ end
70
+
71
+ it "should be valid with letters and digits" do
72
+ expect(@adapter.valid_table_name?("abc_123")).to be_truthy
73
+ end
74
+
75
+ it "should be valid with schema name" do
76
+ expect(@adapter.valid_table_name?("abc_123.def_456")).to be_truthy
77
+ end
78
+
79
+ it "should be valid with schema name and object name in different case" do
80
+ expect(@adapter.valid_table_name?("TEST_DBA.def_456")).to be_truthy
81
+ end
82
+
83
+ it "should be valid with $ in name" do
84
+ expect(@adapter.valid_table_name?("sys.v$session")).to be_truthy
85
+ end
86
+
87
+ it "should be valid with upcase schema name" do
88
+ expect(@adapter.valid_table_name?("ABC_123.DEF_456")).to be_truthy
89
+ end
90
+
91
+ it "should be valid with irregular schema name and database links" do
92
+ expect(@adapter.valid_table_name?('abc$#_123.abc$#_123@abc$#@._123')).to be_truthy
93
+ end
94
+
95
+ it "should not be valid with two dots in name" do
96
+ expect(@adapter.valid_table_name?("abc_123.def_456.ghi_789")).to be_falsey
97
+ end
98
+
99
+ it "should not be valid with invalid characters" do
100
+ expect(@adapter.valid_table_name?("warehouse-things")).to be_falsey
101
+ end
102
+
103
+ it "should not be valid with for camel-case" do
104
+ expect(@adapter.valid_table_name?("Abc")).to be_falsey
105
+ expect(@adapter.valid_table_name?("aBc")).to be_falsey
106
+ expect(@adapter.valid_table_name?("abC")).to be_falsey
107
+ end
108
+
109
+ it "should not be valid for names > 30 characters" do
110
+ expect(@adapter.valid_table_name?("a" * 31)).to be_falsey
111
+ end
112
+
113
+ it "should not be valid for schema names > 30 characters" do
114
+ expect(@adapter.valid_table_name?(("a" * 31) + ".validname")).to be_falsey
115
+ end
116
+
117
+ it "should not be valid for database links > 128 characters" do
118
+ expect(@adapter.valid_table_name?("name@" + "a" * 129)).to be_falsey
119
+ end
120
+
121
+ it "should not be valid for names that do not begin with alphabetic characters" do
122
+ expect(@adapter.valid_table_name?("1abc")).to be_falsey
123
+ expect(@adapter.valid_table_name?("_abc")).to be_falsey
124
+ expect(@adapter.valid_table_name?("abc.1xyz")).to be_falsey
125
+ expect(@adapter.valid_table_name?("abc._xyz")).to be_falsey
126
+ end
127
+ end
128
+
129
+ describe "table quoting" do
130
+
131
+ def create_warehouse_things_table
132
+ ActiveRecord::Schema.define do
133
+ suppress_messages do
134
+ create_table "warehouse-things" do |t|
135
+ t.string :name
136
+ t.integer :foo
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ def create_camel_case_table
143
+ ActiveRecord::Schema.define do
144
+ suppress_messages do
145
+ create_table "CamelCase" do |t|
146
+ t.string :name
147
+ t.integer :foo
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ before(:all) do
154
+ @conn = ActiveRecord::Base.connection
155
+ end
156
+
157
+ after(:each) do
158
+ ActiveRecord::Schema.define do
159
+ suppress_messages do
160
+ drop_table "warehouse-things", if_exists: true
161
+ drop_table "CamelCase", if_exists: true
162
+ end
163
+ end
164
+ Object.send(:remove_const, "WarehouseThing") rescue nil
165
+ Object.send(:remove_const, "CamelCase") rescue nil
166
+ end
167
+
168
+ it "should allow creation of a table with non alphanumeric characters" do
169
+ create_warehouse_things_table
170
+ class ::WarehouseThing < ActiveRecord::Base
171
+ self.table_name = "warehouse-things"
172
+ end
173
+
174
+ wh = WarehouseThing.create!(name: "Foo", foo: 2)
175
+ expect(wh.id).not_to be_nil
176
+
177
+ expect(@conn.tables).to include("warehouse-things")
178
+ end
179
+
180
+ it "should allow creation of a table with CamelCase name" do
181
+ create_camel_case_table
182
+ class ::CamelCase < ActiveRecord::Base
183
+ self.table_name = "CamelCase"
184
+ end
185
+
186
+ cc = CamelCase.create!(name: "Foo", foo: 2)
187
+ expect(cc.id).not_to be_nil
188
+
189
+ expect(@conn.tables).to include("CamelCase")
190
+ end
191
+
192
+ it "properly quotes database links" do
193
+ expect(@conn.quote_table_name("asdf@some.link")).to eq('"ASDF"@"SOME.LINK"')
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,492 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe "OracleEnhancedAdapter schema dump" do
4
+ include SchemaSpecHelper
5
+ include SchemaDumpingHelper
6
+
7
+ before(:all) do
8
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
9
+ @conn = ActiveRecord::Base.connection
10
+ @oracle11g_or_higher = !! @conn.select_value(
11
+ "select * from product_component_version where product like 'Oracle%' and to_number(substr(version,1,2)) >= 11")
12
+ end
13
+
14
+ def standard_dump(options = {})
15
+ stream = StringIO.new
16
+ ActiveRecord::SchemaDumper.ignore_tables = options[:ignore_tables] || []
17
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
18
+ stream.string
19
+ end
20
+
21
+ def create_test_posts_table(options = {})
22
+ options.merge! force: true
23
+ schema_define do
24
+ create_table :test_posts, options do |t|
25
+ t.string :title
26
+ t.timestamps null: true
27
+ end
28
+ add_index :test_posts, :title
29
+ end
30
+ end
31
+
32
+ def drop_test_posts_table
33
+ schema_define do
34
+ drop_table :test_posts
35
+ end
36
+ rescue
37
+ nil
38
+ end
39
+
40
+ describe "tables" do
41
+ after(:each) do
42
+ drop_test_posts_table
43
+ end
44
+
45
+ it "should not include ignored table names in schema dump" do
46
+ create_test_posts_table
47
+ expect(standard_dump(ignore_tables: %w(test_posts))).not_to match(/create_table "test_posts"/)
48
+ end
49
+
50
+ it "should not include ignored table regexes in schema dump" do
51
+ create_test_posts_table
52
+ expect(standard_dump(ignore_tables: [ /test_posts/i ])).not_to match(/create_table "test_posts"/)
53
+ end
54
+
55
+ end
56
+
57
+ describe "dumping default values" do
58
+ before :each do
59
+ schema_define do
60
+ create_table "test_defaults", force: true do |t|
61
+ t.string "regular", default: "c"
62
+ t.string "special_c", default: "\n"
63
+ end
64
+ end
65
+ end
66
+
67
+ after(:each) do
68
+ schema_define do
69
+ drop_table "test_defaults"
70
+ end
71
+ end
72
+
73
+ it "should be able to dump default values using special characters" do
74
+ output = dump_table_schema "test_defaults"
75
+ expect(output).to match(/t.string \"special_c\", default: "\\n"/)
76
+ end
77
+ end
78
+
79
+ describe "table with non-default primary key" do
80
+ after(:each) do
81
+ drop_test_posts_table
82
+ end
83
+
84
+ it "should include non-default primary key in schema dump" do
85
+ create_test_posts_table(primary_key: "post_id")
86
+ output = dump_table_schema "test_posts"
87
+ expect(output).to match(/create_table "test_posts", primary_key: "post_id"/)
88
+ end
89
+
90
+ end
91
+
92
+ describe "table with ntext columns" do
93
+ before :each do
94
+ schema_define do
95
+ create_table "test_ntexts", force: true do |t|
96
+ t.ntext :ntext_column
97
+ end
98
+ end
99
+ end
100
+
101
+ after(:each) do
102
+ schema_define do
103
+ drop_table "test_ntexts"
104
+ end
105
+ end
106
+
107
+ it "should be able to dump ntext columns" do
108
+ output = dump_table_schema "test_ntexts"
109
+ expect(output).to match(/t.ntext \"ntext_column\"/)
110
+ end
111
+ end
112
+
113
+ describe "table with primary key trigger" do
114
+
115
+ after(:each) do
116
+ drop_test_posts_table
117
+ end
118
+
119
+ it "should include primary key trigger in schema dump" do
120
+ create_test_posts_table(primary_key_trigger: true)
121
+ expect(standard_dump).to match(/create_table "test_posts".*add_primary_key_trigger "test_posts"/m)
122
+ end
123
+
124
+ it "should include primary key trigger with non-default primary key in schema dump" do
125
+ create_test_posts_table(primary_key_trigger: true, primary_key: "post_id")
126
+ expect(standard_dump).to match(/create_table "test_posts", primary_key: "post_id".*add_primary_key_trigger "test_posts", primary_key: "post_id"/m)
127
+ end
128
+
129
+ end
130
+
131
+ describe "foreign key constraints" do
132
+ before(:all) do
133
+ schema_define do
134
+ create_table :test_posts, force: true do |t|
135
+ t.string :title
136
+ end
137
+ create_table :test_comments, force: true do |t|
138
+ t.string :body, limit: 4000
139
+ t.references :test_post
140
+ end
141
+ end
142
+ end
143
+
144
+ after(:each) do
145
+ schema_define do
146
+ remove_foreign_key :test_comments, :test_posts rescue nil
147
+ remove_foreign_key :test_comments, name: "comments_posts_baz_fooz_fk" rescue nil
148
+ end
149
+ end
150
+ after(:all) do
151
+ schema_define do
152
+ drop_table :test_comments, if_exists: true
153
+ drop_table :test_posts, if_exists: true
154
+ end
155
+ end
156
+
157
+ it "should include foreign key in schema dump" do
158
+ schema_define do
159
+ add_foreign_key :test_comments, :test_posts
160
+ end
161
+ output = dump_table_schema "test_comments"
162
+ expect(output).to match(/add_foreign_key "test_comments", "test_posts"/)
163
+ end
164
+
165
+ it "should include foreign key with delete dependency in schema dump" do
166
+ schema_define do
167
+ add_foreign_key :test_comments, :test_posts, on_delete: :cascade
168
+ end
169
+ output = dump_table_schema "test_comments"
170
+ expect(output).to match(/add_foreign_key "test_comments", "test_posts", on_delete: :cascade/)
171
+ end
172
+
173
+ it "should include foreign key with nullify dependency in schema dump" do
174
+ schema_define do
175
+ add_foreign_key :test_comments, :test_posts, on_delete: :nullify
176
+ end
177
+ output = dump_table_schema "test_comments"
178
+ expect(output).to match(/add_foreign_key "test_comments", "test_posts", on_delete: :nullify/)
179
+ end
180
+
181
+ it "should not include foreign keys on ignored table names in schema dump" do
182
+ schema_define do
183
+ add_foreign_key :test_comments, :test_posts
184
+ end
185
+ expect(standard_dump(ignore_tables: %w(test_comments))).not_to match(/add_foreign_key "test_comments"/)
186
+ end
187
+
188
+ it "should not include foreign keys on ignored table regexes in schema dump" do
189
+ schema_define do
190
+ add_foreign_key :test_comments, :test_posts
191
+ end
192
+ expect(standard_dump(ignore_tables: [ /test_comments/i ])).not_to match(/add_foreign_key "test_comments"/)
193
+ end
194
+
195
+ it "should include foreign keys referencing ignored table names in schema dump" do
196
+ schema_define do
197
+ add_foreign_key :test_comments, :test_posts
198
+ end
199
+ expect(standard_dump(ignore_tables: %w(test_posts))).to match(/add_foreign_key "test_comments"/)
200
+ end
201
+
202
+ it "should include foreign keys referencing ignored table regexes in schema dump" do
203
+ schema_define do
204
+ add_foreign_key :test_comments, :test_posts
205
+ end
206
+ expect(standard_dump(ignore_tables: [ /test_posts/i ])).to match(/add_foreign_key "test_comments"/)
207
+ end
208
+
209
+ it "should include foreign keys following all tables" do
210
+ # if foreign keys precede declaration of all tables
211
+ # it can cause problems when using db:test rake tasks
212
+ schema_define do
213
+ add_foreign_key :test_comments, :test_posts
214
+ end
215
+ dump = standard_dump
216
+ expect(dump.rindex("create_table")).to be < dump.index("add_foreign_key")
217
+ end
218
+
219
+ it "should include primary_key when reference column name is not 'id'" do
220
+ schema_define do
221
+ create_table :test_posts, force: true, primary_key: "baz_id" do |t|
222
+ t.string :title
223
+ end
224
+ create_table :test_comments, force: true do |t|
225
+ t.string :body, limit: 4000
226
+ t.integer :baz_id
227
+ end
228
+ end
229
+
230
+ @conn.execute <<-SQL
231
+ ALTER TABLE TEST_COMMENTS
232
+ ADD CONSTRAINT TEST_COMMENTS_BAZ_ID_FK FOREIGN KEY (baz_id) REFERENCES test_posts(baz_id)
233
+ SQL
234
+
235
+ output = dump_table_schema "test_comments"
236
+ expect(output).to match(/add_foreign_key "test_comments", "test_posts", column: "baz_id", primary_key: "baz_id", name: "test_comments_baz_id_fk"/)
237
+ end
238
+
239
+ end
240
+
241
+ describe "synonyms" do
242
+ after(:each) do
243
+ schema_define do
244
+ remove_synonym :test_synonym
245
+ end
246
+ end
247
+
248
+ it "should include synonym to other schema table in schema dump" do
249
+ schema_define do
250
+ add_synonym :test_synonym, "schema_name.table_name", force: true
251
+ end
252
+ expect(standard_dump).to match(/add_synonym "test_synonym", "schema_name.table_name", force: true/)
253
+ end
254
+
255
+ it "should include synonym to other database table in schema dump" do
256
+ schema_define do
257
+ add_synonym :test_synonym, "table_name@link_name", force: true
258
+ end
259
+ expect(standard_dump).to match(/add_synonym "test_synonym", "table_name@link_name(\.[-A-Za-z0-9_]+)*", force: true/)
260
+ end
261
+
262
+ it "should not include ignored table names in schema dump" do
263
+ schema_define do
264
+ add_synonym :test_synonym, "schema_name.table_name", force: true
265
+ end
266
+ expect(standard_dump(ignore_tables: %w(test_synonym))).not_to match(/add_synonym "test_synonym"/)
267
+ end
268
+
269
+ it "should not include ignored table regexes in schema dump" do
270
+ schema_define do
271
+ add_synonym :test_synonym, "schema_name.table_name", force: true
272
+ end
273
+ expect(standard_dump(ignore_tables: [ /test_synonym/i ])).not_to match(/add_synonym "test_synonym"/)
274
+ end
275
+
276
+ it "should include synonyms to ignored table regexes in schema dump" do
277
+ schema_define do
278
+ add_synonym :test_synonym, "schema_name.table_name", force: true
279
+ end
280
+ expect(standard_dump(ignore_tables: [ /table_name/i ])).to match(/add_synonym "test_synonym"/)
281
+ end
282
+
283
+ end
284
+
285
+ describe "temporary tables" do
286
+ after(:each) do
287
+ drop_test_posts_table
288
+ end
289
+
290
+ it "should include temporary options" do
291
+ create_test_posts_table(temporary: true)
292
+ output = dump_table_schema "test_posts"
293
+ expect(output).to match(/create_table "test_posts", temporary: true/)
294
+ end
295
+ end
296
+
297
+ describe "indexes" do
298
+ after(:each) do
299
+ drop_test_posts_table
300
+ end
301
+
302
+ it "should not specify default tablespace in add index" do
303
+ create_test_posts_table
304
+ output = dump_table_schema "test_posts"
305
+ expect(output).to match(/t\.index \["title"\], name: "index_test_posts_on_title"$/)
306
+ end
307
+
308
+ it "should specify non-default tablespace in add index" do
309
+ tablespace_name = @conn.default_tablespace
310
+ allow(@conn).to receive(:default_tablespace).and_return("dummy")
311
+ create_test_posts_table
312
+ output = dump_table_schema "test_posts"
313
+ expect(output).to match(/t\.index \["title"\], name: "index_test_posts_on_title", tablespace: "#{tablespace_name}"$/)
314
+ end
315
+
316
+ it "should create and dump function-based indexes" do
317
+ create_test_posts_table
318
+ @conn.add_index :test_posts, "NVL(created_at, updated_at)", name: "index_test_posts_cr_upd_at"
319
+ output = dump_table_schema "test_posts"
320
+ expect(output).to match(/t\.index \["NVL\(\\"CREATED_AT\\",\\"UPDATED_AT\\"\)"\], name: "index_test_posts_cr_upd_at"$/)
321
+ end
322
+
323
+ end
324
+
325
+ describe "materialized views" do
326
+ after(:each) do
327
+ @conn.execute "DROP MATERIALIZED VIEW test_posts_mv" rescue nil
328
+ drop_test_posts_table
329
+ end
330
+
331
+ it "should not include materialized views in schema dump" do
332
+ create_test_posts_table
333
+ @conn.execute "CREATE MATERIALIZED VIEW test_posts_mv AS SELECT * FROM test_posts"
334
+ expect(standard_dump).not_to match(/create_table "test_posts_mv"/)
335
+ end
336
+ end
337
+
338
+ describe "virtual columns" do
339
+ before(:all) do
340
+ skip "Not supported in this database version" unless @oracle11g_or_higher
341
+ schema_define do
342
+ create_table :test_names, force: true do |t|
343
+ t.string :first_name
344
+ t.string :last_name
345
+ t.virtual :full_name, as: "first_name || ', ' || last_name"
346
+ t.virtual :short_name, as: "COALESCE(first_name, last_name)", type: :string, limit: 300
347
+ t.virtual :abbrev_name, as: "SUBSTR(first_name,1,50) || ' ' || SUBSTR(last_name,1,1) || '.'", type: "VARCHAR(100)"
348
+ t.virtual :name_ratio, as: "(LENGTH(first_name)*10/LENGTH(last_name)*10)"
349
+ t.column :full_name_length, :virtual, as: "length(first_name || ', ' || last_name)", type: :integer
350
+ t.virtual :field_with_leading_space, as: "' ' || first_name || ' '", limit: 300, type: :string
351
+ end
352
+ end
353
+ end
354
+
355
+ before(:each) do
356
+ if @oracle11g_or_higher
357
+ class ::TestName < ActiveRecord::Base
358
+ self.table_name = "test_names"
359
+ end
360
+ end
361
+ end
362
+
363
+ after(:all) do
364
+ if @oracle11g_or_higher
365
+ schema_define do
366
+ drop_table :test_names
367
+ end
368
+ end
369
+ end
370
+
371
+ it "should dump correctly" do
372
+ output = dump_table_schema "test_names"
373
+ expect(output).to match(/t\.virtual "full_name",(\s*)type: :string,(\s*)limit: 512,(\s*)as: "\\"FIRST_NAME\\"\|\|', '\|\|\\"LAST_NAME\\""/)
374
+ expect(output).to match(/t\.virtual "short_name",(\s*)type: :string,(\s*)limit: 300,(\s*)as:(.*)/)
375
+ expect(output).to match(/t\.virtual "full_name_length",(\s*)type: :integer,(\s*)precision: 38,(\s*)as:(.*)/)
376
+ expect(output).to match(/t\.virtual "name_ratio",(\s*)as:(.*)\"$/) # no :type
377
+ expect(output).to match(/t\.virtual "abbrev_name",(\s*)type: :string,(\s*)limit: 100,(\s*)as:(.*)/)
378
+ expect(output).to match(/t\.virtual "field_with_leading_space",(\s*)type: :string,(\s*)limit: 300,(\s*)as: "' '\|\|\\"FIRST_NAME\\"\|\|' '"/)
379
+ end
380
+
381
+ context "with index on virtual column" do
382
+ before(:all) do
383
+ if @oracle11g_or_higher
384
+ schema_define do
385
+ add_index "test_names", "field_with_leading_space", name: "index_on_virtual_col"
386
+ end
387
+ end
388
+ end
389
+ after(:all) do
390
+ if @oracle11g_or_higher
391
+ schema_define do
392
+ remove_index "test_names", name: "index_on_virtual_col"
393
+ end
394
+ end
395
+ end
396
+ it "should dump correctly" do
397
+ output = dump_table_schema "test_names"
398
+ expect(output).not_to match(/t\.index .+FIRST_NAME.+$/)
399
+ expect(output).to match(/t\.index .+field_with_leading_space.+$/)
400
+ end
401
+ end
402
+ end
403
+
404
+ describe ":float datatype" do
405
+ before(:each) do
406
+ schema_define do
407
+ create_table :test_floats, force: true do |t|
408
+ t.float :hourly_rate
409
+ end
410
+ end
411
+ end
412
+
413
+ after(:each) do
414
+ schema_define do
415
+ drop_table :test_floats
416
+ end
417
+ end
418
+
419
+ it "should dump float type correctly" do
420
+ output = dump_table_schema "test_floats"
421
+ expect(output).to match(/t\.float "hourly_rate"$/)
422
+ end
423
+ end
424
+
425
+ describe "table comments" do
426
+ before(:each) do
427
+ schema_define do
428
+ create_table :test_table_comments, comment: "this is a \"table comment\"!", force: true do |t|
429
+ t.string :blah
430
+ end
431
+ end
432
+ end
433
+
434
+ after(:each) do
435
+ schema_define do
436
+ drop_table :test_table_comments
437
+ end
438
+ end
439
+
440
+ it "should dump table comments" do
441
+ output = dump_table_schema "test_table_comments"
442
+ expect(output).to match(/create_table "test_table_comments", comment: "this is a \\"table comment\\"!", force: :cascade do \|t\|$/)
443
+ end
444
+ end
445
+
446
+ describe "column comments" do
447
+ before(:each) do
448
+ schema_define do
449
+ create_table :test_column_comments, force: true do |t|
450
+ t.string :blah, comment: "this is a \"column comment\"!"
451
+ end
452
+ end
453
+ end
454
+
455
+ after(:each) do
456
+ schema_define do
457
+ drop_table :test_column_comments
458
+ end
459
+ end
460
+
461
+ it "should dump column comments" do
462
+ output = dump_table_schema "test_column_comments"
463
+ expect(output).to match(/comment: "this is a \\"column comment\\"!"/)
464
+ end
465
+ end
466
+
467
+ describe "schema.rb format" do
468
+ before do
469
+ create_test_posts_table
470
+
471
+ schema_define do
472
+ create_table :test_comments, force: true do |t|
473
+ t.string :title
474
+ end
475
+
476
+ add_index :test_comments, :title
477
+ end
478
+ end
479
+
480
+ it "should be only one blank line between create_table methods in schema dump" do
481
+ expect(standard_dump).to match(/end\n\n create_table/)
482
+ end
483
+
484
+ after do
485
+ schema_define do
486
+ drop_table :test_comments, if_exists: true
487
+ end
488
+
489
+ drop_test_posts_table
490
+ end
491
+ end
492
+ end