activerecord-oracle_enhanced-adapter 8.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/History.md +1971 -0
- data/License.txt +20 -0
- data/README.md +947 -0
- data/VERSION +1 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +24 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +137 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +359 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +47 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +325 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +63 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +71 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +629 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +57 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +465 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +195 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +186 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +99 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +197 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +739 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +394 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +3 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +886 -0
- data/lib/active_record/type/oracle_enhanced/boolean.rb +19 -0
- data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/integer.rb +14 -0
- data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
- data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
- data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
- data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
- data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
- data/lib/activerecord-oracle_enhanced-adapter.rb +25 -0
- data/lib/arel/visitors/oracle.rb +216 -0
- data/lib/arel/visitors/oracle12.rb +121 -0
- data/lib/arel/visitors/oracle_common.rb +51 -0
- data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +24 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +40 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/composite_spec.rb +84 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +589 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/dbconsole_spec.rb +63 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1318 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +485 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
- data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
- data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
- data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
- data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
- data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
- data/spec/active_record/oracle_enhanced/type/integer_spec.rb +101 -0
- data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
- data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
- data/spec/active_record/oracle_enhanced/type/text_spec.rb +295 -0
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +107 -0
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +225 -0
- data/spec/support/alter_system_set_open_cursors.sql +1 -0
- data/spec/support/alter_system_user_password.sql +2 -0
- data/spec/support/create_oracle_enhanced_users.sql +31 -0
- metadata +181 -0
|
@@ -0,0 +1,485 @@
|
|
|
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 check constraints" do
|
|
220
|
+
@conn.execute <<~SQL
|
|
221
|
+
ALTER TABLE test_posts ADD CONSTRAINT test_posts_title_check CHECK (LENGTH(title) > 0)
|
|
222
|
+
SQL
|
|
223
|
+
dump = ActiveRecord::Base.connection.structure_dump_check_constraints("test_posts")
|
|
224
|
+
expect(dump.first).to match(/ALTER TABLE "TEST_POSTS" ADD CONSTRAINT "TEST_POSTS_TITLE_CHECK" CHECK/)
|
|
225
|
+
|
|
226
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
|
227
|
+
expect(dump).to match(/ALTER TABLE "TEST_POSTS" ADD CONSTRAINT "TEST_POSTS_TITLE_CHECK" CHECK/)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "should dump table comments" do
|
|
231
|
+
comment_sql = %Q(COMMENT ON TABLE "TEST_POSTS" IS 'Test posts with ''some'' "quotes"')
|
|
232
|
+
@conn.execute comment_sql
|
|
233
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
|
234
|
+
expect(dump).to match(/#{comment_sql}/)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it "should dump column comments" do
|
|
238
|
+
comment_sql = %Q(COMMENT ON COLUMN "TEST_POSTS"."TITLE" IS 'The title of the post with ''some'' "quotes"')
|
|
239
|
+
@conn.execute comment_sql
|
|
240
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
|
241
|
+
expect(dump).to match(/#{comment_sql}/)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "temporary tables" do
|
|
246
|
+
after(:all) do
|
|
247
|
+
@conn.drop_table :test_comments, if_exists: true
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should dump correctly" do
|
|
251
|
+
@conn.create_table :test_comments, temporary: true, id: false do |t|
|
|
252
|
+
t.integer :post_id
|
|
253
|
+
end
|
|
254
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
|
255
|
+
expect(dump).to match(/CREATE GLOBAL TEMPORARY TABLE "?TEST_COMMENTS"?/i)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe "sequences" do
|
|
260
|
+
let(:sequence_name) { "test_sequence_a" }
|
|
261
|
+
before(:each) do
|
|
262
|
+
@conn.execute sql
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
after(:each) do
|
|
266
|
+
@conn.execute "drop SEQUENCE \"#{sequence_name}\""
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
subject do
|
|
270
|
+
ActiveRecord::Base.connection.structure_dump
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
context "default sequence" do
|
|
274
|
+
let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\"" }
|
|
275
|
+
it { is_expected.to_not match(%r{CREATE SEQUENCE "#{sequence_name}" MAXVALUE \d+ MINVALUE \d+ NOORDER NOCYCLE}) }
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context "noorder" do
|
|
279
|
+
let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" NOORDER" }
|
|
280
|
+
it { is_expected.to include("NOORDER") }
|
|
281
|
+
it { is_expected.to_not include(" ORDER") }
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
context "order" do
|
|
285
|
+
let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" ORDER" }
|
|
286
|
+
it { is_expected.to include(" ORDER") }
|
|
287
|
+
it { is_expected.to_not include("NOORDER") }
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
context "min max values" do
|
|
291
|
+
let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" MINVALUE 7 MAXVALUE 444" }
|
|
292
|
+
it { is_expected.to include("MINVALUE 7") }
|
|
293
|
+
it { is_expected.to include("MAXVALUE 444") }
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
describe "database structure dump extensions" do
|
|
298
|
+
before(:all) do
|
|
299
|
+
@conn.execute <<~SQL
|
|
300
|
+
CREATE TABLE nvarchartable (
|
|
301
|
+
unq_nvarchar NVARCHAR2(255) DEFAULT NULL
|
|
302
|
+
)
|
|
303
|
+
SQL
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
after(:all) do
|
|
307
|
+
@conn.execute "DROP TABLE nvarchartable"
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "should return the character size of nvarchar fields" do
|
|
311
|
+
if /.*unq_nvarchar nvarchar2\((\d+)\).*/ =~ @conn.structure_dump
|
|
312
|
+
expect("#$1").to eq("255")
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
describe "temp_table_drop" do
|
|
318
|
+
before(:each) do
|
|
319
|
+
@conn.create_table :temp_tbl, temporary: true do |t|
|
|
320
|
+
t.string :foo
|
|
321
|
+
end
|
|
322
|
+
@conn.create_table :not_temp_tbl do |t|
|
|
323
|
+
t.string :foo
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it "should dump drop sql for just temp tables" do
|
|
328
|
+
dump = @conn.temp_table_drop
|
|
329
|
+
expect(dump).to match(/DROP TABLE "TEMP_TBL"/)
|
|
330
|
+
expect(dump).not_to match(/DROP TABLE "?NOT_TEMP_TBL"?/i)
|
|
331
|
+
end
|
|
332
|
+
after(:each) do
|
|
333
|
+
@conn.drop_table :temp_tbl
|
|
334
|
+
@conn.drop_table :not_temp_tbl
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
describe "schema migrations" do
|
|
339
|
+
let(:versions) do
|
|
340
|
+
(1..10).map do |i|
|
|
341
|
+
Time.parse("2016.01.#{i}").strftime("%Y%m%d%H%M%S")
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
let(:dump) { ActiveRecord::Base.connection.dump_schema_versions }
|
|
346
|
+
|
|
347
|
+
before do
|
|
348
|
+
ActiveRecord::Base.connection_pool.schema_migration.create_table
|
|
349
|
+
versions.each do |i|
|
|
350
|
+
ActiveRecord::Base.connection_pool.schema_migration.create_version(i)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
context "multi insert is supported" do
|
|
355
|
+
it "should dump schema migrations using multi inserts" do
|
|
356
|
+
skip "Not supported in this database version" unless ActiveRecord::Base.connection.supports_multi_insert?
|
|
357
|
+
|
|
358
|
+
expect(dump).to eq <<~SQL
|
|
359
|
+
INSERT ALL
|
|
360
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160101000000')
|
|
361
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160102000000')
|
|
362
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160103000000')
|
|
363
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160104000000')
|
|
364
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160105000000')
|
|
365
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160106000000')
|
|
366
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160107000000')
|
|
367
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160108000000')
|
|
368
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160109000000')
|
|
369
|
+
INTO "SCHEMA_MIGRATIONS" (version) VALUES ('20160110000000')
|
|
370
|
+
SELECT * FROM DUAL
|
|
371
|
+
SQL
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
context "multi insert is NOT supported" do
|
|
376
|
+
let(:insert_statement_per_migration) {
|
|
377
|
+
1.step(10).map { |i|
|
|
378
|
+
%Q|INSERT INTO "SCHEMA_MIGRATIONS" (version) VALUES ('201601#{sprintf("%02d", i)}000000')|
|
|
379
|
+
}.join("\n\n/\n\n")
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
it "should dump schema migrations one version per insert" do
|
|
383
|
+
skip "Not supported in this database version" if ActiveRecord::Base.connection.supports_multi_insert?
|
|
384
|
+
|
|
385
|
+
expect(dump).to eq insert_statement_per_migration
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
after do
|
|
390
|
+
ActiveRecord::Base.connection_pool.schema_migration.drop_table
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
describe "full drop" do
|
|
395
|
+
before(:each) do
|
|
396
|
+
@conn.create_table :full_drop_test do |t|
|
|
397
|
+
t.string :foo
|
|
398
|
+
end
|
|
399
|
+
@conn.create_table :full_drop_test_temp, temporary: true do |t|
|
|
400
|
+
t.string :foo
|
|
401
|
+
end
|
|
402
|
+
# view
|
|
403
|
+
@conn.execute <<~SQL
|
|
404
|
+
create or replace view full_drop_test_view (foo) as select id as "foo" from full_drop_test
|
|
405
|
+
SQL
|
|
406
|
+
# materialized view
|
|
407
|
+
@conn.execute <<~SQL
|
|
408
|
+
create materialized view full_drop_test_mview (foo) as select id as "foo" from full_drop_test
|
|
409
|
+
SQL
|
|
410
|
+
# package
|
|
411
|
+
@conn.execute <<~SQL
|
|
412
|
+
create or replace package full_drop_test_package as
|
|
413
|
+
function test_func return varchar2;
|
|
414
|
+
end test_package;
|
|
415
|
+
SQL
|
|
416
|
+
@conn.execute <<~SQL
|
|
417
|
+
create or replace package body full_drop_test_package as
|
|
418
|
+
function test_func return varchar2 is
|
|
419
|
+
begin
|
|
420
|
+
return ('foo');
|
|
421
|
+
end test_func;
|
|
422
|
+
end test_package;
|
|
423
|
+
SQL
|
|
424
|
+
# function
|
|
425
|
+
@conn.execute <<~SQL
|
|
426
|
+
create or replace function full_drop_test_function
|
|
427
|
+
return varchar2
|
|
428
|
+
is
|
|
429
|
+
foo varchar2(3);
|
|
430
|
+
begin
|
|
431
|
+
return('foo');
|
|
432
|
+
end;
|
|
433
|
+
SQL
|
|
434
|
+
# procedure
|
|
435
|
+
@conn.execute <<~SQL
|
|
436
|
+
create or replace procedure full_drop_test_procedure
|
|
437
|
+
begin
|
|
438
|
+
delete from full_drop_test where id=1231231231
|
|
439
|
+
exception
|
|
440
|
+
when no_data_found then
|
|
441
|
+
dbms_output.put_line('foo');
|
|
442
|
+
end;
|
|
443
|
+
SQL
|
|
444
|
+
# synonym
|
|
445
|
+
@conn.execute <<~SQL
|
|
446
|
+
create or replace synonym full_drop_test_synonym for full_drop_test
|
|
447
|
+
SQL
|
|
448
|
+
# type
|
|
449
|
+
@conn.execute <<~SQL
|
|
450
|
+
create or replace type full_drop_test_type as table of number
|
|
451
|
+
SQL
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
after(:each) do
|
|
455
|
+
@conn.drop_table :full_drop_test
|
|
456
|
+
@conn.drop_table :full_drop_test_temp
|
|
457
|
+
@conn.execute "DROP VIEW FULL_DROP_TEST_VIEW" rescue nil
|
|
458
|
+
@conn.execute "DROP MATERIALIZED VIEW FULL_DROP_TEST_MVIEW" rescue nil
|
|
459
|
+
@conn.execute "DROP SYNONYM FULL_DROP_TEST_SYNONYM" rescue nil
|
|
460
|
+
@conn.execute "DROP PACKAGE FULL_DROP_TEST_PACKAGE" rescue nil
|
|
461
|
+
@conn.execute "DROP FUNCTION FULL_DROP_TEST_FUNCTION" rescue nil
|
|
462
|
+
@conn.execute "DROP PROCEDURE FULL_DROP_TEST_PROCEDURE" rescue nil
|
|
463
|
+
@conn.execute "DROP TYPE FULL_DROP_TEST_TYPE" rescue nil
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
it "should contain correct sql" do
|
|
467
|
+
drop = @conn.full_drop
|
|
468
|
+
expect(drop).to match(/DROP TABLE "FULL_DROP_TEST" CASCADE CONSTRAINTS/)
|
|
469
|
+
expect(drop).to match(/DROP SEQUENCE "FULL_DROP_TEST_SEQ"/)
|
|
470
|
+
expect(drop).to match(/DROP VIEW "FULL_DROP_TEST_VIEW"/)
|
|
471
|
+
expect(drop).not_to match(/DROP TABLE "?FULL_DROP_TEST_MVIEW"?/i)
|
|
472
|
+
expect(drop).to match(/DROP MATERIALIZED VIEW "FULL_DROP_TEST_MVIEW"/)
|
|
473
|
+
expect(drop).to match(/DROP PACKAGE "FULL_DROP_TEST_PACKAGE"/)
|
|
474
|
+
expect(drop).to match(/DROP FUNCTION "FULL_DROP_TEST_FUNCTION"/)
|
|
475
|
+
expect(drop).to match(/DROP PROCEDURE "FULL_DROP_TEST_PROCEDURE"/)
|
|
476
|
+
expect(drop).to match(/DROP SYNONYM "FULL_DROP_TEST_SYNONYM"/)
|
|
477
|
+
expect(drop).to match(/DROP TYPE "FULL_DROP_TEST_TYPE"/)
|
|
478
|
+
end
|
|
479
|
+
it "should not drop tables when preserve_tables is true" do
|
|
480
|
+
drop = @conn.full_drop(true)
|
|
481
|
+
expect(drop).to match(/DROP TABLE "FULL_DROP_TEST_TEMP"/)
|
|
482
|
+
expect(drop).not_to match(/DROP TABLE "?FULL_DROP_TEST"? CASCADE CONSTRAINTS/i)
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
end
|