activerecord-oracle_enhanced-adapter 1.8.2 → 5.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +190 -5
  3. data/README.md +10 -10
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +2 -0
  6. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +9 -71
  7. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +84 -73
  8. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +12 -12
  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 +35 -7
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +2 -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 +379 -402
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +7 -1
  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 +242 -247
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +9 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +3 -1
  19. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +25 -9
  20. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +9 -6
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +10 -5
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +48 -51
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +261 -59
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +2 -34
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +267 -222
  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 +2 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +136 -547
  29. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/boolean.rb +4 -2
  30. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/integer.rb +4 -2
  31. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  32. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/national_character_string.rb +5 -3
  33. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  34. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/raw.rb +4 -2
  35. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/string.rb +4 -2
  36. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/text.rb +4 -2
  37. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  38. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/timestamptz.rb +4 -2
  39. data/lib/activerecord-oracle_enhanced-adapter.rb +2 -6
  40. data/spec/active_record/connection_adapters/{oracle_enhanced_emulate_oracle_adapter_spec.rb → emulation/oracle_adapter_spec.rb} +2 -0
  41. data/spec/active_record/connection_adapters/{oracle_enhanced_connection_spec.rb → oracle_enhanced/connection_spec.rb} +82 -38
  42. data/spec/active_record/connection_adapters/{oracle_enhanced_context_index_spec.rb → oracle_enhanced/context_index_spec.rb} +20 -16
  43. data/spec/active_record/connection_adapters/{oracle_enhanced_database_tasks_spec.rb → oracle_enhanced/database_tasks_spec.rb} +17 -5
  44. data/spec/active_record/connection_adapters/{oracle_enhanced_dbms_output_spec.rb → oracle_enhanced/dbms_output_spec.rb} +2 -0
  45. data/spec/active_record/connection_adapters/{oracle_enhanced_procedures_spec.rb → oracle_enhanced/procedures_spec.rb} +26 -33
  46. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +196 -0
  47. data/spec/active_record/connection_adapters/{oracle_enhanced_schema_dump_spec.rb → oracle_enhanced/schema_dumper_spec.rb} +61 -90
  48. data/spec/active_record/connection_adapters/{oracle_enhanced_schema_statements_spec.rb → oracle_enhanced/schema_statements_spec.rb} +95 -28
  49. data/spec/active_record/connection_adapters/{oracle_enhanced_structure_dump_spec.rb → oracle_enhanced/structure_dump_spec.rb} +48 -2
  50. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +202 -331
  51. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +15 -1106
  52. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  53. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +207 -0
  54. data/spec/active_record/{connection_adapters/oracle_enhanced_dirty_spec.rb → oracle_enhanced/type/dirty_spec.rb} +3 -1
  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_helper.rb +15 -1
  64. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  65. metadata +63 -48
  66. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +0 -28
  67. data/lib/active_record/oracle_enhanced/type/json.rb +0 -8
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe "OracleEnhancedAdapter context index" do
2
4
  include SchemaSpecHelper
3
5
  include LoggerSpecHelper
6
+ include SchemaDumpingHelper
4
7
 
5
8
  def create_table_posts
6
9
  schema_define do
@@ -313,13 +316,6 @@ describe "OracleEnhancedAdapter context index" do
313
316
 
314
317
  describe "schema dump" do
315
318
 
316
- def standard_dump
317
- stream = StringIO.new
318
- ActiveRecord::SchemaDumper.ignore_tables = []
319
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
320
- stream.string
321
- end
322
-
323
319
  describe "without table prefixe and suffix" do
324
320
 
325
321
  before(:all) do
@@ -333,13 +329,15 @@ describe "OracleEnhancedAdapter context index" do
333
329
 
334
330
  it "should dump definition of single column index" do
335
331
  @conn.add_context_index :posts, :title
336
- expect(standard_dump).to match(/add_context_index "posts", \["title"\], name: \"index_posts_on_title\"$/)
332
+ output = dump_table_schema "posts"
333
+ expect(output).to match(/add_context_index "posts", \["title"\], name: \"index_posts_on_title\"$/)
337
334
  @conn.remove_context_index :posts, :title
338
335
  end
339
336
 
340
337
  it "should dump definition of multiple column index" do
341
338
  @conn.add_context_index :posts, [:title, :body]
342
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body\]$/)
339
+ output = dump_table_schema "posts"
340
+ expect(output).to match(/add_context_index "posts", \[:title, :body\]$/)
343
341
  @conn.remove_context_index :posts, [:title, :body]
