activerecord-oracle_enhanced-adapter 7.2.1-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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +1977 -0
  3. data/License.txt +20 -0
  4. data/README.md +863 -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 +344 -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 +295 -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 +561 -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 +45 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +457 -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 +94 -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 +738 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +366 -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 +865 -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 +36 -0
  46. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +574 -0
  47. data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
  48. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
  49. data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
  50. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
  51. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
  52. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
  53. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1289 -0
  54. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +474 -0
  55. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
  56. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
  57. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  58. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
  59. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
  60. data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
  61. data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
  62. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
  63. data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
  64. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +99 -0
  65. data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
  66. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +56 -0
  67. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
  68. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
  69. data/spec/active_record/oracle_enhanced/type/text_spec.rb +244 -0
  70. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +77 -0
  71. data/spec/spec_config.yaml.template +11 -0
  72. data/spec/spec_helper.rb +214 -0
  73. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  74. data/spec/support/alter_system_user_password.sql +2 -0
  75. data/spec/support/create_oracle_enhanced_users.sql +31 -0
  76. metadata +177 -0
@@ -0,0 +1,474 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe "OracleEnhancedAdapter structure dump" do
4
+ include LoggerSpecHelper
5
+
6
+ before(:all) do
7
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
8
+ @conn = ActiveRecord::Base.connection
9
+ @oracle11g_or_higher = !! @conn.select_value(
10
+ "select * from product_component_version where product like 'Oracle%' and to_number(substr(version,1,2)) >= 11")
11
+ end
12
+
13
+ describe "structure dump" do
14
+ before(:each) do
15
+ @conn.create_table :test_posts, force: true do |t|
16
+ t.string :title
17
+ t.string :foo
18
+ t.integer :foo_id
19
+ end
20
+ @conn.create_table :foos do |t|
21
+ end
22
+ class ::TestPost < ActiveRecord::Base
23
+ end
24
+ TestPost.table_name = "test_posts"
25
+ end
26
+
27
+ after(:each) do
28
+ @conn.drop_table :test_posts
29
+ @conn.drop_table :foos
30
+ @conn.execute "DROP SEQUENCE test_posts_seq" rescue nil
31
+ @conn.execute "ALTER TABLE test_posts drop CONSTRAINT fk_test_post_foo" rescue nil
32
+ @conn.execute "DROP TRIGGER test_post_trigger" rescue nil
33
+ @conn.execute "DROP TYPE TEST_TYPE" rescue nil
34
+ @conn.execute "DROP TABLE bars" rescue nil
35
+ @conn.execute "ALTER TABLE foos drop CONSTRAINT UK_BAZ" rescue nil
36
+ @conn.execute "ALTER TABLE foos drop CONSTRAINT UK_FOOZ_BAZ" rescue nil
37
+ @conn.execute "ALTER TABLE foos drop column fooz_id" rescue nil
38
+ @conn.execute "ALTER TABLE foos drop column baz_id" rescue nil
39
+ @conn.execute "ALTER TABLE test_posts drop column fooz_id" rescue nil
40
+ @conn.execute "ALTER TABLE test_posts drop column baz_id" rescue nil
41
+ @conn.execute "DROP VIEW test_posts_view_z" rescue nil
42
+ @conn.execute "DROP VIEW test_posts_view_a" rescue nil
43
+ end
44
+
45
+ it "should dump single primary key" do
46
+ dump = ActiveRecord::Base.connection.structure_dump
47
+ expect(dump).to match(/CONSTRAINT (.+) PRIMARY KEY \(ID\)\n/)
48
+ end
49
+
50
+ it "should dump composite primary keys" do
51
+ pk = @conn.send(:select_one, <<~SQL)
52
+ select constraint_name from user_constraints where table_name = 'TEST_POSTS' and constraint_type='P'
53
+ SQL
54
+ @conn.execute <<~SQL
55
+ alter table test_posts drop constraint #{pk["constraint_name"]}
56
+ SQL
57
+ @conn.execute <<~SQL
58
+ ALTER TABLE TEST_POSTS
59
+ add CONSTRAINT pk_id_title PRIMARY KEY (id, title)
60
+ SQL
61
+ dump = ActiveRecord::Base.connection.structure_dump
62
+ expect(dump).to match(/CONSTRAINT (.+) PRIMARY KEY \(ID,TITLE\)\n/)
63
+ end
64
+
65
+ it "should dump foreign keys" do
66
+ @conn.execute <<~SQL
67
+ ALTER TABLE TEST_POSTS
68
+ ADD CONSTRAINT fk_test_post_foo FOREIGN KEY (foo_id) REFERENCES foos(id)
69
+ SQL
70
+ dump = ActiveRecord::Base.connection.structure_dump
71
+ expect(dump.split('\n').length).to eq(1)
72
+ expect(dump).to match(/ALTER TABLE "?TEST_POSTS"? ADD CONSTRAINT "?FK_TEST_POST_FOO"? FOREIGN KEY \("?FOO_ID"?\) REFERENCES "?FOOS"?\("?ID"?\)/i)
73
+ end
74
+
75
+ it "should dump foreign keys when reference column name is not 'id'" do
76
+ @conn.add_column :foos, :baz_id, :integer
77
+
78
+ @conn.execute <<~SQL
79
+ ALTER TABLE FOOS
80
+ ADD CONSTRAINT UK_BAZ UNIQUE (BAZ_ID)
81
+ SQL
82
+
83
+ @conn.add_column :test_posts, :baz_id, :integer
84
+
85
+ @conn.execute <<~SQL
86
+ ALTER TABLE TEST_POSTS
87
+ ADD CONSTRAINT fk_test_post_baz FOREIGN KEY (baz_id) REFERENCES foos(baz_id)
88
+ SQL
89
+
90
+ dump = ActiveRecord::Base.connection.structure_dump
91
+ expect(dump.split('\n').length).to eq(1)
92
+ expect(dump).to match(/ALTER TABLE "?TEST_POSTS"? ADD CONSTRAINT "?FK_TEST_POST_BAZ"? FOREIGN KEY \("?BAZ_ID"?\) REFERENCES "?FOOS"?\("?BAZ_ID"?\)/i)
93
+ end
94
+
95
+ it "should not error when no foreign keys are present" do
96
+ dump = ActiveRecord::Base.connection.structure_dump_fk_constraints
97
+ expect(dump.split('\n').length).to eq(0)
98
+ expect(dump).to eq("")
99
+ end
100
+
101
+ it "should dump triggers" do
102
+ @conn.execute <<~SQL
103
+ create or replace TRIGGER TEST_POST_TRIGGER
104
+ BEFORE INSERT
105
+ ON TEST_POSTS
106
+ FOR EACH ROW
107
+ BEGIN
108
+ SELECT 'bar' INTO :new.FOO FROM DUAL;
109
+ END;
110
+ SQL
111
+ dump = ActiveRecord::Base.connection.structure_dump_db_stored_code.gsub(/\n|\s+/, " ")
112
+ expect(dump).to match(/CREATE OR REPLACE TRIGGER TEST_POST_TRIGGER/)
113
+ end
114
+
115
+ it "should dump types" do
116
+ @conn.execute <<~SQL
117
+ create or replace TYPE TEST_TYPE AS TABLE OF VARCHAR2(10);
118
+ SQL
119
+ dump = ActiveRecord::Base.connection.structure_dump_db_stored_code.gsub(/\n|\s+/, " ")
120
+ expect(dump).to match(/CREATE OR REPLACE TYPE TEST_TYPE/)
121
+ end
122
+
123
+ it "should dump views" do
124
+ @conn.execute "create or replace VIEW test_posts_view_z as select * from test_posts"
125
+ @conn.execute "create or replace VIEW test_posts_view_a as select * from test_posts_view_z"
126
+ dump = ActiveRecord::Base.connection.structure_dump.gsub(/\n|\s+/, " ")
127
+ expect(dump).to match(/CREATE OR REPLACE FORCE VIEW TEST_POSTS_VIEW_A.*CREATE OR REPLACE FORCE VIEW TEST_POSTS_VIEW_Z/)
128
+ end
129
+
130
+ it "should dump virtual columns" do
131
+ skip "Not supported in this database version" unless @oracle11g_or_higher
132
+ @conn.execute <<~SQL
133
+ CREATE TABLE bars (
134
+ id NUMBER(38,0) NOT NULL,
135
+ id_plus NUMBER GENERATED ALWAYS AS(id + 2) VIRTUAL,
136
+ PRIMARY KEY (ID)
137
+ )
138
+ SQL
139
+ dump = ActiveRecord::Base.connection.structure_dump
140
+ expect(dump).to match(/"?ID_PLUS"? NUMBER GENERATED ALWAYS AS \(ID\+2\) VIRTUAL/)
141
+ end
142
+
143
+ it "should dump RAW virtual columns" do
144
+ skip "Not supported in this database version" unless @oracle11g_or_higher
145
+ @conn.execute <<~SQL
146
+ CREATE TABLE bars (
147
+ id NUMBER(38,0) NOT NULL,
148
+ super RAW(255) GENERATED ALWAYS AS \( HEXTORAW\(ID\) \) VIRTUAL,
149
+ PRIMARY KEY (ID)
150
+ )
151
+ SQL
152
+ dump = ActiveRecord::Base.connection.structure_dump
153
+ expect(dump).to match(/CREATE TABLE "BARS" \(\n "ID" NUMBER\(38,0\) NOT NULL,\n "SUPER" RAW\(255\) GENERATED ALWAYS AS \(HEXTORAW\(TO_CHAR\(ID\)\)\) VIRTUAL/)
154
+ end
155
+
156
+ it "should dump NCLOB columns" do
157
+ @conn.execute <<~SQL
158
+ CREATE TABLE bars (
159
+ id NUMBER(38,0) NOT NULL,
160
+ nclob_text NCLOB,
161
+ PRIMARY KEY (ID)
162
+ )
163
+ SQL
164
+ dump = ActiveRecord::Base.connection.structure_dump
165
+ expect(dump).to match(/CREATE TABLE "BARS" \(\n "ID" NUMBER\(38,0\) NOT NULL,\n "NCLOB_TEXT" NCLOB/)
166
+ end
167
+
168
+ it "should dump unique keys" do
169
+ @conn.execute <<~SQL
170
+ ALTER TABLE test_posts
171
+ add CONSTRAINT uk_foo_foo_id UNIQUE (foo, foo_id)
172
+ SQL
173
+ dump = ActiveRecord::Base.connection.structure_dump_unique_keys("test_posts")
174
+ expect(dump).to eq(["ALTER TABLE TEST_POSTS ADD CONSTRAINT UK_FOO_FOO_ID UNIQUE (FOO,FOO_ID)"])
175
+
176
+ dump = ActiveRecord::Base.connection.structure_dump
177
+ expect(dump).to match(/CONSTRAINT UK_FOO_FOO_ID UNIQUE \(FOO,FOO_ID\)/)
178
+ end
179
+
180
+ it "should dump indexes" do
181
+ ActiveRecord::Base.connection.add_index(:test_posts, :foo, name: :ix_test_posts_foo)
182
+ ActiveRecord::Base.connection.add_index(:test_posts, :foo_id, name: :ix_test_posts_foo_id, unique: true)
183
+
184
+ @conn.execute <<~SQL
185
+ ALTER TABLE test_posts
186
+ add CONSTRAINT uk_foo_foo_id UNIQUE (foo, foo_id)
187
+ SQL
188
+
189
+ dump = ActiveRecord::Base.connection.structure_dump
190
+ expect(dump).to match(/CREATE UNIQUE INDEX "?IX_TEST_POSTS_FOO_ID"? ON "?TEST_POSTS"? \("?FOO_ID"?\)/i)
191
+ expect(dump).to match(/CREATE INDEX "?IX_TEST_POSTS_FOO"? ON "?TEST_POSTS"? \("?FOO"?\)/i)
192
+ expect(dump).not_to match(/CREATE UNIQUE INDEX "?UK_TEST_POSTS_/i)
193
+ end
194
+
195
+ it "should dump multi-value and function value indexes" do
196
+ ActiveRecord::Base.connection.add_index(:test_posts, [:foo, :foo_id], name: :ix_test_posts_foo_foo_id)
197
+
198
+ @conn.execute <<~SQL
199
+ CREATE INDEX "IX_TEST_POSTS_FUNCTION" ON "TEST_POSTS" (TO_CHAR(LENGTH("FOO"))||"FOO")
200
+ SQL
201
+
202
+ dump = ActiveRecord::Base.connection.structure_dump
203
+ expect(dump).to match(/CREATE INDEX "?IX_TEST_POSTS_FOO_FOO_ID"? ON "?TEST_POSTS"? \("?FOO"?, "?FOO_ID"?\)/i)
204
+ expect(dump).to match(/CREATE INDEX "?IX_TEST_POSTS_FUNCTION"? ON "?TEST_POSTS"? \(TO_CHAR\(LENGTH\("?FOO"?\)\)\|\|"?FOO"?\)/i)
205
+ end
206
+
207
+ it "should dump RAW columns" do
208
+ @conn.execute <<~SQL
209
+ CREATE TABLE bars (
210
+ id NUMBER(38,0) NOT NULL,
211
+ super RAW(255),
212
+ PRIMARY KEY (ID)
213
+ )
214
+ SQL
215
+ dump = ActiveRecord::Base.connection.structure_dump
216
+ expect(dump).to match(/CREATE TABLE "BARS" \(\n "ID" NUMBER\(38,0\) NOT NULL,\n "SUPER" RAW\(255\)/)
217
+ end
218
+
219
+ it "should dump table comments" do
220
+ comment_sql = %Q(COMMENT ON TABLE "TEST_POSTS" IS 'Test posts with ''some'' "quotes"')
221
+ @conn.execute comment_sql
222
+ dump = ActiveRecord::Base.connection.structure_dump
223
+ expect(dump).to match(/#{comment_sql}/)
224
+ end
225
+
226
+ it "should dump column comments" do
227
+ comment_sql = %Q(COMMENT ON COLUMN "TEST_POSTS"."TITLE" IS 'The title of the post with ''some'' "quotes"')
228
+ @conn.execute comment_sql
229
+ dump = ActiveRecord::Base.connection.structure_dump
230
+ expect(dump).to match(/#{comment_sql}/)
231
+ end
232
+ end
233
+
234
+ describe "temporary tables" do
235
+ after(:all) do
236
+ @conn.drop_table :test_comments, if_exists: true
237
+ end
238
+
239
+ it "should dump correctly" do
240
+ @conn.create_table :test_comments, temporary: true, id: false do |t|
241
+ t.integer :post_id
242
+ end
243
+ dump = ActiveRecord::Base.connection.structure_dump
244
+ expect(dump).to match(/CREATE GLOBAL TEMPORARY TABLE "?TEST_COMMENTS"?/i)
245
+ end
246
+ end
247
+
248
+ describe "sequences" do
249
+ let(:sequence_name) { "test_sequence_a" }
250
+ before(:each) do
251
+ @conn.execute sql
252
+ end
253
+
254
+ after(:each) do
255
+ @conn.execute "drop SEQUENCE \"#{sequence_name}\""
256
+ end
257
+
258
+ subject do
259
+ ActiveRecord::Base.connection.structure_dump
260
+ end
261
+
262
+ context "default sequence" do
263
+ let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\"" }
264
+ it { is_expected.to_not match(%r{CREATE SEQUENCE "#{sequence_name}" MAXVALUE \d+ MINVALUE \d+ NOORDER NOCYCLE}) }
265
+ end
266
+
267
+ context "noorder" do
268
+ let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" NOORDER" }
269
+ it { is_expected.to include("NOORDER") }
270
+ it { is_expected.to_not include(" ORDER") }
271
+ end
272
+
273
+ context "order" do
274
+ let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" ORDER" }
275
+ it { is_expected.to include(" ORDER") }
276
+ it { is_expected.to_not include("NOORDER") }
277
+ end
278
+
279
+ context "min max values" do
280
+ let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" MINVALUE 7 MAXVALUE 444" }
281
+ it { is_expected.to include("MINVALUE 7") }
282
+ it { is_expected.to include("MAXVALUE 444") }
283
+ end
284
+ end
285
+
286
+ describe "database structure dump extensions" do
287
+ before(:all) do
288
+ @conn.execute <<~SQL
289
+ CREATE TABLE nvarchartable (
290
+ unq_nvarchar NVARCHAR2(255) DEFAULT NULL
291
+ )
292
+ SQL
293
+ end
294
+
295
+ after(:all) do
296
+ @conn.execute "DROP TABLE nvarchartable"
297
+ end
298
+
299
+ it "should return the character size of nvarchar fields" do
300
+ if /.*unq_nvarchar nvarchar2\((\d+)\).*/ =~ @conn.structure_dump
301
+ expect("#$1").to eq("255")
302
+ end
303
+ end
304
+ end
305
+
306
+ describe "temp_table_drop" do
307
+ before(:each) do
308
+ @conn.create_table :temp_tbl, temporary: true do |t|
309
+ t.string :foo
310
+ end
311
+ @conn.create_table :not_temp_tbl do |t|
312
+ t.string :foo
313
+ end
314
+ end
315
+
316
+ it "should dump drop sql for just temp tables" do
317
+ dump = @conn.temp_table_drop
318
+ expect(dump).to match(/DROP TABLE "TEMP_TBL"/)
319
+ expect(dump).not_to match(/DROP TABLE "?NOT_TEMP_TBL"?/i)
320
+ end
321
+ after(:each) do
322
+ @conn.drop_table :temp_tbl
323
+ @conn.drop_table :not_temp_tbl
324
+ end
325
+ end
326
+
327
+ describe "schema migrations" do
328
+ let(:versions) do
329
+ (1..10).map do |i|
330
+ Time.parse("2016.01.#{i}").strftime("%Y%m%d%H%M%S")
331
+ end
332
+ end
333
+
334
+ let(:dump) { ActiveRecord::Base.connection.dump_schema_information }
335
+
336
+ before do
337
+ ActiveRecord::Base.connection_pool.schema_migration.create_table
338
+ versions.each do |i|
339
+ ActiveRecord::Base.connection_pool.schema_migration.create_version(i)
340
+ end
341
+ end
342
+
343
+ context "multi insert is supported" do
344
+ it "should dump schema migrations using multi inserts" do
345
+ skip "Not supported in this database version" unless ActiveRecord::Base.connection.supports_multi_insert?
346
+
347
+ expect(dump).to eq <<~SQL
348
+ INSERT ALL
349
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160101000000')
350
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160102000000')
351
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160103000000')
352
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160104000000')
353
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160105000000')
354
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160106000000')
355
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160107000000')
356
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160108000000')
357
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160109000000')
358
+ INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160110000000')
359
+ SELECT * FROM DUAL
360
+ SQL
361
+ end
362
+ end
363
+
364
+ context "multi insert is NOT supported" do
365
+ let(:insert_statement_per_migration) {
366
+ 1.step(10).map { |i|
367
+ %Q|INSERT INTO "SCHEMA_MIGRATIONS" (version) VALUES ('201601#{sprintf("%02d", i)}000000')|
368
+ }.join("\n\n/\n\n")
369
+ }
370
+
371
+ it "should dump schema migrations one version per insert" do
372
+ skip "Not supported in this database version" if ActiveRecord::Base.connection.supports_multi_insert?
373
+
374
+ expect(dump).to eq insert_statement_per_migration
375
+ end
376
+ end
377
+
378
+ after do
379
+ ActiveRecord::Base.connection_pool.schema_migration.drop_table
380
+ end
381
+ end
382
+
383
+ describe "full drop" do
384
+ before(:each) do
385
+ @conn.create_table :full_drop_test do |t|
386
+ t.string :foo
387
+ end
388
+ @conn.create_table :full_drop_test_temp, temporary: true do |t|
389
+ t.string :foo
390
+ end
391
+ # view
392
+ @conn.execute <<~SQL
393
+ create or replace view full_drop_test_view (foo) as select id as "foo" from full_drop_test
394
+ SQL
395
+ # materialized view
396
+ @conn.execute <<~SQL
397
+ create materialized view full_drop_test_mview (foo) as select id as "foo" from full_drop_test
398
+ SQL
399
+ # package
400
+ @conn.execute <<~SQL
401
+ create or replace package full_drop_test_package as
402
+ function test_func return varchar2;
403
+ end test_package;
404
+ SQL
405
+ @conn.execute <<~SQL
406
+ create or replace package body full_drop_test_package as
407
+ function test_func return varchar2 is
408
+ begin
409
+ return ('foo');
410
+ end test_func;
411
+ end test_package;
412
+ SQL
413
+ # function
414
+ @conn.execute <<~SQL
415
+ create or replace function full_drop_test_function
416
+ return varchar2
417
+ is
418
+ foo varchar2(3);
419
+ begin
420
+ return('foo');
421
+ end;
422
+ SQL
423
+ # procedure
424
+ @conn.execute <<~SQL
425
+ create or replace procedure full_drop_test_procedure
426
+ begin
427
+ delete from full_drop_test where id=1231231231
428
+ exception
429
+ when no_data_found then
430
+ dbms_output.put_line('foo');
431
+ end;
432
+ SQL
433
+ # synonym
434
+ @conn.execute <<~SQL
435
+ create or replace synonym full_drop_test_synonym for full_drop_test
436
+ SQL
437
+ # type
438
+ @conn.execute <<~SQL
439
+ create or replace type full_drop_test_type as table of number
440
+ SQL
441
+ end
442
+
443
+ after(:each) do
444
+ @conn.drop_table :full_drop_test
445
+ @conn.drop_table :full_drop_test_temp
446
+ @conn.execute "DROP VIEW FULL_DROP_TEST_VIEW" rescue nil
447
+ @conn.execute "DROP MATERIALIZED VIEW FULL_DROP_TEST_MVIEW" rescue nil
448
+ @conn.execute "DROP SYNONYM FULL_DROP_TEST_SYNONYM" rescue nil
449
+ @conn.execute "DROP PACKAGE FULL_DROP_TEST_PACKAGE" rescue nil
450
+ @conn.execute "DROP FUNCTION FULL_DROP_TEST_FUNCTION" rescue nil
451
+ @conn.execute "DROP PROCEDURE FULL_DROP_TEST_PROCEDURE" rescue nil
452
+ @conn.execute "DROP TYPE FULL_DROP_TEST_TYPE" rescue nil
453
+ end
454
+
455
+ it "should contain correct sql" do
456
+ drop = @conn.full_drop
457
+ expect(drop).to match(/DROP TABLE "FULL_DROP_TEST" CASCADE CONSTRAINTS/)
458
+ expect(drop).to match(/DROP SEQUENCE "FULL_DROP_TEST_SEQ"/)
459
+ expect(drop).to match(/DROP VIEW "FULL_DROP_TEST_VIEW"/)
460
+ expect(drop).not_to match(/DROP TABLE "?FULL_DROP_TEST_MVIEW"?/i)
461
+ expect(drop).to match(/DROP MATERIALIZED VIEW "FULL_DROP_TEST_MVIEW"/)
462
+ expect(drop).to match(/DROP PACKAGE "FULL_DROP_TEST_PACKAGE"/)
463
+ expect(drop).to match(/DROP FUNCTION "FULL_DROP_TEST_FUNCTION"/)
464
+ expect(drop).to match(/DROP PROCEDURE "FULL_DROP_TEST_PROCEDURE"/)
465
+ expect(drop).to match(/DROP SYNONYM "FULL_DROP_TEST_SYNONYM"/)
466
+ expect(drop).to match(/DROP TYPE "FULL_DROP_TEST_TYPE"/)
467
+ end
468
+ it "should not drop tables when preserve_tables is true" do
469
+ drop = @conn.full_drop(true)
470
+ expect(drop).to match(/DROP TABLE "FULL_DROP_TEST_TEMP"/)
471
+ expect(drop).not_to match(/DROP TABLE "?FULL_DROP_TEST"? CASCADE CONSTRAINTS/i)
472
+ end
473
+ end
474
+ end