activerecord-oracle_enhanced-adapter 1.4.3 → 5.2.0

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