344
342
  end
345
343
 
@@ -352,7 +350,8 @@ describe "OracleEnhancedAdapter context index" do
352
350
  }
353
351
  sub_query = "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
354
352
  @conn.add_context_index :posts, [:title, :body, sub_query], options
355
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body, "#{sub_query}"\], #{options.inspect[1..-2]}$/)
353
+ output = dump_table_schema "posts"
354
+ expect(output).to match(/add_context_index "posts", \[:title, :body, "#{sub_query}"\], #{options.inspect[1..-2]}$/)
356
355
  @conn.remove_context_index :posts, name: "post_and_comments_index"
357
356
  end
358
357
 
@@ -365,7 +364,8 @@ describe "OracleEnhancedAdapter context index" do
365
364
  }
366
365
  sub_query = "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id#{' AND 1=1' * 500}"
367
366
  @conn.add_context_index :posts, [:title, :body, sub_query], options
368
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body, "#{sub_query}"\], #{options.inspect[1..-2]}$/)
367
+ output = dump_table_schema "posts"
368
+ expect(output).to match(/add_context_index "posts", \[:title, :body, "#{sub_query}"\], #{options.inspect[1..-2]}$/)
369
369
  @conn.remove_context_index :posts, name: "post_and_comments_index"
370
370
  end
371
371
 
@@ -378,7 +378,8 @@ describe "OracleEnhancedAdapter context index" do
378
378
  }
379
379
  sub_query = "SELECT comments.author AS comment_author, comments.body AS comment_body\nFROM comments\nWHERE comments.post_id = :id"
380
380
  @conn.add_context_index :posts, [:title, :body, sub_query], options
381
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body, "#{sub_query.gsub(/\n/, ' ')}"\], #{options.inspect[1..-2]}$/)
381
+ output = dump_table_schema "posts"
382
+ expect(output).to match(/add_context_index "posts", \[:title, :body, "#{sub_query.gsub(/\n/, ' ')}"\], #{options.inspect[1..-2]}$/)
382
383
  @conn.remove_context_index :posts, name: "post_and_comments_index"
383
384
  end
384
385
 
@@ -399,13 +400,15 @@ describe "OracleEnhancedAdapter context index" do
399
400
 
400
401
  it "should dump definition of single column index" do
401
402
  schema_define { add_context_index :posts, :title }
402
- expect(standard_dump).to match(/add_context_index "posts", \["title"\], name: "i_xxx_posts_xxx_title"$/)
403
+ output = dump_table_schema "posts"
404
+ expect(output).to match(/add_context_index "posts", \["title"\], name: "i_xxx_posts_xxx_title"$/)
403
405
  schema_define { remove_context_index :posts, :title }
404
406
  end
405
407
 
406
408
  it "should dump definition of multiple column index" do
407
409
  schema_define { add_context_index :posts, [:title, :body] }
408
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body\]$/)
410
+ output = dump_table_schema "posts"
411
+ expect(output).to match(/add_context_index "posts", \[:title, :body\]$/)
409
412
  schema_define { remove_context_index :posts, [:title, :body] }
410
413
  end
411
414
 
@@ -423,8 +426,9 @@ describe "OracleEnhancedAdapter context index" do
423
426
  "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
424
427
  ], options
425
428
  end
426
- expect(standard_dump).to match(/add_context_index "posts", \[:title, :body, "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"\], #{
427
- options.inspect[1..-2].gsub(/[{}]/) { |s| '\\' << s }}$/)
429
+ output = dump_table_schema "posts"
430
+ expect(output).to match(/add_context_index "posts", \[:title, :body, "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"\], #{
431
+ options.inspect[1..-2].gsub(/[{}]/) { |s| '\\'.dup << s }}$/)
428
432
  schema_define { remove_context_index :posts, name: "xxx_post_and_comments_i" }
429
433
  end
430
434
 
@@ -1,8 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record/connection_adapters/oracle_enhanced/database_tasks"
2
4
  require "stringio"
3
5
  require "tempfile"
4
6
 
5
7
  describe "Oracle Enhanced adapter database tasks" do
8
+ include SchemaSpecHelper
9
+
6
10
  let(:config) { CONNECTION_PARAMS.with_indifferent_access }
7
11
 
8
12
  describe "create" do
@@ -17,7 +21,7 @@ describe "Oracle Enhanced adapter database tasks" do
17
21
  expect(ActiveRecord::Base.connection.select_value(query)).to eq(1)
18
22
  end
19
23
  after do
20
- ActiveRecord::Base.connection.execute("DROP USER #{new_user_config[:username]}");
24
+ ActiveRecord::Base.connection.execute("DROP USER #{new_user_config[:username]}")
21
25
  end
22
26
 
23
27
  def fake_terminal(input)
@@ -44,7 +48,11 @@ describe "Oracle Enhanced adapter database tasks" do
44
48
 
45
49
  before do
46
50
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
47
- ActiveRecord::Base.connection.execute "CREATE TABLE test_posts (name VARCHAR2(20))"
51
+ schema_define do
52
+ create_table :test_posts, force: true do |t|
53
+ t.string :name, limit: 20
54
+ end
55
+ end
48
56
  end
49
57
 
50
58
  describe "drop" do
@@ -63,7 +71,7 @@ describe "Oracle Enhanced adapter database tasks" do
63
71
  end
64
72
 
65
73
  describe "structure" do
66
- let(:temp_file) { Tempfile.new(["oracle_enhanced", ".sql"]).path }
74
+ let(:temp_file) { Tempfile.create(["oracle_enhanced", ".sql"]).path }
67
75
  before do
68
76
  ActiveRecord::SchemaMigration.create_table
69
77
  ActiveRecord::Base.connection.execute "INSERT INTO schema_migrations (version) VALUES ('20150101010000')"
@@ -90,11 +98,15 @@ describe "Oracle Enhanced adapter database tasks" do
90
98
  end
91
99
 
92
100
  after do
93
- File.delete(temp_file)
101
+ File.unlink(temp_file)
94
102
  ActiveRecord::SchemaMigration.drop_table
95
103
  end
96
104
  end
97
105
 
98
- after { ActiveRecord::Base.connection.execute "DROP TABLE test_posts" rescue nil }
106
+ after do
107
+ schema_define do
108
+ drop_table :test_posts, if_exists: true
109
+ end
110
+ end
99
111
  end
100
112
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe "OracleEnhancedAdapter logging dbms_output from plsql" do
2
4
  include LoggerSpecHelper
3
5
 
@@ -1,33 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "ruby-plsql"
2
4
 
3
5
  describe "OracleEnhancedAdapter custom methods for create, update and destroy" do
4
6
  include LoggerSpecHelper
7
+ include SchemaSpecHelper
5
8
 
6
9
  before(:all) do
7
10
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
8
11
  @conn = ActiveRecord::Base.connection
9
12
  plsql.activerecord_class = ActiveRecord::Base
10
- @conn.execute("DROP TABLE test_employees") rescue nil
11
- @conn.execute <<-SQL
12
- CREATE TABLE test_employees (
13
- employee_id NUMBER(6,0) PRIMARY KEY,
14
- first_name VARCHAR2(20),
15
- last_name VARCHAR2(25),
16
- hire_date DATE,
17
- salary NUMBER(8,2),
18
- description CLOB,
19
- version NUMBER(15,0),
20
- create_time DATE,
21
- update_time DATE,
22
- created_at DATE,
23
- updated_at DATE
24
- )
25
- SQL
26
- @conn.execute("DROP SEQUENCE test_employees_s") rescue nil
27
- @conn.execute <<-SQL
28
- CREATE SEQUENCE test_employees_s MINVALUE 1
29
- INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
30
- SQL
13
+ schema_define do
14
+ create_table :test_employees, force: true do |t|
15
+ t.string :first_name, limit: 20
16
+ t.string :last_name, limit: 25
17
+ t.date :hire_date
18
+ t.decimal :salary, scale: 2, precision: 8
19
+ t.text :description
20
+ t.decimal :version, scale: 0, precision: 15
21
+ t.date :create_time
22
+ t.date :update_time
23
+ t.timestamps null: true
24
+ end
25
+ end
31
26
  @conn.execute <<-SQL
32
27
  CREATE OR REPLACE PACKAGE test_employees_pkg IS
33
28
  PROCEDURE create_employee(
@@ -59,8 +54,8 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
59
54
  p_employee_id OUT NUMBER)
60
55
  IS
61
56
  BEGIN
62
- SELECT test_employees_s.NEXTVAL INTO p_employee_id FROM dual;
63
- INSERT INTO test_employees (employee_id, first_name, last_name, hire_date, salary, description,
57
+ SELECT test_employees_seq.NEXTVAL INTO p_employee_id FROM dual;
58
+ INSERT INTO test_employees (id, first_name, last_name, hire_date, salary, description,
64
59
  version, create_time, update_time)
65
60
  VALUES (p_employee_id, p_first_name, p_last_name, p_hire_date, p_salary, p_description,
66
61
  1, SYSDATE, SYSDATE);
@@ -76,19 +71,19 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
76
71
  IS
77
72
  v_version NUMBER;
78
73
  BEGIN
79
- SELECT version INTO v_version FROM test_employees WHERE employee_id = p_employee_id FOR UPDATE;
74
+ SELECT version INTO v_version FROM test_employees WHERE id = p_employee_id FOR UPDATE;
80
75
  UPDATE test_employees
81
76
  SET first_name = p_first_name, last_name = p_last_name,
82
77
  hire_date = p_hire_date, salary = p_salary, description = p_description,
83
78
  version = v_version + 1, update_time = SYSDATE
84
- WHERE employee_id = p_employee_id;
79
+ WHERE id = p_employee_id;
85
80
  END update_employee;
86
81
 
87
82
  PROCEDURE delete_employee(
88
83
  p_employee_id NUMBER)
89
84
  IS
90
85
  BEGIN
91
- DELETE FROM test_employees WHERE employee_id = p_employee_id;
86
+ DELETE FROM test_employees WHERE id = p_employee_id;
92
87
  END delete_employee;
93
88
  END;
94
89
  SQL
@@ -97,15 +92,13 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
97
92
 
98
93
  after(:all) do
99
94
  @conn = ActiveRecord::Base.connection
100
- @conn.execute "DROP TABLE test_employees"
101
- @conn.execute "DROP SEQUENCE test_employees_s"
95
+ @conn.drop_table :test_employees, if_exists: true
102
96
  @conn.execute "DROP PACKAGE test_employees_pkg"
103
97
  end
104
98
 
105
99
  before(:each) do
106
100
  class ::TestEmployee < ActiveRecord::Base
107
101
  include ActiveRecord::OracleEnhancedProcedures
108
- self.primary_key = :employee_id
109
102
 
110
103
  validates_presence_of :first_name, :last_name, :hire_date
111
104
 
@@ -255,7 +248,7 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
255
248
  empl_id = @employee.id
256
249
  @employee.destroy
257
250
  expect(@employee).to be_frozen
258
- expect(TestEmployee.find_by_employee_id(empl_id)).to be_nil
251
+ expect(TestEmployee.find_by_id(empl_id)).to be_nil
259
252
  end
260
253
 
261
254
  it "should delete record and set destroyed flag" do
@@ -284,7 +277,7 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
284
277
  @employee.destroy
285
278
  }.to raise_error("Make the transaction rollback")
286
279
  expect(@employee.id).to eq(empl_id)
287
- expect(TestEmployee.find_by_employee_id(empl_id)).not_to be_nil
280
+ expect(TestEmployee.find_by_id(empl_id)).not_to be_nil
288
281
  clear_logger
289
282
  end
290
283
 
@@ -333,7 +326,7 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
333
326
  )
334
327
  set_logger
335
328
  @employee.save!
336
- expect(@logger.logged(:debug).last).to match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with employee_id=#{@employee.id}$/)
329
+ expect(@logger.logged(:debug).last).to match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with id=#{@employee.id}$/)
337
330
  clear_logger
338
331
  end
339
332
 
@@ -345,7 +338,7 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
345
338
  )
346
339
  set_logger
347
340
  @employee.destroy
348
- expect(@logger.logged(:debug).last).to match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with employee_id=#{@employee.id}$/)
341
+ expect(@logger.logged(:debug).last).to match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with id=#{@employee.id}$/)
349
342
  clear_logger
350
343
  end
351
344
 
@@ -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